Память AI-агента между сессиями: файл прогресса, журнал решений, git и init-скрипт
У AI-агента нет памяти между сессиями: всё, что не записано в файлы репозитория, новая сессия не знает. Память AI агента строят из артефактов — PROGRESS.md (где мы сейчас), DECISIONS.md (почему так и что отвергли), git-коммитов с объяснением замысла и протокола смены в AGENTS.md, который велит прочитать их в начале и обновить в конце; init-скрипт проверяет окружение и печатает текущее состояние.
Почему агент ничего не помнит
Модель не хранит состояние между запусками. Всё, что агент «знает» о вашей задаче, лежит в окне контекста текущей сессии: прочитанные файлы, вывод команд, диалог с вами. Сессия закрылась или контекст переполнился — новая начинает с нуля и видит только то, что записано на диске.
Полезная модель: гениальный инженер, который каждое утро приходит на работу с полностью стёртой памятью. Он быстро разберётся в коде, но не вспомнит, какой вариант архитектуры вчера выбрали, почему отвергли остальные и в каком состоянии тесты. Без записей он потратит пятнадцать-двадцать минут на разведку и с хорошей вероятностью переделает то, что вы уже сознательно отвергли.
Поэтому память AI агента — это не свойство модели, а часть харнеса: набор файлов и правил, который вы проектируете сами. Хорошая новость в том, что для этого не нужны векторные базы и специальные сервисы. Хватает нескольких Markdown-файлов, git и дисциплины.
Почему большое окно контекста не решает проблему
Кажется, что достаточно дождаться модели с окном побольше. Но сложная задача заполнит любое окно: агент читает кодовую базу, копит историю решений, получает многословный вывод тестов и держит весь диалог. Потребности растут вместе с окном. Это архитектурная проблема, а не вопрос объёма.
Есть и второй эффект. Ближе к границе окна многие модели начинают торопиться закончить: пропускают проверку, выбирают простое решение вместо правильного. Anthropic описывает это наблюдение для своих моделей, а выраженность эффекта отличается от модели к модели. Длинная сессия на пределе контекста — не только риск потерять информацию, но и риск ухудшить качество работы.
Компакция: что сохраняется, а что теряется
Компакция — сжатие ранней части диалога в краткое резюме, чтобы освободить место в той же сессии. В Claude Code это делает команда /compact, и сжатие также происходит автоматически при приближении к лимиту. Команда /clear, наоборот, очищает историю и начинает разговор заново.
Проблема компакции в том, что резюме обычно сохраняет «что» и теряет «почему». Готовый код остаётся в файлах, а рассуждения — почему выбран вариант Б, почему не взяли библиотеку, почему сознательно пропустили оптимизацию — сжимаются до пары слов или исчезают. Следующий шаг агента «улучшает» осознанное решение, потому что больше не видит причин.
| Компакция | Сброс (новая сессия) | |
|---|---|---|
| Что происходит | Ранняя часть диалога заменяется резюме | Сессия закрывается, новая читает файлы состояния |
| Что сохраняется | То, что модель сочла важным при сжатии | Ровно то, что вы записали в файлы |
| Спешка у границы окна | Может сохраниться | Обнуляется |
| Когда уместно | Задача точно уместится в текущую сессию | Горизонт задачи длинный или неясен |
Практическое правило без сложных метрик: когда задача заняла примерно 60% окна, перестаньте писать код и подготовьте передачу дел. Если же контекст занят на 40% и до конца задачи рукой подать, хватит компакции.
Четыре артефакта, из которых состоит память агента
Вместо того чтобы надеяться на память модели, заведите бортовой журнал. Он состоит из четырёх частей, и у каждой своя роль.
- PROGRESS.md — где мы сейчас.
- DECISIONS.md — почему сделано так, а не иначе.
- Git-коммиты — бесплатные чекпоинты состояния.
- Протокол смены в AGENTS.md — что делать при приходе и уходе.
PROGRESS.md: файл прогресса
Отвечает на один вопрос: в каком состоянии проект прямо сейчас. Агент читает его первым в начале сессии и обновляет последним перед уходом. Файл короткий, его переписывают, а не дописывают бесконечно: история живёт в git.
# PROGRESS.md
## Текущая цель
Поиск по каталогу товаров (фича search-01)
## Состояние
- HEAD: 4f2a9c1
- make check: зелёный, 142/142 теста
- Сделано: индекс в PostgreSQL (tsvector), ручка GET /search
- Проверено: юнит-тесты + ручной запрос curl по 3 запросам
## Блокеры
- Нет данных о морфологии для казахского языка — ждём решения
## Следующий шаг
Добавить пагинацию в GET /search, критерий: тест на 2-ю страницу
Обратите внимание на четыре поля, которых достаточно для передачи дел: хеш коммита, доля проходящих тестов, блокеры и следующий шаг. Если свежая сессия по этому файлу не может однозначно продолжить работу, значит, в шаблоне не хватает поля.
DECISIONS.md: журнал решений
Хранит то самое «почему», которое теряется при компакции. Формат записи: решение, причина, что отвергли и почему, ограничения.
## 2026-03-14 — Кэш пользовательских настроек в Redis
- Решение: Redis, TTL 5 минут, активная инвалидация при записи.
- Причина: читается на каждом запросе, объём данных крошечный.
- Отвергли: materialized view в PostgreSQL — слишком частые изменения,
поддержка не окупается.
- Ограничение: не кэшировать настройки оплаты.
Самая ценная строка здесь — «Отвергли». Именно она не даёт следующей сессии «оптимизировать» решение обратно к варианту, который уже рассматривали и отбросили. Журнал решений, в отличие от файла прогресса, только пополняется: старые записи не удаляют, а помечают как заменённые новыми.
Git-история как чекпоинты
Коммиты — уже встроенные в работу версионированные снимки состояния. Агент может прочитать git log и git diff и восстановить, что менялось. Чтобы история работала как память, сообщение коммита должно объяснять замысел, а не пересказывать диф.
# плохо
git commit -m "update search.py"
# хорошо
git commit -m "search: индекс tsvector вместо LIKE
LIKE '%q%' не использует индекс, на 200k товаров запрос 1.8 с.
Пагинация ещё не сделана, см. PROGRESS.md."
Небольшие частые коммиты после каждого зелёного прогона тестов дают ещё и точку отката. Если сессия ушла не туда, проще вернуться к последнему проверенному состоянию, чем распутывать полуготовые правки.
Протокол смены в AGENTS.md
Файлы состояния бесполезны, если агент о них не знает. Поэтому во входном файле инструкций (AGENTS.md или CLAUDE.md) пишут короткий протокол: что делать при приходе и при уходе.
## Приход на смену
1. Прочитать PROGRESS.md и DECISIONS.md.
2. Найти активную задачу в .agent/feature_list.json.
3. Прогнать make check — убедиться, что репозиторий согласован.
4. Продолжить с «Следующего шага», не переоткрывая решённое.
## Уход со смены
1. Прогнать make check, закоммитить зелёное состояние.
2. Обновить PROGRESS.md: HEAD, тесты, блокеры, следующий шаг.
3. Дописать новые решения в DECISIONS.md.
4. Не оставлять недоделанного в рабочем дереве.
Протокол лучше держать коротким: это несколько строк во входном файле, а не отдельная простыня.
Init-скрипт: как ускорить старт сессии
Чтобы агент не собирал картину вручную, дайте ему один скрипт, который проверяет окружение и печатает состояние. Скрипт должен быть идемпотентным — его можно запускать сколько угодно раз — и заканчиваться явным сообщением о готовности.
#!/usr/bin/env bash
set -euo pipefail
echo "== 1. Окружение =="
command -v uv >/dev/null || { echo "FAIL: uv не установлен"; exit 1; }
uv sync --frozen
echo "== 2. Репозиторий =="
if [ -n "$(git status --porcelain)" ]; then
echo "WARN: рабочее дерево грязное"
else
echo "OK: чисто"
fi
echo "HEAD: $(git log -1 --oneline)"
echo "== 3. Проверка =="
make check
echo "== 4. Состояние =="
cat PROGRESS.md
echo "Готов к работе"
В протоколе прихода тогда достаточно одной строки: «запусти scripts/init.sh». В Claude Code такой запуск можно автоматизировать хуком на старт сессии (событие SessionStart), но и без хука агент выполнит скрипт по инструкции из файла.
Что класть в память агента, а что нет
Главная ошибка — превратить память в свалку. Каждая строка, которую агент читает при старте, занимает место в контексте, а лишнее размывает важное.
| Класть | Не класть |
|---|---|
| Текущую цель и следующий шаг | Пересказ кода, который агент прочитает сам |
| Решения с причинами и отвергнутые варианты | Полный лог диалога и вывод команд |
| Хеш коммита и статус тестов | Список зависимостей — он есть в манифесте пакетов |
| Блокеры и открытые вопросы | «Сделал отлично, всё работает» без указания, как проверено |
| Тупики: что пробовали и почему не сработало | Секреты, токены, пароли |
| Задачи с критериями приёмки | Устаревшие заметки о закрытых задачах |
Разделяйте и по времени жизни. Правила проекта меняются редко и касаются всех задач — им место во входном файле инструкций. Состояние меняется каждую сессию — ему место в файле прогресса. Если смешать их, входной файл быстро разрастётся устаревшими заметками.
Первая сессия: инициализация как отдельная фаза
Память между сессиями не поможет, если первая сессия ушла в хаос. Типичная картина: вы пишете на чистом репозитории «добавь поиск», а через полчаса выясняется, что тестовый фреймворк настроен неверно, а формат миграций не тот. Поиск появился, но фундамент кривой.
Причина в том, что реализация и инициализация оптимизируют разное: первая — число готовых фич в этой сессии, вторая — скорость и надёжность всех следующих. Агент склоняется к видимому результату, то есть к коду. Поэтому инициализацию стоит выделить в отдельную сессию с понятным критерием готовности из четырёх условий.
- Запуститься:
make setupиmake devработают с чистого клона. - Проверяться: есть
make testи хотя бы один настоящий проходящий тест. - Видеть прогресс: файл состояния существует и читается.
- Подхватить работу: есть список задач с критериями приёмки.
Если вы часто начинаете новые проекты, заведите шаблон репозитория: Makefile, тестовый фреймворк, скелет AGENTS.md, папку .agent/, scripts/init.sh, линтер и CI. Тогда инициализация сведётся к специфике конкретного проекта.
Как проверить, что память работает
Самая честная метрика — время от старта новой сессии до первого осмысленного изменения кода. Без артефактов это обычно пятнадцать-двадцать минут разведки, с хорошей передачей дел — две-три. Замерьте один раз до и после, и станет видно, окупается ли дисциплина.
Второй способ — тест холодного старта. Откройте свежую сессию, напишите «продолжай» и задайте пять вопросов: какая текущая цель, в каком состоянии тесты, какое решение принято по ключевой теме и почему, что блокирует, какой следующий шаг. Если агент отвечает на все пять по файлам, без догадок, — память устроена правильно. Каждый неуверенный ответ — недостающее поле в шаблоне.
Типичные ошибки
- Файл прогресса только растёт. Через месяц в нём сотни строк истории. Переписывайте его под текущее состояние, история — в git.
- Нет строки «отвергли». Журнал решений без отвергнутых вариантов не защищает от повторных споров.
- Агент обновляет состояние «на глаз». Пишите, как проверено: команда и результат, а не «всё работает».
- Передача дел на пределе окна. У границы контекста агент уже торопится; начинайте handoff заранее, примерно с 60%.
- Грязное рабочее дерево на выходе. Полуготовые правки без коммита сбивают следующую сессию с толку.
Итог
Память AI агента между сессиями строится не на модели, а на файлах: PROGRESS.md хранит текущее состояние, DECISIONS.md — причины и отвергнутые варианты, git-коммиты — чекпоинты с объяснением замысла, а протокол смены в AGENTS.md заставляет всё это читать и обновлять. Init-скрипт сокращает старт до одной команды, а тест холодного старта показывает, хватает ли записей. Бортовой журнал агента и bootstrap-контракт разобраны на практике в курсе по харнес-инжинирингу.
Частые вопросы
Можно ли просто попросить агента запомнить что-то на будущее?
Агент запомнит это только в том случае, если запишет в файл, который прочитает следующая сессия. В Claude Code для этого есть файлы памяти и CLAUDE.md, но для состояния конкретной задачи надёжнее явный файл прогресса в репозитории.
Чем PROGRESS.md отличается от CHANGELOG?
CHANGELOG описывает изменения для пользователей по версиям. PROGRESS.md описывает текущее рабочее состояние для следующей сессии агента и переписывается каждый раз, когда состояние меняется.
Нужна ли векторная база для памяти агента-программиста?
Для работы в одном репозитории обычно нет: состояние задачи умещается в несколько коротких файлов, а код агент читает напрямую. Векторный поиск имеет смысл, когда нужно искать по большому объёму внешних документов.
Коммитить ли файлы состояния в git?
Да, так состояние доступно любой сессии и любому участнику команды, а история его изменений сохраняется. Исключение — личные заметки и всё, что содержит секреты.
Что делать, если агент забывает обновить PROGRESS.md в конце?
Сделайте обновление частью критерия готовности в протоколе ухода и проверяйте его механически, например хуком или скриптом, который сравнивает HEAD в файле с текущим коммитом.
Эта тема подробно разобрана с практикой в курсе «Harness Engineering: инженерия надёжности AI-агентов».
Перейти к курсу