Модель не вызывает ваши функции сама — она возвращает намерение их вызвать. Выполняете их вы, результат кладёте обратно в диалог.
tool_calls вместо текста и finish_reason: "tool_calls".messages ответ модели и следом сообщение с ролью tool и тем же tool_call_id.{
"model": "anthropic/claude-sonnet-5",
"messages": [{"role": "user", "content": "Какая погода в Москве?"}],
"tools": [{
"type": "function",
"function": {
"name": "get_weather",
"description": "Текущая погода в городе. Возвращает температуру в °C.",
"parameters": {
"type": "object",
"properties": {
"city": {"type": "string", "description": "Город на русском"}
},
"required": ["city"],
"additionalProperties": false
}
}
}]
}Поле description — не украшение. Модель выбирает инструмент по описанию, и «Погода» работает заметно хуже, чем «Текущая погода в городе, возвращает температуру в °C». Пишите, что функция делает и что возвращает.
{
"choices": [{
"message": {
"role": "assistant",
"content": null,
"tool_calls": [{
"id": "call_01H…",
"type": "function",
"function": {"name": "get_weather", "arguments": "{\"city\":\"Москва\"}"}
}]
},
"finish_reason": "tool_calls"
}]
}arguments приходит строкой с JSON внутри: так задано схемой OpenAI, и мы её не меняем. Разбирать нужно явно, и разбор может упасть — модель иногда выдаёт невалидный JSON. Обработайте это как ошибку и повторите вызов, а не роняйте процесс.messages.append(resp.choices[0].message) # ответ модели целиком
messages.append({
"role": "tool",
"tool_call_id": call.id, # тот же id
"content": json.dumps({"temp_c": 14, "wind_ms": 3}),
})
final = client.chat.completions.create(model=MODEL, messages=messages, tools=TOOLS)Параметр tool_choice принимает "auto" (по умолчанию), "none" — запретить вызовы, или явное указание функции, когда вызов обязателен:
"tool_choice": {"type": "function", "function": {"name": "get_weather"}}Несколько инструментов модель может запросить за один ход — в tool_calls придёт массив. Выполняйте их параллельно и верните столько же сообщений с ролью tool, по одному на каждый tool_call_id. Пропущенный ответ ломает следующий запрос.
Поддержка отмечена бейджем «инструменты» в каталоге и полем в характеристиках модели. Модель без поддержки вернёт 400 на запрос с tools — тихо игнорировать поле мы не будем.