ፋንክሽን ጥራት
functions በጥያቄው ውስጥ ይግለጹ፣ ሞዴሉም እንዲደረጉ የሚፈልጋቸውን ጥሪዎች ይመልሳል። ኮድዎ ያስኬዳቸዋል እና ውጤቶቹን መልሶ ይልካል፦ API የtool ጥሪዎችን ይመልሳል እንጂ ራሱ tool አያስኬድም።
POST https://api.shannon-ai.com/v1/chat/completions
በዚህ ገጽ ላይ ያሉት ናሙናዎች /v1/chat/completionsን ይጠቀማሉ። ተመሳሳዩ loop በ/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 ነው።
Loop ደረጃ በደረጃ
| ደረጃ | ማን | የሚሆነው |
|---|---|---|
| 1 | እርስዎ | ሞዴሉ ሊጠይቃቸው የሚችላቸውን functions ዝርዝር tools ከmessages ጋር ይላኩ። |
| 2 | ሞዴል | ምላሹ tool_calls እና finish_reason: "tool_calls" ይይዛል። እያንዳንዱ ጥሪ function ይሰይማል እና arguments ይሰጣል። |
| 3 | እርስዎ | የእያንዳንዱን ጥሪ arguments parse ያድርጉ እና function ያስኬዱ። |
| 4 | እርስዎ | የassistant መልእክቱን እና ለእያንዳንዱ ጥሪ አንድ tool መልእክት ወደ messages ይጨምሩ፣ ከዚያ ጥያቄውን በተመሳሳይ tools እንደገና ይላኩ። |
| 5 | ሞዴል | ሞዴሉ በfinish_reason: "stop" በጽሑፍ ይመልሳል፣ ወይም ተጨማሪ ጥሪዎችን ይጠይቃል። በዚያ ጊዜ ወደ ደረጃ 3 ይመለሱ። |
አንድ ጥያቄ አንድ የሞዴል ዙር ነው። API በጥያቄዎች መካከል ውይይት አይይዝም እና የዙሮች ብዛት አይወስንም፦ ኮድዎ messagesን ይይዛል እና መቼ እንደሚቆም ይወስናል።
tools መግለጽ
tools ለእያንዳንዱ function አንድ ግቤት ያለው array ነው። የካታሎጉ እያንዳንዱ ሞዴል ይቀበለዋል፤ GET /v1/models ለእያንዳንዱ id capabilities.tools: true ያሳውቃል።
| መስክ | ዓይነት | መግለጫ |
|---|---|---|
type | string | ሁልጊዜ function። |
function.name | string | ሞዴሉ ይህን function ሲጠይቅ የሚጠቀምበት ስም። ግዴታ። |
function.description | string | function የሚያደርገውን በግልጽ ቋንቋ። |
function.parameters | object | arguments እንደ JSON Schema፣ ከላይ type: "object" ያለው። ከታች Schema ቁልፍ ቃላትን ይመልከቱ። |
እያንዳንዱ endpoint ለtool የራሱ አጻጻፍ አለው። ለሚጠሩት 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 ሞዴሉ tool መጥራት ይችላል ወይስ አለበት የሚለውን ይነግራል። የሚነበበው ከtools ጋር ብቻ ነው።
| እሴት | መግለጫ | የሚተገብሩት |
|---|---|---|
"auto" | ሞዴሉ በጽሑፍ መመለስ ወይም tool መጥራት እንዳለበት ራሱ ይወስናል። ይህ default ነው። | ሁሉም ሞዴሎች |
"required" | መልሱ ቢያንስ አንድ tool ይጠራል። | የተስተናገዱ open-weight ሞዴሎች |
{"type": "function", "function": {"name": "get_weather"}} | መልሱ ይህን function ይጠራል። ስሙ በtools ውስጥ ካሉት functions አንዱ መሆን አለበት። ወደ ሌሎች functions የሚደረጉ ጥሪዎች ከመልሱ ይቀራሉ። | የተስተናገዱ open-weight ሞዴሎች |
የShannon ሞዴሎች (shannon-*) እንደ auto በእያንዳንዱ ጥያቄ ራሳቸው ይወስናሉ።
required ወይም ስም የተሰጠው function ሲኖር tool_callsን ከማንበብዎ በፊት finish_reasonን ያንብቡ። ሞዴሉ ምንም ጥሪ ካላመነጨ መልሱ finish_reason: "stop" ያለው የጽሑፍ መልስ ነው።
| ትርጉም | /v1/chat/completions | /v1/responses | /v1/messages |
|---|---|---|---|
| ሞዴሉ ይወስናል | "auto" | "auto" | {"type": "auto"} |
| ቢያንስ አንድ tool ጥራ | "required" | "required" | {"type": "any"} |
| ስም የተሰጠውን አንድ function ጥራ | {"type": "function", "function": {"name": "get_weather"}} | {"type": "function", "name": "get_weather"} | {"type": "tool", "name": "get_weather"} |
ለተኳሃኝነት ተቀባይነት አላቸው፦ tool_choice: "none" እና parallel_tool_calls። የtool ጥሪ ለሌለው ዙር ጥያቄውን ያለ tools ይላኩ።
በምላሹ ውስጥ ያሉ የtool ጥሪዎች
| መስክ | ዓይነት | መግለጫ |
|---|---|---|
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 | የሚሰራው function። |
tool_calls[].function.arguments | string | arguments እንደ JSON string፣ ምንም ከሌሉ "{}"። ከመጠቀምዎ በፊት parse ያድርጉት። |
message.content | string | null | መልሱ ጥሪዎችን ብቻ ሲይዝ null። የተስተናገዱ open-weight ሞዴሎች ከጥሪዎቹ ጎን ጽሑፍ ሊመልሱ ይችላሉ፤ የShannon ሞዴሎች null ይመልሳሉ። |
ተመሳሳዩ ጥሪ በእያንዳንዱ ፎርማት። በ/v1/responses ላይ የoutput function_call ንጥል ነው፣ arguments እንደ JSON string። በ/v1/messages ላይ input የJSON object የሆነ tool_use content block ነው፣ 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 ያለው።
የተስተናገዱ open-weight ሞዴሎች እያንዳንዱን የተለየ ጥሪ አንድ ጊዜ ይመልሳሉ፦ ተመሳሳይ ስምና ተመሳሳይ arguments ያላቸው ሁለት ጥሪዎች እንደ አንድ ይደርሳሉ።
የstream የተደረጉ የtool ጥሪዎች
በstream: true ጥሪ በአንድ ቁራጭ ይደርሳል፦ chunk ሙሉውን arguments string ይይዛል፣ ስለዚህ የሚያጣምሩ ቁርጥራጮች የሉም። 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 (ሙሉው string)፣ response.function_call_arguments.done፣ response.output_item.done። |
/v1/messages | ለእያንዳንዱ ጥሪ፦ content_block_start (ባዶ input ያለው tool_use block)፣ input_json_delta.partial_json ሙሉው የarguments ጽሑፍ የሆነ አንድ content_block_delta፣ 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 የያዘ የstream ጥያቄ የመልሱን ጽሑፍ በዙሩ መጨረሻ በአንድ content delta ያደርሳል። ስትሪሚንግ
ውጤቶችን መልሶ መላክ
ሁለተኛው ጥያቄ ውይይቱን ይደግማል እና ሁለት ነገሮችን ይጨምራል፦ ጥሪዎቹን የጠየቀውን የ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። - ውጤት ጽሑፍ ነው። object ወደ JSON string አድርገው ለ
content(በ/v1/responsesላይ ለoutput) ይላኩ። በ/v1/messagesላይ የtool_resultblockcontentstring ወይም የtext blocks ዝርዝር ነው። - በassistant ዙር ውስጥ
function.argumentsበደረሰው ትክክለኛ መልኩ JSON string ሆኖ ይቆያል። - ውይይቱ በtool ውጤት ሊያልቅ ይችላል። አዲስ የተጠቃሚ መልእክት አያስፈልግም፦ ሞዴሉ ከውጤቱ ይቀጥላል።
- function ሲከሽፍ ውድቀቱን እንደ ውጤት ጽሑፍ ይላኩ። ከዚያ ሞዴሉ ሊያሳውቀው ወይም ሌላ ጥሪ ሊጠይቅ ይችላል።
የSchema ቁልፍ ቃላት
parameters (በ/v1/messages ላይ input_schema) JSON Schema ነው። የShannon 3 ቤተሰብ (shannon-3, shannon-3-pro, shannon-3.1, shannon-3.1-pro) እና የተስተናገዱ open-weight ሞዴሎች እንደላኩት ይቀበሉታል።
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፣ በእያንዳንዱ የschema ደረጃ። |
format | ለint32፣ int64፣ float፣ double፣ byte፣ date፣ date-time እና enum እሴቶች ይነበባል። |
oneOf | እንደ anyOf ይነበባል። |
| እነዚህ ሞዴሎች ከሚቀበሉት schema አካል አይደለም | $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 ከፍተኛውን የtools ብዛት ወይም ከፍተኛውን የዙሮች ብዛት አይወስንም።
- የጥያቄ body እስከ 32 MiB ሊሆን ይችላል፣ እና ውይይቱ ከውጤቶቹ ጋር በሞዴሉ context window ውስጥ መግባት አለበት።
- ጥያቄው
toolsሲይዝshannon-1.6-lite፣shannon-1.6-pro፣shannon-2-liteእናshannon-2-proየ0.2 defaulttemperatureይጠቀማሉ። ሌላ እሴት ለማዘጋጀትtemperatureይላኩ። - እያንዳንዱ ዙር የራሱ ጥያቄ ነው፦ ከቀሪ ሂሳብዎ ይወስዳል እና እንደ ማንኛውም ጥያቄ ወደ የጥያቄ ብዛት ጥበቃ ይቆጠራል። ገደቦች እና ቀሪ ሂሳብ
ስህተቶች
የtool ጥሪ status 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 array አይደለም፣ ወይም ሌላ መስክ የተሳሳተ JSON አይነት አለው። |
413 | invalid_request_error | Failed to buffer the request body: … | የጥያቄው body ከ32 MiB ይበልጣል። ስህተቱ code: "request_too_large" ይይዛል። |
arguments የሚጽፈው ሞዴሉ ነው። function ከማስኬድዎ በፊት ማንኛውንም የውጭ ግብዓት እንደሚፈትሹ ሁሉ ከschema ጋር ያስተያዩዋቸው።
የማረጋገጫ፣ የቀሪ ሂሳብ እና የserver ስህተቶች ለእያንዳንዱ ጥያቄ እንዳሉት ተመሳሳይ ናቸው። ስህተት አስተዳደር