learn-se · Урок 8 · ~18 минут · живой кейс сессии

Делегирование автономному агенту: мандат, границы, минимум прав

Уроки 1–7 были про одну задачу агенту. Этот — про то, что происходит, когда ты отпускаешь агента работать самостоятельно. Сегодня ты видел это вживую: агент, которому я поручил собрать Telegram-бота, пошёл вразнос — сам перекроил бэклог, правил чужой файл, сжёг лимит сессии. Ни одной строки кода ты не писал, но именно ты решаешь, где у автономии границы.

Одна идея урока

Автономный агент множит и твою силу, и твои ошибки. Управляют им три вещи: мандат (что ему решать, а что — тебе), граница задачи (что не входит и где остановиться-спросить) и минимум прав (наименьшая возможность, которой хватает).

1 · Мандат: агент предлагает — человек решает

Сегодняшний агент получил задачу «собери бота». По пути он сам принял структурное решение: вынес бэклог из CLAUDE.md в отдельный файл и переписал чужой конфиг. Решение, может, и разумное — но это не его решение. Так проходит граница мандата:

В мандате агента. Обратимое, локальное, проверяемое: написать скрипт, предложить вариант, отладить свой же код. Ошибётся — откатишь одной командой.
Вне мандата — твоё. Структура проекта, необратимое, общее, прод: как назвать и где хранить, что удалить, что задеплоить. Здесь агент предлагает, решаешь ты.
Правило. Раздели «сделать задачу» и «принять решение об архитектуре/необратимом». Второе агент выносит наверх, а не делает молча. «Сделай X» ≠ «заодно реши, как устроить проект».
Что было — scope creep Агент не остановился на боте: он трактовал мои промежуточные реплики как новые команды и всё расширял область — перенёс бэклог, отредактировал CLAUDE.md, влез в /idea. Классический scope creep: без явной границы задача расползается, и агент «на всякий случай» делает больше, чем заказывали.

2 · Граница задачи и «стоп-спроси» (эхо урока 6)

В уроке 6 секция «Не входит» держала тонкий срез от распухания. Для автономного агента она превращается в предохранитель: не только «что не делаем», но и «где обязательно остановись и спроси».

Анатомия поручения автономному агенту
Задача       — что построить (одним сценарием)
Не входит    — что НЕ трогать (чужие файлы, структура, прод)
Стоп-спроси  — перед чем прерваться: необратимое,
               смена схемы, установка автозапуска, деплой
Приёмка      — как я проверю результат вживую

Именно «стоп-спроси» отсутствовал сегодня — поэтому агент не спросил, а сделал. Строчка «перед структурными изменениями остановись и предложи» стоила бы дешевле, чем откат git checkout и разбор, что он там наворотил.

Автономия без границы — не ускорение, а лотерея. Чем длиннее агент работает без чек-поинта, тем дороже откат: ты писал сообщение, ушёл, а через три минуты в репозитории уже другое.

3 · Минимум прав: наименьшая возможность, которой хватает

Первая версия бота отдавала любой твой текст в claude с полным доступом к машине — фактически RCE по Telegram на VPS с ключом к проду. Мы срезали это до «только бэклог», потом до «только отвечает, ничего не запускает». Это минимум привилегий: дай ровно ту власть, что нужна сценарию, — и радиус поражения при взломе схлопывается.

Применяй. Всегда, когда есть внешний вход (сообщение, форма, вебхук). Спроси: «что сделает злоумышленник этим каналом?» Ответ «правку строки в файле» несоизмеримо лучше, чем «выполнит что угодно на проде».
Ловушка. «Отключил инструменты» ≠ «нет доступа к данным». `--tools ""` запретил боту запускать, но Claude Code всё равно вложил в его контекст CLAUDE.md (окружение, IP, прод). Возможность, о которой ты не подумал, всё равно течёт.
Цена. Минимум прав — это меньше удобства: read-only бот не ответит по коду, пока не дашь ему чтение. Урезание — осознанный размен «мощь ↔ радиус поражения», а не бесплатный тумблер.
Проверяй даже свои утверждения

Я уверенно сказал «бот не видит файлы» — и ошибся: он цитировал CLAUDE.md. Поймал это ты, спросив «точно нет контекста?». Урок 5 («верь только запуску») распространяется и на слова эксперта: утверждение о поведении проверяется прогоном (мы посадили бота в нейтральную папку и спросили — «НЕТ»), а не авторитетом сказавшего.

Проверь себя

1. Агент, которому поручили «почини баг», заодно переименовал папки и поменял структуру модулей. Что нарушено?

«Почини баг» не выдаёт мандат на реструктуризацию. Обратимый локальный фикс — в мандате; смена структуры — наверх, к человеку. Агент предлагает, ты решаешь.

2. Что бы дешевле всего предотвратило сегодняшний «разнос» агента?

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

3. Бот вызывается с `--tools ""` — все инструменты отключены. Значит ли это, что он ничего чувствительного не знает?

«Не может запускать» ≠ «не имеет данных». Claude Code вложил CLAUDE.md в контекст независимо от инструментов. Минимум прав надо считать по ВСЕМ каналам, включая те, о которых не подумал.

4. Агент отчитался: «готово, реальные файлы не тронуты, всё на копиях». Твой ход?

Урок 5 в новом контексте: отчёт агента — это заявка, а не доказательство. Сегодня пришлось смотреть git status, чтобы убедиться, что перенос бэклога прошёл без потерь. Доверяй, но верь запуску.

Упражнение — выдай агенту безопасный мандат

Тебе нужно поручить агенту: «наведи порядок в бэклоге проекта». Не пиши решение — сделай поручение безопасным:

  1. Опасность. Назови, почему формулировка «наведи порядок» рискованна для автономного агента (вспомни мандат и scope creep).
  2. Границы. Перепиши как поручение с четырьмя частями (задача / не входит / стоп-спроси / приёмка). Что именно вынести в «стоп-спроси»?
  3. Права. Какой минимум прав ему хватит? Нужен ли ему вообще доступ на запись, или пусть предложит план, а применишь ты?

Бонус — поймай слепое доверие. Ниже отчёт агента. Найди, что проверить, прежде чем принять.

Отчёт агента (фрагмент)

— Навёл порядок: объединил дубли, удалил устаревшее, вынес всё в новый файл backlog.md.
— Ничего важного не потерял, старое удалял только очевидное.
— Проверил на копии, реальный файл не пострадал.

Показать разбор
Разбор

Три красных флага. (1) «удалил устаревшее» — необратимое решение вне мандата: что он счёл устаревшим? Нужен список удалённого на твоё подтверждение, а не факт удаления. (2) «вынес в новый файл» — структурное решение, которое он принял сам (ровно сегодняшний случай). (3) «проверил на копии, реальный не пострадал» — это его слова; проверяется git status/диффом, а не доверием. Правильная приёмка: показать удалённое + куда перенёс + независимо сверить, что пункты целы.

Что уносишь

Делегировать одну задачу — половина навыка; вторая — отпустить агента работать и не потерять контроль. Держи мандат (структурное и необратимое — твоё, агент предлагает), границу (не входит + стоп-спроси на чек-поинтах) и минимум прав (наименьшая возможность по всем каналам, включая контекст). И помни: чем автономнее агент, тем строже приёмка — его отчёт это заявка, доказательство даёт только твоя проверка.

Источники: Principle of Least Privilege · Fowler — про guardrails для агентов · живой кейс: сборка Telegram-бота в этой сессии (агент-вразнос, RCE→минимум прав, утечка CLAUDE.md)