Перейти к содержимому
Вызов функций

Вызов функций

Опишите свои функции в запросе, и модель ответит вызовами, которые хочет выполнить. Ваш код выполняет их и отправляет результаты обратно: 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)

Первый ответ не отвечает на вопрос. Он просит выполнить вызов:

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}
  }
}

После отправки результата следующий ответ — обычный: message.content содержит текст, а finish_reason равен stop.

Цикл по шагам

Шаг Кто Что происходит
1 Вы Отправьте messages вместе с tools — списком функций, которые модель может запросить.
2 Модель Ответ содержит tool_calls и finish_reason: "tool_calls". Каждый вызов называет функцию и передает ее аргументы.
3 Вы Разберите arguments каждого вызова и выполните свою функцию.
4 Вы Добавьте в messages сообщение ассистента и по одному сообщению tool на каждый вызов, затем отправьте запрос снова с теми же tools.
5 Модель Модель отвечает текстом с finish_reason: "stop" или запрашивает новые вызовы. В этом случае вернитесь к шагу 3.

Один запрос — один ход модели. API не хранит разговор между запросами и не задает число раундов: messages хранит ваш код, и он же решает, когда остановиться.

Определение инструментов

tools — это массив с одной записью на функцию. Его принимает каждая модель каталога; GET /v1/models сообщает capabilities.tools: true для каждого id.

Поле Тип Описание
type string Всегда function.
function.name string Имя, которое модель использует, когда запрашивает эту функцию. Обязательно.
function.description string Что делает функция, простым языком.
function.parameters object Аргументы в виде JSON Schema с type: "object" на верхнем уровне. См. Ключевые слова схемы ниже.

У каждого эндпоинта своя запись инструмента. Отправляйте ту, что соответствует вызываемому эндпоинту:

{
  "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 определяет, может ли модель или должна ли она вызвать инструмент. Читается только вместе с tools.

Значение Описание Применяется на
"auto" Модель решает, ответить текстом или вызвать инструмент. Это значение по умолчанию. Все модели
"required" Ответ вызывает хотя бы один инструмент. Размещенные модели с открытыми весами
{"type": "function", "function": {"name": "get_weather"}} Ответ вызывает эту функцию. Имя должно быть одним из имен функций в tools. Вызовы других функций в ответ не попадают. Размещенные модели с открытыми весами

Модели Shannon (shannon-*) решают в каждом запросе сами, как при auto.

С required или именованной функцией читайте finish_reason, прежде чем читать tool_calls. Если модель не создала ни одного вызова, ответ — текстовый, с 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 это элемент function_call в output, с 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\"}"
        }
      }
    ]
  }
}

Несколько вызовов за один ход

Ответ может содержать несколько вызовов. Выполните каждый из них и отправьте по одному результату на вызов, каждый со своим tool_call_id, в следующем запросе.

Размещенные модели с открытыми весами возвращают каждый уникальный вызов один раз: два вызова с одним именем и одинаковыми аргументами приходят как один.

Потоковые вызовы инструментов

С stream: true вызов приходит целиком: чанк содержит полную строку arguments, поэтому склеивать фрагменты не нужно. index нумерует вызовы хода с 0.

data: один чанк, с форматированием
{
  "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 (элемент function_call с пустыми arguments), response.function_call_arguments.delta (вся строка), response.function_call_arguments.done, response.output_item.done.
/v1/messages На каждый вызов: content_block_start (блок tool_use с пустым input), один 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\"}"
    }
  ]
}
  • Отправьте ход ассистента обратно в том виде, в каком получили его, перед результатами. Каждый результат сопоставляется со своим вызовом по id: tool_call_id на /v1/chat/completions, call_id на /v1/responses, tool_use_id на /v1/messages.
  • Результат — это текст. Сериализуйте объект в JSON-строку для content (output на /v1/responses). На /v1/messages content блока tool_result — строка или список текстовых блоков.
  • В ходе ассистента function.arguments остается JSON-строкой, ровно в том виде, в каком пришла.
  • Разговор может заканчиваться результатом инструмента. Новое сообщение пользователя не нужно: модель продолжает с результата.
  • Если ваша функция завершилась сбоем, отправьте сбой в качестве текста результата. Тогда модель сможет сообщить о нем или запросить другой вызов.

Ключевые слова схемы

parameters (input_schema на /v1/messages) — это 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 используют temperature по умолчанию, равную 0.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".

Аргументы пишет модель. Проверьте их по своей схеме, прежде чем выполнять функцию, как проверяли бы любой внешний ввод.

Ошибки аутентификации, баланса и сервера те же, что и для любого запроса. Обработка ошибок