Coding agents: минимализм, контроль и Docker
Да, я могу придумать флоу работы с агентами. Вот пример текста:
С возрастом мой тулинг для разработки становится все аскетичнее и проще. Меня перестали привлекать бибиканья Vim, бесконечные скобки Emacs и подбор миллионов плагинов для VS Code. Со временем от инструментов я начал ожидать предсказуемости. Это же правило распространилось и на AI-агентов.
Агенты стали обыденным инструментом в моей профессиональной карьере: при помощи AI я пишу статьи, решаю задачи, исследую проекты, провожу ресерчи. И как весь другой мой тулинг, харнес прошел эволюцию от сложного к простому.
Изначально я действительно гнался за кучей фичей, ставил все более и более странные плагины, пока однажды не наткнулся на статью Марио Цехнера о минималистичном агенте pi1. В этой заметке я не хочу слово-в-слово пересказывать пост Марио, вместо этого расскажу, как выглядит мой сетап и почему это работает.

Минимализм #
Изначально у моего агента было множество подключенных MCP, LSP, плагинов, пока я не попробовал поставить pi и начать с чистого листа. Оказывается, ничего из вышеперечисленного лично мне не надо:
- MCP засоряют контекст и хорошо заменяются связкой CLI + skill;
- LSP в целом довольно шумные и путают агентов;
- плагины, как правило, добавляли просто визуальные украшательства и ничего кроме.
Отказавшись от всего, мой агент перестал тратить время на изменение статуса задач в GUI, формирование запроса на отображение вопросов. Флоу стал максимально простым и понятным - обычный чат, в который я пишу, что мне надо, а агент это делает. Если у агента возникает какой-то вопрос, он мне его задает прямым текстом.
Спустя полгода активной агентской разработки и 4 крупных проекта этот принцип ни капли не изменился, ни разу не было задачи, когда мне было неудобно и я полез бы искать плагин для решения проблемы.
Сабагенты #
Еще одна вещь, на которую мне открыл глаза Марио. Возможно, для кого-то это покажется радикальным, но сабагенты не нужны.
Раньше я использовал сабагенты для построения какого-то loop’а разработки или надеялся, что большая и умная модель сама поймет, что нужно запустить второго агента для ревью или ресерча. Это и правда работало, но работало непрозрачно. У меня не было контроля за тем, что сабагент-ресерчер нашел и отдал основному агенту, не нагаллюцинировали ли эти два товарища чего-нибудь.
Сейчас я сам решаю, что мне нужен ресерч. Запускаю обычный чат и в нем провожу исследование.
Результаты записываю в отдельный *.md-файл, который потом использую в качестве контекста в новом
чате. У меня появился контроль над тем, когда нужно провести ресерч, что попадет в контекст при
разработке и когда нужно выполнить ревью. Плюс все md-артефакты переживают перезапуск сессий,
могут использоваться многократно для смежных задач.
Безопасность #
Меня довольно сильно пугает идея давать агентам полный доступ к проекту и к shell. Но, к сожалению, без этого невозможна полноценная агентская разработка. При этом доступ к секретам - отдельный риск: показательный пример - инцидент при оценке моделей OpenAI на Hugging Face2.
Вариант с ручным апрувом выполнения команд и доступа к файлам3 меня быстро утомил. По сути приходится просматривать все действия агентов, что убивает весь вайб от вайбкодинга. Вместо этого я принял компромиссное решение.
Мой агент всегда работает в yolo-режиме. Нужно установить какой-то пакет? Ставит. Нужен sudo-доступ для редактирования системных конфигов? Он есть. Звучит страшно, не так ли? Поэтому агент живет в Docker.
Есть довольно много решений, как запаковать агента в контейнер4 5. У меня небольшой самописный скрипт + свой образ, в который сразу установлены всякие Python/Ruff/Golang/Node/etc. Скрипт нужен, чтобы прокидывать только текущую директорию в режиме rw. Никаких других папок агент не видит и не может испортить. Плюс к агенту в руки не попадают никакие логины в GitHub, GitLab => уменьшается вероятность внезапного опенсорса рабочих проектов.
Однако есть еще один неприятный вектор создания факапов, и тут на сцену выходит мой первый плагин. Агенту на уровне харнеса запрещено вызывать write-команды Git. Он может читать историю, просматривать blame и выполнять любые другие read-команды, но не может коммитить, пушить, пулить и мержить. Плагин просто это все блокирует и бьет агента по рукам. Я сам решаю, когда и что нужно закоммитить, что отправить в стэш.
Как итог, агент может делать все, что хочет в рамках текущего проекта, но не может:
- испортить мне систему;
- испортить соседние проекты;
- испортить ветки коллег.
Понятно, что это не дает 100% гарантии от целенаправленного слива или порчи проектов. Но чтобы агент обошел текущую систему «защиты», ему нужно поставить соответствующую задачу. В обычной жизни, мне кажется, неожиданные факапы сводятся к 0.
Резюмируя, я отказался от всего тулинга, к которому пришла индустрия за годы существования агентов. Взамен я получил свободу агентов и одновременно высокую степень контроля над ними.
Да, из-за этих ограничений я не стал 100x инженером, который за месяц может сделать то, что команда делает за годы. Всего лишь 10x инженер, который ревьюит все изменения перед коммитом и который случайно не форспушнет в ветку коллеги.
OpenAI: инцидент безопасности при оценке моделей на Hugging Face . ↩︎
OpenCode: permissions - настройка разрешённых, запрещённых и требующих подтверждения действий. ↩︎
Docker AI sandboxes - изолированные окружения для запуска агентов. ↩︎
pi-less-yolo - запуск pi в Docker-контейнере с ограниченным доступом к файловой системе. ↩︎