Tool use связывает Claude с остальным вашим стеком. Схемы написаны аккуратно, и агент бронирует рейсы, ходит в базу и управляет браузером. Схемы написаны небрежно, и модель уверенно вызовет get_weather с location: "место, которое упомянул пользователь". В 2026 году Sonnet 4.6 и Opus 4.8 умеют параллельные вызовы и computer use, а JSON соблюдают всё строже. Поэтому разницу между демо и продакшеном почти целиком определяет качество определений инструментов.
Ниже практический гайд. Такой нам самим не хватало, когда мы собирали первых агентов на Claude.
Из чего состоит определение инструмента
Значение имеют ровно три поля:
{
"name": "get_weather",
"description": "Получить текущую погоду и прогноз на 24 часа для конкретного города. Используй, когда пользователь спрашивает о температуре, дожде, снеге или погодных условиях. Не используй для исторической погоды (до сегодня) — для этого есть get_historical_weather.",
"input_schema": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "Название города на английском, например 'San Francisco', 'Tokyo'. Без страны."
},
"units": {
"type": "string",
"enum": ["celsius", "fahrenheit"],
"description": "Единицы температуры. По умолчанию celsius, кроме случаев когда пользователь в США."
}
},
"required": ["city"]
}
}
Расставим их по приоритету.
description. От этого поля сильнее всего зависит точность выбора инструмента. Claude читает его, чтобы решить, вызывать ли инструмент вообще и подходит ли он под запрос. Пишите так, как писали бы docstring для джуниора, который ни разу не видел ваш код.input_schema. JSON Schema аргументов. Смело используйтеenum, добавляйтеdescriptionк каждому свойству, а вrequiredоставляйте только то, без чего вызов невозможен.name. Нижний регистр, snake_case, в начале глагол:get_,create_,search_.
Новички чаще всего ошибаются в одном: принимают description за подпись к функции. Это мини-промпт. Объясните Claude, когда инструмент нужен, когда нет, какие у него побочные эффекты и что означают входные параметры.
Параллельные вызовы в Sonnet 4.6+
Прежние версии Claude отдавали по одному блоку tool_use за ход ассистента. Sonnet 4.6 и Opus 4.8 могут вернуть несколько блоков tool_use в одном ответе, если вызовы независимы. Это существенно, потому что в UX агента основную часть времени съедает задержка round-trip.
Пользователь спрашивает: «какая погода в Токио и Париже и что у меня в календаре на завтра». Интеграция образца 2025 года сделает три последовательных хода. Интеграция 2026 года получит три блока tool_use в одном ответе, выполнит их у себя параллельно и вернёт три tool_result в следующем сообщении. Один round-trip вместо трёх.
Включать ничего не нужно. Достаточно быть готовым к массиву вызовов и запускать их конкурентно.
Рабочий пример: погода и база заказов
Минимальный, но реалистичный цикл агента. Он идёт через шлюз codexkey, который напрямую принимает формат Anthropic Messages API:
import anthropic
import json
client = anthropic.Anthropic(
base_url="https://api.codexkey.ru/v1",
api_key="cxa-..."
)
tools = [
{
"name": "get_weather",
"description": "Текущая погода для города. Используй для вопросов 'какая погода'.",
"input_schema": {
"type": "object",
"properties": {
"city": {"type": "string", "description": "Название города на английском"},
"units": {"type": "string", "enum": ["celsius", "fahrenheit"]}
},
"required": ["city"]
}
},
{
"name": "query_orders",
"description": "Поиск в базе заказов по email клиента или ID заказа. Возвращает до 20 последних заказов.",
"input_schema": {
"type": "object",
"properties": {
"email": {"type": "string", "format": "email"},
"order_id": {"type": "string", "description": "ID заказа вида 'ORD-12345'"}
}
}
}
]
def execute_tool(name, args):
if name == "get_weather":
return {"city": args["city"], "temp_c": 14, "condition": "cloudy"}
if name == "query_orders":
return {"orders": [{"id": "ORD-12345", "total": 89.50, "status": "shipped"}]}
return {"error": f"неизвестный инструмент: {name}"}
messages = [{"role": "user", "content": "Погода в Токио и найди заказы по jane@example.com"}]
while True:
response = client.messages.create(
model="claude-sonnet-5",
max_tokens=2048,
tools=tools,
messages=messages
)
messages.append({"role": "assistant", "content": response.content})
if response.stop_reason != "tool_use":
break
tool_results = []
for block in response.content:
if block.type == "tool_use":
result = execute_tool(block.name, block.input)
tool_results.append({
"type": "tool_result",
"tool_use_id": block.id,
"content": json.dumps(result)
})
messages.append({"role": "user", "content": tool_results})
print(response.content[-1].text)
Посмотрите на цикл. Пока stop_reason == "tool_use", мы выполняем все блоки инструментов, кладём все результаты в одно сообщение user и вызываем модель снова. Вся оркестрация сводится к этому.
Ошибки инструментов: сообщите Claude, что пошло не так
Больше всего надёжности даёт одна привычка: ошибка инструмента это данные, а не исключение. Если инструмент упал (плохой ввод, API недоступен, rate limit), верните ошибку прямо в tool_result и дайте Claude отреагировать:
tool_results.append({
"type": "tool_result",
"tool_use_id": block.id,
"is_error": True,
"content": "Таймаут БД через 5 секунд. Попробуй с более узким фильтром или меньшим числом полей."
})
Claude прочтёт сообщение и нередко повторит вызов с исправленными аргументами или объяснит пользователю, что случилось. Один этот приём заменяет кучу хрупких try/except вокруг модели.
tool_choice: auto, any, tool, none
Параметр tool_choice задаёт, насколько настойчиво Claude обращается к инструментам:
{"type": "auto"}включён по умолчанию. Claude сам решает, вызывать инструмент или ответить текстом.{"type": "any"}обязывает Claude вызвать какой-нибудь инструмент, а какой именно, он выбирает сам.{"type": "tool", "name": "get_weather"}принудительно запускает конкретный инструмент. Удобно для структурированного извлечения: опишите инструментrecord_user_intentс нужной схемой, форсируйте вызов и получите гарантированный JSON.{"type": "none"}запрещает вызовы на этом ходу, даже если инструменты определены.
Принудительный tool_choice остаётся самым чистым способом получить от Claude надёжный структурированный вывод в 2026 году. Возню с JSON-mode можно пропустить: определили инструмент, форсировали, разобрали block.input.
Computer use: когда текстовых инструментов не хватает
Sonnet 4.6+ поддерживает computer use. Модель делает скриншоты, двигает мышь, печатает и кликает на виртуальном рабочем столе. Подключается это специальным инструментом computer_20250124 плюс bash и text_editor. Claude возвращает действия вроде {"action": "screenshot"} или {"action": "click", "coordinate": [512, 384]}, ваш harness их исполняет и присылает свежий скриншот.
Computer use нужен, когда:
- у системы, которой надо управлять, нет API (легаси-админки, порталы вендоров);
- задача по-настоящему визуальная (проверить вёрстку, прочитать график в PDF);
- требуется сквозной QA собственного продукта.
Если есть нормальный API, берите его. Computer use медленнее, менее надёжен и дороже в пересчёте на задачу, чем function calling против полноценного бэкенда.
Форма Anthropic и форма OpenAI
codexkey отдаёт оба эндпоинта. Формы заметно различаются: у Anthropic это content-блоки tool_use и tool_result, у OpenAI tool_calls с function.name и function.arguments в виде JSON-строки.
Если начинаете с нуля, берите форму Anthropic: она структурирована, параллельные вызовы в ней удобнее, а аргументы не приходят строкой. Если переносите готовый код на форме OpenAI, совместимый эндпоинт https://api.codexkey.ru/v1/chat/completions позволит сменить модель, не переписывая слой инструментов. На нативную форму перейдёте позже.
Отладка вызовов инструментов
Когда агент сходит с рельсов, 90% сигнала дают три вещи.
- Логируйте каждый
tool_use_idвместе с input и result. Несовпадение ID чаще всего и ломает работу без шума. - Логируйте
stop_reasonна каждом ходу. Увиделиend_turnтам, где ждалиtool_use: описание непонятное илиtool_choiceвыбран неверно. - После сбоя повторно прогоняйте весь массив сообщений через API. На низкой температуре Claude достаточно детерминирован, и плохой вызов обычно воспроизводится.
Небольшой дашборд, где рядом видны таймлайн сообщений, вызовы и результаты, окупится за неделю.
Итог
Надёжные агенты на Claude в 2026 году держатся на двух привычках. Их надо повторять каждый раз.
- Подробное описание у каждого инструмента и каждого параметра. Относитесь к полю description как к промпту. Напишите, когда инструмент применять не надо, что значат входы и что вернётся в ответ.
- Небольшие инструменты, каждый про одно дело. Пять инструментов с одной задачей каждый всегда лучше одного мегаинструмента с двенадцатью необязательными параметрами. Claude точнее выбирает, схемы проще, а ошибки легче разбирать.
Параллельные вызовы, computer use и принудительный tool_choice сильны, но усиливают они лишь то, что уже заложено в дизайне инструментов. Потратьте час на описания. Во всём стеке агента этот час окупается лучше любого другого.
О стоимости нагрузок с большим числом инструментов читайте в разборе цен Claude API.