Engineering the Agentic Stack · Часть 3

Использование инструментов AI-агентами: MCP, CLI, Skills и выполнение кода

Автоматический перевод Эта статья была автоматически переведена с оригинальной английской версии.

Обновление статьи

Впервые опубликовано 24 марта 2026 года. Проверено и обновлено 6 сентября 2026 года. Обновление охватывает пересмотренную спецификацию MCP, программный вызов инструментов и новые данные о затратах и ограничениях использования инструментов.

Агенту нужен способ действовать: JSON-вызов инструмента, сервис MCP, команда CLI или код в сэндбоксе. Ему также могут понадобиться инструкции по выбору и использованию этого механизма. Skills предоставляют такие инструкции. Харнесс — это обычная программа вокруг модели: она собирает промпты, проверяет предложенный вызов, выполняет одобренный вызов и определяет, когда задача завершена.

Эта третья статья серии добавляет слой действий к циклам ризонинга из части 1 и памяти из части 2. В части 4 рассматривается проверка политики перед выполнением, а в части 6 — харнесс, который выполняет и вызов, и эту проверку.

История инструментов изменилась в 2025–2026 годах. MCP, Model Context Protocol, предоставил вендорам единый способ открывать доступ к внешним сервисам. Агенты с выполнением кода показали, что модель иногда может эффективнее составить небольшую программу, чем отправлять длинную последовательность JSON-вызовов. Anthropic сообщила о сокращении числа токенов на 98,7% для одного процесса переноса данных из Google Drive в Salesforce, а в статье CodeAct сообщалось о приросте успешности задач до 20 процентных пунктов в рамках их бенчмарк-установки. Эти результаты относятся к конкретным задачам и харнессам, а не доказывают универсальное преимущество выполнения кода.

Я сравню JSON-вызовы инструментов, MCP, CLI-инструменты и выполнение кода, а затем покажу, где в этой схеме находятся Skills. В следующем разделе принципы проектирования Agent-Computer Interface (ACI) применяются к Market Analyst Agent — небольшому исследовательскому агенту на LangGraph, которого я создал для части 1. Он получает рыночные данные и пишет аналитический отчёт.

Краткое решение по выбору интерфейса приведено в статье Интерфейсы инструментов AI-агентов.


Поверхности выполнения и процедурные инструкции

Цикл ризонинга предлагает вызов. Харнесс проверяет его аргументы и допустимость, затем отправляет его инструменту или в сэндбокс и возвращает результат. JSON Schema, транспорт MCP, обёртки CLI и раннеры кода могут ограничивать входные данные, но ни один из них не решает, разрешено ли запрошенное действие. Skills предоставляют инструкции для этого пути. Эти поверхности выполнения по-разному балансируют стоимость токенов, гибкость и контроль.

Пять модальностей инструментов AI-агентов и их компромиссыПять модальностей инструментов AI-агентов и их компромиссы

1. JSON-вызовы инструментов: базовый вариант

Исходный паттерн: вы описываете схемы инструментов в JSON, LLM выдаёт структурированные function calls, а ваш код их выполняет. Это хорошо изученный подход, который нормально работает с небольшими наборами инструментов.

# Schema cost depends on its text, structure, and the model tokenizer
tools = [
    {
        "name": "get_stock_price",
        "description": "Get the current stock price for a ticker symbol",
        "input_schema": {
            "type": "object",
            "properties": {
                "ticker": {"type": "string", "description": "Stock ticker (e.g., NVDA)"}
            },
            "required": ["ticker"]
        }
    }
]

Посчитайте токены в реальных схемах. Стоимость зависит от их длины и количества схем, загружаемых хостом; компактный поиск цены и глубоко вложенный контракт API — это не равнозначные единицы. Отложенное обнаружение может избавить от загрузки всего реестра.

2. MCP для общих интеграций

MCP — стандарт, к которому пришло большинство вендоров. MCP-сервер — это процесс, публикующий список инструментов через определённый wire-протокол: stdio для локального процесса и HTTP для удалённого. Ваш агент запускает MCP-клиент, подключается к серверу, запрашивает список его инструментов и пересылает ему вызовы модели. Поэтому один и тот же сервер работает с любым клиентом, поддерживающим протокол. В декабре 2025 года Anthropic передала протокол Linux Foundation в рамках Agentic AI Foundation, которую она основала вместе с OpenAI и Block. Google, Microsoft и AWS поддерживают фонд как платиновые участники. OpenAI добавила поддержку MCP в Responses API. Согласно объявлению Anthropic о передаче протокола в декабре 2025 года, экосистема насчитывала более 10 000 активных публичных MCP-серверов и более 97 млн ежемесячных загрузок SDK для Python и TypeScript.

MCP подходит для SaaS-интеграций между разными вендорами (Figma, Notion, Salesforce), сервисов без эквивалентов CLI и окружений, которым нужна оркестрация OAuth. Его ценность — в общем слое обнаружения и транспорта. Управление по-прежнему зависит от механизмов аутентификации, авторизации, логирования и деплоя на стороне сервера.

Версия протокола теперь является практическим фактором миграции. Редакция от 28.07.2026 меняет поведение, на которое рассчитывают старые туториалы:

ИзменениеЧто проверить в интеграции
Stateless-запросы заменяют handshake и транспортные сессии инициализацииПередавайте метаданные протокола для каждого запроса; используйте server/discover для проверки поддержки. Проверьте версии и клиента, и сервера.
Multi Round-Trip Requests возвращают InputRequiredResultОбрабатывайте запросы дополнительных входных данных, затем повторяйте исходную операцию с ответами и состоянием продолжения.
Tasks перенесены в официальное расширение tasksПроверяйте поддержку расширения, а не рассчитывайте на старый экспериментальный core task API.
Возобновление SSE удаленоПри обрыве потока ответа требуется новый запрос. Независимо предотвращайте дублирование бизнес-эффектов.

Та же редакция объявляет Roots, Sampling, Logging и OAuth Dynamic Client Registration устаревшими; устаревание не означает немедленного удаления. В текущей регистрации клиентов предпочтение отдаётся Client ID Metadata Documents. Существующие интеграции могут по-прежнему использовать старую редакцию, поэтому перед внедрением новой функции проверьте установленный SDK и контракт сервера.

Производственная реальность сложнее, чем предполагают заголовки.

Vulnerable MCP Project собирает сообщения о промпт-инъекциях, валидации входных данных, аутентификации и сетевых контролях. Такая коллекция помогает определить тестовые сценарии, но без знаменателя — числа подверженных воздействию систем — не позволяет сравнить MCP с shell или прямыми вызовами API.

Больше всего меня беспокоит класс атак tool poisoning. Invariant Labs продемонстрировала, что отравленные MCP-инструменты могут эксфильтрировать данные, даже если их никогда не вызывают. Для запуска атаки достаточно, чтобы модель прочитала метаданные инструмента. В бенчмарках MCPTox, где тестировались 20 LLM-агентов против 45 реальных MCP-серверов, сообщалось о средней успешности атак 72,8% для o1-mini в сценарии tool poisoning. Это результат бенчмарка для одной модели, а не среднее значение по 20 агентам и не частота инцидентов в реальном мире.

Операционная проблема — накладные расходы на токены. Одна команда, запускавшая MCP-серверы для GitHub, Slack и Sentry (около 40 инструментов), обнаружила, что до любого запроса пользователя в контекст внедрялось 55 000 токенов определений схем. Другая команда сообщила, что одни только определения инструментов занимали 143 000 из 200 000 доступных токенов (72%).

Сравнение накладных расходов на токеныСравнение накладных расходов на токены

В отчёте Anthropic о Tool Search Tool приводятся примерные границы контекста: 77 000 токенов до начала работы и 8 700 после отложенного обнаружения при примерно 72 000 токенов определений инструментов в традиционной схеме. Загружаются только три–пять инструментов, нужных запросу, но перед вызовом добавляется этап обнаружения; для небольших компактных наборов, инструменты которых часто используются в каждой сессии, этот подход менее полезен.

3. Skills упаковывают экспертизу, а не выполнение

Agent skills — это открытый формат для упаковки инструкций и вспомогательных файлов. Инструменты предоставляют возможности (что агенты умеют делать), а skills — экспертизу (что агенты знают о способах выполнения сложных задач).

Формат SKILL.md определяет skill как markdown-файл с YAML frontmatter. Открытый стандарт требует только name и description; в примере ниже также используются два расширения Claude Code — argument-hint и user-invocable — и его positional-argument placeholder $0:

---
name: deploy
description: Deploy the application to production
argument-hint: "[environment]"
user-invocable: true
---
Deploy the application to the $0 environment (default: staging).
Steps:
1. Run the test suite
2. Build the production bundle
3. Deploy using the deploy script
4. Verify the deployment health check

Skills используют progressive disclosure. На старте агент получает около 100 токенов name и description. Полный SKILL.md загружается только при необходимости, а затем по мере надобности подгружаются скрипты, документы или ассеты, на которые он ссылается. Эти стартовые затраты значительно меньше примерно 55 000 токенов, которые около 40 MCP-инструментов могут занять до начала ризонинга. Активный skill по-прежнему добавляет свои инструкции и ресурсы в контекст.

Используйте skills для предметных знаний, многошаговых процедур и повторяющихся операций — например, миграций баз данных или интеграций платежей. Они подходят для задач, в которых агенту нужны инструкции о том, как использовать уже существующую возможность.

4. CLI и shell-инструменты

Интерфейсы CLI могут требовать гораздо меньше контекста, если модель уже знает команду. Scalekit сообщила о разнице в 4–32 раза по числу токенов между путями CLI и MCP в 75 запусках. Этот кейс измеряет собственные инструменты и задачи Scalekit; он не заменяет сравнение с вашими определениями инструментов и выводом команд.

Широко документированные команды вроде git, docker, kubectl, gh, curl и jq часто требуют лишь небольшого вводного описания схемы. Менее распространённым или внутренним CLI всё ещё нужны доступная для обнаружения справка, примеры и стабильный машиночитаемый вывод.

В руководстве Ugo Enyioha “Writing CLI Tools That AI Agents Actually Want to Use” сформулированы восемь правил проектирования:

  1. Структурированный вывод обязателен — поддерживайте --json
  2. Коды завершения — это control flow — используйте разные коды для разных типов ошибок
  3. Команды должны быть идемпотентными
  4. Self-documenting --help с реалистичными примерами
  5. Проектируйте с расчётом на композицию--quiet для простых значений, поддержка stdin
  6. Предоставьте флаги --dry-run и --yes
  7. Поддерживайте introspection версии
  8. Обрабатывайте аутентификацию через переменные окружения

У CLI нет обнаружения на уровне протокола. JSON-вызовы инструментов могут передавать типизированные схемы, а MCP стандартизирует обнаружение инструментов и для HTTP-транспортов предоставляет модель авторизации. Но ни один из этих вариантов сам по себе не обеспечивает управление: хост, сервер или харнесс должны применять политику и записывать вызовы, необходимые для аудита. Практичный вариант по умолчанию — CLI для разработки и локальных операций, а MCP — для интеграции с общими внешними сервисами, когда межклиентское обнаружение или оркестрация OAuth оправдывают накладные расходы сервера.

5. Выполнение кода для многошаговой работы

Это самое существенное изменение в инструментарии агентов. Вместо того чтобы по одному выдавать структурированный JSON для вызова заранее определённых функций, агент пишет скрипт на Python или bash. Скрипт вызывает несколько инструментов, обрабатывает результаты с помощью циклов и условий и возвращает в контекст модели только итоговое резюме.

Anthropic представила в beta-режиме Programmatic Tool Calling (PTC). В текущем руководстве по API используется обычный Messages API с code_execution_20260120 или более поздней версией; исходный запуск beta имеет историческое значение. Академическая основа подхода — статья CodeAct (Wang et al., ICML 2024), в которой тестировались 17 LLM. В ней code actions обеспечили успешность задач до на 20 процентных пунктов выше и на 30% меньше действий, чем JSON-альтернативы.

Поток выполнения кодаПоток выполнения кода

Три исследования от разработчиков показывают, где этот паттерн может помочь: ниже — Vercel и Cloudflare, затем пример Anthropic с анализом расходов. Рассматривайте их как данные от вендоров и повторите сравнение на собственных задачах.

  • Vercel переработала d0 — своего data-агента для преобразования естественного языка в SQL. В старом примере кода перечислены 17 инструментов, а в новом доступны ExecuteCommand и ExecuteSQL. Vercel описывает редизайн как удаление 80% инструментов, но это заголовочная формулировка Vercel, а не процент, непосредственно следующий из перечисленных в примерах инструментов. На пяти репрезентативных запросах Vercel сообщает, что успешность задач выросла с 4/5 до 5/5, среднее время выполнения сократилось в 3,5 раза (с 274,8 до 77,4 секунды), а среднее использование токенов уменьшилось на 37% (примерно со 102 тыс. до 61 тыс.). Формулировка компании: «Лучшими агентами могут оказаться агенты с наименьшим числом инструментов».

  • Cloudflare разработала «Code Mode», позволяющий агентам писать TypeScript для вызова её API вместо определения схем инструментов, что уменьшает накладные расходы на контекст. Обоснование компании: «У LLM огромный объём реального TypeScript в обучающей выборке, но лишь небольшое количество искусственных примеров tool calls».

Ниже показан паттерн из документации Anthropic по PTC. В последовательном примере Anthropic с анализом расходов традиционные вызовы инструментов требуют более 20 отдельных проходов инференса, а промежуточные данные проходят через контекст. После поиска команды хост, поддерживающий параллельные вызовы инструментов, может объединить независимые запросы расходов; это не делает цифру «более 20» невозможной. Anthropic сообщает, что сгенерированный код, отвечающий на тот же вопрос, сокращает объём данных, попадающих в контекст, с 200 КБ исходных строк расходов — более 2 000 позиций — до 1 КБ результатов. Скрипт ниже иллюстрирует этот control flow с помощью пользовательских async-адаптеров Python: они принимают positional arguments и возвращают декодированные списки и словари. Это не контракт нативной обёртки PTC.

# Custom decoded Python adapters, not native Claude PTC wrappers.
import asyncio
import json

async def main() -> None:
    team = await get_team_members("engineering")
    levels = list(set(member["level"] for member in team))
    budgets = dict(zip(
        levels,
        await asyncio.gather(*(get_budget_by_level(level) for level in levels)),
    ))
    expenses = await asyncio.gather(
        *(get_expenses(member["id"], "Q3") for member in team)
    )
    over_budget = []
    for member, employee_expenses in zip(team, expenses):
        total = sum(expense["amount"] for expense in employee_expenses)
        limit = budgets[member["level"]]["travel_limit"]
        if total > limit:
            over_budget.append(
                {"name": member["name"], "spent": total, "limit": limit}
            )
    # Only this final summary returns to the LLM context
    print(json.dumps(over_budget))

asyncio.run(main())

Чтобы использовать нативные обёртки Claude PTC, передавайте каждому инструменту один словарь аргументов, декодируйте возвращаемую JSON-строку и используйте верхнеуровневый await в управляемом окружении выполнения вместо запуска event loop через asyncio.run. Пример с пользовательскими адаптерами выше предполагает обычный рантайм Python-скрипта; это также не готовый к подключению пример нативного MCP-коннектора. Текущие ограничения PTC API исключают инструменты strict: true и нативные инструменты MCP-коннектора из программных вызовов и ограничивают рекурсивные схемы. Пользовательский мост code-to-MCP — отдельная интеграция. allowed_callers описывает, как Claude вызывает инструмент; это не граница авторизации. Хост должен валидировать каждый возвращённый вызов, включая неожиданный прямой вызов.

LLM видит только итоговое JSON-резюме, а не тысячи строк расходов, обработанных в сэндбоксе. Экономия не специфична для отчётов о расходах: в отдельном материале Anthropic о выполнении кода приведена наиболее наглядная цифра для этого паттерна — процесс переноса данных из Google Drive в Salesforce сократился примерно со 150 000 до 2 000 токенов, то есть на 98,7%.

В текущем руководстве по PTC также приводится контрпример: в задачах tau2-bench для авиакомпаний, ритейла и телекоммуникаций PTC не изменил оценки и оказался примерно на 8% дороже. В отдельном бенчмарке управления проектами со 75 инструментами он сократил оплачиваемые входные токены примерно на 38% без изменения точности. В этих внутренних оценках указана только production-модель Claude, без точного ID. Небольшие последовательные процессы могут не дать достаточной экономии, чтобы компенсировать накладные расходы контейнера и генерации кода.

Эффективность токенов — потенциальное преимущество. Циклы и условия практически ничего не стоят, а выполнение кода позволяет обрабатывать ошибки явными обработчиками, вместо того чтобы заставлять модель рассуждать о сбоях на естественном языке. Путь с выполнением кода может не помещать чувствительные промежуточные данные в контекст модели, но это не означает конфиденциальность: изоляцию, контроль egress, scoped credentials и логирование нужно обеспечивать отдельно.

Когда JSON-вызовы инструментов всё ещё оправданы: для одиночных атомарных операций, окружений без инфраструктуры сэндбоксов, небольших моделей со слабой генерацией кода или требований аудита, при которых нужно логировать каждый отдельный вызов инструмента.


Сравнение выполнения инструментов AI-агентами

ИзмерениеJSON Tool CallingMCPSkills (SKILL.md)CLI/BashCode Execution (PTC)
Лучше всего подходит дляПростых одиночных действийSaaS между разными вендорамиПереиспользуемых процедур, выбирающих поверхностьDev-workflows, локальных операцийМногошаговой оркестрации
Накладные расходы на токеныЗагруженные токены схемЗагруженные или отложенные схемыМетаданные обнаружения примерно на 100 токенов; активные инструкции/ресурсы добавляют контекстТокены справки, команды и выводаВходные схемы, код и вывод
Данные по задачамБазовый уровень в цитируемых исследованияхЗависит от сервера и задачиN/A (слой экспертизы)Измерять на CLI-native задачахCodeAct: до +20 пунктов
КомпозицияУправляется харнессом; зависимые вызовы добавляют ходыУправляется харнессом; зависимые вызовы добавляют ходыНаправляет выбранную поверхностьВысокая (pipes, chaining)Очень высокая (flow/filtering на стороне кода)
Поверхность безопасностиПолномочия на аргументы и эффектыИдентичность сервера и полномочия инструментовЗависит от хоста и ресурсовShell, пути, credentialsКод, доступ к данным и egress
Сложность настройкиНизкаяСредняя (деплой сервера)Низкая для инструкций; зависит от поверхностиОчень низкая (существующие CLI)Средняя (инфраструктура сэндбокса)
Латентность зависимых вызововОбычно один model turn/вызовОбычно один model turn + транспорт/вызовНаследуется от поверхностиОбычно один model turn/вызовОдин ход генерации скрипта; хост выполняет flow
ОтладкаХорошая (структурированные I/O)Средняя (транспортный слой)Хорошая (читаемый markdown)Отличная (видимый вывод)Хорошая (читаемый код)

JSON-вызовы инструментов, MCP, CLI и выполнение кода — это поверхности выполнения. Skills — инструкции, направляющие работу одной из этих поверхностей, поэтому их латентность, контекст и настройка зависят от выбранного механизма. «Meta-tools» — это несколько общих точек входа, необходимых агенту с выполнением кода — например, ExecuteCommand и ExecuteSQL у Vercel, — вместо отдельной схемы для каждой операции. Строки о композиции и латентности описывают вызовы, последующие аргументы которых зависят от предыдущих результатов. JSON-вызовы инструментов и MCP могут отправлять независимые вызовы одновременно, но зависимые вызовы обычно требуют ещё одного хода модели. PTC переносит этот control flow и фильтрацию зависимостей в скрипт, а затем возвращает модели резюме. Ячейки с токенами и успешностью задач суммируют цитируемые примеры, а не результаты одного контролируемого бенчмарка по всем пяти столбцам.


Agent-Computer Interface (ACI) для инструментов AI-агентов

Термин «Agent-Computer Interface» (ACI) ввели John Yang, Carlos E. Jimenez и их коллеги из Princeton в статье SWE-agent (NeurIPS 2024). Качество интерфейсов для людей стало отдельной дисциплиной — human-computer interaction, или HCI. В статье утверждается, что языковые модели заслуживают такого же подхода: это «новая категория конечных пользователей со своими потребностями и возможностями, которым пошли бы на пользу специально созданные интерфейсы».

Их абляционные результаты позволяют выразить это численно. При использовании одной и той же базовой модели GPT-4 Turbo абляция SWE-bench Lite в статье достигла 18,0% с полным ACI SWE-agent на 300 задачах, против 7,3% в режиме только shell без рабочего демонстрационного примера и 11,0% с одним примером. Сравнение показывает, что в этой установке интерфейс и условия демонстрации существенно изменили результат; оно не отделяет дизайн интерфейса от всех остальных различий и не доказывает, что модель не выполняла работу. В рамках той же абляции интерфейса включение linting повысило результат в режиме редактирования с 15,0% до 18,0%; на полном тестовом наборе SWE-bench в 51,7% запусков SWE-agent встретилось хотя бы одно изменение, отклонённое линтером до его применения.

Принципы проектирования ACIПринципы проектирования ACI

Anthropic приняла ACI как фундаментальную концепцию в руководстве “Building Effective Agents”, включив её в число трёх основных принципов: «Тщательно проектируйте интерфейс агент–компьютер с помощью подробной документации и тестирования инструментов». Практическая рекомендация звучит так: «Хорошее эмпирическое правило — подумать о том, сколько усилий вкладывается в интерфейсы человек–компьютер, и планировать столько же усилий на создание качественных интерфейсов агент–компьютер».

Четыре принципа ACI на практике

1. Действия должны быть простыми и понятными. Самая распространённая ошибка — оборачивать API-эндпоинты один к одному. Вместо list_users, list_events, create_event реализуйте schedule_event, который одним вызовом проверяет доступность и создаёт запись. Вместо read_logs реализуйте search_logs, возвращающий только релевантные строки с контекстом.

2. Действия должны быть компактными и эффективными. Объединяйте важные операции в минимальное число действий. В Market Analyst Agent я объединяю получение цены и базовых метрик в один инструмент get_stock_snapshot, вместо того чтобы требовать отдельные вызовы для цены, объёма, рыночной капитализации и PE ratio.

3. Обратная связь от окружения должна быть информативной, но компактной. Не возвращайте исходный HTML или полный payload API. Преобразуйте криптические ID в семантические имена. В тестировании Anthropic был добавлен enum response_format, чтобы агент мог запросить краткий ответ (примерно 72 токена) или подробный (примерно 206 токенов), то есть разницу в стоимости токенов примерно в 3 раза.

4. Валидация должна предотвращать распространение ошибок. Автоматическое обнаружение ошибок помогает агентам быстрее распознавать и исправлять проблемы. В SWE-agent пользовательский редактор файлов со встроенным linting автоматически отклоняет синтаксические ошибки — это этап валидации, лежащий в основе приведённой выше цифры 51,7%. Это валидация входов и выходов инструмента, а не фильтрация содержимого вокруг вызова модели, которую выполняют guardrail-продукты из части 4; одно и то же слово используется в обоих значениях. В Market Analyst Agent я применяю тот же принцип, валидируя аргументы инструментов с помощью схем Pydantic до выполнения:

from pydantic import BaseModel, Field, field_validator

from market_analyst.utils import normalize_ticker

class StockQuery(BaseModel):
    """Validated input for stock queries.

    Pydantic catches malformed tickers before the API call,
    preventing error propagation through the reasoning loop.
    """
    ticker: str = Field(description="Stock ticker symbol (e.g., NVDA)")

    @field_validator("ticker")
    @classmethod
    def validate_ticker(cls, v: str) -> str:
        return normalize_ticker(v)

class StockHistoryQuery(StockQuery):
    """Validated input for price history queries."""

    period: str = Field(default="1mo", description="Time period: 1d, 5d, 1mo, 3mo, 6mo, 1y")

    @field_validator("period")
    @classmethod
    def validate_period(cls, v: str) -> str:
        valid = {"1d", "5d", "1mo", "3mo", "6mo", "1y"}
        if v not in valid:
            raise ValueError(f"Invalid period: {v}. Must be one of {valid}")
        return v

Общий нормализатор удаляет пробелы и переводит значение в верхний регистр, затем принимает цифры тикера и суффиксы с точками или дефисами, например BRK.B и BF-B; StockHistoryQuery, а не StockQuery, владеет period.


Рабочие паттерны проектирования инструментов AI-агентов

В руководстве Anthropic “Writing effective tools for agents” инструменты описываются как «новый вид программного обеспечения, отражающий контракт между детерминированными системами и недетерминированными агентами».

Считайте описания инструментов частью промпт-инжиниринга

Описание должно занимать как минимум три–четыре предложения и охватывать сценарии использования инструмента, обязательные и необязательные параметры, формат вывода и пограничные случаи. Anthropic сообщает, что выбор между namespace на основе префикса и namespace на основе суффикса (asana_search против search_asana) оказал «нетривиальное влияние» на их собственные оценки использования инструментов. При этом не сказано, какая схема лучше, поэтому протестируйте обе на своём наборе инструментов, а не делайте предположений в пользу префиксов. Anthropic также передавала транскрипты своих эвалов агентами обратно в Claude Code и позволяла ему переписывать инструменты. На отложенных тестовых наборах этот цикл находил дальнейшие улучшения «даже сверх того, чего мы достигли с помощью “экспертных” реализаций инструментов» — независимо от того, были ли инструменты написаны исследователями вручную или сгенерированы Claude.

# Bad: vague, no context for when to use
tools = [{
    "name": "search",
    "description": "Search for items",
}]

# Good: specific, with input examples and edge cases
tools = [{
    "name": "search_news",
    "description": (
        "Search for recent news articles about a specific stock or company. "
        "Use this tool when the user asks about recent events, earnings, "
        "announcements, or market-moving news for a specific ticker. "
        "Returns up to 10 articles sorted by relevance. "
        "For company competitors rather than news, use search_competitors instead."
    ),
    "input_schema": {
        "type": "object",
        "properties": {
            "query": {
                "type": "string",
                "description": "Search query. Examples: 'NVDA earnings Q3 2025', 'Tesla delivery numbers'"
            },
            "max_results": {
                "type": "integer",
                "description": "Max articles to return (1-10, default 5)",
                "default": 5
            }
        },
        "required": ["query"]
    }
}]

Внутреннее тестирование Anthropic показало, что добавление поля input_examples повысило точность обработки сложных параметров с 72% до 90%.

Возвращайте высокоинформативный машиночитаемый вывод

Используйте в ответе по умолчанию семантические метки вместо низкоуровневых идентификаторов (uuid, mime_type). Сохраняйте ID, если он потребуется следующему инструменту, либо предоставляйте подробный ответ, содержащий его. Например, результат поиска по Jane может быть компактным для чтения, а подробный результат включает ID, необходимый для send_message. Структурируйте ответ так, чтобы агент мог рассуждать по нему без парсинга служебных данных:

# Bad: raw API response dumped to agent
def get_stock_snapshot(ticker: str) -> dict:
    response = api.get(f"/v1/quotes/{ticker}")
    return response.json()  # 500+ tokens of nested JSON

# Good: high-signal summary the agent can immediately reason about
def get_stock_snapshot(ticker: str) -> dict:
    data = api.get(f"/v1/quotes/{ticker}").json()
    return {
        "ticker": ticker,
        "price": data["regularMarketPrice"],
        "change_pct": round(data["regularMarketChangePercent"], 2),
        "volume": data["regularMarketVolume"],
        "market_cap_b": round(data["marketCap"] / 1e9, 1),
        "pe_ratio": data.get("trailingPE"),
        "summary": f"{ticker} at ${data['regularMarketPrice']:.2f} "
                   f"({'up' if data['regularMarketChangePercent'] > 0 else 'down'} "
                   f"{abs(data['regularMarketChangePercent']):.1f}%)"
    }

Возвращайте ошибки, с которыми цикл может работать

Для обработки ошибок нужны четыре отдельных механизма, поскольку они работают с разными классами сбоев:

  1. Повтор с экспоненциальной задержкой для временных ошибок
  2. Цепочки fallback-моделей при сбоях провайдера
  3. Роутинг по классификации ошибок — временные ошибки повторяются, ошибки, которые может исправить LLM, возвращаются агенту с контекстом, ошибки, требующие человека, эскалируются
  4. Восстановление из чекпоинта для переживания падений

В статье Anthropic “Writing effective tools for agents” рекомендуются понятные ошибки инструментов и дизайн инструментов на основе эвалов, но не приводится универсальное значение того, сколько ошибок восстанавливают эти четыре механизма. Измеряйте коэффициент восстановления, число повторов и эскалаций на собственном наборе задач.

import httpx
from tenacity import retry, retry_if_exception, stop_after_attempt, wait_exponential

def is_transient_error(error: BaseException) -> bool:
    if isinstance(error, (httpx.TimeoutException, httpx.NetworkError)):
        return True
    if isinstance(error, httpx.HTTPStatusError):
        return error.response.status_code == 429 or 500 <= error.response.status_code < 600
    return False

@retry(
    retry=retry_if_exception(is_transient_error),
    stop=stop_after_attempt(3),
    wait=wait_exponential(multiplier=1, min=2, max=10),
    reraise=True,
)
def call_stock_api(ticker: str) -> dict:
    """Fetch stock data with automatic retry on transient failures.

    Mechanism 1 of the four above: exponential backoff for rate limits
    and network blips.
    This only retries transient transport failures. If attempts are exhausted,
    Tenacity re-raises the original httpx exception.
    """
    response = httpx.get(
        f"https://api.example.com/v1/quotes/{ticker}",
        timeout=10.0,
    )
    response.raise_for_status()
    return response.json()

Вызывающая сторона или харнесс всё ещё должны сделать следующий шаг: преобразовать исключение в стабильный результат, указывающий, какая операция завершилась ошибкой, нужно ли повторить её и что делать дальше. Неповторяемая ошибка 4xx пропускает этот декоратор и требует такой же обработки. Повтор запроса не классифицирует его ошибку и не восстанавливает чекпоинт.


Применение паттернов к Market Analyst Agent

Market Analyst Agent из части 1 позволяет увидеть влияние интерфейса.

Консолидация инструментов

Исходные модули инструментов определяли get_stock_price, get_company_metrics, get_price_history, два инструмента поиска и execute_trade. Для базового анализа агенту нужно было выбрать и вызов цены, и вызов метрик; рыночная капитализация и P/E были полями get_company_metrics, а не отдельными инструментами. Исходный код до консолидации показывает прежнюю поверхность.

Я преобразовал поверхность рыночных данных в 5 высокоуровневых инструментов, следуя принципу ACI о компактных и эффективных действиях. В список инструментов ReAct-агента репозитория вместе с ними входят ещё четыре инструмента — загрузчик skill, две CLI-обёртки и ограниченный in-process Python evaluator (allowlist AST, а не сэндбокс; это рассматривается в части 4) — всего три из пяти описанных выше модальностей. MCP представлен sidecar-процессом, а не инструментом в этом списке:

До (исходные инструменты)После (инструменты рыночных данных)Зачем
get_stock_price + get_company_metricsget_stock_snapshotОдин вызов возвращает базовую цену и снимок оценки
get_price_historyget_price_historyСохраняется с валидируемыми периодами и сводкой среднего объёма
search_newssearch_newsВозвращает структурированные элементы с извлечёнными ключевыми пунктами
search_competitorssearch_competitorsСохраняет действие поиска, ориентированное на конкурентов
Нет инструмента финансовой отчётностиget_financialsВыбирает данные о прибылях, балансе или денежных потоках по параметру

Так цена и оценка объединяются в одно определение, ориентированное на задачу, а финансовая отчётность добавляется как явное действие. Улучшает ли это выбор инструментов — утверждение, которое нужно проверять на репрезентативных запросах и трейcах.

Структурированные результаты инструментов

Инструменты акций и новостей возвращают ответы, валидированные Pydantic. CLI- и code-execution-обёртки возвращают str, поэтому приведённые ниже модели описывают структурированные результаты инструментов, а не каждую обёртку в репозитории:

from pydantic import BaseModel

class StockSnapshot(BaseModel):
    """Structured tool response — the agent never sees raw API noise."""
    ticker: str
    price: float
    change_pct: float
    volume: int
    market_cap_b: float
    pe_ratio: float | None
    summary: str  # Human-readable one-liner for direct use in reports

class NewsItem(BaseModel):
    """One news item pre-processed for agent consumption."""
    headline: str
    source: str
    date: str
    relevance_score: float  # Pre-ranked so the agent doesn't waste tokens sorting
    key_points: list[str]  # Extracted by the tool, not the agent

class NewsSearchResult(BaseModel):
    query: str
    results: list[NewsItem]
    summary: str

Поле summary даёт агенту готовую строку для отчёта. NewsItem.key_points избавляют модель от необходимости парсить тела статей. Если следующему действию нужен ID, сохраняйте его в подробном ответе или предоставляйте краткий и подробный режимы; не удаляйте его повсюду.


Компромиссы и соображения

Помимо оговорок, специфичных для каждого паттерна, на выбор влияют несколько общих факторов:

  • Операционная стоимость меняется по разным измерениям. Выполнение кода экономит токены, но добавляет латентность холодного старта сэндбокса. MCP экономит время разработки SaaS-интеграций, но добавляет накладные расходы на деплой сервера. CLI бесплатен на старте, но его сложнее контролировать в масштабе. Оптимизируйте фактическое узкое место — стоимость токенов, латентность или операционную сложность.

  • Важны навыки команды. Выполнение кода предполагает, что ваши агенты и лежащие в их основе модели способны надёжно генерировать Python или TypeScript. CLI предполагает знакомство с соглашениями Unix. MCP требует понимания транспортных протоколов и OAuth-флоу. Сопоставляйте модальность с сильными сторонами команды.

  • Консолидация инструментов может зайти слишком далеко. Если один инструмент накапливает несвязанные режимы и аргументы, агент сталкивается с другой задачей выбора уже внутри схемы. Используйте оценки выбора инструментов и успешности задач, чтобы найти подходящую поверхность для своей нагрузки.

  • Skills основаны на промптах и не обеспечивают enforcement. Skill содержит инструкции, которым агент должен следовать, а не гардрейлы, которым он обязан следовать. Skill bundle может включать произвольные файлы и исполняемые скрипты, поэтому доверяйте источнику, проверяйте bundle и заставляйте хост применять разрешения для каждого ресурса, который он может прочитать, изменить или выполнить. Для критичных процессов объединяйте skills с детерминированной валидацией.

  • Требования к аудиту влияют на выбор. Структурированные MCP- и JSON-вызовы удобно логировать как события, но ни один протокол из коробки не создаёт полный audit trail. Хост, сервер или харнесс должны записывать вызовы и результаты, а затем обеспечивать авторизацию, политику, хранение и проверку. Выполнение кода требует той же инструментализации вокруг сэндбокса; одного скрипта и его вывода недостаточно для compliance-записи.


Три направления развития инструментов AI-агентов в масштабе

Первое — tool RAG для масштабирования. До выбора инструмента моделью извлекайте несколько описаний инструментов, соответствующих запросу, и позволяйте ей выбирать из этого поднабора, а не из полного реестра. В задачах бенчмарка RAG-MCP и стресс-тесте MCP точность выбора инструментов в baseline составляла 13,62%; retrieval повысил её до 43,13% — улучшение в 3,2 раза — и одновременно сократил число токенов промпта с 2 133,84 до 1 084 (примерно на 49,2%). В abstract статьи говорится о «более чем 50%», а описания генератора и эвалуатора расходятся в разных разделах; эти несоответствия ограничивают интерпретацию. Результат является свидетельством для этой эвалуационной установки, а не универсальным показателем для наивного выбора при росте наборов инструментов.

Второе — агенты, создающие собственные инструменты. Фреймворк LATM («LLMs As Tool Makers») сформировал двухфазную парадигму, в которой мощная LLM создаёт переиспользуемые функции Python, а лёгкая LLM использует их. В бенчмарке ToolMaker из 15 задач по статьям с публичными репозиториями кода, представленным URL GitHub и краткими описаниями задач, он правильно реализовал 12 из 15 задач; всего в бенчмарке более 100 тестов. Этот небольшой бенчмарк задач по репозиториям не доказывает надёжность в production. Оба направления указывают за пределы использования инструментов — к созданию инструментов, а затем к управлению библиотекой сгенерированных инструментов.

Третье — двухпротокольный стек A2A + MCP. Google передала A2A Linux Foundation в июне 2025 года. В документации протокола A2A разграничены их обязанности: MCP подключает агента к инструментам и ресурсам, а A2A позволяет независимым агентам находить друг друга, согласовывать взаимодействие, управлять общими задачами и делегировать работу.


Сравнивайте интерфейсы на идентичных задачах и при одинаковом наборе разрешённых операций. Записывайте токены обнаружения, кэшированный и некэшированный ввод, вывод выполнения, повторы, латентность и успешность достижения итогового состояния. Тестируйте не только экономию токенов, но и пропущенное обнаружение; для сгенерированных программ учитывайте синтаксические ошибки, ошибки времени выполнения и частичное завершение.

Основные выводы

  1. Выбирайте поверхность выполнения исходя из действия: JSON-вызовы — для небольших типизированных операций, MCP — для общих сервисов, CLI — для устоявшихся команд, код в сэндбоксе — для локальной композиции. Используйте Skills, чтобы документировать выбор и применение этой поверхности.
  2. Всегда указывайте условия бенчмарка рядом с результатом. CodeAct, Anthropic, Vercel, Cloudflare, Apideck и Scalekit измеряли разные модели, задачи, инструменты и харнессы.
  3. Качество ACI сохраняет значение при изменении протокола. Понятные действия, компактная обратная связь, валидация и полезные ошибки помогают любой модальности.
  4. Объединяйте пересекающиеся инструменты только тогда, когда эвалуации показывают, что меньшая поверхность улучшает выбор или успешность задач.
  5. Безопасность должна соответствовать мощности выполнения. Shell- и code-интерфейсы требуют сэндбоксинга; MCP — scoped identity и политики сервера; Skills остаются инструкциями, а не механизмом enforcement.

Следующий слой — политика

В части 4, AI Agent Security, рассматривается проверка харнесса между предложенным вызовом инструмента и выполнением. В части 5 инструмент и его сэндбокс помещаются в восстанавливаемый рантайм. В части 6 добавляется контракт, которого модель не видит: категория эффекта, правило повтора и структурированный результат, который acceptance check может прочитать без парсинга прозы.


Источники

Статьи

Инженерные материалы Anthropic

  • Advanced Tool Use / Programmatic Tool Calling — Tool Search (примерные границы контекста около 77K и 8,7K), PTC и примеры использования инструментов
  • Code Execution with MCP — Сокращение числа токенов на 98,7% (со 150K до 2K) за счёт оркестрации инструментов на основе кода
  • Writing Effective Tools for Agents — Инжиниринг описаний инструментов; входные примеры повышают точность; enum response_format (72 против 206 токенов)
  • Building Effective Agents — ACI как фундаментальный принцип проектирования

Спецификации протоколов

Отраслевые кейсы

  • Vercel: We Removed 80% of Our Agent’s Tools — в старом примере названы 17 инструментов, в новом доступны ExecuteCommand и ExecuteSQL; Vercel описывает редизайн как удаление 80%; успешность выросла с 4/5 до 5/5 на пяти репрезентативных запросах, скорость — в 3,5 раза, число токенов — на 37%
  • Cloudflare: Code Mode — вызовы API через TypeScript вместо схем инструментов
  • Apideck: MCP Server Eating Your Context Window — 550–1 400 токенов на инструмент, 55K токенов для примерно 40 MCP-инструментов, 143K/200K занятого контекста
  • Scalekit: MCP vs CLI Token Benchmark — накладные расходы MCP по токенам в 4–32 раза выше CLI в 75 бенчмарк-запусках

Безопасность

Дизайн CLI

Демонстрационный проект

  • Market Analyst Agent — Полная реализация с консолидацией инструментов и паттернами ACI

Полный код Market Analyst Agent, включая описанные в этой статье дизайны инструментов, находится на GitHub.