КЛАСТЕР 04 · MCP АНАТОМИЯ ИНСТРУМЕНТА ~16 МИНУТ
День 17 · из 35

Первый
инструмент

В Дне 16 ты понял, что такое MCP концептуально. Сегодня — внутрь: как именно инструмент попадает в контекст модели и от чего зависит, будет ли модель им пользоваться правильно. Это поверхностно технический урок, но за ним — главный навык: писать описания инструментов.

Суть урока

Инструмент в контексте модели — это не код. Это описание на естественном языке: имя, краткое описание, схема параметров. Модель ничего не знает про внутренности инструмента — она видит только его «вывеску». Поэтому качество описания — это всё. Плохо описанный инструмент = модель его не использует, или использует не так. Хорошее описание — это уже промпт-инжиниринг, просто маленького масштаба.

Что модель видит про инструмент

Когда MCP-клиент подключается к серверу, он получает список инструментов. Каждый инструмент описан тремя полями:

  • Имя (name) — короткий идентификатор: send_email, list_files
  • Описание (description) — текст в свободной форме о том, что делает инструмент
  • Схема параметров (inputSchema) — JSON Schema, описывающая аргументы

Эти три поля собираются в стандартный формат tool calling и попадают в system prompt модели. Это всё, что модель «знает» про инструмент. Не больше, не меньше.

Вот как это выглядит в реальности — пример описания одного инструмента из MCP-сервера для GitHub:

То, что видит модель
create_pull_request
Создаёт новый pull request в указанном репозитории. Используй, когда пользователь явно просит создать PR. Перед вызовом проверь, что в репозитории есть нужная ветка с готовыми изменениями.
owner: string · required
repo: string · required
title: string · required — заголовок PR, 5-100 символов
head: string · required — название ветки с изменениями
base: string · — ветка назначения, по умолчанию main
body: string · — описание PR в формате markdown
draft: boolean · — создать как черновик (default: false)

Это и всё. Модель видит описание и схему — и на их основе решает: стоит ли вызвать этот инструмент сейчас, и с какими параметрами.

Описание инструмента — это микропромпт. Не «техническая документация». Каждое слово в нём попадёт в контекст модели и будет на неё влиять.

Анатомия хорошего описания

Хорошее описание инструмента отвечает на четыре вопроса. Не обязательно в этом порядке, но все четыре должны быть покрыты:

Вопрос 01

Что инструмент делает

Действие, описанное глаголом + объектом. Не «утилита для PR», а «создаёт pull request». Чем короче и точнее — тем лучше.

Вопрос 02

Когда его использовать

Сигналы из запроса пользователя, по которым модель должна выбрать именно этот инструмент. «Когда нужно X». Без этого модель путается между похожими инструментами.

Вопрос 03

Когда НЕ использовать

Опционально, но мощно. «Не используй для X — для этого есть Y». Помогает модели не выбирать инструмент в неподходящих случаях.

Вопрос 04

Что вернёт

Какого вида результат модель получит. Это меняет, как она будет планировать следующие шаги. «Вернёт ID созданного PR» vs «вернёт ошибку, если PR уже существует».

Что писать в схеме параметров

JSON Schema у параметров — это не просто типы. Это дополнительный канал, чтобы объяснить модели нюансы каждого параметра. Что туда стоит класть:

  • Описание каждого параметра в свободной форме. Не "title": "string", а "title": "string, заголовок PR, 5-100 символов, в повелительном наклонении"
  • Примеры значений"example": "fix: handle null in user input". Особенно полезно для нетривиальных форматов
  • Ограничения — длина строки, диапазон чисел, перечисление значений (enum). Модель учитывает эти ограничения
  • Что обязательно, что нет — поле required и осмысленные дефолты

Чем больше осмысленных подсказок в схеме — тем меньше модель «галлюцинирует» неподходящие аргументы.

i
Эмпирическое правило длины описания
Для простого инструмента — 1-2 предложения. Для сложного с нюансами — до 4-5. Длиннее почти никогда не нужно: если требуется три абзаца объяснений, значит инструмент слишком сложный и его надо разбить на несколько. Один инструмент = одно действие, описываемое за пару предложений.

Хороший vs плохой инструмент

Возьмём один и тот же концептуальный инструмент — «послать email» — и сравним два описания:

Плохое описание
send
Отправляет сообщение. Принимает данные.
Что не так: имя не специфично (что именно «send»?). Описание не говорит, что это email, не говорит, когда использовать. Параметры не описаны. Модель будет либо игнорировать инструмент, либо вызывать его наугад с неверными данными.
Хорошее описание
send_email
Отправляет email через корпоративный SMTP. Используй, когда пользователь явно просит отправить письмо. Не используй для черновиков — для них есть draft_email. Возвращает message_id при успехе или ошибку SMTP.
Что хорошо: точное имя, чёткое «что», явное «когда», явное «когда нет», описан возврат. Модель сможет осмысленно выбрать инструмент и использовать его.

Распространённые типы плохих описаний

«Endpoint POST /api/v2/emails с авторизацией Bearer. Принимает payload в формате RFC-5321...». Это полезно человеку, который пишет код вокруг инструмента. Модели — бесполезно: ей не нужно знать про endpoint, она не делает прямой HTTP-запрос.

Описание для модели должно быть о смысле: что делает, когда применять, что вернёт. Технические детали оставляй разработчику в README.

«manage_users: создаёт, редактирует, удаляет пользователей. Параметр action: create/update/delete». Модели плохо с такими «инструментами-комбайнами». Они путаются в значениях action, забывают передать нужные параметры для конкретной операции.

Лучше три отдельных инструмента: create_user, update_user, delete_user. Каждый с чёткой схемой только для нужных параметров. Тренд в индустрии: больше инструментов с узкими задачами, меньше «универсалов».

В описании написано «отправляет email», а на самом деле — добавляет письмо в очередь, которая иногда падает с retry, иногда нет, и через час сообщает по webhook. Модель планирует следующие шаги, исходя из «отправлено», а на самом деле могут быть задержки.

Описание должно отражать реальное поведение: «добавляет письмо в очередь отправки. Письмо обычно доставляется в течение 5 минут. При успехе ставит в очередь возвращает task_id».

process, handle, execute, run — это не имена инструментов, это слова без значения. Когда у тебя в контексте 10 инструментов и один из них называется process — модель часто его вызывает «на всякий случай», потому что слово подходит под любую задачу.

Имя должно быть специфичным: process_payment, handle_refund_request, execute_sql_query. Чем уникальнее имя — тем точнее модель его использует.

Решения AI-инженера

Развилка 1. Один большой инструмент или несколько маленьких

Когда стоит выбор «manage_files с операциями vs отдельные read_file, write_file, delete_file» — почти всегда выигрывают маленькие.

Маленькие инструменты дороже в плане числа токенов (больше описаний в контексте) — но сильно лучше в плане точности (модель выбирает конкретный, не путается в action). А точность — это то, что определяет, работает агент или нет.

Исключение: когда у тебя десятки похожих операций (например, «получить пользователя по 20 разным фильтрам»). Тогда комбайн с параметром filter может быть оправдан. Но это редкие кейсы.

Развилка 2. Инструменты в system или динамически

Стандартный паттерн: все инструменты описаны в system prompt при старте задачи. Это просто и работает.

Альтернативный паттерн — динамическое включение: показывать модели только те инструменты, которые релевантны текущему шагу. На первом шаге — общие, на следующих — после понимания задачи. Это сэкономит токены и снизит «шум выбора».

Динамика стоит того, когда у тебя больше 15-20 инструментов. Для маленького набора — overkill.

Концептуальные грабли

«Имя send_email очевидное, описание ему не нужно». Модель понимает по имени примерно, но не точно. send_email — это «отправить любое письмо»? «отправить из этой системы»? «отправить от моего имени или от системы»? Без описания — гадание.

Имя задаёт категорию, описание уточняет контракт. Оба нужны.

Инструмент «прочитать файл» возвращает 50KB сырого текста. Это сразу падает в контекст модели и съедает токены. На следующих итерациях этот блок продолжает «весить».

Возвращаемся к Дням 8-10 (управление контекстом): что инструмент кладёт в контекст — это часть его дизайна. Большие результаты нужно сжимать, обрезать, давать структурированно. Иначе плохой контекст-инженерия.

Инструмент при ошибке возвращает {"error": true} или, ещё хуже, бросает исключение. Модель не понимает, что произошло, что попробовать дальше.

Ошибки — это тоже сообщения модели. Хорошая ошибка: {"error": "rate_limit", "message": "Превышен лимит 100 запросов в минуту. Попробуй через минуту или сократи количество вызовов"}. Модель сможет принять решение: подождать, выбрать другой путь, отказаться от подхода.

Практика

Эксперимент 01 · Прочитай описания инструментов в готовом MCP

Открой код реального сервера

Зайди в репозиторий любого готового MCP-сервера (github.com/modelcontextprotocol/servers — официальный набор). Открой код одного из инструментов. Посмотри, как там описано: какое имя, какое description, какие поля в схеме, какие там описания. Сравни хороший пример (GitHub MCP) с менее удачным (какой-нибудь экспериментальный). Это лучше любой теории показывает, что работает.

Эксперимент 02 · Опиши инструмент для своего проекта

Один инструмент, 20 минут

Возьми твою идею AI-агента. Выбери один инструмент, который ему точно нужен. Распиши его в трёх полях: name, description, schema. По описанию — пройди по четырём вопросам (что/когда/когда нет/что вернёт). По схеме — добавь description к каждому параметру, не только тип. Это упражнение прокачивает важнейший микро-навык: умение писать описание, которое работает.

Эксперимент 03 · Подсмотри, как Claude видит твои инструменты

Открой Claude Desktop в developer mode

В Claude Desktop включи Developer Tools (есть в настройках). Подключи любой MCP-сервер. Открой DevTools и найди логи MCP-взаимодействия. Ты увидишь, какой именно JSON был отправлен модели, как описаны инструменты, какие параметры были переданы при вызове. Это даёт тебе физическое ощущение того, что именно «видит» модель — а это половина работы AI-инженера в работе с MCP.

Что в Дне 18
Когда у агента один инструмент — он его и вызывает. Когда пять — обычно тоже выбирает правильно. А когда двадцать? Начинаются проблемы выбора. В Дне 18 — про tool selection как отдельную задачу: как помочь модели выбрать правильный инструмент в большом наборе, не путаясь.