Что это решает
Агент, собранный по умолчанию, отказывает предсказуемым набором способов: зовёт не тот инструмент, ходит кругами до упора в лимит, останавливается на середине задачи, докладывает о работе, которой не было. Настройка ИИ-агента лечит каждый симптом адресно — конкретным узлом конфигурации, а не переписыванием инструкции с нуля. Вторая задача — удержать стоимость: без ограничителей один запрос уходит в цикл и расходует бюджет целого дня. Третья — не дать агенту с доступом к почте, репозиторию и базе сделать необратимое.
Как устроено
Агент крутит один и тот же цикл: запрос попадает в контекст → модель выбирает инструмент → инструмент выполняется → результат возвращается в контекст → круг повторяется → срабатывает условие остановки. Настройка сводится к управлению тем, что попадает в контекст на каждом витке, что разрешено вызвать и когда цикл обязан прекратиться.
Инструкция. Роль, порядок действий, запреты, формат ответа. Работают проверяемые формулировки: «перед правкой файла прочитать его целиком», «не создавать ветку с именем вне шаблона». Не работают пожелания: «будь аккуратен», «старайся не ошибаться».
Инструменты. Имя, описание, схема параметров, текст ошибки. Модель видит только этот текст и по нему решает, звать инструмент или нет. Половина случаев «агент игнорирует инструмент» лечится переписыванием описания, а не инструкции.
Разрешения. Три корзины: выполняется молча, спрашивает подтверждение, запрещено полностью. Корзины задаются списком разрешённого, остальное закрыто по умолчанию.
Контекст. Что подкладывается при старте — файл правил проекта, память, схема данных, документы. И что обрезается — вывод инструментов, история длинного диалога.
Параметры генерации. Модель, потолок длины ответа, глубина рассуждения. Дешёвая модель на классификацию и дорогая на разбор — рабочая схема; выбор делается по типу шага, а не «везде самая мощная».
Ограничители. Потолок витков цикла, таймаут на шаг и на задачу, бюджет на одну задачу, обрезка вывода инструмента, число параллельных вызовов.
Наблюдаемость. Трасса вызовов: какой инструмент, с какими параметрами, что вернул, сколько занял и сколько стоил. Без трассы настройка превращается в гадание по финальному тексту.
Как подключить
1. Задать границу. Одна задача, один признак готовности. «Помощник по данным» не настраивается. «Отвечает на вопросы по остаткам и оплатам за период, на остальное отказывается» настраивается.
2. Написать инструкцию сверху вниз. Сначала запреты и обязательный порядок, затем формат вывода, в конце примеры. Порядок имеет значение: то, что стоит первым, соблюдается устойчивее.
3. Собрать минимальный набор инструментов. Каждый лишний ухудшает выбор среди остальных. Два инструмента с похожими именами дают путаницу гарантированно — их объединяют в один с параметром.
4. Переписать описания под модель.
Плохо: get_data — получает данные из базы
Хорошо: list_unpaid_invoices — счета со статусом «не оплачен» за период.
Параметры: date_from (обяз., YYYY-MM-DD), date_to (обяз.),
customer_inn (опц., 10 или 12 цифр).
Возвращает до limit строк, отсортированных по дате.
При обрезке в ответе truncated: true — сузить период.
5. Разложить разрешения.
{
"allow": ["db.select", "docs.read", "git.status"],
"ask": ["db.write", "mail.send", "git.push"],
"deny": ["shell.rm", "secrets.read", "prod.deploy"]
}
Правило раскладки простое: обратимое и дешёвое — в allow, обратимое и заметное для людей — в ask, необратимое — в deny, даже когда очень удобно было бы разрешить.
6. Поставить ограничители до первого боевого запуска.
max_steps потолок витков цикла
max_tool_output обрезка вывода инструмента
timeout на шаг и на всю задачу
budget потолок расхода на одну задачу
parallel сколько инструментов работает разом
Значения подбираются по трассам удачных прогонов: берётся типовое число шагов и закладывается запас, а не круглое число из головы.
7. Включить логирование каждого вызова. Инструмент, параметры, длительность, статус, стоимость. Секреты маскируются на уровне обёртки, а не договорённостью «мы туда не смотрим».
8. Собрать регресс-набор. Реальные запросы из переписки и тикетов, включая кривые и бессмысленные. Один и тот же набор гоняется после каждой правки конфигурации.
Отладка: симптом → узел
| Симптом | Что править |
|---|---|
| Инструмент не вызывается никогда | описание и имя инструмента, пример вызова в инструкции |
| Вызывается не тот инструмент | схлопнуть похожие в один, развести описания по границам применения |
| Ходит кругами по одному инструменту | текст ошибки инструмента: он обязан подсказывать следующий шаг |
| Обрывается на середине | потолок витков и таймаут, дробление задачи на этапы |
| Отвечает, но ничего не сделал | требовать артефакт в инструкции и проверять результат отдельным инструментом |
| Захлёбывается контекстом | обрезка вывода инструментов, справочные данные через поиск вместо вкладывания целиком |
| Выполнил запрещённое | закрывать разрешениями; инструкция здесь не помогает |
| Стоимость скачет от запуска к запуску | ограничить параллелизм и объём выборок, вынести тяжёлые шаги на дешёвую модель |
Полезные сценарии
- Аналитик только на чтение: пишущих инструментов физически нет, главный ограничитель — размер выборки.
- Дежурный по алертам: узкий набор инструментов, жёсткий таймаут, отправка сообщения людям через подтверждение.
- Кодовый агент: чтение и правка файлов свободно, push и деплой через ask, деструктивные команды в deny.
- Агент поддержки: база знаний в контексте, эскалация человеку отдельным инструментом, запрет называть сроки и скидки в инструкции.
- Пакетная обработка: параллелизм ограничен, ретраи с паузой, бюджет считается на элемент, а не на весь прогон.
- Ночной сборщик отчёта: интерактивных подтверждений некому давать, поэтому пишущие операции убраны и остаётся выгрузка в файл.
Ограничения
Настройка не создаёт данные. Если нужного поля нет в системе, никакой параметр не заставит агента ответить верно — он придумает правдоподобное.
Инструкция не гарантия. Текстом задаётся склонность. Всё, чего быть не должно, убирается на уровне разрешений или отсутствием инструмента.
Число инструментов работает против качества выбора. Набор растёт незаметно, и в какой-то момент агент начинает промахиваться там, где раньше был стабилен. Лечится ревизией набора, а не более подробной инструкцией.
Жёсткие ограничители режут длинные задачи. Потолок витков, подобранный по короткому сценарию, обрывает сложный на середине. Отсюда разные профили под разные типы задач вместо одного универсального.
Конфигурация стареет. Смена версии модели меняет поведение при том же конфиге. Регресс-набор перегоняется после каждого обновления, а не раз в полгода.
Наблюдаемость стоит денег и рисков. Подробные трассы занимают место и содержат фрагменты рабочих данных. Срок хранения и правила маскирования определяются заранее.
Как проверить результат
Прогнать регресс-набор и посмотреть четыре числа: доля выполненных задач, среднее число витков, стоимость на задачу, доля обращений за подтверждением. Ухудшение любого после правки конфигурации — повод откатить правку, а не объяснять её пользу.
Читать трассы, а не финальные ответы. Верный ответ, полученный шестью лишними вызовами, тоже дефект: он оплачивается на каждом запуске и рано или поздно упрётся в лимит.
Прогнать негативные тесты. Запрос, который должен упереться в deny, обязан упереться. Кривой ввод должен получить внятный отказ. Вопрос за границей роли — отказ вместо импровизации.
Проверить честность отчёта. Задача, где работа физически невозможна (сервис недоступен, база пуста), должна заканчиваться сообщением о невозможности, а не рапортом об успехе.
Проверить логи на секреты: поиск по фрагментам ключей и токенов в трассах после прогона. Нашлось — маскирование не работает, и это чинится раньше всего остального.
Правило одной строкой: то, чего агент делать не должен, задаётся разрешениями, а не текстом инструкции.
