फङ्क्शन कलिङ
अनुरोधमा आफ्ना फङ्सनहरू वर्णन गर्नुहोस् र मोडलले चलाउन चाहेका कलहरूसहित जवाफ दिन्छ। तपाईंको कोडले तिनलाई चलाउँछ र नतिजा फर्काउँछ: API ले टुल कलहरू फर्काउँछ, आफैं टुल चलाउँदैन।
POST https://api.shannon-ai.com/v1/chat/completions
यो पेजका नमूनाहरूले /v1/chat/completions प्रयोग गर्छन्। उही लुप /v1/responses र /v1/messages मा पनि चल्छ; कुनै ढाँचाले कुनै कुरा फरक तरिकाले लेख्दा तलका खण्डहरूले तीनवटै देखाउँछन्।
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"]
}
}
}]
}' पहिलो जवाफले प्रश्नको उत्तर दिँदैन। यसले कल माग्छ:
{
"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}
}
} नतिजा पठाएपछि अर्को जवाफ सामान्य उत्तर हुन्छ: message.content मा टेक्स्ट हुन्छ र finish_reason stop हुन्छ।
लुप, चरणबद्ध
| चरण | को | के हुन्छ |
|---|---|---|
| 1 | तपाईं | messages सँगै tools पठाउनुहोस्, जुन मोडलले माग्न सक्ने फङ्सनहरूको सूची हो। |
| 2 | मोडल | जवाफमा tool_calls र finish_reason: "tool_calls" हुन्छ। हरेक कलले फङ्सनको नाम र त्यसका आर्गुमेन्टहरू दिन्छ। |
| 3 | तपाईं | हरेक कलको arguments पार्स गर्नुहोस् र आफ्नो फङ्सन चलाउनुहोस्। |
| 4 | तपाईं | असिस्टेन्ट सन्देश र प्रत्येक कलको एउटा tool सन्देश messages मा थप्नुहोस्, त्यसपछि उही tools सहित अनुरोध फेरि पठाउनुहोस्। |
| 5 | मोडल | मोडलले finish_reason: "stop" सहित टेक्स्टमा जवाफ दिन्छ, वा थप कल माग्छ। त्यस अवस्थामा चरण 3 मा फर्कनुहोस्। |
एउटा अनुरोध एउटा मोडल टर्न हो। API ले अनुरोधहरूबीच कुराकानी राख्दैन र राउन्डको संख्या तोक्दैन: तपाईंको कोडले messages राख्छ र कहिले रोक्ने भनेर निर्णय गर्छ।
टुल परिभाषित गर्ने
tools हरेक फङ्सनको एउटा प्रविष्टि भएको एरे हो। क्याटलगका हरेक मोडलले यसलाई स्वीकार गर्छ; GET /v1/models ले हरेक id का लागि capabilities.tools: true रिपोर्ट गर्छ।
| फिल्ड | प्रकार | विवरण |
|---|---|---|
type | string | सधैं function। |
function.name | string | मोडलले यो फङ्सन माग्दा प्रयोग गर्ने नाम। आवश्यक। |
function.description | string | फङ्सनले के गर्छ, सरल भाषामा। |
function.parameters | object | माथि type: "object" भएको JSON Schema को रूपमा आर्गुमेन्टहरू। तलको स्कीमा किवर्डहरू हेर्नुहोस्। |
हरेक इन्डपोइन्टमा टुल लेख्ने आफ्नै तरिका छ। तपाईंले कल गर्ने इन्डपोइन्टको तरिका पठाउनुहोस्:
{
"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 ले मोडलले टुल कल गर्न सक्छ, वा गर्नैपर्छ भनेर बताउँछ। यो tools सँगै मात्र पढिन्छ।
| मान | विवरण | लागू गर्ने |
|---|---|---|
"auto" | मोडलले टेक्स्टमा जवाफ दिने कि टुल कल गर्ने भनेर निर्णय गर्छ। यो पूर्वनिर्धारित हो। | सबै मोडलहरू |
"required" | जवाफले कम्तीमा एउटा टुल कल गर्छ। | होस्ट गरिएका ओपन-वेट मोडलहरू |
{"type": "function", "function": {"name": "get_weather"}} | जवाफले यो फङ्सनलाई कल गर्छ। नाम tools का फङ्सनहरूमध्ये एउटा हुनैपर्छ। अरू फङ्सनका कलहरू जवाफबाट छुट्छन्। | होस्ट गरिएका ओपन-वेट मोडलहरू |
Shannon मोडलहरू (shannon-*) ले auto मा जस्तै हरेक अनुरोधमा आफैं निर्णय गर्छन्।
required वा नाम दिइएको फङ्सनमा, tool_calls पढ्नु अघि finish_reason पढ्नुहोस्। मोडलले कुनै कल नबनाएमा जवाफ finish_reason: "stop" सहितको टेक्स्ट उत्तर हुन्छ।
| अर्थ | /v1/chat/completions | /v1/responses | /v1/messages |
|---|---|---|---|
| मोडलले निर्णय गर्छ | "auto" | "auto" | {"type": "auto"} |
| कम्तीमा एउटा टुल कल गर्नुहोस् | "required" | "required" | {"type": "any"} |
| नाम दिइएको एउटा फङ्सन कल गर्नुहोस् | {"type": "function", "function": {"name": "get_weather"}} | {"type": "function", "name": "get_weather"} | {"type": "tool", "name": "get_weather"} |
अनुकूलताका लागि स्वीकार गरिन्छ: tool_choice: "none" र parallel_tool_calls। टुल कल नभएको टर्नका लागि अनुरोध tools बिना पठाउनुहोस्।
जवाफमा टुल कलहरू
| फिल्ड | प्रकार | विवरण |
|---|---|---|
finish_reason | string | जवाफमा कम्तीमा एउटा कल हुँदा tool_calls। |
message.tool_calls | array | प्रत्येक कलको एउटा प्रविष्टि। मोडलले कल माग्दा मात्र यो फिल्ड हुन्छ। |
tool_calls[].id | string | call_ पछि 32 हेक्साडेसिमल अक्षर। नतिजासँगै यसलाई tool_call_id का रूपमा फर्काउनुहोस्। |
tool_calls[].type | string | सधैं function। |
tool_calls[].function.name | string | चलाउनुपर्ने फङ्सन। |
tool_calls[].function.arguments | string | आर्गुमेन्टहरू JSON स्ट्रिङ का रूपमा, केही नभए "{}"। प्रयोग गर्नु अघि यसलाई पार्स गर्नुहोस्। |
message.content | string | null | जवाफमा कलहरू मात्र हुँदा null। होस्ट गरिएका ओपन-वेट मोडलहरूले कलहरूसँगै टेक्स्ट फर्काउन सक्छन्; Shannon मोडलहरूले null फर्काउँछन्। |
हरेक ढाँचामा उही कल। /v1/responses मा यो output को function_call आइटम हो, जसको arguments JSON स्ट्रिङ हुन्छ। /v1/messages मा यो tool_use कन्टेन्ट ब्लक हो जसको input JSON अब्जेक्ट हुन्छ, id toolu_ बाट सुरु हुन्छ, र stop_reason 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"}
}
]
} एउटै टर्नमा धेरै कल
एउटा जवाफमा धेरै कल हुन सक्छन्। ती सबै चलाउनुहोस् र अर्को अनुरोधमा प्रत्येक कलको एउटा नतिजा, हरेकसँग आफ्नै tool_call_id सहित, पठाउनुहोस्।
होस्ट गरिएका ओपन-वेट मोडलहरूले हरेक भिन्न कल एकपटक मात्र फर्काउँछन्: उही नाम र उही आर्गुमेन्ट भएका दुई कल एउटाका रूपमा आउँछन्।
स्ट्रिम गरिएका टुल कलहरू
stream: true सँग कल एकै टुक्रामा आउँछ: चङ्कमा पूरा arguments स्ट्रिङ हुन्छ, त्यसैले जोड्नुपर्ने टुक्राहरू हुँदैनन्। index ले टर्नका कलहरू 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
}
]
} | इन्डपोइन्ट | के आउँछ |
|---|---|
/v1/chat/completions | प्रत्येक कलको एउटा chat.completion.chunk, कल delta.tool_calls[0] मा। अन्तिम चङ्कमा finish_reason: "tool_calls" र usage हुन्छ। |
/v1/responses | प्रत्येक कलमा: response.output_item.added (खाली arguments भएको function_call आइटम), response.function_call_arguments.delta (पूरै स्ट्रिङ), response.function_call_arguments.done, response.output_item.done। |
/v1/messages | प्रत्येक कलमा: content_block_start (खाली input भएको tool_use ब्लक), एउटा content_block_delta जसको input_json_delta.partial_json पूरा आर्गुमेन्ट टेक्स्ट हुन्छ, content_block_stop। त्यसपछि message_delta मा stop_reason: "tool_use" हुन्छ। |
shannon-1.6-lite, shannon-1.6-pro, shannon-2-lite, shannon-2-pro र shannon-coder-1 मा, tools भएको स्ट्रिम अनुरोधले आफ्नो उत्तर टेक्स्ट टर्नको अन्त्यमा एउटै content डेल्टामा दिन्छ। स्ट्रिमिङ
नतिजा फर्काउने
दोस्रो अनुरोधले कुराकानी दोहोर्याउँछ र दुई कुरा थप्छ: कल माग्ने असिस्टेन्ट टर्न, र प्रत्येक कलको एउटा नतिजा।
{
"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\"}"
}
]
}
]
} - असिस्टेन्ट टर्न नतिजाहरू अघि, जसरी पाउनुभयो त्यसै फर्काउनुहोस्। हरेक नतिजा id द्वारा आफ्नो कलसँग मिलाइन्छ:
/v1/chat/completionsमाtool_call_id,/v1/responsesमाcall_id,/v1/messagesमाtool_use_id। - नतिजा टेक्स्ट हो। अब्जेक्टलाई
contentका लागि (/v1/responsesमाoutput) JSON स्ट्रिङमा सिरियलाइज गर्नुहोस्।/v1/messagesमाtool_resultब्लककोcontentस्ट्रिङ वा टेक्स्ट ब्लकहरूको सूची हुन्छ। - असिस्टेन्ट टर्नमा
function.argumentsजस्ताको तस्तै आएको JSON स्ट्रिङ नै रहन्छ। - कुराकानी टुल नतिजामा सकिन सक्छ। नयाँ प्रयोगकर्ता सन्देश चाहिँदैन: मोडल नतिजाबाटै अघि बढ्छ।
- तपाईंको फङ्सन असफल हुँदा असफलतालाई नतिजा टेक्स्टका रूपमा पठाउनुहोस्। त्यसपछि मोडलले त्यसको रिपोर्ट गर्न वा अर्को कल माग्न सक्छ।
स्कीमा किवर्डहरू
parameters (/v1/messages मा input_schema) JSON Schema हो। Shannon 3 परिवार (shannon-3, shannon-3-pro, shannon-3.1, shannon-3.1-pro) र होस्ट गरिएका ओपन-वेट मोडलहरूले यसलाई तपाईंले पठाएजस्तै पाउँछन्।
shannon-1.6-lite, shannon-1.6-pro, shannon-2-lite, shannon-2-pro र shannon-coder-1 ले तीनवटै इन्डपोइन्टमा यो सबसेट पाउँछन्:
| व्यवहार | किवर्डहरू |
|---|---|
| पठाएजस्तै पढिन्छ | तलका पङ्क्तिमा नाम नदिइएको हरेक किवर्ड, उदाहरणका लागि type, properties, required, items, enum, description, minimum, maximum, anyOf र allOf, स्कीमाको हरेक तहमा। |
format | int32, int64, float, double, byte, date, date-time र enum मानहरूका लागि पढिन्छ। |
oneOf | anyOf का रूपमा पढिन्छ। |
| यी मोडलहरूले पाउने स्कीमाको भाग होइन | $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 र exclusiveMaximum; format का अन्य मानहरू। |
व्यवहार र सीमाहरू
- API ले टुलको अधिकतम संख्या र राउन्डको अधिकतम संख्या तोक्दैन।
- अनुरोध बडी 32 MiB सम्म हुन सक्छ, र नतिजासहितको कुराकानी मोडलको कन्टेक्स्ट विन्डोमा अट्नुपर्छ।
- अनुरोधमा
toolsहुँदाshannon-1.6-lite,shannon-1.6-pro,shannon-2-liteरshannon-2-proले पूर्वनिर्धारितtemperature0.2 प्रयोग गर्छन्। अर्को मान सेट गर्नtemperatureपठाउनुहोस्। - हरेक राउन्ड आफ्नै अनुरोध हो: यसले तपाईंको ब्यालेन्सबाट खर्च गर्छ र अरू अनुरोधजस्तै फ्लड प्रोटेक्सनमा गनिन्छ। सीमा र ब्यालेन्स
त्रुटिहरू
टुल कल स्टेटस 200 सहितको सामान्य जवाफ हो। यी त्रुटिहरू अनुरोधसँगै सम्बन्धित छन्:
| स्थिति | प्रकार | सन्देश | कहिले |
|---|---|---|---|
400 | invalid_request_error | unknown model: <id> | model प्रकाशित सूचीको id होइन। |
422 | invalid_request_error | Failed to deserialize the JSON body into the target type: … | tools एरे होइन, वा अर्को फिल्डको JSON प्रकार गलत छ। |
413 | invalid_request_error | Failed to buffer the request body: … | अनुरोध बडी 32 MiB भन्दा ठूलो छ। त्रुटिमा code: "request_too_large" हुन्छ। |
आर्गुमेन्टहरू मोडलले लेख्छ। फङ्सन चलाउनु अघि तिनलाई आफ्नो स्कीमासँग जाँच्नुहोस्, जसरी तपाईं कुनै बाहिरी इनपुट जाँच्नुहुन्छ।
प्रमाणीकरण, ब्यालेन्स र सर्भर त्रुटिहरू हरेक अनुरोधमा जस्तै हुन्छन्। त्रुटि व्यवस्थापन