0.4.11
07 · Техническая документация

07. Память (Memories)

Memories — система долгосрочной памяти AstraCode. Она читает прошлые сессии (rollout'ы), извлекает из них устойчивые факты о пользователе, проекте, предпочтениях, и подмешивает их в новые сессии.

Реализация — крейты memories/read/ и memories/write/. Хранилище — ~/.astracode/memories/, под git-контролем.

Два факта, которые ломают интуицию (и порождают сообщения об ошибках «память не работает»): 1. Функция выключена по умолчанию. Feature::MemoryTool имеет default_enabled: false (features/src/lib.rs:654-663), стадия — Experimental. Настройки [memories] (use_memories, generate_memories) по умолчанию true, но не дают эффекта, пока не включён сам feature-флаг ([features] memories = true или приглашение в /memories). 2. Агент не пишет память во время текущего разговора — у него нет такого инструмента. Инжектируемая read-инструкция прямо запрещает: «Never update memories. You can only read them» (memories/read/templates/memories/read_path.md:6). Всю запись делает отдельный фоновый пайплайн (memories/write/, этапы Phase 1/2) при старте будущих сессий. Просьба пользователя «запомни X» в текущем разговоре в память не попадёт.

1. Общая идея

text
Сессия 1: пользователь говорит "I prefer Rust over Python"
  ↓ (через несколько часов / при старте новой сессии)
Phase 1: модель читает rollout, извлекает "user prefers Rust"
  ↓
raw_memories.md  — сюда падает извлечённый факт
  ↓ (когда накопилось достаточно или раз в N часов)
Phase 2: модель консолидирует raw_memories в структурированные блоки
  ↓
MEMORY.md, memory_summary.md — оконсолидированная база
  ↓
Сессия 2: при старте в system prompt инжектится memory_summary.md,
          а MEMORY.md и связанные файлы агент читает сам по необходимости

Идея: долгосрочная память наполняется фоновым пайплайном (а не агентом в текущем разговоре), без ручной разметки. Аналог ChatGPT Memory, но локально и под git. Сам агент в сессии работает с памятью только на чтение.

2. Конфигурация

toml
[features]
memories = true                            # МАСТЕР-ВЫКЛЮЧАТЕЛЬ функции (по умолчанию false)

[memories]
generate_memories = true                   # разрешает Phase 1+2 (по умолчанию true, но без эффекта при выключенном feature-флаге)
use_memories = true                        # инжектит memory_summary.md в новые сессии (по умолчанию true)
disable_on_external_context = false        # пометить тред "загрязнённым" при внешнем контексте
max_raw_memories_for_consolidation = 256   # сколько raw-памятей берёт Phase 2 (дефолт 256)
max_rollout_age_days = 10                  # окно по возрасту сессий (дефолт 10)
min_rollout_idle_hours = 6                 # ждать N часов после сессии перед Phase 1 (дефолт 6)
extract_model = "claude-haiku-4-5"         # дешёвая модель для Phase 1
consolidation_model = "claude-sonnet-4-6"  # умная модель для Phase 2

Без [features] memories = true остальные настройки игнорируются: read-инструкции не инжектятся, фоновый пайплайн не стартует.

disable_on_external_context = true помечает тред как «загрязнённый» при внешнем контексте — полезно, если в проекте уже есть большой AGENTS.md/CLAUDE.md.

3. Структура ~/.astracode/memories/

text
~/.astracode/memories/
├── .git/                       # автоматический git-репо
├── MEMORY.md                   # консолидированный поисковый индекс (читается агентом по необходимости)
├── memory_summary.md           # короткая сводка (именно она инжектится в system prompt, если не пуста)
├── raw_memories.md             # сырая память (Phase 1 output)
├── phase2_workspace_diff.md    # git-стиль diff что изменилось
├── rollout_summaries/          # резюме по rollout'ам
│   ├── 2026-05-15-abc123.md
│   └── 2026-05-20-def456.md
├── user_profile.md             # тип: user
├── feedback_testing.md         # тип: feedback
├── project_<name>.md           # тип: project
└── reference_<name>.md         # тип: reference

Папка под git → можно cd ~/.astracode/memories && git log чтобы видеть историю изменений памяти.

4. Типы памяти

Phase 2 классифицирует факты по 4 типам:

Тип Что хранит Примеры
user Роль, опыт, цели пользователя "Магистрант ИУ-1, технически сильный"
feedback Корректировки/одобрения подходов "Прекращать суммировать после каждого ответа"
project Контекст проектов: цели, дедлайны, мотивация "Релиз X запланирован на 2026-06-01"
reference Указатели на внешние ресурсы "Баги трекаются в Linear проект INGEST"

В каждом файле памяти — frontmatter:

markdown
---
name: user_profile
description: "Кратко о пользователе и его предпочтениях"
metadata:
  type: user
---

Тимур, магистрант МГТУ им. Баумана (каф. ИУ-1).
Работает на русском, технически сильный — пропускает базовые объяснения.

5. Phase 1 — извлечение

Запускается асинхронно при старте сессии (если выполнены условия):

  1. Берёт rollout'ы из ~/.astracode/sessions/... за последние max_rollout_age_days.
  2. Фильтрует те, что не моложе min_rollout_idle_hours (даём сессии "остыть").
  3. Для каждого rollout отправляет в extract_model промпт: «извлеки факты о пользователе, проекте, предпочтениях».
  4. Результат пишет в raw_memories.md (append-only).
  5. Краткое резюме — в rollout_summaries/<date>-<id>.md.

Phase 1 фоновый, не блокирует TUI.

6. Phase 2 — консолидация

Запускается фоново при старте сессии, когда накопилось достаточно «сырой» памяти (превышен порог max_raw_memories_for_consolidation) или прошло достаточно времени с прошлой консолидации. Отдельной ручной кнопки запуска в /memories нет.

Шаги: 1. Загружает топ-N raw-памятей (по частоте использования). 2. Запускает внутреннего агента-консолидатора (consolidation_model) без сетевого доступа. 3. Агент обновляет MEMORY.md, создаёт/удаляет файлы памяти по типам, пишет diff в phase2_workspace_diff.md. 4. Коммитит результат в локальный .git.

Агент работает по системному промпту, описывающему правила (что хранить, что не хранить, как структурировать).

7. Использование в новых сессиях

Read-инструкции инжектятся, только если выполнены все условия (core/src/session/mod.rs:2509-2515, memories/read/src/prompts.rs:42): включён feature-флаг и use_memories = true и файл memory_summary.md существует и не пуст. Тогда при старте сессии: 1. Содержимое memory_summary.md подмешивается в system prompt. 2. Агенту даётся инструкция при необходимости прочитать MEMORY.md и связанные файлы обычными инструментами чтения. 3. Файлы, на которые ссылается индекс ([[name]]), агент читает сам по необходимости.

Цитирование: в конце ответа агент добавляет блок <oai-mem-citation> с использованными источниками. Запись/обновление памяти агенту недоступны.

8. Команда /memories

В TUI:

text
/memories

Если функция выключена — сначала показывается приглашение её включить (отправляет UpdateFeatureFlags { memories: true }, применяется со следующей сессии). Если включена — открывается экран настроек с двумя переключателями и действием сброса: - Use memories (use_memories) — подмешивать память в новые сессии. - Generate memories (generate_memories) — разрешить фоновую генерацию. - Reset all memories — стереть всю накопленную память.

(Реализация — MemoriesSettingsView, tui/src/bottom_pane/memories_settings_view.rs.)

9. Безопасность памяти

  • Файлы памяти не шифруются (но лежат в ~/.astracode, привилегированном).
  • Phase 2 запускается без сетевого доступа → агент-консолидатор не может «слить» данные.
  • API-ключи и секреты не должны попадать в память (модель явно проинструктирована не извлекать их).
  • Чтобы убрать факт: отредактировать соответствующий файл памяти, либо удалить весь файл.

10. Что НЕ хранится в памяти

(Из инструкции консолидатора)

  • Код, конвенции, архитектура — выводится из git и репо.
  • Git-история и изменения — есть git log.
  • Решения багов — есть в коммитах.
  • AGENTS.md/CLAUDE.md — уже в контексте.
  • Эфемерные детали текущей задачи.

11. Отключить память

Полностью — выключить feature-флаг:

toml
[features]
memories = false

Либо точечно отключить генерацию/использование, не трогая флаг:

toml
[memories]
generate_memories = false
use_memories = false

CLI-флага --no-memories не существует. Отключение — только через конфиг или /memories.

12. Сброс памяти

bash
rm -rf ~/.astracode/memories

При следующем старте папка будет создана заново, пустая. История git тоже сотрётся.

13. Отладка

bash
# Где живут rollout'ы:
ls ~/.astracode/sessions/

# История консолидации:
cd ~/.astracode/memories
git log --oneline

# Текущий diff Phase 2:
cat ~/.astracode/memories/phase2_workspace_diff.md

# Логи извлечения:
grep memories ~/.astracode/log/astracode-tui.log

14. Файлы кода

  • Чтение: astracode-rs/memories/read/
  • Запись: astracode-rs/memories/write/
  • Phase 1 entry: memories/write/src/phase1.rs
  • Phase 2 entry: memories/write/src/phase2.rs
  • Команда /memories: astracode-rs/tui/src/chatwidget/slash_dispatch.rs (ветка Memories)