Tool use — учим Claude вызывать функции
До этого Claude просто отвечал текстом. Tool use превращает его в агента: ты описываешь функции — он сам решает когда их вызвать, с какими параметрами, и встраивает результат в ответ. Это база для всего что мы делаем дальше — от чат-ботов с базой данных до агентов которые правят файлы на сервере.
Зачем tool use
Claude знает много, но не знает СВЕЖЕЕ. Не знает погоду в Киеве сейчас, не знает что в твоей базе данных, не умеет делать математику со 100% точностью на больших числах. Tools — это способ закрыть эти дыры: даёшь ему функцию get_weather(city) или query_db(sql) — и Claude использует её когда нужно. То же самое у OpenAI называется function calling — концепция идентичная.
Анатомия tool definition
Каждый tool — это объект с тремя полями: name (короткое имя функции), description (описание в свободной форме — что делает, когда вызывать), input_schema (JSON Schema параметров: какие поля, какого типа, какие обязательные). От качества description сильно зависит будет ли Claude вызывать функцию правильно. Пиши описания развёрнуто, с примерами входов и выходов.
Цикл tool_use → tool_result
1) Шлёшь запрос с массивом tools и messages. 2) Claude отвечает либо обычным текстом (stop_reason: end_turn), либо запросом на вызов функций (stop_reason: tool_use). 3) Если tool_use — в content будут блоки
Ты исполняешь эти функции у себя в коде. 4) Шлёшь следующий запрос со старой историей + новое user-сообщение с блоками
5) Claude видит результаты и формирует финальный ответ или просит ещё вызовов.
Параллельные вызовы
Claude может попросить вызвать НЕСКОЛЬКО функций сразу за один раунд — например get_weather("Киев") и get_weather("Львов") параллельно. В content придёт несколько tool_use блоков. Исполняй их параллельно (Promise.all) и возвращай все результаты в одном следующем сообщении. Это ускоряет агента в разы.
Tool choice — управление поведением
Опциональный параметр tool_choice: auto (дефолт — Claude решает сам), any (обязательно вызвать какой-то tool), tool: { name: "X" } (обязательно вызвать конкретный). Полезно когда у тебя сценарий «всегда сначала проверь авторизацию» — заставляешь Claude в первом ходе вызвать check_auth().
import Anthropic from '@anthropic-ai/sdk';
const client = new Anthropic();
// === ОПИСЫВАЕМ TOOL ===
const tools = [
{
name: 'calculate',
description:
'Точно вычисляет математическое выражение. Используй когда нужны точные расчёты с большими числами или сложными операциями. Пример: input { expression: "1234 * 5678 + 999" } → результат "7008871".',
input_schema: {
type: 'object',
properties: {
expression: {
type: 'string',
description: 'Математическое выражение в JS-синтаксисе',
},
},
required: ['expression'],
},
},
];
// === ИСПОЛНИТЕЛЬ ===
function calculate({ expression }) {
// ВАЖНО: в реальном коде НЕ используй eval с произвольным input.
// Это пример — для демо. Возьми expr-eval или mathjs.
try {
return { result: String(Function(`"use strict"; return (${expression})`)()) };
} catch (e) {
return { error: 'Не смог вычислить' };
}
}
// === ЦИКЛ АГЕНТА ===
async function ask(userMessage) {
const messages = [{ role: 'user', content: userMessage }];
for (let i = 0; i < 5; i++) {
const r = await client.messages.create({
model: 'claude-sonnet-4-6',
max_tokens: 1024,
tools,
messages,
});
messages.push({ role: 'assistant', content: r.content });
if (r.stop_reason !== 'tool_use') {
return r.content.find((b) => b.type === 'text')?.text;
}
// Параллельно исполняем все запрошенные tools
const toolUses = r.content.filter((b) => b.type === 'tool_use');
const results = await Promise.all(
toolUses.map(async (use) => ({
type: 'tool_result',
tool_use_id: use.id,
content: JSON.stringify(calculate(use.input)),
}))
);
messages.push({ role: 'user', content: results });
}
}
// Использование
const answer = await ask('Сколько будет 1234 × 5678 + 999?');
console.log(answer);
// → Claude вызывает calculate({expression: "1234 * 5678 + 999"})
// получает 7008871, и отвечает «Получится 7,008,871»
//
// Без tool Claude мог бы ошибиться в третьей цифре —
// LLM плохо считает большие числа, это известное ограничение.Простой пример: Claude вызывает калькулятор для точной математики