Агент-инженер по репозиторию · Модуль 3 · Урок 3.4
Чекпойнт v2: память сессии и компакция истории
Зачем (какую проблему чиним)
Многошаговая задача накапливает длинную историю сообщений: старые tool-результаты (содержимое файлов, выводы тестов) распухают и съедают окно. Нужна память сессии с компакцией: удерживать суть, отбрасывать устаревшие детали — не ломая prompt caching.
Решение и альтернативы
Решение: менеджер истории, который (1) держит стабильный префикс (системный промпт, список инструментов) байт-в-байт неизменным ради кэша; (2) компактит хвост — старые большие tool-результаты заменяет краткими резюме («прочитан main.go, 120 строк; ключевое: …»); (3) хранит краткую «рабочую память» задачи (что уже выяснено, что осталось). Собираем рабочий агент версии v2 и тегируем v2.
Альтернативы: обрезать историю с начала — ломает кэш и теряет системный контекст; не компактить вовсе — упираемся в окно и стоимость. Компакция только хвоста при стабильном префиксе — правильный компромисс.
DIFF
Добавляем менеджер истории с компакцией хвоста и сохранением стабильного префикса; подключаем к циклу.
⚠ Безопасность
Компакция не должна затягивать в долговременную память секреты или вредоносные инструкции из прочитанных файлов (prompt injection). Резюмируем фактическое содержание, помечая внешний контент как данные, а не как инструкции. Это мостик к guardrails версии v4.
Проверка
Длинная сессия (десятки шагов) не упирается в окно: в логах видно, как старые tool-результаты сворачиваются в резюме, а usage.CacheReadInputTokens подтверждает, что префикс читается из кэша. Затем git tag v2 — рабочий read-only агент с retrieval и памятью.
Глубже
Архитектуры памяти (эпизодическая/семантическая/процедурная), консолидация и забывание — курс «Продакшн-разработка», Модуль 2 (гл. 4); компакция и стабильный префикс ради кэша — Модуль 1 (гл. 2).
+package main
+
+import "github.com/anthropics/anthropic-sdk-go"
+
+// History управляет окном: стабильный префикс ради кэша + компакция хвоста.
+type History struct {
+ prefixLen int // первые N сообщений не трогаем (кэш)
+ msgs []anthropic.MessageParam
+}
+
+// compact сворачивает старые крупные tool-результаты в краткие резюме,
+// НЕ затрагивая стабильный префикс (иначе инвалидируется prompt cache).
+func (h *History) compact(maxTokens int) {
+ for i := h.prefixLen; i < len(h.msgs)-keepRecent; i++ {
+ if isBulkyToolResult(h.msgs[i]) {
+ h.msgs[i] = summarize(h.msgs[i]) // "прочитан X, ключевое: ..."
+ }
+ }
+}Anti-patterns
| Грабля | Почему плохо | Как правильно |
|---|---|---|
| Компактить/переписывать начало истории (системный префикс) | Любой изменённый байт префикса инвалидирует prompt cache целиком — стоимость растёт | Префикс держать неизменным; компактить только хвост (старые tool-результаты) |
| Обрезать историю простым отбрасыванием первых сообщений | Теряются системный контекст и инструменты; ломается кэш | Резюмировать устаревшие детали, сохраняя суть и стабильный префикс |
| Затягивать в долгую память внешний контент как инструкции | Prompt injection из файла переживает компакцию и влияет на будущие шаги | Хранить внешний контент как данные с пометкой источника, не как инструкции |
Практическое задание (RA-v2)
- Добавить менеджер истории: стабильный префикс + компакция хвоста (резюме крупных tool-результатов).
- Подтвердить чтение кэша по
usage.CacheReadInputTokensна длинной сессии. - Зафиксировать версию:
git commit -m "v2: session memory and compaction"иgit tag v2.
Проверка знаний
Чтобы экономить, инженер добавил компакцию, которая суммирует и переписывает начало истории, включая системный промпт и список инструментов. Счёт за токены вырос.
Наиболее вероятная причина?
Верный ответ: B
B. Prompt caching — это префиксное совпадение: изменение любого байта в начале (системный промпт, инструменты) сбрасывает кэш, и каждый запрос платит премию за холодную запись. Компакция должна трогать только хвост, удерживая префикс байт-в-байт.