Funkci-alvokoj
Priskribu viajn funkciojn en la peto kaj la modelo respondas per la vokoj, kiujn ĝi volas fari. Via kodo plenumas ilin kaj resendas la rezultojn: la API redonas vokojn de iloj kaj mem ne plenumas ilon.
POST https://api.shannon-ai.com/v1/chat/completions
La ekzemploj en ĉi tiu paĝo uzas /v1/chat/completions. La sama ciklo funkcias ĉe /v1/responses kaj /v1/messages; kie formato literumas ion alie, la sekcioj sube montras ĉiujn 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"]
}
}
}]
}' La unua respondo ne respondas la demandon. Ĝi petas vokon:
{
"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}
}
} Post kiam vi sendas la rezulton, la sekva respondo estas ordinara respondo: message.content enhavas la tekston kaj finish_reason estas stop.
La ciklo, paŝo post paŝo
| Paŝo | Kiu | Kio okazas |
|---|---|---|
| 1 | Vi | Sendu messages kune kun tools, la listo de funkcioj, kiujn la modelo rajtas peti. |
| 2 | Modelo | La respondo portas tool_calls kaj finish_reason: "tool_calls". Ĉiu voko nomas funkcion kaj donas ĝiajn argumentojn. |
| 3 | Vi | Analizu la arguments de ĉiu voko kaj plenumu vian funkcion. |
| 4 | Vi | Almetu la mesaĝon de la asistanto kaj unu mesaĝon tool por voko al messages, poste resendu la peton kun la samaj tools. |
| 5 | Modelo | La modelo respondas per teksto kun finish_reason: "stop", aŭ petas pliajn vokojn. En tiu kazo reiru al paŝo 3. |
Unu peto estas unu vico de la modelo. La API ne konservas konversacion inter petoj kaj fiksas neniun nombron da rondoj: via kodo tenas messages kaj decidas kiam halti.
Difino de iloj
tools estas tabelo kun unu ero por funkcio. Ĉiu modelo de la katalogo akceptas ĝin; GET /v1/models raportas capabilities.tools: true por ĉiu id.
| Kampo | Tipo | Priskribo |
|---|---|---|
type | string | Ĉiam function. |
function.name | string | La nomo, kiun la modelo uzas, kiam ĝi petas ĉi tiun funkcion. Deviga. |
function.description | string | Kion la funkcio faras, en simpla lingvo. |
function.parameters | object | La argumentoj kiel JSON Schema kun type: "object" supre. Vidu Ŝlosilvortoj de skemo sube. |
Ĉiu endpoint havas sian propran literumon de ilo. Sendu tiun, kiu apartenas al la endpoint, kiun vi vokas:
{
"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 diras, ĉu la modelo rajtas aŭ devas voki ilon. Ĝi estas legata nur kune kun tools.
| Valoro | Priskribo | Aplikata de |
|---|---|---|
"auto" | La modelo decidas, ĉu respondi per teksto aŭ voki ilon. Tio estas la defaŭlto. | Ĉiuj modeloj |
"required" | La respondo vokas almenaŭ unu ilon. | Gastigitaj malfermpezaj modeloj |
{"type": "function", "function": {"name": "get_weather"}} | La respondo vokas ĉi tiun funkcion. La nomo devas esti unu el la funkcioj en tools. Vokoj al aliaj funkcioj estas lasitaj ekster la respondo. | Gastigitaj malfermpezaj modeloj |
La Shannon-modeloj (shannon-*) decidas en ĉiu peto, kiel kun auto.
Kun required aŭ nomita funkcio, legu finish_reason antaŭ ol legi tool_calls. Kiam la modelo produktas neniun vokon, la respondo estas teksta kun finish_reason: "stop".
| Signifo | /v1/chat/completions | /v1/responses | /v1/messages |
|---|---|---|---|
| La modelo decidas | "auto" | "auto" | {"type": "auto"} |
| Voki almenaŭ unu ilon | "required" | "required" | {"type": "any"} |
| Voki unu nomitan funkcion | {"type": "function", "function": {"name": "get_weather"}} | {"type": "function", "name": "get_weather"} | {"type": "tool", "name": "get_weather"} |
Akceptitaj pro kongrueco: tool_choice: "none" kaj parallel_tool_calls. Por vico sen vokoj de iloj, sendu la peton sen tools.
Vokoj de iloj en la respondo
| Kampo | Tipo | Priskribo |
|---|---|---|
finish_reason | string | tool_calls kiam la respondo portas almenaŭ unu vokon. |
message.tool_calls | array | Unu ero por voko. La kampo ĉeestas nur kiam la modelo petis vokon. |
tool_calls[].id | string | call_ sekvata de 32 deksesumaj signoj. Resendu ĝin kiel tool_call_id kun la rezulto. |
tool_calls[].type | string | Ĉiam function. |
tool_calls[].function.name | string | La funkcio plenumenda. |
tool_calls[].function.arguments | string | La argumentoj kiel JSON-ĉeno, "{}" kiam ne ekzistas argumentoj. Analizu ĝin antaŭ uzo. |
message.content | string | null | null kiam la respondo enhavas nur vokojn. La gastigitaj malfermpezaj modeloj povas redoni tekston apud la vokoj; la Shannon-modeloj redonas null. |
La sama voko en ĉiu formato. Ĉe /v1/responses ĝi estas ero function_call de output, kun arguments kiel JSON-ĉeno. Ĉe /v1/messages ĝi estas enhavbloko tool_use, kies input estas JSON-objekto, ĝia id komenciĝas per toolu_, kaj stop_reason estas 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"}
}
]
} Pluraj vokoj en unu vico
Respondo povas porti plurajn vokojn. Plenumu ĉiun el ili kaj sendu unu rezulton por voko, ĉiun kun sia propra tool_call_id, en la sekva peto.
La gastigitaj malfermpezaj modeloj redonas ĉiun diferencan vokon unufoje: du vokoj kun la sama nomo kaj la samaj argumentoj alvenas kiel unu.
Fluataj vokoj de iloj
Kun stream: true, voko alvenas en unu peco: la peco enhavas la kompletan ĉenon arguments, do ne ekzistas fragmentoj kunigendaj. index nombras la vokojn de la vico ekde 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 | Kio alvenas |
|---|---|
/v1/chat/completions | Unu chat.completion.chunk por voko, kun la voko en delta.tool_calls[0]. La lasta peco havas finish_reason: "tool_calls" kaj usage. |
/v1/responses | Por voko: response.output_item.added (ero function_call kun malplenaj arguments), response.function_call_arguments.delta (la tuta ĉeno), response.function_call_arguments.done, response.output_item.done. |
/v1/messages | Por voko: content_block_start (bloko tool_use kun malplena input), unu content_block_delta, kies input_json_delta.partial_json estas la tuta teksto de la argumentoj, content_block_stop. message_delta poste portas stop_reason: "tool_use". |
Ĉe shannon-1.6-lite, shannon-1.6-pro, shannon-2-lite, shannon-2-pro kaj shannon-coder-1, fluata peto kun tools liveras sian respondan tekston en unu delta content ĉe la fino de la vico. Fluigo
Resendo de rezultoj
La dua peto ripetas la konversacion kaj aldonas du aferojn: la vicon de la asistanto, kiu petis la vokojn, kaj unu rezulton por voko.
{
"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\"}"
}
]
}
]
} - Resendu la vicon de la asistanto tiel, kiel vi ricevis ĝin, antaŭ la rezultoj. Ĉiu rezulto estas kongruigita al sia voko per id:
tool_call_idĉe/v1/chat/completions,call_idĉe/v1/responses,tool_use_idĉe/v1/messages. - Rezulto estas teksto. Serialigu objekton al JSON-ĉeno por
content(outputĉe/v1/responses). Ĉe/v1/messageslacontentde blokotool_resultestas ĉeno aŭ listo de tekstblokoj. - En la vico de la asistanto,
function.argumentsrestas JSON-ĉeno, ĝuste kiel ĝi alvenis. - La konversacio povas finiĝi per rezulto de ilo. Nova mesaĝo de uzanto ne necesas: la modelo daŭrigas el la rezulto.
- Kiam via funkcio malsukcesas, sendu la malsukceson kiel rezultan tekston. La modelo tiam povas raporti ĝin aŭ peti alian vokon.
Ŝlosilvortoj de skemo
parameters (input_schema ĉe /v1/messages) estas JSON Schema. La familio Shannon 3 (shannon-3, shannon-3-pro, shannon-3.1, shannon-3.1-pro) kaj la gastigitaj malfermpezaj modeloj ricevas ĝin tiel, kiel vi sendas ĝin.
shannon-1.6-lite, shannon-1.6-pro, shannon-2-lite, shannon-2-pro kaj shannon-coder-1 ricevas ĉi tiun subaron, ĉe ĉiuj tri endpoints:
| Traktado | Ŝlosilvortoj |
|---|---|
| Legata kiel sendita | Ĉiu ŝlosilvorto, kiu ne estas nomita en la vicoj sube, ekzemple type, properties, required, items, enum, description, minimum, maximum, anyOf kaj allOf, je ĉiu nivelo de la skemo. |
format | Legata por la valoroj int32, int64, float, double, byte, date, date-time kaj enum. |
oneOf | Legata kiel anyOf. |
| Ne parto de la skemo, kiun ĉi tiuj modeloj ricevas | $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 kaj exclusiveMaximum kiam ili estas nombroj; aliaj valoroj de format. |
Konduto kaj limoj
- La API fiksas neniun maksimuman nombron da iloj kaj neniun maksimuman nombron da rondoj.
- Korpo de peto povas esti ĝis 32 MiB, kaj la konversacio kun siaj rezultoj devas eniri la kuntekstan fenestron de la modelo.
- Kiam peto portas
tools,shannon-1.6-lite,shannon-1.6-pro,shannon-2-litekajshannon-2-prouzas defaŭltantemperaturede 0.2. Sendutemperaturepor agordi alian valoron. - Ĉiu rondo estas aparta peto: ĝi prenas el via saldo kaj kalkuliĝas por flood protection kiel ajna alia peto. Limoj kaj saldo
Eraroj
Voko de ilo estas normala respondo kun stato 200. Ĉi tiuj eraroj koncernas la peton mem:
| Stato | Tipo | Mesaĝo | Kiam |
|---|---|---|---|
400 | invalid_request_error | unknown model: <id> | model ne estas id de la publikigita listo. |
422 | invalid_request_error | Failed to deserialize the JSON body into the target type: … | tools ne estas tabelo, aŭ alia kampo havas malĝustan JSON-tipon. |
413 | invalid_request_error | Failed to buffer the request body: … | La korpo de la peto estas pli granda ol 32 MiB. La eraro portas code: "request_too_large". |
La modelo skribas la argumentojn. Kontrolu ilin kontraŭ via skemo antaŭ ol plenumi la funkcion, kiel vi kontrolus ajnan eksteran enigon.
Aŭtentigo, saldo kaj servilaj eraroj estas samaj kiel ĉe ĉiu peto. Erarotraktado