Как писать инструменты для ИИ-агентов, а не для программистов

· 2 мин · BadRabbit

Сегодня в посте про llm-wiki я упомянул, что переписывал описания MCP-инструментов несколько раз. Вот статья, которая меня на это подтолкнула.

Главная мысль

Обычный API пишут для программиста: он прочитает документацию один раз, напишет код и дальше всё детерминированно. Агент читает описание инструмента каждый раз и каждый раз решает, звать его или нет. Это совсем другой пользователь. Как говорят авторы, агент хорош настолько, насколько хороши его инструменты.

Процесс

  1. Прототип. Быстро собрать инструменты и попробовать их с агентом вживую.
  2. Оценки. Набор реалистичных задач, на которых видно, справляется ли агент. Не игрушечные «найди пользователя по id», а настоящие многошаговые сценарии.
  3. Итерации вместе с агентом. Можно отдать модели логи прогонов и попросить улучшить описания инструментов. Это реально работает.

Принципы

Меньше, но лучше. Не надо оборачивать каждый эндпоинт. Лучше несколько продуманных инструментов под частые задачи. Пример: вместо list_users + list_events + create_event — один schedule_meeting, который сам находит свободное время.

Пространства имён. Префиксы вроде asana_search и jira_search помогают агенту не путать похожие инструменты из разных систем.

Возвращать смысл, а не технические детали. Агенту нужно имя файла и краткое содержание, а не UUID и MIME-тип. Хорошая идея — параметр response_format, где агент выбирает подробный или краткий ответ.

Экономить контекст. Пагинация, фильтры, обрезка длинных ответов с разумными значениями по умолчанию. И полезные ошибки: не «400 Bad Request», а «параметр date должен быть в формате ГГГГ-ММ-ДД, например 2026-10-06».

Описание — это промпт. Небольшие правки в описаниях дают большой прирост качества. Пишите так, будто объясняете инструмент новому сотруднику.

Мой комментарий

Как эти принципы выглядят в llm-wiki:

  • инструменты построены вокруг задач агента, а не вокруг таблиц: search, get_rule, list_rules, get_instructions (готовая инструкция под профиль) и цепочка create_proposal → validate_proposal → submit_proposal;
  • сервер отказывается от аргументов, которых инструмент не объявляет. Иначе агент выдумывает параметры, они молча игнорируются, и он уверен, что фильтр сработал;
  • выдача урезается по бюджету символов, а сервис записывает, сколько было доступно, сколько отдано и сколько страниц обрезано. По этой статистике видно, не голодает ли агент.

Агенты учатся по ошибкам прямо во время работы. Хорошее сообщение об ошибке — это бесплатный few-shot пример.