Μετάβαση στο περιεχόμενο
Κλήση συναρτήσεων

Κλήση συναρτήσεων

Περιγράψτε τις συναρτήσεις σας στο αίτημα και το μοντέλο απαντά με τις κλήσεις που θέλει να γίνουν. Ο κώδικάς σας τις εκτελεί και στέλνει πίσω τα αποτελέσματα: το API επιστρέφει κλήσεις εργαλείων και δεν εκτελεί το ίδιο κανένα εργαλείο.

POST https://api.shannon-ai.com/v1/chat/completions

Τα παραδείγματα σε αυτή τη σελίδα χρησιμοποιούν το /v1/chat/completions. Ο ίδιος βρόχος λειτουργεί στα /v1/responses και /v1/messages· όπου μια μορφή γράφει κάτι διαφορετικά, οι ενότητες παρακάτω δείχνουν και τις τρεις.

import json
from openai import OpenAI

client = OpenAI(api_key="YOUR_API_KEY", base_url="https://api.shannon-ai.com/v1")

tools = [{
    "type": "function",
    "function": {
        "name": "get_weather",
        "description": "Get the current weather for a city.",
        "parameters": {
            "type": "object",
            "properties": {
                "city": {"type": "string", "description": "City name, for example Paris"},
                "unit": {"type": "string", "enum": ["celsius", "fahrenheit"]},
            },
            "required": ["city"],
        },
    },
}]

def get_weather(city, unit="celsius"):
    # Your code: ask a weather service here.
    return {"city": city, "temperature": 18, "unit": unit, "conditions": "cloudy"}

messages = [{"role": "user", "content": "What is the weather in Paris right now?"}]
answer = None

for _ in range(5):  # the API sets no limit on rounds: set your own
    response = client.chat.completions.create(
        model="Kimi-K3-3BIT-REAP",
        messages=messages,
        tools=tools,
    )
    choice = response.choices[0]
    if choice.finish_reason != "tool_calls":
        answer = choice.message.content
        break

    messages.append(choice.message)  # the assistant turn with its tool_calls
    for call in choice.message.tool_calls:
        args = json.loads(call.function.arguments)  # arguments is a JSON string
        result = get_weather(**args)
        messages.append({
            "role": "tool",
            "tool_call_id": call.id,
            "content": json.dumps(result),
        })

print(answer)

Η πρώτη απάντηση δεν απαντά στην ερώτηση. Ζητά μια κλήση:

200 JSON
{
  "id": "chatcmpl-5b0c1d8e7f6a4b3c9d2e1f0a8b7c6d5e",
  "object": "chat.completion",
  "created": 1791590400,
  "model": "Kimi-K3-3BIT-REAP",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": null,
        "reasoning_content": "The user asks for the current weather in Paris. I should call get_weather.",
        "tool_calls": [
          {
            "id": "call_9f1c2ab34d5e4f60a7b8c9d0e1f2a3b4",
            "type": "function",
            "function": {
              "name": "get_weather",
              "arguments": "{\"city\":\"Paris\"}"
            }
          }
        ]
      },
      "finish_reason": "tool_calls"
    }
  ],
  "usage": {
    "prompt_tokens": 312,
    "completion_tokens": 58,
    "total_tokens": 370,
    "prompt_tokens_details": {"cached_tokens": 0},
    "completion_tokens_details": {"reasoning_tokens": 31}
  }
}

Αφού στείλετε το αποτέλεσμα, η επόμενη απάντηση είναι συνηθισμένη: το message.content περιέχει το κείμενο και το finish_reason είναι stop.

Ο βρόχος, βήμα προς βήμα

Βήμα Ποιος Τι συμβαίνει
1 Εσείς Στείλτε τα messages μαζί με τα tools, τη λίστα των συναρτήσεων που μπορεί να ζητήσει το μοντέλο.
2 Μοντέλο Η απάντηση φέρει tool_calls και finish_reason: "tool_calls". Κάθε κλήση ονομάζει μια συνάρτηση και δίνει τα ορίσματά της.
3 Εσείς Κάντε parse τα arguments κάθε κλήσης και εκτελέστε τη συνάρτησή σας.
4 Εσείς Προσθέστε στα messages το μήνυμα του assistant και ένα μήνυμα tool για κάθε κλήση, και στείλτε ξανά το αίτημα με τα ίδια tools.
5 Μοντέλο Το μοντέλο απαντά με κείμενο και finish_reason: "stop", ή ζητά κι άλλες κλήσεις. Στη δεύτερη περίπτωση γυρίστε στο βήμα 3.

Ένα αίτημα είναι ένας γύρος του μοντέλου. Το API δεν κρατά συνομιλία ανάμεσα στα αιτήματα και δεν ορίζει αριθμό γύρων: ο κώδικάς σας κρατά τα messages και αποφασίζει πότε θα σταματήσει.

Ορισμός εργαλείων

Το tools είναι πίνακας με μία εγγραφή ανά συνάρτηση. Το δέχεται κάθε μοντέλο του καταλόγου· το GET /v1/models αναφέρει capabilities.tools: true για κάθε id.

Πεδίο Τύπος Περιγραφή
type string Πάντα function.
function.name string Το όνομα που χρησιμοποιεί το μοντέλο όταν ζητά αυτή τη συνάρτηση. Υποχρεωτικό.
function.description string Τι κάνει η συνάρτηση, σε απλή γλώσσα.
function.parameters object Τα ορίσματα ως JSON Schema με type: "object" στην κορυφή. Δείτε Λέξεις-κλειδιά του schema παρακάτω.

Κάθε endpoint έχει τη δική του γραφή για ένα εργαλείο. Στείλτε αυτή που ανήκει στο endpoint που καλείτε:

{
  "type": "function",
  "function": {
    "name": "get_weather",
    "description": "Get the current weather for a city.",
    "parameters": {
      "type": "object",
      "properties": {
        "city": {
          "type": "string",
          "description": "City name, for example Paris"
        },
        "unit": {"type": "string", "enum": ["celsius", "fahrenheit"]}
      },
      "required": ["city"]
    }
  }
}

tool_choice

Το tool_choice ορίζει αν το μοντέλο μπορεί ή πρέπει να καλέσει εργαλείο. Διαβάζεται μόνο μαζί με το tools.

Τιμή Περιγραφή Εφαρμόζεται από
"auto" Το μοντέλο αποφασίζει αν θα απαντήσει με κείμενο ή αν θα καλέσει εργαλείο. Αυτή είναι η προεπιλογή. Όλα τα μοντέλα
"required" Η απάντηση καλεί τουλάχιστον ένα εργαλείο. Φιλοξενούμενα μοντέλα ανοιχτών βαρών
{"type": "function", "function": {"name": "get_weather"}} Η απάντηση καλεί αυτή τη συνάρτηση. Το όνομα πρέπει να είναι μία από τις συναρτήσεις του tools. Οι κλήσεις άλλων συναρτήσεων παραλείπονται από την απάντηση. Φιλοξενούμενα μοντέλα ανοιχτών βαρών

Τα μοντέλα Shannon (shannon-*) αποφασίζουν σε κάθε αίτημα, όπως με το auto.

Με required ή με συνάρτηση που ορίζεται με όνομα, διαβάστε το finish_reason πριν διαβάσετε το tool_calls. Όταν το μοντέλο δεν παράγει κλήση, η απάντηση είναι κείμενο με finish_reason: "stop".

Σημασία /v1/chat/completions /v1/responses /v1/messages
Το μοντέλο αποφασίζει "auto" "auto" {"type": "auto"}
Κλήση τουλάχιστον ενός εργαλείου "required" "required" {"type": "any"}
Κλήση μιας συγκεκριμένης συνάρτησης {"type": "function", "function": {"name": "get_weather"}} {"type": "function", "name": "get_weather"} {"type": "tool", "name": "get_weather"}

Γίνονται δεκτά για συμβατότητα: tool_choice: "none" και parallel_tool_calls. Για γύρο χωρίς κλήσεις εργαλείων, στείλτε το αίτημα χωρίς tools.

Κλήσεις εργαλείων στην απάντηση

Πεδίο Τύπος Περιγραφή
finish_reason string tool_calls όταν η απάντηση φέρει τουλάχιστον μία κλήση.
message.tool_calls array Μία εγγραφή ανά κλήση. Το πεδίο υπάρχει μόνο όταν το μοντέλο ζήτησε κλήση.
tool_calls[].id string call_ ακολουθούμενο από 32 δεκαεξαδικούς χαρακτήρες. Στείλτε το πίσω ως tool_call_id μαζί με το αποτέλεσμα.
tool_calls[].type string Πάντα function.
tool_calls[].function.name string Η συνάρτηση που θα εκτελεστεί.
tool_calls[].function.arguments string Τα ορίσματα ως string JSON, "{}" όταν δεν υπάρχουν. Κάντε parse πριν από τη χρήση.
message.content string | null null όταν η απάντηση περιέχει μόνο κλήσεις. Τα φιλοξενούμενα μοντέλα ανοιχτών βαρών μπορούν να επιστρέψουν κείμενο δίπλα στις κλήσεις· τα μοντέλα Shannon επιστρέφουν null.

Η ίδια κλήση σε κάθε μορφή. Στο /v1/responses είναι ένα στοιχείο function_call του output, με τα arguments ως string JSON. Στο /v1/messages είναι ένα block περιεχομένου tool_use με input αντικείμενο JSON, το id του αρχίζει με toolu_ και το stop_reason είναι tool_use.

{
  "finish_reason": "tool_calls",
  "message": {
    "role": "assistant",
    "content": null,
    "tool_calls": [
      {
        "id": "call_9f1c2ab34d5e4f60a7b8c9d0e1f2a3b4",
        "type": "function",
        "function": {
          "name": "get_weather",
          "arguments": "{\"city\":\"Paris\"}"
        }
      }
    ]
  }
}

Πολλές κλήσεις σε έναν γύρο

Μια απάντηση μπορεί να φέρει πολλές κλήσεις. Εκτελέστε όλες και στείλτε ένα αποτέλεσμα ανά κλήση, καθένα με το δικό του tool_call_id, στο επόμενο αίτημα.

Τα φιλοξενούμενα μοντέλα ανοιχτών βαρών επιστρέφουν κάθε διακριτή κλήση μία φορά: δύο κλήσεις με το ίδιο όνομα και τα ίδια ορίσματα φτάνουν ως μία.

Κλήσεις εργαλείων με streaming

Με stream: true, μια κλήση φτάνει σε ένα κομμάτι: το chunk περιέχει ολόκληρο το string arguments, οπότε δεν υπάρχουν θραύσματα για συνένωση. Το index μετρά τις κλήσεις του γύρου από το 0.

data: ένα chunk, μορφοποιημένο
{
  "id": "chatcmpl-5b0c1d8e7f6a4b3c9d2e1f0a8b7c6d5e",
  "object": "chat.completion.chunk",
  "created": 1791590400,
  "model": "Kimi-K3-3BIT-REAP",
  "choices": [
    {
      "index": 0,
      "delta": {
        "tool_calls": [
          {
            "index": 0,
            "id": "call_9f1c2ab34d5e4f60a7b8c9d0e1f2a3b4",
            "type": "function",
            "function": {
              "name": "get_weather",
              "arguments": "{\"city\":\"Paris\"}"
            }
          }
        ]
      },
      "finish_reason": null
    }
  ]
}
Endpoint Τι φτάνει
/v1/chat/completions Ένα chat.completion.chunk ανά κλήση, με την κλήση στο delta.tool_calls[0]. Το τελευταίο chunk έχει finish_reason: "tool_calls" και usage.
/v1/responses Ανά κλήση: response.output_item.added (στοιχείο function_call με κενά arguments), response.function_call_arguments.delta (ολόκληρο το string), response.function_call_arguments.done, response.output_item.done.
/v1/messages Ανά κλήση: content_block_start (block tool_use με κενό input), ένα content_block_delta του οποίου το input_json_delta.partial_json είναι ολόκληρο το κείμενο των ορισμάτων, content_block_stop. Έπειτα το message_delta φέρει stop_reason: "tool_use".

Στα shannon-1.6-lite, shannon-1.6-pro, shannon-2-lite, shannon-2-pro και shannon-coder-1, ένα αίτημα με streaming που φέρει tools παραδίδει το κείμενο της απάντησης σε ένα μόνο delta content στο τέλος του γύρου. Ροή

Αποστολή αποτελεσμάτων πίσω

Το δεύτερο αίτημα επαναλαμβάνει τη συνομιλία και προσθέτει δύο πράγματα: τον γύρο του assistant που ζήτησε τις κλήσεις και ένα αποτέλεσμα ανά κλήση.

{
  "messages": [
    {"role": "user", "content": "What is the weather in Paris right now?"},
    {
      "role": "assistant",
      "content": null,
      "tool_calls": [
        {
          "id": "call_9f1c2ab34d5e4f60a7b8c9d0e1f2a3b4",
          "type": "function",
          "function": {
            "name": "get_weather",
            "arguments": "{\"city\":\"Paris\"}"
          }
        }
      ]
    },
    {
      "role": "tool",
      "tool_call_id": "call_9f1c2ab34d5e4f60a7b8c9d0e1f2a3b4",
      "content": "{\"city\":\"Paris\",\"temperature\":18,\"unit\":\"celsius\",\"conditions\":\"cloudy\"}"
    }
  ]
}
  • Στείλτε τον γύρο του assistant πίσω όπως τον λάβατε, πριν από τα αποτελέσματα. Κάθε αποτέλεσμα αντιστοιχίζεται στην κλήση του με το id: tool_call_id στο /v1/chat/completions, call_id στο /v1/responses, tool_use_id στο /v1/messages.
  • Ένα αποτέλεσμα είναι κείμενο. Σειριοποιήστε ένα αντικείμενο σε string JSON για το content (output στο /v1/responses). Στο /v1/messages το content ενός block tool_result είναι string ή λίστα από blocks κειμένου.
  • Στον γύρο του assistant, το function.arguments παραμένει string JSON, ακριβώς όπως έφτασε.
  • Η συνομιλία μπορεί να τελειώνει με αποτέλεσμα εργαλείου. Δεν χρειάζεται νέο μήνυμα χρήστη: το μοντέλο συνεχίζει από το αποτέλεσμα.
  • Όταν η συνάρτησή σας αποτύχει, στείλτε την αποτυχία ως κείμενο αποτελέσματος. Το μοντέλο μπορεί τότε να την αναφέρει ή να ζητήσει άλλη κλήση.

Λέξεις-κλειδιά του schema

Το parameters (input_schema στο /v1/messages) είναι ένα JSON Schema. Η οικογένεια Shannon 3 (shannon-3, shannon-3-pro, shannon-3.1, shannon-3.1-pro) και τα φιλοξενούμενα μοντέλα ανοιχτών βαρών το λαμβάνουν όπως το στέλνετε.

Τα shannon-1.6-lite, shannon-1.6-pro, shannon-2-lite, shannon-2-pro και shannon-coder-1 λαμβάνουν αυτό το υποσύνολο, και στα τρία endpoints:

Χειρισμός Λέξεις-κλειδιά
Διαβάζεται όπως στάλθηκε Κάθε λέξη-κλειδί που δεν αναφέρεται στις παρακάτω γραμμές, για παράδειγμα type, properties, required, items, enum, description, minimum, maximum, anyOf και allOf, σε κάθε επίπεδο του schema.
format Διαβάζεται για τις τιμές int32, int64, float, double, byte, date, date-time και enum.
oneOf Διαβάζεται ως anyOf.
Δεν ανήκει στο schema που λαμβάνουν αυτά τα μοντέλα $schema, $id, $ref, $defs, $comment, definitions, additionalProperties, unevaluatedProperties, patternProperties, propertyNames, examples, default, title, const, not, if, then, else, contains, minContains, maxContains, dependentRequired, dependentSchemas, dependencies, readOnly, writeOnly, deprecated, contentEncoding, contentMediaType, contentSchema, multipleOf, uniqueItems· τα exclusiveMinimum και exclusiveMaximum όταν είναι αριθμοί· άλλες τιμές του format.

Συμπεριφορά και όρια

  • Το API δεν ορίζει μέγιστο αριθμό εργαλείων ούτε μέγιστο αριθμό γύρων.
  • Το σώμα ενός αιτήματος μπορεί να φτάσει τα 32 MiB, και η συνομιλία μαζί με τα αποτελέσματα πρέπει να χωράει στο παράθυρο συμφραζομένων του μοντέλου.
  • Όταν ένα αίτημα φέρει tools, τα shannon-1.6-lite, shannon-1.6-pro, shannon-2-lite και shannon-2-pro χρησιμοποιούν προεπιλεγμένη temperature 0.2. Στείλτε temperature για να ορίσετε άλλη τιμή.
  • Κάθε γύρος είναι ξεχωριστό αίτημα: αφαιρεί από το υπόλοιπό σας και προσμετράται στην προστασία από υπερφόρτωση όπως κάθε άλλο αίτημα. Όρια και υπόλοιπο

Σφάλματα

Μια κλήση εργαλείου είναι κανονική απάντηση με κατάσταση 200. Αυτά τα σφάλματα αφορούν το ίδιο το αίτημα:

Κατάσταση Τύπος Μήνυμα Πότε
400 invalid_request_error unknown model: <id> Το model δεν είναι id της δημοσιευμένης λίστας.
422 invalid_request_error Failed to deserialize the JSON body into the target type: … Το tools δεν είναι πίνακας ή κάποιο άλλο πεδίο έχει λάθος τύπο JSON.
413 invalid_request_error Failed to buffer the request body: … Το σώμα του αιτήματος είναι μεγαλύτερο από 32 MiB. Το σφάλμα φέρει code: "request_too_large".

Τα ορίσματα τα γράφει το μοντέλο. Ελέγξτε τα με βάση το schema σας πριν εκτελέσετε τη συνάρτηση, όπως θα ελέγχατε οποιαδήποτε εξωτερική είσοδο.

Τα σφάλματα ταυτοποίησης, υπολοίπου και διακομιστή είναι ίδια με κάθε άλλο αίτημα. Χειρισμός σφαλμάτων