Skip to Content
ДизайнAuto MemoryПамять — система управления памятью

Память — система управления памятью

В этом разделе описывается механизм управления памятью Managed Auto-Memory (управляемая автоматическая память) в Qwen Code, условия его срабатывания и детали реализации.


Содержание

  1. Обзор
  2. Структура хранения
  3. Типы памяти
  4. Формат записей памяти
  5. Основной жизненный цикл
  6. Extract — Извлечение
  7. Dream — Интеграция
  8. Recall — Припоминание
  9. Forget — Забывание
  10. Перестроение индекса
  11. Телеметрические точки

Обзор

Managed Auto-Memory — это постоянная система памяти, которая автоматически накапливает, интегрирует и извлекает знания, связанные с пользователем, в ходе сеансов ИИ. Она поддерживает жизненный цикл памяти с помощью четырёх основных операций:

ОперацияАнглийскийТриггерНазначение
ИзвлечениеExtractАвтоматически (после каждого раунда диалога)Выделение новых знаний из записей диалога и запись в файлы памяти
ИнтеграцияDreamАвтоматически (периодическая фоновая задача)Дедупликация, слияние файлов памяти для поддержания чистоты
ПрипоминаниеRecallАвтоматически (перед каждым раундом диалога)Поиск релевантных записей памяти и внедрение в системный промпт
ЗабываниеForgetВручную (команда пользователя /forget)Точное удаление указанных записей памяти

Структура хранения

Расположение директорий

~/.qwen/ ← Глобальная базовая директория (по умолчанию) └── projects/ └── <sanitized-git-root>/ ← Идентификатор проекта (на основе корня Git) ├── meta.json ← Метаданные (временные метки извлечения/интеграции, статус) ├── extract-cursor.json ← Курсор извлечения (обработанное смещение диалога) ├── consolidation.lock ← Мьютекс для процесса Dream └── memory/ ← Основная директория памяти ├── MEMORY.md ← Индексный файл (автоматически генерируется, собирает все записи) ├── user.md ← Память о предпочтениях пользователя (пример) ├── feedback.md ← Память о правилах обратной связи (пример) ├── project/ │ └── milestone.md ← Память о проекте (поддерживает поддиректории) └── reference/ └── grafana.md ← Память о внешних ресурсах

Переопределение через переменные окружения:

  • QWEN_CODE_MEMORY_BASE_DIR — заменяет глобальную базовую директорию
  • QWEN_CODE_MEMORY_LOCAL=1 — использует путь внутри проекта .qwen/memory/

Описание ключевых файлов

ФайлОписание
meta.jsonЗаписывает время последнего Extract / Dream, ID сессии, затронутые типы памяти, статус выполнения
extract-cursor.jsonЗаписывает, на каком смещении в истории диалога остановилась обработка текущей сессии, чтобы избежать повторного извлечения
consolidation.lockФайловая блокировка во время работы Dream, содержит PID владельца; автоматически теряет силу через 1 час
MEMORY.mdИндекс всех тематических файлов, перестраивается после каждого Extract/Dream, формат — список Markdown

Типы памяти

Система поддерживает четыре встроенных типа памяти, каждый из которых соответствует определённому измерению информации:

ТипСодержимоеКогда записываетсяКогда считывается
userРоль пользователя, навыки, рабочие привычкиКогда узнаётся роль/предпочтения/фон знаний пользователяКогда ответ требует настройки под конкретного пользователя
feedbackУказания пользователя по поведению ИИ: чего избегать, что продолжатьКогда пользователь исправляет ИИ или подтверждает неочевидные действияКогда это влияет на поведение ИИ
projectХод проекта, цели, решения, сроки, отслеживание ошибокКогда узнаётся, кто что делает, почему и к какому срокуКогда помогает ИИ понять рабочий контекст и мотивацию
referenceУказатели на внешние системные ресурсы (дашборды, тикет-системы, каналы Slack и т.п.)Когда становится известно о внешнем ресурсе и его назначенииКогда пользователь упоминает внешнюю систему или связанную информацию

Что не должно сохраняться в памяти: шаблоны/соглашения кода, история Git, варианты отладки, временные статусы задач, содержимое, уже задокументированное в QWEN.md/AGENTS.md.


Формат записей памяти

Каждый тематический файл использует формат YAML frontmatter + Markdown body:

--- name: Имя памяти description: Краткое описание (для оценки релевантности при припоминании; должно быть конкретным) type: user|feedback|project|reference --- Основное содержимое памяти (строка summary) Why: Причина (чтобы ИИ понимал граничные случаи, а не слепо следовал правилам) How to apply: Сценарии применения и способ использования

Для типов feedback и project настоятельно рекомендуется заполнять поля Why и How to apply, чтобы память правильно применялась даже в граничных ситуациях.


Основной жизненный цикл


Extract — Извлечение

Условие срабатывания

После каждого раунда завершения ответа ИИ автоматически запускается функция scheduleAutoMemoryExtract (фоновая, неблокирующая).

Логика планировщика (extractScheduler.ts)

Пояснения причин пропуска:

ПричинаЗначение
memory_toolГлавный агент в этом раунде уже напрямую записал файл памяти; пропуск для избежания конфликта
already_runningИзвлечение уже выполняется и постановка в очередь невозможна
queuedИзвлечение уже выполняется, текущий запрос поставлен в очередь

Основной процесс извлечения (extract.ts)

Примечание: Проверка isUnderMemoryPressure находится в MemoryManager.runExtract(), а не в этом потоке. Когда монитор сообщает о давлении hard/critical, MemoryManager пропускает вызов extract и не продвигает cursor.

Курсор извлечения (Cursor):

  • Поля: { sessionId, processedOffset, updatedAt }
  • Перед извлечением вызывается readExtractCursor для чтения текущего прогресса, затем history.slice(processedOffset) обрабатывает только непрочитанную часть.
  • После каждого извлечения processedOffset обновляется до текущей длины истории (params.history.length).
  • При смене сессии (sessionId меняется) offset сбрасывается на 0.
  • Обратите внимание: больше не используются buildTranscriptMessages / loadUnprocessedTranscriptSlice для построения транскрипта — hasNewUserMessages проверяется через history.slice(startOffset).some(m => m.role === 'user' && partToString(m.parts).trim().length > 0), только лёгкое строковое преобразование на необработанном срезе; полная история больше не обрабатывается.

Правила фильтрации патчей:

  • Длина summary < 12 символов → отбрасывается
  • Summary заканчивается на ? → отбрасывается (вопросительное предложение)
  • Содержит временные ключевые слова (today/now/currently/temporary и т.п.) → отбрасывается
  • Комбинация topic:summary уже существует → дедупликация

Dream — Интеграция

Условие срабатывания

После каждого раунда завершения ответа ИИ автоматически запускается функция scheduleManagedAutoMemoryDream (фоновая, неблокирующая). Однако она защищена несколькими шлюзовыми условиями, поэтому в большинстве случаев будет пропущена.

Шлюзовые проверки планировщика (dreamScheduler.ts)

Параметры шлюзов:

ПараметрЗначение по умолчаниюОписание
minHoursBetweenDreams24 часаМинимальный интервал между двумя Dream
minSessionsBetweenDreams5 сессийМинимальное количество новых сессий для срабатывания Dream
SESSION_SCAN_INTERVAL_MS10 минутИнтервал троттлинга сканирования файлов сессий
DREAM_LOCK_STALE_MS1 часПорог, после которого файл блокировки считается истёкшим

Механизм блокировки:

  • Файл блокировки находится в <project-state-dir>/consolidation.lock
  • Содержимое — PID процесса-владельца
  • При проверке: если процесс с PID больше не существует (сбой kill(pid, 0)) или блокировке больше 1 часа → считается истёкшей, автоматически очищается

Процесс выполнения интеграции (dream.ts)

Логика механической дедупликации:

  1. Внутри каждого тематического файла: дедупликация по summary.toLowerCase(), объединение полей why/howToApply
  2. Пересортировка по алфавиту summary
  3. Между файлами: записи с одинаковым type:summary объединяются в первый обнаруженный файл, дублирующий файл удаляется

Recall — Припоминание

Условие срабатывания

Перед каждым раундом обработки пользовательского запроса ИИ автоматически вызывается функция resolveRelevantAutoMemoryPromptForQuery, которая внедряет релевантные воспоминания в системный промпт.

Процесс припоминания (recall.ts)

Правила оценки (эвристика):

УсловиеБонус
Токен query присутствует в содержимом документа+2 (за каждый токен)
Токен query является характерным ключевым словом типа+1 (за каждый токен)
Body документа непустое+1

Ключевые слова для каждого типа:

  • user: user, preference, background, role, terse
  • feedback: feedback, rule, avoid, style, summary
  • project: project, goal, incident, deadline, release
  • reference: reference, dashboard, ticket, docs, link

Правила построения промпта:

  • Не более 5 документов (MAX_RELEVANT_DOCS)
  • Body каждого документа обрезается до 1200 символов (MAX_DOC_BODY_CHARS)
  • При обрезке добавляется подсказка: “NOTE: Relevant memory truncated for prompt budget.”
  • Включается информация о свежести документа (на основе mtime файла)

Forget — Забывание

Условие срабатывания

Запускается вручную командой пользователя /forget <query>.

Процесс забывания (forget.ts)

Дизайн Entry ID:

  • Одноэлементный файл (распространённый случай): relativePath (например, feedback/no-summary.md)
  • Многоэлементный файл: relativePath:index (например, feedback/style.md:2)
  • Стабильный ID позволяет модели точно указать запись, не затрагивая другие записи в том же файле.

Перестроение индекса

MEMORY.md — навигационный индекс по всем тематическим файлам. Перестраивается вызовом rebuildManagedAutoMemoryIndex после каждого Extract или Dream:

- [Предпочтения пользователя](user/preferences.md) — пользователь — опытный Go-инженер, впервые сталкивается с React - [Правила обратной связи](feedback/style.md) — отвечать кратко, без итоговых резюме - [Веха проекта](project/milestone.md) — окно замёрзших изменений перед слиянием ветки перед релизом мобильного приложения

Ограничения индекса:

  • Не более 150 символов на строку (если превышает — обрезается с )
  • Не более 200 строк
  • Общий размер не более 25 000 байт

Телеметрические точки

Система включает три типа телеметрических событий для мониторинга производительности и эффективности операций памяти.

Телеметрия Extract

ПолеТипОписание
trigger'auto'Способ запуска (сейчас только автоматический)
status'completed' | 'failed'Результат выполнения
patches_countnumberКоличество извлечённых валидных патчей
touched_topicsstring[]Список затронутых типов памяти
duration_msnumberОбщее время выполнения (мс)

Телеметрия Dream

ПолеТипОписание
trigger'auto'Способ запуска
status'updated' | 'noop' | 'failed'Результат выполнения
deduped_entriesnumberКоличество записей, дедуплицированных механическим путём
touched_topicsstring[]Список изменённых типов памяти
duration_msnumberОбщее время выполнения (мс)

Телеметрия Recall

ПолеТипОписание
query_lengthnumberДлина строки запроса
docs_scannednumberОбщее количество просканированных документов
docs_selectednumberКоличество внедрённых документов
strategy'none' | 'heuristic' | 'model'Стратегия выбора
duration_msnumberОбщее время выполнения (мс)

Указатель связанных исходных файлов

ФайлОбязанности
packages/core/src/memory/types.tsОпределения типов: AutoMemoryType, AutoMemoryMetadata, AutoMemoryExtractCursor
packages/core/src/memory/paths.tsВычисление путей: getAutoMemoryRoot, isAutoMemPath, различные helpers для путей файлов
packages/core/src/memory/store.tsИнициализация каркаса: ensureAutoMemoryScaffold, чтение/запись индекса и метаданных
packages/core/src/memory/scan.tsСканирование тематических файлов: scanAutoMemoryTopicDocuments, парсинг frontmatter
packages/core/src/memory/entries.tsПарсинг и рендеринг записей: parseAutoMemoryEntries, renderAutoMemoryBody
packages/core/src/memory/extract.tsОсновная логика извлечения: runAutoMemoryExtract, управление курсором, дедупликация патчей
packages/core/src/memory/extractScheduler.tsПланировщик извлечения: ManagedAutoMemoryExtractRuntime, очередь/состояние выполнения
packages/core/src/memory/extractionAgentPlanner.tsАгент извлечения: runAutoMemoryExtractionByAgent
packages/core/src/memory/dream.tsОсновная логика интеграции: runManagedAutoMemoryDream, путь агента + механическая дедупликация
packages/core/src/memory/dreamScheduler.tsПланировщик интеграции: ManagedAutoMemoryDreamRuntime, шлюзовые проверки, управление блокировками
packages/core/src/memory/dreamAgentPlanner.tsАгент интеграции: planManagedAutoMemoryDreamByAgent
packages/core/src/memory/recall.tsЛогика припоминания: resolveRelevantAutoMemoryPromptForQuery, двойной путь эвристика+модель
packages/core/src/memory/forget.tsЛогика забывания: forgetManagedAutoMemoryEntries, генерация кандидатов + точное удаление
packages/core/src/memory/indexer.tsПерестроение индекса: rebuildManagedAutoMemoryIndex, buildManagedAutoMemoryIndex
packages/core/src/memory/prompt.tsШаблоны системного промпта: описание типов памяти, примеры форматов, правила использования
packages/core/src/memory/governance.tsТипы предложений по управлению: AutoMemoryGovernanceSuggestionType
packages/core/src/memory/state.tsСостояние выполнения Extract: isExtractRunning, markExtractRunning, clearExtractRunning
packages/core/src/memory/memoryAge.tsОписание свежести: memoryAge, memoryFreshnessText
Last updated on