Обзор

Короткий файл памяти разваливается на масштабе: токены против приоритета правил

Совет держать файл памяти крошечным верен для соло-репозитория. Но комплаенс-правила нескольких организаций не прибьёшь к путям — их надо маршрутизировать.

Anubhav потратил полгода на тюнинг своего рабочего окружения для агента и описал восьмислойный стек, который «finally worked»: короткий файл памяти проекта (по его словам, держать его «under 500 tokens on purpose» ради попаданий в кэш), path-scoped правила, режим планирования, один read-only subagent-ревьюер на дешёвой модели, навыки, хуки, пять MCP-серверов и параллельные worktrees с headless-режимом в CI. Вывод он формулирует жёстко: «The stack is the workflow. The workflow is the multiplier. The prompt is just the last five percent.» С этим финальным тезисом я согласен полностью. Проблема в другом: я выстраиваю похожий стек дольше полугода — с командами из нескольких агентов, параллельными ревью и тестами, маршрутизацией контекста и слоями жёстких правил, — и ровно тот первый слой, который Anubhav называет фундаментом, у меня разваливается на масштабе.

Мой тезис простой. Совет «держи файл памяти крошечным» верен для одного разработчика в одном репозитории. Но как только у тебя появляются комплаенс-правила нескольких организаций, которые нельзя «прибить» к путям файлов, маленький плоский файл перестаёт быть добродетелью и становится недостающей возможностью. Anubhav смешивает две разные проблемы: стоимость фонового контекста в токенах и авторитет и приоритет правил. Его восьмислойный рецепт решает только первую.

Где он прав, и прав по-настоящему

Почти всё в его статье — это то, с чего я когда-то начинал, и это правильные примитивы. Path-scoped правила экономят токены ровно так, как он описывает: файл с конвенциями для миграций не должен грузиться, когда агент трогает фронтенд. Режим планирования с read-only subagent, которому явно запрещены write и edit, — нормальная гигиена: исследование и проверка живут в изолированном контексте, а не в основном цикле.

Особенно хорош его акцент на Deferred Permissions. Возможность поставить агента на паузу в headless-прогоне, одобрить действие вне процесса и продолжить ровно с того же места — это правильный примитив для ночных запусков. Раньше, как он точно замечает, ночной прогон, которому нужно было запушить в main, либо шёл с выключенными проверками, либо падал в три часа ночи. Его субагенты с узким allowlist инструментов и пониженной до дешёвой модели тоже разумны: дорогая модель остаётся на тяжёлых рассуждениях, ревьюер крутится дёшево в фоне. Здесь я не спорю — я это использую.

Где упирается в потолок

Потолок начинается там, где Anubhav кладёт фундамент. Его первый слой — это совет держать корневой файл памяти крошечным, потому что «Cache hit rates drop noticeably past ~500 tokens». Аргумент про токены верен. Но он молча приравнивает «дешевле в токенах» к «лучше устроено» — а это разные оси.

У меня правила приходят сразу от нескольких организаций и команд. Часть из них — жёсткие комплаенс-правила: что можно и нельзя писать в коммитах для определённых удалённых репозиториев, какие действия в проде требуют именованного одобрения, какие правила организации не может переопределить более узкий слой команды. Эти правила не глобятся по путям файлов. Они должны срабатывать по организации, команде и функции — по тому, где ты находишься и от чьего имени работаешь, а не по тому, какой файл редактируешь. Path-scoped механизм Anubhav здесь просто не применим: нет такого glob, который выражает «это правило организации перебивает правило команды».

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

Второе место, где упирается потолок, — его единственный read-only ревьюер. Subagent-ревьюер без гарантии остановки опасен ровно тем, что он молчаливо предполагает: что один проход ревью сходится. У меня ревью и тесты идут параллельно, и у них бывают конфликты — ревьюер говорит «блокер», тестировщик говорит «зелено». Кто прав? У одного субагента нет ответа на этот вопрос, и нет верхней границы на число итераций. Поэтому в моей архитектуре стоит жёсткий guard на пять итераций и есть оркестратор-арбитр, который разрешает конфликт ревьюера и тестировщика. Это и есть та самая дорогая часть, которую командная архитектура берёт на себя, — и которую один ревьюер на дешёвой модели не закрывает.

И ещё одна деталь про его approval gate. Его хук-предохранитель на push в main — это сопоставление строки: case "$cmd" in *"git push"*" main"*). Оно ловит знакомую форму команды. Но строковый матч обходится тривиально — другой синонимичной командой, переменной, алиасом. Мои approval-гейты семантические: они срабатывают на класс действия (запись в общую внешнюю систему, деструктивная операция в проде), а не на конкретную строку. Это разница между «защита от опечатки» и «защита от обхода».

Что с этим делать

Если вы работаете соло в одном репозитории — берите рецепт Anubhav целиком, он точен. Маленький императивный файл памяти, два-три path-scoped правила, один formatting-хук, режим планирования для всего рискованного. Deferred Permissions — обязательно.

Но как только в игру входят правила нескольких организаций, перестаньте думать про размер файла и начните думать про маршрутизацию и приоритет. Разделите две оси, которые Anubhav склеивает: токены — это про кэш, авторитет — это про то, какое правило перебивает какое. Жёсткие комплаенс-правила вынесите в слой, который грузится по контексту сессии, а не по glob. И как только ревью становится больше одного прохода, дайте ему явную верхнюю границу итераций и арбитра для конфликтов — иначе «дешёвый ревьюер» однажды зациклится на дорогом прогоне.

Мы сходимся в главном: стек важнее промпта. Anubhav просто останавливается на той базовой линии, с которой я начал. Его восьмой слой — это мой нулевой.