Chuyển đến nội dung
Gọi hàm

Gọi hàm

Hãy mô tả các hàm của bạn trong yêu cầu và model sẽ trả lời bằng những lần gọi nó muốn thực hiện. Mã của bạn chạy chúng và gửi kết quả trở lại: API trả về các lần gọi tool và tự nó không chạy tool.

POST https://api.shannon-ai.com/v1/chat/completions

Các mẫu trên trang này dùng /v1/chat/completions. Cùng vòng lặp đó chạy trên /v1/responses và /v1/messages; ở chỗ mỗi định dạng viết khác nhau, các phần bên dưới cho thấy cả ba.

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)

Phản hồi đầu tiên không trả lời câu hỏi. Nó yêu cầu một lần gọi:

200 JSON
{
  "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}
  }
}

Sau khi bạn gửi kết quả, phản hồi tiếp theo là một câu trả lời thông thường: message.content chứa văn bản và finish_reason là stop.

Vòng lặp, từng bước

Bước Ai Điều xảy ra
1 Bạn Gửi messages cùng với tools, danh sách các hàm mà model có thể yêu cầu.
2 Model Phản hồi mang tool_calls và finish_reason: "tool_calls". Mỗi lần gọi nêu tên một hàm và đưa ra các đối số của nó.
3 Bạn Phân tích arguments của từng lần gọi và chạy hàm của bạn.
4 Bạn Thêm tin nhắn assistant và một tin nhắn tool cho mỗi lần gọi vào messages, rồi gửi lại yêu cầu với cùng tools.
5 Model Model trả lời bằng văn bản với finish_reason: "stop", hoặc yêu cầu thêm các lần gọi. Trong trường hợp đó hãy quay lại bước 3.

Một yêu cầu là một lượt của model. API không giữ cuộc hội thoại giữa các yêu cầu và không đặt số vòng: mã của bạn giữ messages và quyết định khi nào dừng.

Định nghĩa tool

tools là một mảng với mỗi hàm một phần tử. Mọi model trong danh mục đều chấp nhận nó; GET /v1/models báo capabilities.tools: true cho mọi id.

Trường Loại Mô tả
type string Luôn là function.
function.name string Tên mà model dùng khi yêu cầu hàm này. Bắt buộc.
function.description string Hàm làm gì, bằng ngôn ngữ thông thường.
function.parameters object Các đối số dưới dạng JSON Schema với type: "object" ở trên cùng. Xem Từ khóa schema bên dưới.

Mỗi endpoint có cách viết riêng cho một tool. Hãy gửi dạng thuộc về endpoint bạn gọi:

{
  "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"]
    }
  }
}

tool_choice

tool_choice cho biết model được phép, hoặc phải, gọi một tool hay không. Nó chỉ được đọc cùng với tools.

Giá trị Mô tả Áp dụng bởi
"auto" Model tự quyết định trả lời bằng văn bản hay gọi một tool. Đây là mặc định. Tất cả model
"required" Phản hồi gọi ít nhất một tool. Các model open-weight hosted
{"type": "function", "function": {"name": "get_weather"}} Phản hồi gọi hàm này. Tên phải là một trong các hàm trong tools. Các lần gọi tới hàm khác bị loại khỏi phản hồi. Các model open-weight hosted

Các model Shannon (shannon-*) tự quyết định trong mọi yêu cầu, như với auto.

Với required hoặc một hàm có tên, hãy đọc finish_reason trước khi đọc tool_calls. Khi model không tạo ra lần gọi nào, phản hồi là câu trả lời văn bản với finish_reason: "stop".

Ý nghĩa /v1/chat/completions /v1/responses /v1/messages
Model tự quyết định "auto" "auto" {"type": "auto"}
Gọi ít nhất một tool "required" "required" {"type": "any"}
Gọi một hàm có tên {"type": "function", "function": {"name": "get_weather"}} {"type": "function", "name": "get_weather"} {"type": "tool", "name": "get_weather"}

Được chấp nhận để tương thích: tool_choice: "none" và parallel_tool_calls. Với lượt không gọi tool, hãy gửi yêu cầu không có tools.

Các lần gọi tool trong phản hồi

Trường Loại Mô tả
finish_reason string tool_calls khi phản hồi mang ít nhất một lần gọi.
message.tool_calls array Mỗi lần gọi một phần tử. Trường này chỉ có khi model yêu cầu một lần gọi.
tool_calls[].id string call_ theo sau là 32 ký tự thập lục phân. Hãy gửi lại dưới dạng tool_call_id cùng với kết quả.
tool_calls[].type string Luôn là function.
tool_calls[].function.name string Hàm cần chạy.
tool_calls[].function.arguments string Các đối số dưới dạng chuỗi JSON, "{}" khi không có đối số nào. Hãy phân tích nó trước khi dùng.
message.content string | null null khi phản hồi chỉ chứa các lần gọi. Các model open-weight hosted có thể trả về văn bản bên cạnh các lần gọi; các model Shannon trả về null.

Cùng một lần gọi trong từng định dạng. Trên /v1/responses nó là một mục function_call của output, với arguments là chuỗi JSON. Trên /v1/messages nó là một content block tool_use có input là đối tượng JSON, id của nó bắt đầu bằng toolu_, và stop_reason là 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\"}"
        }
      }
    ]
  }
}

Nhiều lần gọi trong một lượt

Một phản hồi có thể mang nhiều lần gọi. Hãy chạy tất cả và gửi một kết quả cho mỗi lần gọi, mỗi kết quả với tool_call_id riêng, trong yêu cầu tiếp theo.

Các model open-weight hosted trả về mỗi lần gọi khác nhau một lần: hai lần gọi có cùng tên và cùng đối số đến dưới dạng một.

Các lần gọi tool dạng streaming

Với stream: true, một lần gọi đến thành một khối: chunk chứa chuỗi arguments đầy đủ, nên không có mảnh nào cần ghép. index đếm các lần gọi của lượt, bắt đầu từ 0.

data: một chunk, đã định dạng
{
  "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 Điều được gửi đến
/v1/chat/completions Một chat.completion.chunk cho mỗi lần gọi, với lần gọi nằm trong delta.tool_calls[0]. Chunk cuối có finish_reason: "tool_calls" và usage.
/v1/responses Với mỗi lần gọi: response.output_item.added (một mục function_call với arguments rỗng), response.function_call_arguments.delta (toàn bộ chuỗi), response.function_call_arguments.done, response.output_item.done.
/v1/messages Với mỗi lần gọi: content_block_start (một block tool_use với input rỗng), một content_block_delta có input_json_delta.partial_json là toàn bộ văn bản đối số, content_block_stop. Sau đó message_delta mang stop_reason: "tool_use".

Trên shannon-1.6-lite, shannon-1.6-pro, shannon-2-lite, shannon-2-pro và shannon-coder-1, yêu cầu streaming có mang tools đưa văn bản câu trả lời trong một delta content ở cuối lượt. Truyền phát

Gửi kết quả trở lại

Yêu cầu thứ hai lặp lại cuộc hội thoại và thêm hai thứ: lượt assistant đã yêu cầu các lần gọi, và một kết quả cho mỗi lần gọi.

{
  "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\"}"
    }
  ]
}
  • Hãy gửi lại lượt assistant đúng như bạn nhận được, trước các kết quả. Mỗi kết quả được ghép với lần gọi của nó bằng id: tool_call_id trên /v1/chat/completions, call_id trên /v1/responses, tool_use_id trên /v1/messages.
  • Kết quả là văn bản. Hãy tuần tự hóa đối tượng thành chuỗi JSON cho content (output trên /v1/responses). Trên /v1/messages, content của block tool_result là một chuỗi hoặc một danh sách các block văn bản.
  • Trong lượt assistant, function.arguments vẫn là chuỗi JSON, đúng như khi nó đến.
  • Cuộc hội thoại có thể kết thúc bằng một kết quả tool. Không cần tin nhắn người dùng mới: model tiếp tục từ kết quả đó.
  • Khi hàm của bạn lỗi, hãy gửi lỗi đó làm văn bản kết quả. Khi đó model có thể báo lại hoặc yêu cầu một lần gọi khác.

Từ khóa schema

parameters (input_schema trên /v1/messages) là một JSON Schema. Dòng Shannon 3 (shannon-3, shannon-3-pro, shannon-3.1, shannon-3.1-pro) và các model open-weight hosted nhận nó đúng như bạn gửi.

shannon-1.6-lite, shannon-1.6-pro, shannon-2-lite, shannon-2-pro và shannon-coder-1 nhận tập con này, trên cả ba endpoint:

Cách xử lý Từ khóa
Được đọc như đã gửi Mọi từ khóa không được nêu tên trong các hàng bên dưới, ví dụ type, properties, required, items, enum, description, minimum, maximum, anyOf và allOf, ở mọi cấp của schema.
format Được đọc với các giá trị int32, int64, float, double, byte, date, date-time và enum.
oneOf Được đọc như anyOf.
Không thuộc schema mà các model này nhận được $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 và exclusiveMaximum khi chúng là số; các giá trị khác của format.

Hành vi và giới hạn

  • API không đặt số tool tối đa và không đặt số vòng tối đa.
  • Nội dung yêu cầu có thể lên tới 32 MiB, và cuộc hội thoại cùng các kết quả của nó phải vừa với cửa sổ ngữ cảnh của model.
  • Khi yêu cầu mang tools, shannon-1.6-lite, shannon-1.6-pro, shannon-2-lite và shannon-2-pro dùng temperature mặc định là 0.2. Hãy gửi temperature để đặt giá trị khác.
  • Mỗi vòng là một yêu cầu riêng: nó trừ vào số dư của bạn và được tính vào flood protection như mọi yêu cầu khác. Giới hạn và số dư

Lỗi

Một lần gọi tool là một phản hồi bình thường với trạng thái 200. Các lỗi này liên quan đến chính yêu cầu:

Trạng thái Loại Thông báo Khi nào
400 invalid_request_error unknown model: <id> model không phải là id trong danh sách đã công bố.
422 invalid_request_error Failed to deserialize the JSON body into the target type: … tools không phải là mảng, hoặc một trường khác có kiểu JSON sai.
413 invalid_request_error Failed to buffer the request body: … Nội dung yêu cầu lớn hơn 32 MiB. Lỗi mang code: "request_too_large".

Model viết các đối số. Hãy kiểm tra chúng theo schema của bạn trước khi chạy hàm, như bạn kiểm tra mọi đầu vào từ bên ngoài.

Lỗi xác thực, số dư và server giống như với mọi yêu cầu. Xử lý lỗi