Funktionskald
Beskriv dine funktioner i anmodningen, og modellen svarer med de kald, den vil have udført. Din kode kører dem og sender resultaterne tilbage: API'et returnerer værktøjskald og kører ikke selv et værktøj.
POST https://api.shannon-ai.com/v1/chat/completions
Eksemplerne på denne side bruger /v1/chat/completions. Den samme løkke kører på /v1/responses og /v1/messages; hvor et format staver noget anderledes, viser afsnittene nedenfor alle tre.
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"]
}
}
}]
}' Det første svar besvarer ikke spørgsmålet. Det beder om et kald:
{
"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}
}
} Når du har sendt resultatet, er det næste svar et almindeligt svar: message.content indeholder teksten, og finish_reason er stop.
Løkken, trin for trin
| Trin | Hvem | Hvad der sker |
|---|---|---|
| 1 | Dig | Send messages sammen med tools, listen over de funktioner, modellen må bede om. |
| 2 | Model | Svaret indeholder tool_calls og finish_reason: "tool_calls". Hvert kald nævner en funktion og angiver dens argumenter. |
| 3 | Dig | Parse arguments for hvert kald, og kør din funktion. |
| 4 | Dig | Føj assistentbeskeden og én tool-besked per kald til messages, og send derefter anmodningen igen med de samme tools. |
| 5 | Model | Modellen svarer med tekst og finish_reason: "stop" eller beder om flere kald. I så fald gå tilbage til trin 3. |
Én anmodning er én modeltur. API'et gemmer ingen samtale mellem anmodninger og fastsætter intet antal runder: din kode holder messages og afgør, hvornår den stopper.
Definition af værktøjer
tools er et array med én post per funktion. Alle modeller i kataloget accepterer det; GET /v1/models rapporterer capabilities.tools: true for hvert id.
| Felt | Type | Beskrivelse |
|---|---|---|
type | string | Altid function. |
function.name | string | Det navn, modellen bruger, når den beder om denne funktion. Påkrævet. |
function.description | string | Hvad funktionen gør, i almindeligt sprog. |
function.parameters | object | Argumenterne som et JSON Schema med type: "object" øverst. Se Skemanøgleord nedenfor. |
Hvert endpoint har sin egen stavemåde for et værktøj. Send den, der hører til det endpoint, du kalder:
{
"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 angiver, om modellen må eller skal kalde et værktøj. Det læses kun sammen med tools.
| Værdi | Beskrivelse | Anvendes af |
|---|---|---|
"auto" | Modellen afgør, om den vil svare med tekst eller kalde et værktøj. Dette er standarden. | Alle modeller |
"required" | Svaret kalder mindst ét værktøj. | Hostede open-weight-modeller |
{"type": "function", "function": {"name": "get_weather"}} | Svaret kalder denne funktion. Navnet skal være en af funktionerne i tools. Kald til andre funktioner udelades af svaret. | Hostede open-weight-modeller |
Shannon-modellerne (shannon-*) afgør det selv i hver anmodning, som med auto.
Med required eller en navngiven funktion skal du læse finish_reason, før du læser tool_calls. Når modellen ikke frembringer noget kald, er svaret et tekstsvar med finish_reason: "stop".
| Betydning | /v1/chat/completions | /v1/responses | /v1/messages |
|---|---|---|---|
| Modellen afgør | "auto" | "auto" | {"type": "auto"} |
| Kald mindst ét værktøj | "required" | "required" | {"type": "any"} |
| Kald én navngiven funktion | {"type": "function", "function": {"name": "get_weather"}} | {"type": "function", "name": "get_weather"} | {"type": "tool", "name": "get_weather"} |
Accepteret af hensyn til kompatibilitet: tool_choice: "none" og parallel_tool_calls. For en tur uden værktøjskald skal du sende anmodningen uden tools.
Værktøjskald i svaret
| Felt | Type | Beskrivelse |
|---|---|---|
finish_reason | string | tool_calls, når svaret indeholder mindst ét kald. |
message.tool_calls | array | Én post per kald. Feltet findes kun, når modellen bad om et kald. |
tool_calls[].id | string | call_ efterfulgt af 32 hexadecimale tegn. Send det tilbage som tool_call_id sammen med resultatet. |
tool_calls[].type | string | Altid function. |
tool_calls[].function.name | string | Den funktion, der skal køres. |
tool_calls[].function.arguments | string | Argumenterne som en JSON-streng, "{}" når der ingen er. Parse den, før du bruger den. |
message.content | string | null | null, når svaret kun indeholder kald. De hostede open-weight-modeller kan returnere tekst ved siden af kaldene; Shannon-modellerne returnerer null. |
Det samme kald i hvert format. På /v1/responses er det et function_call-element i output med arguments som en JSON-streng. På /v1/messages er det en tool_use-indholdsblok, hvis input er et JSON-objekt, hvis id begynder med toolu_, og hvor stop_reason er 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\"}"
}
}
]
}
} {
"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"}
}
]
} Flere kald i én tur
Et svar kan indeholde flere kald. Kør hvert af dem, og send ét resultat per kald, hvert med sit eget tool_call_id, i den næste anmodning.
De hostede open-weight-modeller returnerer hvert forskelligt kald én gang: to kald med samme navn og samme argumenter kommer som ét.
Streamede værktøjskald
Med stream: true kommer et kald i ét stykke: chunken indeholder den komplette arguments-streng, så der er ingen fragmenter at sætte sammen. index tæller turens kald fra 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
}
]
} | Endpoint | Hvad der kommer |
|---|---|
/v1/chat/completions | Én chat.completion.chunk per kald, med kaldet i delta.tool_calls[0]. Den sidste chunk har finish_reason: "tool_calls" og usage. |
/v1/responses | Per kald: response.output_item.added (et function_call-element med tomme arguments), response.function_call_arguments.delta (hele strengen), response.function_call_arguments.done, response.output_item.done. |
/v1/messages | Per kald: content_block_start (en tool_use-blok med tomt input), én content_block_delta, hvis input_json_delta.partial_json er hele argumentteksten, content_block_stop. message_delta indeholder derefter stop_reason: "tool_use". |
På shannon-1.6-lite, shannon-1.6-pro, shannon-2-lite, shannon-2-pro og shannon-coder-1 leverer en streamet anmodning med tools sin svartekst i én content-delta i slutningen af turen. Streaming
Resultater sendes tilbage
Den anden anmodning gentager samtalen og tilføjer to ting: assistentturen, der bad om kaldene, og ét resultat per kald.
{
"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\"}"
}
]
}
]
} - Send assistentturen tilbage, som du modtog den, før resultaterne. Hvert resultat kobles til sit kald via id:
tool_call_idpå/v1/chat/completions,call_idpå/v1/responses,tool_use_idpå/v1/messages. - Et resultat er tekst. Serialisér et objekt til en JSON-streng for
content(outputpå/v1/responses). På/v1/messagesercontenti entool_result-blok en streng eller en liste af tekstblokke. - I assistentturen forbliver
function.argumentsen JSON-streng, præcis som den kom. - Samtalen må gerne slutte med et værktøjsresultat. Der skal ikke bruges en ny brugerbesked: modellen fortsætter fra resultatet.
- Når din funktion fejler, så send fejlen som resultatteksten. Modellen kan så rapportere den eller bede om et andet kald.
Skemanøgleord
parameters (input_schema på /v1/messages) er et JSON Schema. Shannon 3-familien (shannon-3, shannon-3-pro, shannon-3.1, shannon-3.1-pro) og de hostede open-weight-modeller modtager det, som du sender det.
shannon-1.6-lite, shannon-1.6-pro, shannon-2-lite, shannon-2-pro og shannon-coder-1 modtager denne delmængde, på alle tre endpoints:
| Behandling | Nøgleord |
|---|---|
| Læses som sendt | Alle nøgleord, der ikke er nævnt i rækkerne nedenfor, f.eks. type, properties, required, items, enum, description, minimum, maximum, anyOf og allOf, på alle niveauer af skemaet. |
format | Læses for værdierne int32, int64, float, double, byte, date, date-time og enum. |
oneOf | Læses som anyOf. |
| Indgår ikke i det skema, disse modeller modtager | $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 og exclusiveMaximum, når de er tal; andre værdier af format. |
Adfærd og grænser
- API'et sætter intet maksimum for antallet af værktøjer og intet maksimum for antallet af runder.
- En anmodnings body kan være op til 32 MiB, og samtalen med dens resultater skal kunne være i modellens kontekstvindue.
- Når en anmodning indeholder
tools, brugershannon-1.6-lite,shannon-1.6-pro,shannon-2-liteogshannon-2-proen standard-temperaturepå 0.2. Sendtemperaturefor at angive en anden værdi. - Hver runde er en anmodning for sig: den trækker fra din saldo og tæller med i flood protection som enhver anden anmodning. Grænser og saldo
Fejl
Et værktøjskald er et normalt svar med status 200. Disse fejl vedrører selve anmodningen:
| Status | Type | Besked | Hvornår |
|---|---|---|---|
400 | invalid_request_error | unknown model: <id> | model er ikke et id fra den offentliggjorte liste. |
422 | invalid_request_error | Failed to deserialize the JSON body into the target type: … | tools er ikke et array, eller et andet felt har den forkerte JSON-type. |
413 | invalid_request_error | Failed to buffer the request body: … | Anmodningens body er større end 32 MiB. Fejlen indeholder code: "request_too_large". |
Modellen skriver argumenterne. Kontrollér dem mod dit skema, før du kører funktionen, som du ville kontrollere ethvert eksternt input.
Fejl ved godkendelse, saldo og server er de samme som for enhver anmodning. Fejlhåndtering