Skip to main content

Вызов инструментов (Function Calling)

Позвольте моделям вызывать внешние функции и API через структурированные инструменты.

Обзор

Tool calling позволяет модели запрашивать внешние данные или действия. Вы описываете инструменты, модель возвращает tool_calls с JSON-аргументами.

Ваше приложение выполняет инструмент и возвращает результат в сообщении role: tool, после чего модель формирует ответ.

Типовые сценарии

  • Данные в реальном времени (погода, цены, метрики).
  • Поиск и извлечение свежей информации.
  • Вычисления и преобразования.
  • Внутренние API, базы данных и бизнес-логика.

Доступность зависит от модели

GonkaGate передает tools в модель. Проверьте Models или эндпоинт /v1/models для актуальной поддержки.

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

Каждый инструмент — JSON-объект с type: "function" и описанием функции.

Аргументы описываются JSON Schema в parameters. Обязательные поля: name, description, parameters.

tool-weather.json
{
  "type": "function",
  "function": {
    "name": "get_weather",
    "description": "Get current weather for a location",
    "parameters": {
      "type": "object",
      "properties": {
        "location": {
          "type": "string",
          "description": "City name, e.g., "Tokyo""
        },
        "unit": {
          "type": "string",
          "enum": ["celsius", "fahrenheit"],
          "description": "Temperature unit"
        }
      },
      "required": ["location"]
    }
  }
}

Советы по описанию

  • Используйте короткие имена в snake_case и избегайте пробелов.
  • Пишите точные описания и подсказки для входных данных.
  • Добавляйте enum, min/max и required для ограничений.

Запросы с инструментами

Передайте массив tools и при необходимости задайте политику tool_choice.

request.json
{
  "model": "qwen/qwen3-235b-a22b-instruct-2507-fp8",
  "messages": [
    { "role": "user", "content": "What's the weather in Tokyo?" }
  ],
  "tools": [
    {
      "type": "function",
      "function": {
        "name": "get_weather",
        "description": "Get current weather for a location",
        "parameters": {
          "type": "object",
          "properties": {
            "location": { "type": "string" },
            "unit": { "type": "string", "enum": ["celsius", "fahrenheit"] }
          },
          "required": ["location"]
        }
      }
    }
  ],
  "tool_choice": "auto"
}

Поля запроса описаны в эндпоинте chat completions в справочнике API.

Опции tool_choice

Контролируйте, когда модель должна использовать инструменты.

auto
Поведение
Модель сама решает, вызывать ли инструмент.
none
Поведение
Отключить инструменты для этого запроса.
required
Поведение
Обязать модель вызвать хотя бы один инструмент.
{ type: "function", function: { name: "tool_name" } }
Поведение
Принудительно вызвать конкретный инструмент.

Обработка tool_calls

Когда нужен инструмент, ассистент возвращает tool_calls и finish_reason: "tool_calls".

response.json
{
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": null,
        "tool_calls": [
          {
            "id": "call_abc123",
            "type": "function",
            "function": {
              "name": "get_weather",
              "arguments": "{"location":"Tokyo","unit":"celsius"}"
            }
          }
        ]
      },
      "finish_reason": "tool_calls"
    }
  ]
}

Возврат результатов

Отправляйте результаты как сообщения role: "tool" с ссылкой на tool_call_id.

tool-result.json
{
  "role": "tool",
  "tool_call_id": "call_abc123",
  "content": "{"location":"Tokyo","temp_c":24,"conditions":"Cloudy"}"
}

Формат вывода

Поле content — строка. Если результат JSON, сериализуйте через JSON.stringify или json.dumps.

Полный пример

Сквозной сценарий: описание инструментов, обработка вызовов, возврат результатов и финальный ответ.

tool-calling.py
from openai import OpenAI
import json

client = OpenAI(
    base_url="https://api.gonkagate.com/v1",
    api_key="gp-your-api-key"
)

tools = [
    {
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "Get weather for a location",
            "parameters": {
                "type": "object",
                "properties": {
                    "location": {"type": "string"},
                    "unit": {"type": "string", "enum": ["celsius", "fahrenheit"]}
                },
                "required": ["location"]
            }
        }
    }
]

def get_weather(location: str, unit: str = "celsius"):
    # Replace with your real API call
    return {"location": location, "unit": unit, "temp": 24, "conditions": "Cloudy"}

messages = [{"role": "user", "content": "What's the weather in Tokyo?"}]

response = client.chat.completions.create(
    model="qwen/qwen3-235b-a22b-instruct-2507-fp8",
    messages=messages,
    tools=tools,
    tool_choice="auto"
)

tool_calls = response.choices[0].message.tool_calls or []
if tool_calls:
    # Add assistant tool call message
    messages.append(response.choices[0].message)

    for call in tool_calls:
        args = json.loads(call.function.arguments or "{}")
        result = get_weather(**args)

        messages.append({
            "role": "tool",
            "tool_call_id": call.id,
            "content": json.dumps(result)
        })

    final_response = client.chat.completions.create(
        model="qwen/qwen3-235b-a22b-instruct-2507-fp8",
        messages=messages,
        tools=tools
    )

    print(final_response.choices[0].message.content)

Параллельные вызовы

Модель может запросить несколько инструментов за один ход. Выполняйте их параллельно и возвращайте отдельные сообщения.

parallel-tools.ts
const toolCalls = response.choices[0]?.message?.tool_calls ?? [];
messages.push(response.choices[0].message);

const results = await Promise.all(
  toolCalls.map(async (call) => {
    const args = JSON.parse(call.function.arguments || "{}");
    const output = await runTool(call.function.name, args);

    return {
      role: "tool",
      tool_call_id: call.id,
      content: JSON.stringify(output)
    };
  })
);

messages.push(...results);

Streaming с инструментами

В streaming режиме tool_calls приходят дельтами. Накапливайте частичные arguments для каждого вызова перед разбором JSON.

streaming-tools.ts
const stream = await client.chat.completions.create({
  model: "qwen/qwen3-235b-a22b-instruct-2507-fp8",
  messages,
  tools,
  stream: true
});

const toolCalls: Record<string, { name?: string; arguments: string }> = {};

for await (const chunk of stream) {
  const delta = chunk.choices[0]?.delta;
  const calls = delta?.tool_calls ?? [];

  for (const call of calls) {
    const id = call.id ?? String(call.index);
    const current = toolCalls[id] ?? { arguments: "" };

    if (call.function?.name) {
      current.name = call.function.name;
    }

    if (call.function?.arguments) {
      current.arguments += call.function.arguments;
    }

    toolCalls[id] = current;
  }
}

const finalized = Object.values(toolCalls).map((call) => ({
  name: call.name ?? "unknown",
  args: JSON.parse(call.arguments || "{}")
}));

Лучшие практики

Сделайте tool calling надежным с этими правилами:

  • Держите список инструментов коротким и релевантным задаче.
  • Валидируйте и очищайте аргументы перед выполнением.
  • Используйте тайм-ауты и обработку ошибок для внешних API.
  • Возвращайте компактные и структурированные результаты.
  • Ограничивайте глубину цепочки инструментов, чтобы избежать циклов.

Совместимость моделей

Поддержка tool calling зависит от модели. Проверьте возможности до продакшена.

Проверьте в каталоге Models или через GET /models в справочнике API.

UI каталог
Что смотреть
Бейджи capabilities и заметки по моделям.
Зачем это нужно
Быстрая визуальная проверка.
API список
Что смотреть
Поля capabilities в ответе /v1/models.
Зачем это нужно
Программная проверка в CI.
Fallback-план
Что смотреть
Путь без tools для моделей без поддержки.
Зачем это нужно
Снижение риска ошибок в рантайме.

Troubleshooting

Частые проблемы и решения:

  • Инструмент не вызывается — уточните описания, установите tool_choice=required или выберите модель с поддержкой.
  • Некорректные JSON-аргументы — повторите запрос или валидируйте/исправляйте перед выполнением.
  • tool_call_id не совпадает — убедитесь, что каждому вызову соответствует правильный id и порядок сообщений.

Ключевые моменты

Была ли эта страница полезной?