فنکشن کالنگ
درخواست میں اپنے فنکشنز بیان کریں اور ماڈل ان کالز کے ساتھ جواب دیتا ہے جو وہ کروانا چاہتا ہے۔ آپ کا کوڈ انہیں چلاتا ہے اور نتائج واپس بھیجتا ہے: 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 | آپ | assistant پیغام اور ہر کال کے لیے ایک 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 | آرگیومنٹس بطور JSON Schema، جس کے اوپر type: "object" ہو۔ نیچے اسکیما کے کلیدی الفاظ دیکھیں۔ |
ہر endpoint میں ٹول لکھنے کا اپنا طریقہ ہے۔ وہ بھیجیں جو اس endpoint کا ہے جسے آپ کال کرتے ہیں:
{
"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 کے ساتھ کال ایک ہی ٹکڑے میں آتی ہے: chunk میں مکمل 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
}
]
} | Endpoint | کیا آتا ہے |
|---|---|
/v1/chat/completions | ہر کال کے لیے ایک chat.completion.chunk، کال delta.tool_calls[0] میں۔ آخری chunk میں 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 ڈیلٹا میں دیتی ہے۔ اسٹریمنگ
نتائج واپس بھیجنا
دوسری درخواست گفتگو کو دہراتی ہے اور دو چیزیں جوڑتی ہے: وہ assistant ٹرن جس نے کالز مانگی تھیں، اور ہر کال کا ایک نتیجہ۔
{
"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\"}"
}
]
}
]
} - assistant ٹرن کو ویسے ہی واپس بھیجیں جیسے آپ کو ملا، نتائج سے پہلے۔ ہر نتیجہ 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سٹرنگ یا ٹیکسٹ بلاکس کی فہرست ہوتا ہے۔ - assistant ٹرن میں
function.argumentsJSON سٹرنگ ہی رہتا ہے، بالکل ویسا جیسا آیا تھا۔ - گفتگو ٹول کے نتیجے پر ختم ہو سکتی ہے۔ نئے صارف پیغام کی ضرورت نہیں: ماڈل نتیجے سے آگے بڑھتا ہے۔
- جب آپ کا فنکشن ناکام ہو تو ناکامی کو نتیجے کے متن کے طور پر بھیجیں۔ پھر ماڈل اسے رپورٹ کر سکتا ہے یا دوسری کال مانگ سکتا ہے۔
اسکیما کے کلیدی الفاظ
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 تینوں endpoints پر یہ ذیلی سیٹ وصول کرتے ہیں:
| سلوک | کلیدی الفاظ |
|---|---|
| جیسا بھیجا گیا ویسا پڑھا جاتا ہے | ہر وہ کلیدی لفظ جس کا نام نیچے کی قطاروں میں نہیں، مثلاً 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بھیجیں۔ - ہر راؤنڈ اپنی درخواست ہے: یہ آپ کے بیلنس سے خرچ کرتا ہے اور کسی بھی دوسری درخواست کی طرح flood protection میں شمار ہوتا ہے۔ حدود اور بیلنس
ایررز
ٹول کال اسٹیٹس 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" ہوتا ہے۔ |
آرگیومنٹس ماڈل لکھتا ہے۔ فنکشن چلانے سے پہلے انہیں اپنی اسکیما کے مطابق جانچیں، جیسے آپ کسی بھی بیرونی ان پٹ کو جانچتے ہیں۔
توثیق، بیلنس اور سرور کے ایررز ہر درخواست کی طرح ہی ہیں۔ غلطیاں