Tool Calling (или Function Calling) — это механизм, позволяющий модели LLM запрашивать выполнение внешних функций в структурированном формате JSON. Вместо того чтобы полагаться на «галлюцинации» модели для получения точных данных (например, погоды или курсов валют), вы предоставляете ей описание функции. Модель возвращает запрос на её вызов, ваш код исполняет функцию и возвращает результат, после чего модель формирует финальный ответ.
Ключевая проблема большинства туториалов: они привязаны к одному провайдеру (обычно OpenAI). При переходе на Claude или open-source модели (Llama, Mistral) часто требуется переписывать схему инструментов или логику парсинга. OpenRouter решает эту проблему, предоставляя единый API-шлюз, совместимый с форматом OpenAI. Вы пишете цикл один раз, меняя только строку с именем модели.
011. Определение инструмента (Tool Schema)
Сначала определим инструмент. Мы используем стандартную схему JSON, понятную всем современным LLM. В примере — функция получения погоды get_weather. Обратите внимание: модель никогда не исполняет код сама, она только генерирует JSON-запрос.
Схема должна включать имя, описание и параметры (с типами данных и обязательными полями).
arguments в ответе модели — это строка, а не объект. Её нужно обязательно парсить через JSON.parse или json.loads. Также не доверяйте модели слепо: всегда проверяйте ключи JSON перед передачей в функцию, так как модель может выдать лишние или невалидные параметры.022. Реализация цикла на Python
Для работы потребуется Python 3.10+ и библиотека openai (даже для работы с OpenRouter, так как API совместим). Установите пакет:
pip install openaiНиже представлен полный цикл обработки. Он делает два запроса к API: первый — чтобы получить запрос на вызов инструмента, второй — чтобы получить финальный ответ на основе результата выполнения функции.
import json
import os
from openai import OpenAI
# Инициализация клиента OpenRouter
client = OpenAI(
base_url="https://openrouter.ai/api/v1",
api_key=os.environ["OPENROUTER_API_KEY"],
)
# Схема инструмента
tools = [{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get the current weather for a location.",
"parameters": {
"type": "object",
"properties": {
"location": {"type": "string", "description": "City name, e.g. 'Paris'"},
"unit": {"type": "string", "enum": ["celsius", "fahrenheit"]}
},
"required": ["location"]
}
}
}]
def get_weather(location, unit="celsius"):
# Здесь должна быть реальная логика (API запрос)
return {"location": location, "temperature": 18, "unit": unit, "sky": "clear"}
def run_tool_loop(model, user_message):
messages = [{"role": "user", "content": user_message}]
# Шаг 1: Запрос к модели
response = client.chat.completions.create(
model=model,
messages=messages,
tools=tools
)
msg = response.choices[0].message
# Если инструмент не нужен, возвращаем прямой ответ
if not msg.tool_calls:
return msg.content
# Шаг 2: Добавляем ответ ассистента в контекст
messages.append(msg)
# Шаг 3: Исполняем инструменты
for call in msg.tool_calls:
args = json.loads(call.function.arguments)
result = get_weather(**args)
messages.append({
"role": "tool",
"tool_call_id": call.id,
"content": json.dumps(result)
})
# Шаг 4: Запрос финального ответа
final = client.chat.completions.create(
model=model,
messages=messages,
tools=tools
)
return final.choices[0].message.content033. Реализация на JavaScript/TypeScript (Node.js)
Для Node.js 22+ используйте пакет openai. Логика идентична Python-версии.
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://openrouter.ai/api/v1",
apiKey: process.env.OPENROUTER_API_KEY,
});
const tools = [{
type: "function",
function: {
name: "get_weather",
description: "Get the current weather for a location.",
parameters: {
type: "object",
properties: {
location: { type: "string", description: "City name, e.g. 'Paris'" },
unit: { type: "string", enum: ["celsius", "fahrenheit"] }
},
required: ["location"]
}
}
}];
function getWeather(location, unit = "celsius") {
return { location, temperature: 18, unit, sky: "clear" };
}
async function runToolLoop(model, userMessage) {
const messages = [{ role: "user", content: userMessage }];
const response = await client.chat.completions.create({ model, messages, tools });
const msg = response.choices[0].message;
if (!msg.tool_calls) return msg.content;
messages.push(msg);
for (const call of msg.tool_calls) {
const args = JSON.parse(call.function.arguments);
const result = getWeather(args.location, args.unit);
messages.push({
role: "tool",
tool_call_id: call.id,
content: JSON.stringify(result)
});
}
const final = await client.chat.completions.create({ model, messages, tools });
return final.choices[0].message.content;
}044. Сравнение моделей и производительность
Самое важное преимущество подхода — кросс-провайдерность. Ниже приведена таблица моделей, поддерживающих Tool Calling, и пример их поведения с одним и тем же кодом.
| Модель (OpenRouter ID) | Провайдер | Тип | Пример результата |
|---|---|---|---|
anthropic/claude-opus-4.8 |
Anthropic | Флагман | «It's currently 18°C and clear in Paris.» |
openai/gpt-4o |
OpenAI | Универсальная | «The weather in Paris is 18°C and clear.» |
meta-llama/llama-3.1-405b |
Meta | Open Source | «Paris weather: 18°C, clear sky.» |
055. Обработка ошибок и Edge Cases
В продакшене необходимо добавить обработку ошибок при парсинге JSON. Модель может вернуть невалидную строку или параметры, отсутствующие в схеме.
- Валидация JSON: Оберните
json.loadsв блокtry/except. Если парсинг не удался, верните ошибку в чат, чтобы модель попробовала переформулировать запрос. - Проверка ключей: Используйте библиотеки валидации (например,
pydanticв Python илиzodв JS) для проверки входящих аргументов перед вызовом бизнес-логики. - Multiple Tool Calls: Модель может запросить выполнение нескольких функций одновременно. Цикл
for call in msg.tool_callsобрабатывает массив, поэтому код выше уже готов к этому сценарию.
06Кому подойдёт / что запустится
Этот подход идеален для разработчиков, строящих AI-агентов или чат-ботов с доступом к внешним данным. Вам не нужно поддерживать отдельные SDK для OpenAI, Anthropic и Llama. Достаточно одного клиента OpenRouter.
Что запустится прямо сейчас:
- Python 3.10+ с
pip install openai. - Node.js 22+ с
npm install openai. - Любая модель из каталога OpenRouter, помеченная как поддерживающая
tools(Claude Opus/Sonnet, GPT-4o, Llama 3.1 405B/70B, Mistral Large).
Для тестирования скопируйте код Python, установите ключ API и запустите run_tool_loop("anthropic/claude-opus-4.8", "What's the weather in Paris?"). Результат будет получен через два API-вызова.
Источник: OpenRouter ↗
