Panggilan Fungsi
Huraikan fungsi anda dalam permintaan dan model membalas dengan panggilan yang ia mahu dibuat. Kod anda menjalankannya dan menghantar keputusan kembali: API memulangkan panggilan alat dan tidak menjalankan sebarang alat sendiri.
POST https://api.shannon-ai.com/v1/chat/completions
Sampel pada halaman ini menggunakan /v1/chat/completions. Gelung yang sama berjalan pada /v1/responses dan /v1/messages; apabila sesuatu format mengejanya secara berbeza, bahagian di bawah menunjukkan ketiga-tiganya.
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"]
}
}
}]
}' Balasan pertama tidak menjawab soalan. Ia meminta satu panggilan:
{
"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}
}
} Selepas anda menghantar keputusan, balasan seterusnya ialah jawapan biasa: message.content memegang teks dan finish_reason ialah stop.
Gelung, langkah demi langkah
| Langkah | Siapa | Apa yang berlaku |
|---|---|---|
| 1 | Anda | Hantar messages bersama tools, iaitu senarai fungsi yang boleh diminta oleh model. |
| 2 | Model | Balasan membawa tool_calls dan finish_reason: "tool_calls". Setiap panggilan menamakan satu fungsi dan memberikan argumennya. |
| 3 | Anda | Huraikan arguments bagi setiap panggilan dan jalankan fungsi anda. |
| 4 | Anda | Tambahkan mesej assistant dan satu mesej tool bagi setiap panggilan pada messages, kemudian hantar permintaan sekali lagi dengan tools yang sama. |
| 5 | Model | Model menjawab dengan teks dan finish_reason: "stop", atau meminta lebih banyak panggilan. Dalam hal itu, kembali ke langkah 3. |
Satu permintaan ialah satu giliran model. API tidak menyimpan perbualan antara permintaan dan tidak menetapkan bilangan pusingan: kod anda memegang messages dan memutuskan bila hendak berhenti.
Mentakrifkan alat
tools ialah tatasusunan dengan satu entri bagi setiap fungsi. Setiap model dalam katalog menerimanya; GET /v1/models melaporkan capabilities.tools: true untuk setiap id.
| Medan | Jenis | Penerangan |
|---|---|---|
type | string | Sentiasa function. |
function.name | string | Nama yang digunakan model apabila ia meminta fungsi ini. Wajib. |
function.description | string | Apa yang fungsi itu lakukan, dalam bahasa mudah. |
function.parameters | object | Argumen sebagai JSON Schema dengan type: "object" di bahagian atas. Lihat Kata kunci skema di bawah. |
Setiap endpoint mempunyai ejaan alat tersendiri. Hantar yang sesuai dengan endpoint yang anda panggil:
{
"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 menentukan sama ada model boleh, atau mesti, memanggil alat. Ia dibaca hanya bersama tools.
| Nilai | Penerangan | Dilaksanakan oleh |
|---|---|---|
"auto" | Model memutuskan sama ada hendak menjawab dengan teks atau memanggil alat. Ini ialah nilai lalai. | Semua model |
"required" | Balasan memanggil sekurang-kurangnya satu alat. | Model open-weight yang dihoskan |
{"type": "function", "function": {"name": "get_weather"}} | Balasan memanggil fungsi ini. Namanya mesti salah satu fungsi dalam tools. Panggilan kepada fungsi lain tidak dimasukkan dalam balasan. | Model open-weight yang dihoskan |
Model Shannon (shannon-*) memutuskan dalam setiap permintaan, seperti dengan auto.
Dengan required atau fungsi yang dinamakan, baca finish_reason sebelum membaca tool_calls. Apabila model tidak menghasilkan panggilan, balasan ialah jawapan teks dengan finish_reason: "stop".
| Maksud | /v1/chat/completions | /v1/responses | /v1/messages |
|---|---|---|---|
| Model memutuskan | "auto" | "auto" | {"type": "auto"} |
| Panggil sekurang-kurangnya satu alat | "required" | "required" | {"type": "any"} |
| Panggil satu fungsi yang dinamakan | {"type": "function", "function": {"name": "get_weather"}} | {"type": "function", "name": "get_weather"} | {"type": "tool", "name": "get_weather"} |
Diterima untuk keserasian: tool_choice: "none" dan parallel_tool_calls. Untuk giliran tanpa panggilan alat, hantar permintaan tanpa tools.
Panggilan alat dalam balasan
| Medan | Jenis | Penerangan |
|---|---|---|
finish_reason | string | tool_calls apabila balasan membawa sekurang-kurangnya satu panggilan. |
message.tool_calls | array | Satu entri bagi setiap panggilan. Medan ini hanya wujud apabila model meminta panggilan. |
tool_calls[].id | string | call_ diikuti 32 aksara heksadesimal. Hantar semula sebagai tool_call_id bersama keputusan. |
tool_calls[].type | string | Sentiasa function. |
tool_calls[].function.name | string | Fungsi yang hendak dijalankan. |
tool_calls[].function.arguments | string | Argumen sebagai rentetan JSON, "{}" apabila tiada. Huraikan (parse) sebelum digunakan. |
message.content | string | null | null apabila balasan hanya mengandungi panggilan. Model open-weight yang dihoskan boleh memulangkan teks di sebelah panggilan; model Shannon memulangkan null. |
Panggilan yang sama dalam setiap format. Pada /v1/responses ia ialah item function_call dalam output, dengan arguments sebagai rentetan JSON. Pada /v1/messages ia ialah blok kandungan tool_use yang inputnya ialah objek JSON, idnya bermula dengan toolu_, dan stop_reason ialah 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"}
}
]
} Beberapa panggilan dalam satu giliran
Satu balasan boleh membawa beberapa panggilan. Jalankan semuanya dan hantar satu keputusan bagi setiap panggilan, masing-masing dengan tool_call_id sendiri, dalam permintaan seterusnya.
Model open-weight yang dihoskan memulangkan setiap panggilan yang berbeza sekali sahaja: dua panggilan dengan nama dan argumen yang sama tiba sebagai satu.
Panggilan alat yang distream
Dengan stream: true, panggilan tiba sekali gus: chunk memegang rentetan arguments yang lengkap, jadi tiada serpihan untuk digabungkan. index mengira panggilan dalam giliran itu bermula dari 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 | Apa yang tiba |
|---|---|
/v1/chat/completions | Satu chat.completion.chunk bagi setiap panggilan, dengan panggilan itu dalam delta.tool_calls[0]. Chunk terakhir mempunyai finish_reason: "tool_calls" dan usage. |
/v1/responses | Bagi setiap panggilan: response.output_item.added (item function_call dengan arguments kosong), response.function_call_arguments.delta (keseluruhan rentetan), response.function_call_arguments.done, response.output_item.done. |
/v1/messages | Bagi setiap panggilan: content_block_start (blok tool_use dengan input kosong), satu content_block_delta yang input_json_delta.partial_jsonnya ialah keseluruhan teks argumen, content_block_stop. message_delta kemudian membawa stop_reason: "tool_use". |
Pada shannon-1.6-lite, shannon-1.6-pro, shannon-2-lite, shannon-2-pro dan shannon-coder-1, permintaan stream yang membawa tools menghantar teks jawapannya dalam satu delta content pada penghujung giliran. Penstriman
Menghantar keputusan kembali
Permintaan kedua mengulang perbualan dan menambah dua perkara: giliran assistant yang meminta panggilan, dan satu keputusan bagi setiap panggilan.
{
"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\"}"
}
]
}
]
} - Hantar semula giliran assistant seperti yang anda terima, sebelum keputusan. Setiap keputusan dipadankan dengan panggilannya melalui id:
tool_call_idpada/v1/chat/completions,call_idpada/v1/responses,tool_use_idpada/v1/messages. - Keputusan ialah teks. Bersirikan objek kepada rentetan JSON untuk
content(outputpada/v1/responses). Pada/v1/messages,contentbagi bloktool_resultialah rentetan atau senarai blok teks. - Dalam giliran assistant,
function.argumentskekal sebagai rentetan JSON, tepat seperti yang diterima. - Perbualan boleh berakhir dengan keputusan alat. Tiada mesej pengguna baharu diperlukan: model menyambung daripada keputusan itu.
- Apabila fungsi anda gagal, hantar kegagalan itu sebagai teks keputusan. Model kemudian boleh melaporkannya atau meminta panggilan lain.
Kata kunci skema
parameters (input_schema pada /v1/messages) ialah JSON Schema. Keluarga Shannon 3 (shannon-3, shannon-3-pro, shannon-3.1, shannon-3.1-pro) dan model open-weight yang dihoskan menerimanya seperti yang anda hantar.
shannon-1.6-lite, shannon-1.6-pro, shannon-2-lite, shannon-2-pro dan shannon-coder-1 menerima subset ini, pada ketiga-tiga endpoint:
| Layanan | Kata kunci |
|---|---|
| Dibaca seperti yang dihantar | Setiap kata kunci yang tidak dinamakan dalam baris di bawah, contohnya type, properties, required, items, enum, description, minimum, maximum, anyOf dan allOf, pada setiap peringkat skema. |
format | Dibaca untuk nilai int32, int64, float, double, byte, date, date-time dan enum. |
oneOf | Dibaca sebagai anyOf. |
| Bukan sebahagian daripada skema yang diterima oleh model ini | $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 dan exclusiveMaximum apabila ia nombor; nilai lain bagi format. |
Tingkah laku dan had
- API tidak menetapkan bilangan maksimum alat dan tiada bilangan maksimum pusingan.
- Badan permintaan boleh sehingga 32 MiB, dan perbualan beserta keputusannya mesti muat dalam tetingkap konteks model.
- Apabila permintaan membawa
tools,shannon-1.6-lite,shannon-1.6-pro,shannon-2-litedanshannon-2-promenggunakantemperaturelalai 0.2. Hantartemperatureuntuk menetapkan nilai lain. - Setiap pusingan ialah permintaan tersendiri: ia menggunakan baki anda dan dikira dalam flood protection seperti permintaan lain. Had dan baki
Ralat
Panggilan alat ialah balasan biasa dengan status 200. Ralat ini berkaitan dengan permintaan itu sendiri:
| Status | Jenis | Mesej | Bila |
|---|---|---|---|
400 | invalid_request_error | unknown model: <id> | model bukan id dalam senarai yang diterbitkan. |
422 | invalid_request_error | Failed to deserialize the JSON body into the target type: … | tools bukan tatasusunan, atau medan lain mempunyai jenis JSON yang salah. |
413 | invalid_request_error | Failed to buffer the request body: … | Badan permintaan lebih besar daripada 32 MiB. Ralat itu membawa code: "request_too_large". |
Model menulis argumen. Semak argumen itu berdasarkan skema anda sebelum menjalankan fungsi, seperti anda menyemak sebarang input luar.
Ralat pengesahan, baki dan server adalah sama seperti bagi setiap permintaan. Pengendalian Ralat