Описания, которые работают
С тремя инструментами короткие WHEN TO USE / WHEN NOT TO USE ещё тянут.
Добавите четвёртый, пятый, а потом ещё и субагентов... и модель снова поплывёт:
полезет в bash там, где хватило бы read.
Лекарство то же: описания. Просто их нужно сделать жёстче и полнее.
read / grep / bash.
Слова, которые встретятся
- Контракт описания — фиксированный шаблон текста у инструмента. Все tools пишутся одинаково, модели проще сравнивать.
- Мягкий запрет (WHEN NOT TO USE) — «лучше возьми другой tool».
- Жёсткий запрет (DO NOT USE FOR) — «этим вообще не решают задачу X». Да, похоже на мягкий. Намеренно: модели нужно сказать дважды.
- Bash gravity — привычка модели хвататься за терминал, как за швейцарский нож. Наша задача — отговорить её вежливым, но упорным текстом.
Быстрый путь
- Расширьте docstring каждого tool до пяти секций.
- Добавьте USAGE (ограничения параметров) и EXAMPLES (конкретные вызовы).
- Оставьте оба негатива: WHEN NOT TO USE и DO NOT USE FOR.
Упражнение 2.1
Приведите описания read, grep и bash к полному контракту.
- Первая строка — что делает tool и что возвращает.
- WHEN TO USE — 2–4 сценария словами из реальных промптов.
- WHEN NOT TO USE — мягко указать другой инструмент по имени.
- DO NOT USE FOR — жёсткие границы («никогда не для поиска / не для cat»).
- USAGE — лимиты, дефолты, то, чего не видно из типов аргументов.
- EXAMPLES — 2–3 конкретных набора аргументов.
Зачем два «не делай так»
Кажется, что WHEN NOT TO USE и DO NOT USE FOR дублируют друг друга.
Так и есть. Под нагрузкой (неясный промпт, много tools) модель
«забывает» мягкий намёк и снова тянется к bash.
Второй запрет — ремень безопасности. Сказал один раз — может проскочить.
Сказал два — почти всегда держится.
Полный контракт на примере
docstring для grep
"""Поиск по содержимому файлов через regex. Строки с путями к файлам.
WHEN TO USE: паттерны по многим файлам, определения функций,
импорты, TODO, сообщения об ошибках.
WHEN NOT TO USE: чтение уже известного файла (используй read).
Запуск команд (используй bash).
DO NOT USE FOR: чтение файлов (read), список каталогов (bash),
правка файлов (edit / write — появятся позже).
USAGE: pattern — строка regex. glob — маска вроде "*.py".
Результат обрезается на 50 совпадениях.
EXAMPLES:
- TODO: pattern "TODO" glob "*.py"
- определения функций: pattern "def \\w+" glob "*.py"
- импорт пакета: pattern "from pydantic_ai" glob "*.py"
"""
docstring для read
"""Прочитать файл проекта. Возвращает пронумерованные строки.
WHEN TO USE: просмотр содержимого, конфигов, исходников,
кусок файла через offset/limit.
WHEN NOT TO USE: поиск по многим файлам (используй grep).
Запуск команд (используй bash).
DO NOT USE FOR: поиск по коду (grep), выполнение в shell (bash),
изменение файлов (edit / write).
USAGE: path — относительно рабочей директории.
offset и limit необязательны. Вывод не больше 500 строк.
"""
docstring для bash
"""Выполнить shell-команду в рабочей директории.
WHEN TO USE: сборка, установка пакетов, тесты, git, список файлов.
WHEN NOT TO USE: чтение файла (используй read).
Поиск по паттерну (используй grep).
DO NOT USE FOR: чтение файлов (read), поиск по коду (grep).
USAGE: command — одна строка shell. Команды вне белого списка
блокируются и возвращают понятное сообщение.
EXAMPLES:
- список файлов: command "ls -la"
- статус git: command "git status"
- тесты: command "pytest" # если добавите в белый список
"""
| Секция | Зачем |
|---|---|
| Первая строка | Что делает и что отдаёт |
| WHEN TO USE | Сценарии и слова из промптов пользователя |
| WHEN NOT TO USE | Мягкий редирект на другой tool |
| DO NOT USE FOR | Жёсткая граница, повтор |
| USAGE | Лимиты и дефолты, которых нет в типах |
| EXAMPLES | Конкретные вызовы «скопируй как образец» |
Описания стали длиннее — нормально. Они живут рядом с системными инструкциями; платите токенами один раз, а не на каждом чихе логики.
Проверьте
По одному промпту на каждый «характер» инструмента:
uv run python main.py . "Найди все TODO-комментарии в проекте"
uv run python main.py . "Прочитай pyproject.toml"
uv run python main.py . "Перечисли файлы в этой директории"
Ожидание: TODO → grep, файл → read,
список → bash с ls.
Смешанные фразы вроде «покажи содержимое pyproject через cat»
могут уйти и в read, и в bash — это
размытый промпт, не обязательно баг маршрутизации.
Готово, если:
- У всех трёх tools есть все пять секций описания
- Поиск TODO уходит в
grep - Чтение файла уходит в
read - Список файлов уходит в
bash - (бонус) Убрали EXAMPLES — и поймали, где маршрутизация впервые ломается