Funktionsaufrufe
Beschreiben Sie Ihre Funktionen in der Anfrage, und das Modell antwortet mit den Aufrufen, die ausgeführt werden sollen. Ihr Code führt sie aus und sendet die Ergebnisse zurück: Die API liefert Tool-Aufrufe und führt selbst kein Tool aus.
POST https://api.shannon-ai.com/v1/chat/completions
Die Beispiele auf dieser Seite verwenden /v1/chat/completions. Dieselbe Schleife läuft bei /v1/responses und /v1/messages; wo ein Format etwas anders schreibt, zeigen die Abschnitte unten alle drei.
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) import OpenAI from "openai";
const client = new OpenAI({ apiKey: "YOUR_API_KEY", baseURL: "https://api.shannon-ai.com/v1" });
const 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"],
},
},
}];
// Your code: ask a weather service here.
function getWeather({ city, unit = "celsius" }) {
return { city, temperature: 18, unit, conditions: "cloudy" };
}
const messages = [{ role: "user", content: "What is the weather in Paris right now?" }];
let answer = null;
// The API sets no limit on rounds: set your own.
for (let round = 0; round < 5; round++) {
const response = await client.chat.completions.create({
model: "Kimi-K3-3BIT-REAP",
messages,
tools,
});
const choice = response.choices[0];
if (choice.finish_reason !== "tool_calls") {
answer = choice.message.content;
break;
}
messages.push(choice.message); // the assistant turn with its tool_calls
for (const call of choice.message.tool_calls) {
const args = JSON.parse(call.function.arguments); // arguments is a JSON string
messages.push({
role: "tool",
tool_call_id: call.id,
content: JSON.stringify(getWeather(args)),
});
}
}
console.log(answer); # 1. Send the conversation with the tools.
curl https://api.shannon-ai.com/v1/chat/completions \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "Kimi-K3-3BIT-REAP",
"messages": [
{"role": "user", "content": "What is the weather in Paris right now?"}
],
"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"]
}
}
}]
}'
# 2. Run the function yourself, then send the assistant turn and the result.
# Use the id of the call you received.
curl https://api.shannon-ai.com/v1/chat/completions \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "Kimi-K3-3BIT-REAP",
"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\"}"}
],
"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"]
}
}
}]
}' Die erste Antwort beantwortet die Frage nicht. Sie fordert einen Aufruf an:
{
"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}
}
} Nachdem Sie das Ergebnis gesendet haben, ist die nächste Antwort eine gewöhnliche Antwort: message.content enthält den Text, und finish_reason ist stop.
Die Schleife, Schritt für Schritt
| Schritt | Wer | Was passiert |
|---|---|---|
| 1 | Sie | Senden Sie messages zusammen mit tools, der Liste der Funktionen, die das Modell anfordern darf. |
| 2 | Modell | Die Antwort enthält tool_calls und finish_reason: "tool_calls". Jeder Aufruf nennt eine Funktion und gibt deren Argumente an. |
| 3 | Sie | Parsen Sie die arguments jedes Aufrufs und führen Sie Ihre Funktion aus. |
| 4 | Sie | Hängen Sie die Assistant-Nachricht und eine tool-Nachricht pro Aufruf an messages an und senden Sie die Anfrage dann erneut mit denselben tools. |
| 5 | Modell | Das Modell antwortet mit Text und finish_reason: "stop" oder fordert weitere Aufrufe an. In diesem Fall gehen Sie zurück zu Schritt 3. |
Eine Anfrage ist ein Modell-Turn. Die API speichert zwischen Anfragen keine Konversation und legt keine Rundenzahl fest: Ihr Code hält messages und entscheidet, wann er aufhört.
Tools definieren
tools ist ein Array mit einem Eintrag pro Funktion. Jedes Modell des Katalogs akzeptiert es; GET /v1/models meldet für jede ID capabilities.tools: true.
| Feld | Typ | Beschreibung |
|---|---|---|
type | string | Immer function. |
function.name | string | Der Name, den das Modell verwendet, wenn es diese Funktion anfordert. Erforderlich. |
function.description | string | Was die Funktion tut, in einfacher Sprache. |
function.parameters | object | Die Argumente als JSON-Schema mit type: "object" auf oberster Ebene. Siehe Schema-Schlüsselwörter weiter unten. |
Jeder Endpunkt hat seine eigene Schreibweise für ein Tool. Senden Sie die, die zum Endpunkt gehört, den Sie aufrufen:
{
"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"]
}
}
} {
"type": "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"]
}
} {
"name": "get_weather",
"description": "Get the current weather for a city.",
"input_schema": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "City name, for example Paris"
},
"unit": {"type": "string", "enum": ["celsius", "fahrenheit"]}
},
"required": ["city"]
}
} tool_choice
tool_choice legt fest, ob das Modell ein Tool aufrufen darf oder muss. Es wird nur zusammen mit tools gelesen.
| Wert | Beschreibung | Angewendet von |
|---|---|---|
"auto" | Das Modell entscheidet, ob es mit Text antwortet oder ein Tool aufruft. Dies ist der Standard. | Alle Modelle |
"required" | Die Antwort ruft mindestens ein Tool auf. | Gehostete Open-Weight-Modelle |
{"type": "function", "function": {"name": "get_weather"}} | Die Antwort ruft diese Funktion auf. Der Name muss eine der Funktionen in tools sein. Aufrufe anderer Funktionen werden aus der Antwort weggelassen. | Gehostete Open-Weight-Modelle |
Die Shannon-Modelle (shannon-*) entscheiden bei jeder Anfrage selbst, wie bei auto.
Lesen Sie bei required oder einer benannten Funktion finish_reason, bevor Sie tool_calls lesen. Erzeugt das Modell keinen Aufruf, ist die Antwort ein Text mit finish_reason: "stop".
| Bedeutung | /v1/chat/completions | /v1/responses | /v1/messages |
|---|---|---|---|
| Das Modell entscheidet | "auto" | "auto" | {"type": "auto"} |
| Mindestens ein Tool aufrufen | "required" | "required" | {"type": "any"} |
| Eine benannte Funktion aufrufen | {"type": "function", "function": {"name": "get_weather"}} | {"type": "function", "name": "get_weather"} | {"type": "tool", "name": "get_weather"} |
Aus Kompatibilitätsgründen akzeptiert: tool_choice: "none" und parallel_tool_calls. Für einen Turn ohne Tool-Aufrufe senden Sie die Anfrage ohne tools.
Tool-Aufrufe in der Antwort
| Feld | Typ | Beschreibung |
|---|---|---|
finish_reason | string | tool_calls, wenn die Antwort mindestens einen Aufruf enthält. |
message.tool_calls | array | Ein Eintrag pro Aufruf. Das Feld ist nur vorhanden, wenn das Modell einen Aufruf angefordert hat. |
tool_calls[].id | string | call_ gefolgt von 32 hexadezimalen Zeichen. Senden Sie sie mit dem Ergebnis als tool_call_id zurück. |
tool_calls[].type | string | Immer function. |
tool_calls[].function.name | string | Die Funktion, die ausgeführt werden soll. |
tool_calls[].function.arguments | string | Die Argumente als JSON-String, "{}", wenn es keine gibt. Parsen Sie ihn vor der Verwendung. |
message.content | string | null | null, wenn die Antwort nur Aufrufe enthält. Die gehosteten Open-Weight-Modelle können neben den Aufrufen Text zurückgeben; die Shannon-Modelle geben null zurück. |
Derselbe Aufruf in jedem Format. Bei /v1/responses ist er ein Element function_call in output, mit arguments als JSON-String. Bei /v1/messages ist er ein Content-Block tool_use, dessen input ein JSON-Objekt ist, dessen id mit toolu_ beginnt und dessen stop_reason tool_use ist.
{
"finish_reason": "tool_calls",
"message": {
"role": "assistant",
"content": null,
"tool_calls": [
{
"id": "call_9f1c2ab34d5e4f60a7b8c9d0e1f2a3b4",
"type": "function",
"function": {
"name": "get_weather",
"arguments": "{\"city\":\"Paris\"}"
}
}
]
}
} {
"output": [
{
"id": "fc_3d2c1b0a9f8e4d7c6b5a4f3e2d1c0b9a",
"type": "function_call",
"call_id": "call_9f1c2ab34d5e4f60a7b8c9d0e1f2a3b4",
"name": "get_weather",
"arguments": "{\"city\":\"Paris\"}",
"status": "completed"
}
]
} {
"stop_reason": "tool_use",
"content": [
{
"type": "tool_use",
"id": "toolu_9f1c2ab34d5e4f60a7b8c9d0e1f2a3b4",
"name": "get_weather",
"input": {"city": "Paris"}
}
]
} Mehrere Aufrufe in einem Turn
Eine Antwort kann mehrere Aufrufe enthalten. Führen Sie jeden davon aus und senden Sie in der nächsten Anfrage ein Ergebnis pro Aufruf, jeweils mit seiner eigenen tool_call_id.
Die gehosteten Open-Weight-Modelle geben jeden verschiedenen Aufruf einmal zurück: Zwei Aufrufe mit demselben Namen und denselben Argumenten kommen als einer an.
Gestreamte Tool-Aufrufe
Mit stream: true trifft ein Aufruf in einem Stück ein: Der Chunk enthält den vollständigen arguments-String, sodass keine Fragmente zusammenzufügen sind. index zählt die Aufrufe des Turns ab 0.
{
"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
}
]
} | Endpunkt | Was eintrifft |
|---|---|
/v1/chat/completions | Ein chat.completion.chunk pro Aufruf, mit dem Aufruf in delta.tool_calls[0]. Der letzte Chunk hat finish_reason: "tool_calls" und usage. |
/v1/responses | Pro Aufruf: response.output_item.added (ein Element function_call mit leeren arguments), response.function_call_arguments.delta (der gesamte String), response.function_call_arguments.done, response.output_item.done. |
/v1/messages | Pro Aufruf: content_block_start (ein tool_use-Block mit leerem input), ein content_block_delta, dessen input_json_delta.partial_json der gesamte Argumenttext ist, content_block_stop. message_delta enthält dann stop_reason: "tool_use". |
Bei shannon-1.6-lite, shannon-1.6-pro, shannon-2-lite, shannon-2-pro und shannon-coder-1 liefert eine gestreamte Anfrage mit tools ihren Antworttext am Ende des Turns in einem einzigen content-Delta. Streaming
Ergebnisse zurücksenden
Die zweite Anfrage wiederholt die Konversation und fügt zwei Dinge hinzu: den Assistant-Turn, der die Aufrufe angefordert hat, und ein Ergebnis pro Aufruf.
{
"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\"}"
}
]
} {
"input": [
{"role": "user", "content": "What is the weather in Paris right now?"},
{
"type": "function_call",
"call_id": "call_9f1c2ab34d5e4f60a7b8c9d0e1f2a3b4",
"name": "get_weather",
"arguments": "{\"city\":\"Paris\"}"
},
{
"type": "function_call_output",
"call_id": "call_9f1c2ab34d5e4f60a7b8c9d0e1f2a3b4",
"output": "{\"city\":\"Paris\",\"temperature\":18,\"unit\":\"celsius\",\"conditions\":\"cloudy\"}"
}
]
} {
"messages": [
{"role": "user", "content": "What is the weather in Paris right now?"},
{
"role": "assistant",
"content": [
{
"type": "tool_use",
"id": "toolu_9f1c2ab34d5e4f60a7b8c9d0e1f2a3b4",
"name": "get_weather",
"input": {"city": "Paris"}
}
]
},
{
"role": "user",
"content": [
{
"type": "tool_result",
"tool_use_id": "toolu_9f1c2ab34d5e4f60a7b8c9d0e1f2a3b4",
"content": "{\"city\":\"Paris\",\"temperature\":18,\"unit\":\"celsius\",\"conditions\":\"cloudy\"}"
}
]
}
]
} - Senden Sie den Assistant-Turn so zurück, wie Sie ihn erhalten haben, vor den Ergebnissen. Jedes Ergebnis wird seinem Aufruf über die ID zugeordnet:
tool_call_idbei/v1/chat/completions,call_idbei/v1/responses,tool_use_idbei/v1/messages. - Ein Ergebnis ist Text. Serialisieren Sie ein Objekt für
contentzu einem JSON-String (outputbei/v1/responses). Bei/v1/messagesist dercontenteinestool_result-Blocks ein String oder eine Liste von Textblöcken. - Im Assistant-Turn bleibt
function.argumentsein JSON-String, genau so, wie er eingetroffen ist. - Die Konversation darf mit einem Tool-Ergebnis enden. Eine neue User-Nachricht ist nicht nötig: Das Modell macht mit dem Ergebnis weiter.
- Schlägt Ihre Funktion fehl, senden Sie den Fehler als Ergebnistext. Das Modell kann ihn dann melden oder einen weiteren Aufruf anfordern.
Schema-Schlüsselwörter
parameters (input_schema bei /v1/messages) ist ein JSON-Schema. Die Shannon-3-Familie (shannon-3, shannon-3-pro, shannon-3.1, shannon-3.1-pro) und die gehosteten Open-Weight-Modelle erhalten es so, wie Sie es senden.
shannon-1.6-lite, shannon-1.6-pro, shannon-2-lite, shannon-2-pro und shannon-coder-1 erhalten diese Teilmenge, an allen drei Endpunkten:
| Behandlung | Schlüsselwörter |
|---|---|
| Wie gesendet gelesen | Jedes Schlüsselwort, das nicht in den Zeilen unten genannt ist, zum Beispiel type, properties, required, items, enum, description, minimum, maximum, anyOf und allOf, auf jeder Ebene des Schemas. |
format | Wird für die Werte int32, int64, float, double, byte, date, date-time und enum gelesen. |
oneOf | Wird als anyOf gelesen. |
| Nicht Teil des Schemas, das diese Modelle erhalten | $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 und exclusiveMaximum, wenn sie Zahlen sind; andere Werte von format. |
Verhalten und Limits
- Die API legt keine maximale Anzahl an Tools und keine maximale Anzahl an Runden fest.
- Ein Request-Body darf bis zu 32 MiB groß sein, und die Konversation mit ihren Ergebnissen muss in das Kontextfenster des Modells passen.
- Enthält eine Anfrage
tools, verwendenshannon-1.6-lite,shannon-1.6-pro,shannon-2-liteundshannon-2-proeine Standard-temperaturevon 0.2. Senden Sietemperature, um einen anderen Wert zu setzen. - Jede Runde ist eine eigene Anfrage: Sie zieht von Ihrem Guthaben ab und zählt wie jede andere Anfrage für den Flood-Schutz. Limits und Guthaben
Fehler
Ein Tool-Aufruf ist eine normale Antwort mit Status 200. Diese Fehler betreffen die Anfrage selbst:
| Status | Typ | Nachricht | Wann |
|---|---|---|---|
400 | invalid_request_error | unknown model: <id> | model ist keine ID der veröffentlichten Liste. |
422 | invalid_request_error | Failed to deserialize the JSON body into the target type: … | tools ist kein Array, oder ein anderes Feld hat den falschen JSON-Typ. |
413 | invalid_request_error | Failed to buffer the request body: … | Der Request-Body ist größer als 32 MiB. Der Fehler enthält code: "request_too_large". |
Das Modell schreibt die Argumente. Prüfen Sie sie anhand Ihres Schemas, bevor Sie die Funktion ausführen, wie Sie jede externe Eingabe prüfen würden.
Authentifizierungs-, Guthaben- und Serverfehler sind dieselben wie bei jeder Anfrage. Fehlerbehandlung