Klicanje funkcij
V zahtevku opišite svoje funkcije, model pa odgovori s klici, ki jih želi izvesti. Vaša koda jih zažene in pošlje rezultate nazaj: API vrne klice orodij in orodja sam ne zažene.
POST https://api.shannon-ai.com/v1/chat/completions
Primeri na tej strani uporabljajo /v1/chat/completions. Ista zanka deluje na /v1/responses in /v1/messages; kjer format nekaj zapiše drugače, spodnji razdelki prikažejo vse tri.
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"]
}
}
}]
}' Prvi odgovor ne odgovori na vprašanje. Zahteva klic:
{
"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}
}
} Ko pošljete rezultat, je naslednji odgovor običajen odgovor: message.content vsebuje besedilo, finish_reason pa je stop.
Zanka po korakih
| Korak | Kdo | Kaj se zgodi |
|---|---|---|
| 1 | Vi | Pošljite messages skupaj z tools, seznamom funkcij, ki jih model lahko zahteva. |
| 2 | Model | Odgovor vsebuje tool_calls in finish_reason: "tool_calls". Vsak klic navaja funkcijo in njene argumente. |
| 3 | Vi | Razčlenite arguments vsakega klica in zaženite svojo funkcijo. |
| 4 | Vi | V messages dodajte sporočilo asistenta in po eno sporočilo tool za vsak klic, nato zahtevek znova pošljite z istimi tools. |
| 5 | Model | Model odgovori z besedilom in finish_reason: "stop" ali pa zahteva nove klice. V tem primeru se vrnite na korak 3. |
En zahtevek je en obrat modela. API med zahtevki ne hrani pogovora in ne določa števila krogov: messages hrani vaša koda, ki tudi odloči, kdaj se ustaviti.
Definiranje orodij
tools je polje (array) z enim vnosom na funkcijo. Sprejme ga vsak model v katalogu; GET /v1/models za vsak id sporoča capabilities.tools: true.
| Polje | Tip | Opis |
|---|---|---|
type | string | Vedno function. |
function.name | string | Ime, ki ga model uporabi, ko zahteva to funkcijo. Obvezno. |
function.description | string | Kaj funkcija počne, v preprostem jeziku. |
function.parameters | object | Argumenti kot JSON Schema z type: "object" na vrhu. Glejte Ključne besede sheme spodaj. |
Vsaka končna točka ima svoj zapis orodja. Pošljite tistega, ki pripada končni točki, ki jo kličete:
{
"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 določa, ali sme model poklicati orodje oziroma ali ga mora. Upošteva se samo skupaj z tools.
| Vrednost | Opis | Uporabljajo |
|---|---|---|
"auto" | Model sam odloči, ali bo odgovoril z besedilom ali pa poklical orodje. To je privzeta vrednost. | Vsi modeli |
"required" | Odgovor pokliče vsaj eno orodje. | Gostovani modeli z odprtimi utežmi |
{"type": "function", "function": {"name": "get_weather"}} | Odgovor pokliče to funkcijo. Ime mora biti ena od funkcij v tools. Klici drugih funkcij so iz odgovora izpuščeni. | Gostovani modeli z odprtimi utežmi |
Modeli Shannon (shannon-*) se odločijo pri vsakem zahtevku, kot pri auto.
Pri required ali poimenovani funkciji preberite finish_reason, preden preberete tool_calls. Kadar model ne ustvari klica, je odgovor besedilni odgovor z finish_reason: "stop".
| Pomen | /v1/chat/completions | /v1/responses | /v1/messages |
|---|---|---|---|
| Model odloči sam | "auto" | "auto" | {"type": "auto"} |
| Pokliči vsaj eno orodje | "required" | "required" | {"type": "any"} |
| Pokliči eno poimenovano funkcijo | {"type": "function", "function": {"name": "get_weather"}} | {"type": "function", "name": "get_weather"} | {"type": "tool", "name": "get_weather"} |
Sprejeto zaradi združljivosti: tool_choice: "none" in parallel_tool_calls. Za obrat brez klicev orodij pošljite zahtevek brez tools.
Klici orodij v odgovoru
| Polje | Tip | Opis |
|---|---|---|
finish_reason | string | tool_calls, kadar odgovor vsebuje vsaj en klic. |
message.tool_calls | array | En vnos na klic. Polje je prisotno samo, kadar je model zahteval klic. |
tool_calls[].id | string | call_, ki mu sledi 32 šestnajstiških znakov. Skupaj z rezultatom ga pošljite nazaj kot tool_call_id. |
tool_calls[].type | string | Vedno function. |
tool_calls[].function.name | string | Funkcija, ki jo je treba zagnati. |
tool_calls[].function.arguments | string | Argumenti kot niz JSON, "{}", kadar jih ni. Pred uporabo ga razčlenite. |
message.content | string | null | null, kadar odgovor vsebuje samo klice. Gostovani modeli z odprtimi utežmi lahko poleg klicev vrnejo besedilo; modeli Shannon vrnejo null. |
Isti klic v vsakem formatu. Na /v1/responses je to element function_call v output, pri čemer so arguments niz JSON. Na /v1/messages je to blok vsebine tool_use, katerega input je objekt JSON, njegov id se začne z toolu_, stop_reason pa je 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"}
}
]
} Več klicev v enem obratu
Odgovor lahko vsebuje več klicev. Zaženite vse in v naslednjem zahtevku pošljite po en rezultat za vsak klic, vsakega z lastnim tool_call_id.
Gostovani modeli z odprtimi utežmi vrnejo vsak različen klic enkrat: dva klica z istim imenom in istimi argumenti prispeta kot eden.
Klici orodij med pretakanjem
Z stream: true klic prispe v enem kosu: kos vsebuje celoten niz arguments, zato ni fragmentov za združevanje. index šteje klice obrata od 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
}
]
} | Končna točka | Kaj prispe |
|---|---|
/v1/chat/completions | Po en chat.completion.chunk na klic, s klicem v delta.tool_calls[0]. Zadnji kos ima finish_reason: "tool_calls" in usage. |
/v1/responses | Za vsak klic: response.output_item.added (element function_call s praznimi arguments), response.function_call_arguments.delta (celoten niz), response.function_call_arguments.done, response.output_item.done. |
/v1/messages | Za vsak klic: content_block_start (blok tool_use s praznim input), en content_block_delta, katerega input_json_delta.partial_json je celotno besedilo argumentov, content_block_stop. message_delta nato vsebuje stop_reason: "tool_use". |
Na shannon-1.6-lite, shannon-1.6-pro, shannon-2-lite, shannon-2-pro in shannon-coder-1 zahtevek s pretakanjem, ki vsebuje tools, besedilo odgovora dostavi v enem samem delta content ob koncu obrata. Pretakanje
Pošiljanje rezultatov nazaj
Drugi zahtevek ponovi pogovor in doda dve stvari: obrat asistenta, ki je zahteval klice, in en rezultat za vsak klic.
{
"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\"}"
}
]
}
]
} - Obrat asistenta pošljite nazaj tak, kot ste ga prejeli, pred rezultati. Vsak rezultat se z njegovim klicem poveže prek id:
tool_call_idna/v1/chat/completions,call_idna/v1/responses,tool_use_idna/v1/messages. - Rezultat je besedilo. Objekt serializirajte v niz JSON za
content(outputna/v1/responses). Na/v1/messagesjecontentblokatool_resultniz ali seznam besedilnih blokov. - V obratu asistenta
function.argumentsostane niz JSON, natanko tak, kot je prispel. - Pogovor se lahko konča z rezultatom orodja. Novo sporočilo uporabnika ni potrebno: model nadaljuje od rezultata.
- Kadar vaša funkcija odpove, pošljite napako kot besedilo rezultata. Model jo lahko nato sporoči ali zahteva drug klic.
Ključne besede sheme
parameters (input_schema na /v1/messages) je shema JSON Schema. Družina Shannon 3 (shannon-3, shannon-3-pro, shannon-3.1, shannon-3.1-pro) in gostovani modeli z odprtimi utežmi jo prejmejo tako, kot jo pošljete.
shannon-1.6-lite, shannon-1.6-pro, shannon-2-lite, shannon-2-pro in shannon-coder-1 prejmejo to podmnožico, na vseh treh končnih točkah:
| Obravnava | Ključne besede |
|---|---|
| Upošteva se, kot je poslano | Vsaka ključna beseda, ki ni navedena v spodnjih vrsticah, na primer type, properties, required, items, enum, description, minimum, maximum, anyOf in allOf, na vsaki ravni sheme. |
format | Upošteva se za vrednosti int32, int64, float, double, byte, date, date-time in enum. |
oneOf | Upošteva se kot anyOf. |
| Ni del sheme, ki jo ti modeli prejmejo | $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 in exclusiveMaximum, kadar sta števili; druge vrednosti format. |
Obnašanje in omejitve
- API ne določa največjega števila orodij niti največjega števila krogov.
- Telo zahtevka je lahko veliko do 32 MiB, pogovor z rezultati pa mora stati v kontekstno okno modela.
- Kadar zahtevek vsebuje
tools,shannon-1.6-lite,shannon-1.6-pro,shannon-2-liteinshannon-2-prouporabljajo privzetitemperature0.2. Ztemperaturenastavite drugo vrednost. - Vsak krog je zahtevek zase: porablja vaše stanje in se kot vsak drug zahtevek všteva v zaščito pred poplavo. Omejitve in stanje
Napake
Klic orodja je običajen odgovor s statusom 200. Te napake se nanašajo na sam zahtevek:
| Stanje | Vrsta | Sporočilo | Kdaj |
|---|---|---|---|
400 | invalid_request_error | unknown model: <id> | model ni id z objavljenega seznama. |
422 | invalid_request_error | Failed to deserialize the JSON body into the target type: … | tools ni polje (array) ali pa ima drugo polje napačen tip JSON. |
413 | invalid_request_error | Failed to buffer the request body: … | Telo zahtevka je večje od 32 MiB. Napaka vsebuje code: "request_too_large". |
Argumente napiše model. Preden zaženete funkcijo, jih preverite glede na svojo shemo, tako kot bi preverili vsak drug zunanji vnos.
Napake pri avtentikaciji, stanju in strežniku so enake kot pri vsakem zahtevku. Obravnava napak