Как разложены документы
Один огромный файл в корне плохо обновляется точечно. Слои такие.
На сервере лежит общий договор для всех агентов на машине (AGENTS.md и соседние правила рантайма). В репозитории проекта — свой AGENTS.md и операционный гайд: куда смотреть, какие инварианты нельзя ломать. В docs/ — потоки (FLOWS), известные проблемы и короткие записи «что искать, где лежит, чего не делать». Отдельно скилы: пошаговые сценарии на повторяющиеся действия, не вторая простыня архитектуры.
сервер: AGENTS.md (+ правила рантайма) проект: AGENTS.md, CLAUDE.md docs/FLOWS.md docs/KNOWN_ISSUES.md (известные проблемы) docs/… (короткие записи по дырам) скилы: skills/*/SKILL.md (пошаговые сценарии) сверка: граф кода → find_doc_drift (markdown ↔ код)
Нюанс нескольких сред запуска: часть агентов подхватывает общий AGENTS.md и объединяет его с проектным, другой формат операционного гайда сама не читает. Устойчивые правки иногда приходится дублировать в оба файла, иначе один агент правило видит, а другой нет.
Обновлять эти слои вручную в конце каждой задачи не тянется: контекст сессии кончается, факт остаётся в чате, другой агент в другой среде его не видит. Дальше три автомата поверх этой раскладки: выжимка закрытых сессий, обновление графа кода и воскресная сверка markdown с кодом.
Дыра в сессии → запись сейчас
Автомат не угадывает, что было важно. Если в сессии всплыла дыра (долго искали ключ или путь, не поняли уже существующий функционал, документ молчал или врал, а код говорил другое), агент или я пишем факт в живой файл сразу. Это единственный ручной шаг в контуре. Память одного агента другие среды не видят, поэтому цель — короткий факт в общем документе.
Формулировка: что искать, где лежит, как работает, чего не делать. Две–пять строк. Эссе в чате не пишем. По ходу максимум одна-две строки, если иначе факт потеряется. В конце нетривиальной задачи уборка поднимает инварианты в общие документы. Любая правка текста сверяется с кодом сейчас.
Три случая, где запись закрыла повтор.
В боевом каталоге агент правил код прямо там, где крутится прод: процесс перечитывает файлы с диска без выкладки, у клиентов оказался недоделанный дифф. В документы ушло правило: код только в отдельной рабочей копии от main, боевой каталог без недоделанных правок. На студии вроде arckep.ru это особенно чувствительно: недоделанный дифф сразу бьёт по регистрации и входу.
На фронте в запросе на слияние добавили маршруты API, а сгенерированный TypeScript-файл типов не обновили. Сборка поймала устаревшие типы, в документах ещё путали имя файла. Правило: любое изменение API или схем — локально перегенерировать типы и закоммитить файл, не тянуть боевой OpenAPI ради быстрой проверки. Когда в продукте десятки моделей и внешних API, и новые подключаются регулярно, без такого правила агент снова оставляет фронт с устаревшими типами.
С HEIC в одном продукте конвертация уже была, в другом белый список jpeg/png/webp без конвертации. Искали регрессию не там. После исправления в файле с известными проблемами зафиксировано, где конвертят на сервере, где в браузере, и что проекты нельзя путать.
Как устроено автообновление
Три независимых контура. Они не ждут, пока я вспомню поправить markdown.
1. Закрылась сессия → через ~30 минут уроки в LEARNED.md
Сессию по таймеру не обрываю. «Около получаса» — не лимит длины чата.
Закрытая сессия сама LEARNED.md не пишет. Агент уже вышел.
Цепочка такая:
Сессия заканчивается. Транскрипт остаётся на диске.
Хук
SessionEndтолько ставитsession_idв очередь (enqueue). Текст уроков он не пишет.Systemd-таймер
agent-learn-distillраз в ~30 минут будитdistill.py.Скрипт берёт сессию из очереди или простаивающую. Если с последнего обновления ещё нет примерно 25 минут простоя и сессия не в очереди — ждёт. Нужно минимум два хода пользователя, иначе пропуск и повтор позже. Строит выдержку из
chat_history: до 12 ходов пользователя и до 4 коротких хвостов ассистента (лимит около 24k символов), не весь сырой транскрипт.Дальше вызывает Grok без интерактива, с готовым промптом и JSON-схемой. В промпт уже вложены текущий
LEARNED.md, заголовок сессии и выдержка; модели нельзя звать инструменты и перечитывать файлы. На выход: либоskip, либо новый полныйLEARNED.md(замена целиком, до ~80 строк и ~8k символов: живое оставить, устаревшее и дубли выкинуть; дата сверху, русский, без дампов кода) плюс список уроков с меткамиlearned/gotcha/decision. Тот же текст зеркалится в секцию Auto-learned файлаMEMORY.mdпроекта.Уроки с меткой
learnedуже в телеLEARNED.md;gotchaиdecisionуходят в inbox на воскресный подъём в общие инструкции. В живой сессии тот же прогон можно форсировать командой/learn.
Итого автор файла: таймер, distill.py и отдельный вызов модели по сохранённому транскрипту. Не «сессия сама дописала» и не чистые эвристики без модели. На выходе сырой конспект, не операционный гайд. В CLAUDE.md и AGENTS.md руками на каждом шаге не копирую.
Пример. В буфере: «черновик в живой папке до влития ломал вход; код — только копия от main». В общие инструкции это попадёт позже, на воскресенье или по явной просьбе, уже как инвариант.
2. Коммит → граф кода догоняет сам
Перед широким поиском или правкой чувствительных путей агент спрашивает граф: символы, кто вызывает, влияние, план изменения (find_symbol, callers_of, endpoint_impact, plan_change).
Индекс не обновляю вручную «когда вспомню»:
post-commitпомечает проект грязным.Примерно через минуту паузы идёт частичная переиндексация (AST, web, embeddings).
После слияния веток и сторожевой таймер раз в несколько часов (у меня раз в шесть часов) — более полный проход.
MCP графа поднимается на сессию по stdio; это не вечный демон в
systemctl.
Как граф понимает расхождения (find_doc_drift)
Это не модель «перечитай документы». Модуль codegraph, детерминированный пайплайн:
Собирает markdown по маскам (
docs/**/*.md,CLAUDE.md,AGENTS.md,README.mdи т.п.).Парсер вытаскивает упоминания в backticks и похожие ссылки: маршруты (
/api/…), функции и символы, таблицы и схемы, иногда числовые утверждения. Отсекает блоки кода, TODO, зачёркнутое, явные «удалён / не использовать».-
Верификатор сверяет каждую ссылку с индексами проекта:
маршрут →
api-mapweb-индексера (route_not_found, если пути нет);символ → AST sqlite (
symbol_not_found);таблица или колонка → кэш схемы БД (
table_not_found).
Делит результат на уверенные срабатывания (например чистый
route_not_found) и сомнительные (бэктикнутое слово могло быть прозой; спорные числовые claims вроде stale_count). В tool оба бакета есть; на практике и в воскресном прогоне оставляем уверенные (include_uncertain=false/ пост-фильтр), иначе тысячи ложных. Weekly дополнительно чистит FP и на правки только в markdown может подключить Grok.
Кто запускает: воскресный weekly.py, либо вручную CLI или MCP find_doc_drift. Поиск расхождений без LLM. Править документ — weekly, я или агент по отчёту.
При частой смене провайдеров и автодобавлении моделей без этой сверки markdown начинает описывать маршруты и таблицы, которых в индексе уже нет.
3. Воскресенье утром → сверка и подъём в общие инструкции
Раз в неделю (воскресенье 09:00 по локальному времени) таймер agent-learn-weekly будит скрипт weekly.py. Он делает то, что вручную на каждой задаче не тянется:
вызывает
find_doc_driftпо горячим проектам и собирает уверенные расхождения;смотрит inbox уроков из
LEARNED.mdи поднимает устойчивое в ветку,AGENTS.md,CLAUDE.mdи файлы с известными проблемами;шлёт короткий отчёт в мессенджер.
Именно здесь буфер сессий превращается в правило для всех агентов. Не весь LEARNED.md оптом, а то, что должно пережить смену среды запуска. Проверка расхождений находит кандидатов; подъём в общие инструкции — отдельный шаг weekly, плюс мой явный ок, если правка спорная.
Кто что делает одной таблицей:
Когда |
Что срабатывает |
Куда пишет |
Кто инициирует |
|---|---|---|---|
По ходу сессии |
правило «дыра → запись» |
живой документ / известные проблемы |
агент или я |
SessionEnd |
хук enqueue |
очередь distill |
автоматически |
каждые ~30 мин |
|
|
systemd |
после коммита |
пометка dirty + пауза ~1 мин |
индекс графа |
git-hook |
раз в ~6 ч / после слияния |
полная переиндексация |
индекс графа |
таймер / hook |
вс 09:00 |
|
правки документов + отчёт |
systemd |
вручную / в сессии |
CLI/MCP |
отчёт о расхождениях |
я или агент |
Хуки и скилы
Подсказка в промпте «не делай X» — это совет. Хук перед действием — это механизм.
Предохранитель на shell режет опасные команды на нескольких средах. Напоминание про граф перед чувствительными правками удерживает шаг, который иначе выпадает к середине длинного контекста. Отдельный предохранитель про дату обучения модели (не отвечать «из головы» про новые продукты и цены) не про сверку markdown с кодом. Расхождения в документах закрывают find_doc_drift и воскресенье.
Скилы — это пошаговые сценарии. Карта и инварианты живут в документах и графе, процедура в скиле. Поменялся шаг — правишь один файл скила, а не пять абзацев в разных гайдах.
Поддержка разных API и моделей плюс автоматическое добавление новых ИИ требуют жёсткой дисциплины действий агентов: сначала схема, тип и инвариант в документах, потом правка кода. Иначе агент угадывает провайдера из головы. На arckep.ru это повседневный режим работы студии.
Минимум для повторения
Развести роли файлов. Писать в живой документ при дыре в сессии. Поставить выжимку закрытых сессий в буфер. Обновлять граф с коммитами и раз в неделю сверять markdown с индексом, поднимая устойчивое из буфера в общие инструкции. Вынести в хуки опасный shell и «сначала граф» перед чувствительными правками.