Вызов инструментов (Function Calling)
Позвольте моделям вызывать внешние функции и API через структурированные инструменты.
Обзор
Tool calling позволяет модели запрашивать внешние данные или действия. Вы описываете инструменты, модель возвращает tool_calls с JSON-аргументами.
Ваше приложение выполняет инструмент и возвращает результат в сообщении role: tool, после чего модель формирует ответ.
Типовые сценарии
- Данные в реальном времени (погода, цены, метрики).
- Поиск и извлечение свежей информации.
- Вычисления и преобразования.
- Внутренние API, базы данных и бизнес-логика.
Доступность зависит от модели
/v1/models для актуальной поддержки.Описание инструментов
Каждый инструмент — JSON-объект с type: "function" и описанием функции.
Аргументы описываются JSON Schema в parameters. Обязательные поля: name, description, parameters.
{
"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.
{
"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".
{
"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.
{
"role": "tool",
"tool_call_id": "call_abc123",
"content": "{"location":"Tokyo","temp_c":24,"conditions":"Cloudy"}"
}Формат вывода
Полный пример
Сквозной сценарий: описание инструментов, обработка вызовов, возврат результатов и финальный ответ.
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)Параллельные вызовы
Модель может запросить несколько инструментов за один ход. Выполняйте их параллельно и возвращайте отдельные сообщения.
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.
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.
- Что смотреть
- Бейджи capabilities и заметки по моделям.
- Зачем это нужно
- Быстрая визуальная проверка.
- Что смотреть
- Поля capabilities в ответе /v1/models.
- Зачем это нужно
- Программная проверка в CI.
- Что смотреть
- Путь без tools для моделей без поддержки.
- Зачем это нужно
- Снижение риска ошибок в рантайме.
Troubleshooting
Частые проблемы и решения:
- Инструмент не вызывается — уточните описания, установите tool_choice=required или выберите модель с поддержкой.
- Некорректные JSON-аргументы — повторите запрос или валидируйте/исправляйте перед выполнением.
- tool_call_id не совпадает — убедитесь, что каждому вызову соответствует правильный id и порядок сообщений.
Ключевые моменты
- Описывайте инструменты через JSON Schema и четкие описания.
- Выполняйте tool_calls и возвращайте role: "tool" с правильными id.
- Проверьте поддержку модели перед продом.