- BrainTools - https://www.braintools.ru -
В начале июля я объявил весь код своего проекта легаси. Не модуль — всё: код, архитектуру, документацию. Месяц до этого проект — джоб‑маркетплейс для синих воротничков: мобильное приложение, web, AI‑ассистент — делала команда. Люди сильные, каждый уже работал с LLM‑агентами; не было другого — методологии работы с агентами. Агент пишет код быстрее человека — и энтропию порождает быстрее: все ветки в main, решения только в чате, документация врёт, персональные данные оседают в access‑логах. Каждый исполнитель локально прав, система в целом не работает. Код, который страшно трогать, появился у нас раньше, чем первый работающий флоу. Я остановил всё и начал заново — один.
Мейнстрим лечит агентскую амнезию памятью [1]: длинные контексты, memory‑фичи, стейтфул‑агенты, которые «помнят проект». Это дорого в прямом смысле: длинная сессия ест токены и отвечает медленнее, а контекст в ней размывается — к концу модель хуже держит то, с чего начинала. Я пошёл в обратную сторону: память проекта живёт не в модели, а в репозитории и в рельсах — правилах, которые агент не может нарушить, потому что их держит pre‑commit‑хук, физически запрещающий коммит в main, CI‑джоб и branch protection, а не инструкция в контексте. Свежая дешёвая сессия — не ограничение, которое надо героически преодолевать, а основа метода.
Ставка тут глубже, чем экономия токенов. В человеческой команде дисциплина — самое дорогое: люди ленятся писать тесты и документацию, а заставлять — значит жечь мотивацию [2]. Агенту дисциплина ничего не стоит: требуют тест — он пишет тест. Если правила держит машина, дисциплина становится бесплатной — и метод отдаёт скорость и устойчивость разом, без привычного размена одного на другое.
Что это дало. Скорость: работающая вертикаль — бэкенд, веб, мобилка, БД, CI с гейтами, деплой на три окружения — за неделю; ещё через полторы — дизайн‑система, синхронизированная с Figma по 99 стилям, и полный гостевой флоу на web и mobile на четырёх языках — от онбординга до SMS‑входа с версионированным согласием. Итого 18 дней, 655 коммитов, ни дня без коммита — не full‑time. Управляемость: беклог этапа вырос по ходу с 28 до 48 задач — так обычно умирают спринты, — но каждая находка стала задачей с адресом: 41 влита в этом же этапе, семь перенесены явными хвостами, у каждого хвоста есть причина и адрес. Измеримость: энтропию я мерил дважды, полным проходом по корпусу — 47 и 93 находки, судьба каждой известна. И главное свойство: система метаболизирует инциденты в правила. Каждый инцидент либо рождает рельс, либо осознанно ложится на полку с триггером включения — молча не исчезает ничто.
Прежде чем вы напишете возражение к сравнению «месяц команды против двух с половиной недель соло» — я напишу его сам. Второй заход опирался на изученные грабли первого, а соло‑разработчик не платит налог координации, который платит любая команда. Чисто выделить вклад метода из такого сравнения невозможно — поэтому процентов производительности в тексте не будет вообще. Будет аргумент, который от оговорок не зависит: из первого захода не выжил ни один артефакт, а второй построил систему, которая позволяет одному человеку вести продакшн‑разработку и уже ловит реальные баги — три истории ниже. И чтобы это не осталось словами: код гейтов, хуки, чеклист ревьюера и каталог правил выложены как есть — отдельным репозиторием‑экстрактом. Продуктовый код я по понятным причинам не публикую; публикую сам харнесс — машинную обвязку метода: гейты с тестами, хуки, чеклисты, промпты. Не верьте описаниям, читайте условия джобов — все гейты в одном файле .github/workflows/ci.yml.
Это репортаж с середины пути: закончен второй из восьми этапов дороги до MVP, методология достраивается вместе с продуктом. Что не сработало — тоже здесь.
У метода семь принципов и 29 рельсов, которые их принуждают; манифест целиком в одну статью не влезает. Здесь — объяснительное ядро: пять наблюдений о том, как ведут себя свежие сессии LLM‑агентов. Всё дальнейшее выведено из них.
1. Агент не учится — он каждый раз собирается заново из репозитория. «Опыт» проекта существует ровно настолько, насколько записан: канон, доки, git‑история. Одинаковая ситуация даёт одинаковый — в том числе одинаково плохой — выбор в каждой свежей сессии. Следствие, ломающее интуицию [3] «введём правило — команда привыкнет»: правило надо калибровать до включения. «Само притрётся» с агентами не бывает.
2. Репозиторий — общая память всех сессий, поэтому качество истории — тоже рельс. Свежие агенты подражают влитым PR. Гейт, который часто краснеет не по делу, наполняет историю образцами обхода — и умирает, продолжая гореть зелёным. Здоровье гейта измеряется частотой лазеек во влитых PR, а лечится починкой условий джоба — не «воспитанием» исполнителей. Их рефлекс [4] — симптом, не болезнь.
3. Принуждение важнее увещевания — по механической причине. Инструкция в контексте размывается по мере роста сессии; хук не размывается. Обратное правило гигиены: правило, закреплённое механикой, сокращается в инструкциях агенту до одной строки — каждый лишний абзац в контексте это налог на все будущие сессии.
4. Привыкает в системе только человек. Замыленное ревью — «кожаная» уязвимость; свежая ревью‑сессия замылиться не может — у неё нет вчера. У меня каждый PR до моего ревью проходит свежую LLM‑сессию с фиксированным чеклистом (rails/review-rails.md в экстракте). Она дважды ловила меня самого — в коде той самой дизайн‑системы, что должна была дисциплинировать остальных: тест, зелёный при сломанной странице, и ESLint‑правило, которое обещало больше, чем проверяло. Автор правил нарушает их так же, как все, — поэтому каждый PR смотрит свежая сессия, а не я.
5. Правила рождаются из инцидентов — или из необратимости. Импортированная «лучшая практика» без прожитой боли [5] попадает не в систему, а на полку с триггером включения: правило, в пользу которого сам не веришь, сам первым и обойдёшь, а одно необязательное правило учит репозиторий тому, что правила бывают необязательными. Исключение одно: необратимые риски — секреты, потеря данных, персональные данные — получают рельс превентивно. Второго раза может не быть.
Рельсов сейчас 29: 12 жёстких канонических правил — работают все — и 17 рельсов метода: 12 работают, два на полке с триггерами, два уезжают в следующий этап, один демонтирован, не успев родиться — при постановке выяснилось, что принуждать нечего. Полный список неинтересен (а вот и он: живой каталог со статусами и графой «механизм принуждения» [6]), интересны типы:
Тихие гейты — детерминированные проверки без человека: CI‑джоб, pre‑commit‑хук, branch protection; код без тестов в PR — красный CI.
Линзы — семантические сверки «прочитай реестр до работы»: задача трогает персональные данные — сверка с GDPR‑реестром до кода.
Ревьюер — свежая LLM‑сессия с фиксированным чеклистом на каждый PR, до ревью человека.
Садовники — периодические проходы по всему корпусу, а не по диффу.
Церемонии — чеклисты границы этапа: этап не закрывается без отчёта, следующий не открывается без переноса хвостов.
Реестры — SSOT‑справочники, которые читают трое в трёх точках времени: исполнитель до работы, ревьюер на PR, садовник после.
Критерий добавления рельса: боль прожита — или риск необратим — и рельс можно сделать тихим. Церемонии — единственный источник бюрократии; их мало, и каждая обязана окупаться многократно. Из этого цикла складывается главное свойство: система самообучается — не модель, а система. Каждый инцидент оставляет след в правилах, и следующая сессия рождается в среде уже строже вчерашней; насколько это работает, видно по двум замерам энтропии в третьей истории ниже.
Таких историй за 18 дней накопились десятки: один только реестр правил ревью насчитывает 37 строк, и у каждой в графе «источник» — конкретный инцидент или вердикт (универсальная часть реестра — в экстракте). Эти три я выбрал за то, что они обобщаются за пределы моего сетапа.
Мои CI‑гейты читали описание PR: на месте ли обязательные секции, стоят ли пометки‑исключения с причиной. Подвёл собственный шаблон PR: в нём уже были заголовки этих секций и комментарии‑подсказки с примерами пометок. Гейты находили в пустом, не тронутом автором описании всё, что искали, — и PR был зелёным до того, как человек написал хоть слово. Так гасли четыре гейта разом. Правило: гейт должен проверять то, что создал исполнитель, а не то, что пришло из шаблона. Обобщается далеко за пределы моего сетапа: если ваш процесс проверяет «в PR есть секция X» — проверьте, не появляется ли секция X сама. Разбор с кодом фикса и тестом на контр‑кейс — в экстракте: case-studies/01-untouched-template-silenced-four-gates.md.
Публичный API отдавал карточку вакансии по прямому id в любом статусе: черновики и архив читались в обход фильтра ленты. Хуже самой дыры было то, почему её не поймал ни один тест: фейковое хранилище в тестах повторяло то же дырявое поведение [7], что и прод. Тесты честно подтверждали: дыра работает как задумано. Нашёл её не человек — садовник кода, проходом по всему корпусу, а не по диффу. Правило: фейк в тестах не должен узаконивать поведение [8] прод‑кода. Разбор — в экстракте: case-studies/02-public-endpoint-served-drafts.md.
Механизмы на PR по построению видят только дифф; энтропия копится между диффами. Увидеть её можно одним способом — периодически проходить корпус целиком; для этого и существуют садовники. Проходов было два. Первый, на закрытии первого этапа: два садовника, 47 находок — ноль нарушений модульных границ, но дубли и разъехавшиеся формулировки уже накопились. Второй, одиннадцать дней спустя: садовников уже четыре, находок 93 — девяносто починены фикс‑агентами внутри самой церемонии, три уехали хвостами. Сравнивать замеры в лоб нельзя — корпус вырос почти вчетверо, а искали уже четыре садовника вместо двух, — но направление видно и сквозь оговорки: находок лишь вдвое больше на вчетверо большем корпусе при вдвое большем числе ищущих. Плотность энтропии падает — система, метаболизирующая инциденты в правила, между замерами стала строже. Тесты и границы модулей честные, безопасность — ноль находок. Энтропия не исчезла — она отступила в маршрутизацию сторожей: правила о том, какие проверки бегут на каком PR.
Единственный блокер закрытия — ровно оттуда. PR, меняющий только миграции базы, не запускал ни одного теста базы: инвариант «каждая таблица под RLS» — рождённый из инцидента, закреплённый тестом — не проверялся на единственном классе PR, который способен его нарушить. Правило было. Тест был. Не было маршрута от одного к другому. Фикс — одна строка в конфиге CI. Если у вас монорепа с path‑фильтрами — проверьте сегодня, какие классы PR проскакивают мимо ровно своих тестов. У меня такой класс нашёл не человек, а штатный проход по целому. Разбор — в экстракте: case-studies/03-entropy-hides-where-no-one-looks.md.
База знаний на момент закрытия второго этапа — 60 документов, около 130 тысяч слов за 18 дней. Для меня это не побочный продукт, а сердце метода: я управляю проектом через документацию, поэтому она и появляется раньше кода. Кто это читает и когда это начнёт врать? Агенты не читают её целиком — входят через указатели, которые генерируются скриптом из канона и руками не правятся; дрейф указателей ловит CI. Расхождение доков с кодом ловится дважды: тихим гейтом на PR — «архитектурно‑значимый код тронут, доки нет — красный CI» — и садовником на границе этапа. А журнал «что поменялось и когда» ведёт git; в доки пишутся решения и «почему» — дублирования, которое гниёт первым, нет по правилу. Честная оговорка: корпусу 18 дней; выдержит ли контур дальнейший рост — покажет только продолжение работы, а не мои заверения сейчас.
Самый дорогой рельс — pixel‑perfect‑вёрстка: численная сверка с Figma, скриншот‑тройки, правило «после двух неудачных заплаток блок пересобирается». Работает, но это самая церемониальная часть системы, и держится она дисциплиной, а не хуками. Честный статус: терпимо для соло, не проверено на команде.
Отдельный сюрприз — сторож, читающий вчерашнюю газету. Мои гейты судят PR по его описанию, и дважды выяснилось, что проверка видит не тот текст, что человек. Один раз API отдал ревью‑сессии устаревшее тело PR — вердикт был вынесен тексту, которого уже не существовало. В другой раз оказалось, что перезапуск CI‑джоба не перечитывает PR, а работает со снимком события, снятым в момент пуша: пометку‑исключение, дописанную в описание позже, гейт не увидит, сколько его ни перезапускай, — только новый коммит приносит новый снимок. Мораль обобщается на любой CI, судящий по метаданным: выясните, какой снимок реальности видит ваш сторож и в какой момент он сделан.
Рельсы понадобились самим рельсам: один рельс жил строкой в каталоге, на него ссылались чеклисты — а документа не было. Метод, который лечит «решения живут только в чате», поймался на «правило живёт только строкой таблицы». Родился гейт «рельс без документа — красный» (код — scripts/ci_rail_doc_gate.py, рядом его тест). А церемония самопроверки уронила деплой: инвариант «web собирается» жил в двух местах, и второе не держал никто — тот же класс дыры, что и блокер с path‑фильтрами, второй раз за одно закрытие. Сторож есть, но стоит не на всех дверях; метод поймал себя даже в момент самопроверки — правда, постфактум: деплоем, не гейтом.
И главное, что не сработало, — весь первый заход. Месяц командной разработки, объявленный легаси, — не чужая история, а моя. Дешевле всего этот текст было бы не писать; я плачу за него месяцем.
Пока всё на ручном управлении: канон пишу руками, рельсы собираю руками; автоматики ровно одна — скрипт, генерирующий из канона указатели агентам. Напрашивающийся следующий шаг — машинный манифест методологии, из которого генерируется весь харнесс: условно, «Terraform для методологии разработки», — но это замысел, не анонс. Пока же всё перечисленное можно потрогать руками в экстракте харнесса [9]: гейты с их тестами (scripts/), хуки, шаблон PR, чеклист ревьюера и каталог правил.
Следующий этап — первый, где в проде появляется LLM‑ядро и импорт чужого контента: вакансии начнут подтягиваться с других площадок и нормализоваться батчами. Когда он закроется, станет видно, выживут ли рельсы на этапе с недетерминированным ядром, что найдёт третий замер садовников, сколько лазеек появится во влитых PR. И параллельно — эксперимент на переносимость: эти же рельсы я начну натягивать на другой свой живой проект, который писался вайб‑кодингом ещё до всякой методологии. Что чужой корпус переварит, а что отторгнет — тоже интересный вопрос. Если формат интересен — скажите; и мне правда интересно: какие гейты вы бы поставили своим агентам, если бы CI мог краснить любое их решение?
Автор: OlegKostrikin-Dev
Источник [10]
Сайт-источник BrainTools: https://www.braintools.ru
Путь до страницы источника: https://www.braintools.ru/article/33500
URLs in this post:
[1] памятью: http://www.braintools.ru/article/4140
[2] мотивацию: http://www.braintools.ru/article/9537
[3] интуицию: http://www.braintools.ru/article/6929
[4] рефлекс: http://www.braintools.ru/article/9352
[5] боли: http://www.braintools.ru/article/9901
[6] а вот и он: живой каталог со статусами и графой «механизм принуждения»: https://github.com/OlegKostrikin-Dev/agent-rails/blob/main/rails/index.md
[7] поведение: http://www.braintools.ru/article/9372
[8] поведение: http://www.braintools.ru/article/5593
[9] экстракте харнесса: https://github.com/OlegKostrikin-Dev/agent-rails
[10] Источник: https://habr.com/ru/articles/1062728/?utm_source=habrahabr&utm_medium=rss&utm_campaign=1062728
Нажмите здесь для печати.