Даём модели возможность «действовать» — вызывать функции (tool). Ключевой момент: модель не выдумывает данные, а просит нас выполнить функцию.
Современные LLM API уже имеют нативную поддержку tools — ты описываешь
tools в запросе через JSON Schema,
и модель сама возвращает tool_calls в структурированном виде.
Не нужно просить «верни JSON» — это уже встроено в протокол.
Ключевой момент: модель решает сама — вызвать tool или ответить текстом.
Ты не пишешь if/else — модель видит описание tools и контекст вопроса,
и принимает решение за тебя.
// src/02-with-tool.ts
import OpenAI from "openai";
import dotenv from "dotenv";
dotenv.config();
const client = new OpenAI({
baseURL: "https://openrouter.ai/api/v1",
apiKey: process.env.OPENROUTER_API_KEY ?? "",
});
// 1. Описываем tools — это просто JSON Schema
const tools: OpenAI.ChatCompletionTool[] = [
{
type: "function",
function: {
name: "get_weather",
description: "Получить текущую погоду в городе",
parameters: {
type: "object",
properties: {
city: {
type: "string",
description: "Название города",
},
},
required: ["city"],
},
},
},
];
// 2. Реализация tool — обычная функция
function get_weather(city: string): string {
// Пока фейковая, потом можно реальный API
const data: Record<string, string> = {
"Москва": "−5°C, снег",
"Анапа": "+8°C, облачно",
"Лондон": "+3°C, дождь",
};
return data[city] ?? `Нет данных для города ${city}`;
}
async function main() {
const response = await client.chat.completions.create({
model: "anthropic/claude-sonnet-4.5",
messages: [
{ role: "user", content: "Какая погода в Анапе?" },
],
tools,
});
const message = response.choices[0].message;
// 3. Смотрим что вернула модель
console.log("=== Ответ модели ===");
console.log("Content:", message.content);
console.log("Tool calls:", JSON.stringify(message.tool_calls, null, 2));
}
main();
Подсказка: если убрать tool_choice, модель будет решать сама — так реалистичнее,
но демо может быть нестабильным.
npx tsx src/02-with-tool.ts
tool_calls с вызовом get_weather и аргументом
city.
tool_calls пустой — проверь, что есть tool_choice, или укажи в
промпте «вызови get_weather».
tool_calls с именем функции и аргументами — попросила нас
выполнить get_weather.
Вот это и есть structured output — нативный, не нужно просить «верни JSON».