Перейти к содержимому
5. Tool Design & Built-ins

Раздел 5 — Дизайн интерфейса инструментов, распределение и встроенные инструменты

Что покрывает этот раздел

Три тесно связанных темы из Domain 2:

  • 2.1 — Как писать определения инструментов (name, description, input_schema, input_examples), чтобы Claude надёжно выбирал нужный инструмент, в том числе как распознавать и устранять неправильную маршрутизацию, вызванную описаниями.
  • 2.3 — Как ограничивать набор инструментов, доступных каждому агенту или субагенту, и как использовать параметр tool_choice (auto, any, forced tool, none) плюс disable_parallel_tool_use, чтобы управлять поведением вызовов.
  • 2.5 — Как применять встроенный набор инструментов Claude Code (Read, Write, Edit, Bash, Grep, Glob, плюс WebFetch, WebSearch, NotebookEdit, Agent, Task*) к реальной работе с кодовой базой, в том числе канонический паттерн «Edit падает на неуникальном якоре → fallback на Read+Write».

Два оцениваемых пункта напрямую опираются на этот материал: Sample Question 2 (минимальные описания get_customer / lookup_order) и Sample Question 9 (ограничение verify_fact для агента синтеза).

Исходный материал (из официального руководства)

2.1 Интерфейсы инструментов с понятными описаниями

Описания инструментов — основной механизм, по которому LLM выбирает инструменты. Минимальные описания приводят к ненадёжному выбору между похожими инструментами — analyze_content vs analyze_document, или get_customer vs lookup_order. Описания должны включать форматы ввода, примеры запросов, граничные случаи и явные ограничивающие фразы («используйте этот инструмент, когда…, не используйте этот инструмент, когда…»). Формулировки в системном промпте чувствительны к ключевым словам и могут перебить даже хорошее описание, поэтому системный промпт — часть поверхности маршрутизации инструментов. Ожидаемые исправления: различать описания по цели / вводам / выводам / случаям использования, переименовать при пересечении (analyze_contentextract_web_results), разделить обобщённые инструменты на целевые (analyze_documentextract_data_points + summarize_content + verify_claim_against_source) и проверять системные промпты на «протекание» ключевых слов.

2.3 Распределение инструментов и tool_choice

Дать агенту 18 инструментов вместо 4–5 измеримо ухудшает надёжность выбора, а агенты с инструментами вне своей специализации склонны их злоупотреблять (агент синтеза пытается выполнять web-поиски). Решение — ограниченный доступ к инструментам плюс небольшое число узких кросс-ролевых инструментов для частых нужд (например, verify_fact, встроенный в агента синтеза, чтобы он не возвращался к координатору). У tool_choice четыре значения — auto, any, {"type": "tool", "name": "..."} и none — подробно ниже.

2.5 Встроенные инструменты (Read/Write/Edit/Bash/Grep/Glob)

Grep ищет в содержимом файлов (regex); Glob сопоставляет пути файлов (**/*.test.tsx). Read/Write — полнофайловые операции; Edit выполняет замену уникальной строки и падает, если old_string не уникален или файл не был прочитан в текущей сессии — корректный fallback в этот момент — Read, затем Write. Стройте понимание инкрементально: Grep для точек входа, Read, чтобы пойти по импортам, затем трассируйте использование, перечислив экспортируемые имена и сделав Grep по каждому.

Как писать отличное описание инструмента

Руководство Anthropic «Define tools» однозначно: подробные описания — безусловно самый важный фактор производительности инструментов, ориентир — «не менее 3–4 предложений на описание инструмента, больше, если инструмент сложный». (Define tools)

Анатомия описания (5 элементов)

  1. Что инструмент делает — действие, в одном предложении.
  2. Когда его использовать (и когда нет) — ограничивающая фраза, разводящая его с соседними инструментами.
  3. Вводы — что означает каждый параметр, допустимые форматы, примеры (AAPL для тикера), обязательные vs опциональные.
  4. Выводы — что инструмент возвращает и чего намеренно не возвращает.
  5. Оговорки / ограничения — rate limits, свежесть, региональное покрытие, единицы измерения.

Плюс опциональный массив input_examples — примеры ввода, проверяемые по схеме, помогающие при сложных или вложенных формах параметров. Примеры стоят ~20–50 токенов для простых вводов и ~100–200 для вложенных объектов.

Примеры «до/после» (плохо vs хорошо)

Плохо — канонический пример Anthropic:

{
  "name": "get_stock_price",
  "description": "Gets the stock price for a ticker.",
  "input_schema": {
    "type": "object",
    "properties": { "ticker": { "type": "string" } },
    "required": ["ticker"]
  }
}

Хорошо — канонический контрпример Anthropic:

{
  "name": "get_stock_price",
  "description": "Retrieves the current stock price for a given ticker symbol. The ticker symbol must be a valid symbol for a publicly traded company on a major US stock exchange like NYSE or NASDAQ. The tool will return the latest trade price in USD. It should be used when the user asks about the current or most recent price of a specific stock. It will not provide any other information about the stock or company.",
  "input_schema": {
    "type": "object",
    "properties": {
      "ticker": {
        "type": "string",
        "description": "The stock ticker symbol, e.g. AAPL for Apple Inc."
      }
    },
    "required": ["ticker"]
  },
  "input_examples": [
    { "ticker": "AAPL" },
    { "ticker": "MSFT" }
  ]
}

Хорошее описание сообщает Claude что, когда, что возвращает и чего не возвращает — ровно те четыре пробела, из-за которых в Sample Question 2 выбирают get_customer вместо lookup_order.

Именование и декомпозиция инструментов

Расщепление слишком широкого инструмента

Один инструмент analyze_document с расплывчатым описанием вынуждает Claude гадать. Декомпозируйте в целевые инструменты, у которых имена и есть различитель:

ОригиналЗамена
analyze_documentextract_data_points, summarize_content, verify_claim_against_source
fetch_url (общий)load_document (проверяет, что URL ведёт на документ)
analyze_content (пересекает web + doc)extract_web_results (только web)

Руководство writing-tools-for-agents от Anthropic делает обратное замечание: избегайте разрастания «один инструмент на endpoint» (list_users, list_events, create_event), когда консолидированный schedule_event лучше отражает реальный рабочий процесс. Правило — один инструмент на естественное подразделение задачи, а не один на каждый вызов API.

Переименование ради ясности

Используйте префиксы сервисов (github_list_prs, slack_send_message, asana_search), когда у одного и того же агента есть инструменты из разных систем. Anthropic явно отмечает, что namespacing через префиксы vs суффиксы имеет измеримый эффект на точность оценок. Переименовывайте инструменты, пересекающиеся по смыслу, до тех пор пока каждое имя не станет однозначным в отрыве от контекста — analyze_content и analyze_document — это учебная коллизия; extract_web_results и summarize_pdf — нет.

Распределение инструментов между агентами

Почему меньше инструментов = лучше выбор

Оценки MCP от Anthropic на Opus 4 показали, как точность выбора инструмента падает с ростом их числа: при 50+ инструментах, загруженных заранее, точность опустилась до 49% и поднялась до 74% только при включении Tool Search с отложенной загрузкой. Формулировка руководства «18 vs 4–5» совпадает с этой кривой — каждый дополнительный инструмент увеличивает шанс ошибочной маршрутизации и сжигает контекст (50 определений инструментов могут стоить 10–20K токенов).

Архитектурный вывод: давайте каждому субагенту минимальный набор инструментов, позволяющий ему закончить свою роль, а большую поверхность держите у координатора. Если набор должен остаться большим, включайте Tool Search, чтобы на каждый ход материализовалось только 3–5 релевантных определений.

Узкие кросс-ролевые инструменты

Паттерн «агент синтеза» из Sample Question 9 — канонический экзаменационный случай. Синтезу законно нужна какая-то проверка фактов (85% его верификаций — простые), но полный web-search-набор даёт ему слишком широкие полномочия. Решение — единственный, ограниченный инструмент verify_fact — узкий ввод, узкий вывод, без общего fetch — он обрабатывает 85% типичного случая, а 15% сложных расследований по-прежнему идут через координатор к специализированному агенту web-поиска. Это принцип наименьших привилегий, применённый к инструментам.

Таблица конфигурации tool_choice

tool_choiceПоведениеКогда использовать
{"type": "auto"}По умолчанию при наличии инструментов. Claude решает, вызывать ли инструменты, возможно несколько параллельно.Общие агентные циклы, где модель должна сама рассуждать, нужны ли инструменты.
{"type": "any"}Claude обязан вызвать хоть какой-то инструмент (любой из переданных). Свободный текст не выдаётся.Агенты со структурированным выводом, где ответ свободным текстом — ошибка. Сочетайте со strict: true, чтобы ввод соответствовал схеме.
{"type": "tool", "name": "extract_metadata"}Заставляет Claude вызвать конкретный инструмент. Сообщение ассистента предзаполнено блоком tool_use.Конвейеры «сначала запусти X» (например, extract_metadata перед обогащением). Последующие шаги обрабатывайте в следующих ходах.
{"type": "none"}По умолчанию, когда инструментов нет. Claude не может вызывать инструменты.Чисто разговорные ходы внутри сессии с инструментами.
disable_parallel_tool_use: trueМодификатор поверх любого из вышеперечисленного. С auto Claude вызывает не более одного инструмента; с any/tool — ровно один.Когда у нижестоящих инструментов есть зависимости по порядку или rate limits.

Три ограничения, которые стоит запомнить:

  • tool_choice: any и режим forced tool не совместимы с extended thinking — в этом режиме работают только auto и none.
  • Смена tool_choice инвалидирует кэшированные блоки сообщений при prompt caching (инструменты и системный промпт остаются в кэше).
  • disable_parallel_tool_use должен быть выставлен на том запросе, который возвращает блок tool_use; установка на последующем запросе не имеет ретроактивного эффекта.

References: Define tools — Forcing tool use и Parallel tool use.

Шпаргалка по встроенным инструментам

Текущая поверхность встроенных инструментов Claude Code (Tools reference):

ИнструментКогда использоватьКогда избегатьFallback / примечание
ReadЗагрузка известного пути к файлу; просмотр изображений, PDF, ноутбуков. Обязателен перед любым Edit или Write к существующему файлу.Листинг каталога (используйте Bash ls или Glob).Падает на слишком больших файлах — повторите с offset/limit.
WriteСоздание новых файлов; перезапись после Read.Точечные правки внутри большого файла (используйте Edit).Падает на существующих файлах, не прочитанных в сессии.
EditТочечная замена уникальной строки в ранее прочитанном файле.Якорная строка неуникальна или файл изменился на диске после прочтения.Прочитайте ещё раз, затем сделайте Write всего обновлённого содержимого; либо поставьте replace_all: true, если действительно нужны все вхождения.
BashЗапуск скриптов, пакетных менеджеров, git, форматтеров. Долгоиграющие процессы через run_in_background: true.Чтение или запись файлов (используйте Read/Write/Edit, чтобы сработали проверки разрешений и пригодности к редактированию).Тайм-аут по умолчанию 2 минуты, поднимается до 10; вывод обрезается на 30K символов (остаток пишется в файл).
GrepПоиск по содержимому в кодовой базе (имена функций, строки ошибок, импорты). Построен поверх ripgrep — экранируйте regex-метасимволы.Поиск файлов чисто по шаблону имени (используйте Glob).Уважает .gitignore; передайте явный путь, чтобы это обойти. Используйте multiline: true, чтобы пересечь границы строк.
GlobСопоставление по шаблону имён файлов: **/*.test.tsx, src/**/*.ts.Поиск внутри содержимого файлов (используйте Grep).Лимит 100 результатов, сортировка по mtime; по умолчанию не уважает .gitignore.
WebFetchЗагрузка известного URL и извлечение ответов через небольшую модель-экстрактор.Когда нужны сырой HTML или конкретные селекторы (используйте Bash curl).По дизайну с потерями — при необходимости перезагрузите с более конкретным экстракционным промптом. Кэш 15 минут на URL.
WebSearchПоиск URL по запросу; до 8 бэкенд-поисков за вызов; поддерживает allowed_domains или blocked_domains (не оба сразу).Чтение страниц-результатов (далее по цепочке используйте WebFetch).У правила разрешения нет уточнителя — разрешайте/запрещайте инструмент целиком.
NotebookEditИзменение Jupyter-ячейки по cell_id (replace, insert, delete).Замена текста между ячейками.Правила разрешений используют формат пути Edit(...).
AgentЗапуск ограниченного субагента.Рутинные операции, которые родитель может сделать сам.Frontmatter субагента tools / disallowedTools ограничивает его поверхность.
Task* (TaskCreate / TaskList / TaskUpdate)Отслеживание многошаговой работы в интерактивных сессиях.Одноразовые тривиальные задачи.TodoWrite — эквивалент для headless-режима.

Релевантный экзамену паттерн — цикл восстановления при падении Edit: Edit требует, чтобы якорь встречался в файле ровно один раз и сам файл был прочитан в этой сессии. Когда якорь повторяется — обычное дело для конфиг-файлов, повторяющихся строк импорта или шаблонного кода — корректный ответ — Read (целиком) → Write (целиком с обновлениями), а не всё более изобретательные regex-трюки.

Экзаменационные акценты

  • «У обоих инструментов минимальные описания» → первое исправление — расширить описания (вводы, примеры, граничные случаи, границы применимости). Few-shot-промпты, маршрутизирующие слои и консолидация инструментов — все это отвлекающие неверные «первые шаги». (Sample Q2.)
  • «Агенту синтеза нужны частые простые верификации» → дайте ему узкий инструмент verify_fact; не вручайте весь web-search-набор. Батчинг и спекулятивное кэширование — неверны. (Sample Q9.)
  • tool_choice: any ≠ «любой инструмент, какой захочу» — он означает Claude обязан вызвать какой-то инструмент, а не свободный текст.
  • Forced tool ({"type": "tool", "name": "..."}) несовместим с extended thinking.
  • Glob ищет файлы, Grep ищет содержимое. **/*.test.tsx — это шаблон Glob.
  • Падения Edit из-за неуникальных якорей → Read + Write, а не повторные попытки Edit.
  • Размер набора инструментов имеет значение: 18 — слишком много для одного агента; ориентир — 4–5. За пределами 30–50 на сессию включайте Tool Search.
  • disable_parallel_tool_use: true принадлежит запросу, который выдаёт блок tool_use.

References

Последнее обновление