Цель лекции
Показать полный путь данных через memory layer: от входного события до повторного использования и забывания.
Ожидаемый результат
Читатель видит сквозной цикл памяти и понимает, где возникают ключевые инженерные решения: что наблюдать, что сохранять, как нормализовать, как искать, как вставлять в контекст, как обновлять и когда забывать.
Зачем это нужно
После Module 02 у нас есть словарь типов памяти: working, session, episodic, semantic, procedural, reflection, world и shared memory. Но одного словаря недостаточно для проектирования системы.
Нужно понять, как данные движутся через memory layer.
Память агента не появляется в момент, когда система записала строку в базу. До записи нужно решить, стоит ли вообще сохранять событие. После записи нужно сделать его доступным для поиска. Перед использованием нужно извлечь релевантные записи, отобрать их, вставить в context window и проверить, не устарели ли они. Потом память может быть уточнена, объединена, архивирована или удалена.
Поэтому memory layer лучше мыслить как lifecycle:
Observe -> Decide -> Extract -> Normalize -> Store -> Retrieve -> Inject -> Update -> Forget
Каждый этап влияет на качество агента. Ошибка на входе может привести к мусорной памяти. Ошибка retrieval может достать нерелевантный факт. Ошибка update может оставить старое предпочтение активным. Ошибка forgetting может нарушить privacy или разрастить контекст до шума.
Основная идея
Память - это pipeline с политиками, а не просто операция записи в базу.
В простом чат-боте "память" часто означает историю сообщений. В агентской системе память должна отвечать на вопросы:
- что считать наблюдением;
- что можно сохранять;
- что нельзя сохранять;
- как выделять факты, события, сущности и процедуры;
- как задавать scope, source, confidence и time fields;
- где хранить разные типы памяти;
- как индексировать их для retrieval;
- когда обращаться к памяти;
- как ранжировать найденное;
- что вставлять в context window;
- как обновлять устаревшее;
- когда архивировать или удалять.
Lifecycle помогает разложить эти решения по этапам. Вместо одного большого вопроса "как сделать память?" появляются конкретные инженерные вопросы: write policy, representation, storage, retrieval, context assembly, update policy, forgetting policy.
Ключевые термины
| Термин | Короткое определение |
|---|---|
Memory lifecycle |
Полный путь данных через память: наблюдение, запись, поиск, использование, обновление и забывание. |
Observe |
Получение входного события: сообщения, результата инструмента, файла, действия пользователя или состояния среды. |
Should remember |
Решение, стоит ли сохранять информацию и в какой слой памяти. |
Extract |
Выделение фактов, событий, сущностей, процедур или lessons learned из сырого входа. |
Normalize |
Приведение записи к устойчивому формату: поля, scope, timestamps, source, confidence. |
Deduplicate |
Устранение дублей и близких записей. |
Store |
Сохранение записи в подходящее хранилище. |
Index |
Подготовка записи к будущему поиску: embeddings, keyword index, graph links, temporal index. |
Retrieve |
Извлечение кандидатов памяти под текущую задачу. |
Rank |
Выбор самых полезных записей из retrieved candidates. |
Inject |
Вставка выбранной памяти в working memory или prompt. |
Update |
Уточнение, замена, подтверждение или изменение статуса записи. |
Forget |
Удаление, архивирование, истечение TTL или снижение веса старой памяти. |
Сквозная схема lifecycle
Схема показывает две половины lifecycle.
Первая половина - write path: от наблюдения до сохранения и индексации.
Вторая половина - read and maintenance path: от будущей задачи до retrieval, использования, обновления и забывания.
В реальной системе эти пути могут быть синхронными или асинхронными. Например, агент может сразу сохранить важный user preference, но extraction эпизодов и consolidation выполнить фоновым процессом.
Observe: что становится входом памяти
Observe - это все, что агент может заметить.
Источники наблюдений:
- сообщение пользователя;
- ответ модели;
- tool call;
- результат инструмента;
- ошибка команды;
- изменение файла;
- найденный документ;
- user feedback;
- событие в приложении;
- изменение CRM;
- статус тикета;
- результат тестов;
- handoff от другого агента.
Не каждое наблюдение является памятью. Наблюдение - это raw material.
Пример:
User:
"Для этого курса финальные ответы лучше делать короткими, а сами лекции подробными."
Это наблюдение содержит потенциальные записи:
- user preference: краткие финальные ответы;
- project preference: подробные лекции;
- scope: для этого курса;
- возможная procedural note: при writing tasks не сокращать основное содержание.
На этапе observe система еще не должна слепо писать все в long-term memory. Сначала нужен отбор.
Should remember: решение о сохранении
Should remember - один из самых важных этапов.
Сохранять все подряд опасно:
- память заполняется шумом;
- retrieval возвращает нерелевантные записи;
- растут privacy risks;
- устаревшие сведения остаются активными;
- модель получает конфликтующий контекст;
- стоимость хранения и поиска растет;
- пользователь теряет контроль.
Write policy должна решить:
- полезна ли информация за пределами текущего шага;
- какой у нее scope;
- есть ли разрешение на сохранение;
- не содержит ли она sensitive data;
- является ли она фактом, событием, процедурой или reflection;
- насколько она стабильна;
- насколько источник надежен;
- нужно ли сохранять синхронно или фоном.
Пример решения:
| Наблюдение | Решение |
|---|---|
| "Сегодня отвечай совсем кратко." | Session memory, не long-term. |
| "Всегда для этого проекта финальный отчет делай кратким." | Candidate for semantic/project preference. |
| "Команда тестов упала с ошибкой X." | Episodic memory, если событие важно для задачи. |
| "Похоже, причина в Y." | Не сохранять как факт без evidence; возможно reflection draft. |
| "API key: ..." | Не сохранять; secrets filtering. |
Extract: выделение смысла
Extract превращает raw observation в структурированные кандидаты памяти.
Из одного сообщения можно выделить разные типы записей:
Raw observation:
"В проекте теперь используем Vitest вместо Jest. Перед финалом запускай npm test,
если меняли код, но не запускай тесты для чистых Markdown-правок."
Возможные извлечения:
Semantic fact:
- Project uses Vitest instead of Jest.
Procedural rule:
- Run npm test before final response when code changed.
Exception:
- Do not run tests for Markdown-only edits.
Contradiction:
- Old memory "project uses Jest" may be stale.
Extraction не должна быть слишком агрессивной. Если агент извлекает слишком много фактов из случайных фраз, память быстро становится ошибочной. Лучше сохранять меньше, но с source, scope и confidence.
Normalize: приведение к устойчивому формату
Normalize отвечает за то, чтобы записи памяти были не просто текстовыми заметками, а управляемыми объектами.
Типичные поля:
id
type
summary
scope
source
confidence
created_at
last_confirmed_at
status
ttl
tags
related_entities
Для разных типов памяти поля отличаются. Эпизоду нужен timestamp и outcome. Факту нужен subject, predicate, object, confidence и staleness. Процедуре нужны applies_when, steps и constraints. Reflection нужна evidence и applicability.
Нормализация важна для будущих этапов:
- retrieval использует scope, tags и entities;
- update использует source и timestamps;
- conflict detection использует subject/relation;
- forgetting использует TTL и status;
- access control использует visibility и permissions.
Без metadata память становится кучей заметок, которую трудно поддерживать.
Deduplicate и merge
Memory layer часто получает похожие записи.
Примеры:
- User prefers concise final answers.
- User likes short final summaries.
- For this course, final responses should be brief.
Это могут быть дубли, уточнения или разные scopes.
Deduplicate должен ответить:
- это та же запись или новая;
- новый факт уточняет старый или противоречит ему;
- нужно повысить confidence старой записи;
- нужно разделить scopes;
- нужно создать новую версию.
Плохой deduplication удаляет важные различия. Хороший deduplication уменьшает шум, но сохраняет смысл.
Пример:
Existing memory:
- User prefers concise final answers. Scope: all tasks.
New observation:
- For lectures, make the lecture detailed but final report short.
Это не простой дубль. Новая запись уточняет scope: основной материал может быть подробным, финальный отчет - кратким.
Store: выбор хранилища
Store - это физическая или логическая запись памяти.
Разные типы памяти могут храниться по-разному:
- session state в key-value store;
- facts в SQL или document store;
- documents в object storage;
- chunks в vector database;
- entity relations в graph;
- policies в files или configuration service;
- episodic logs в append-only store;
- summaries в Markdown или JSON.
Выбор хранилища зависит от:
- структуры данных;
- объема;
- требований к поиску;
- требований к аудиту;
- permissions;
- latency;
- стоимости;
- требований к удалению.
Важно: storage - только один этап lifecycle. Даже идеальная база не решит плохой write policy или retrieval noise.
Index: подготовка к поиску
Запись памяти должна быть доступна для будущего retrieval.
Индексы могут быть разными:
- vector index для semantic similarity;
- keyword index для точных терминов;
- temporal index для поиска по времени;
- graph links для сущностей и отношений;
- metadata filters для scope, source, permissions;
- importance scores для приоритета;
- recency scores для свежести.
Пример: memory record о проекте может быть доступен по нескольким путям:
Text similarity:
- "Какие conventions у курса?"
Keyword:
- "content_plan.md"
Entity:
- Project: ai-agent-memory-guide
Relation:
- has_structure_source -> guide/content_plan.md
Scope:
- project/course-writing
Индексация определяет, сможет ли агент найти запись в нужный момент.
Retrieve: обращение к памяти
Retrieve происходит, когда агенту нужно вспомнить контекст для текущей задачи.
Read policy должна решить:
- нужно ли вообще обращаться к long-term memory;
- какие слои памяти искать;
- какие scopes разрешены;
- какие типы записей нужны;
- какой запрос сформировать;
- сколько кандидатов вернуть;
- какие permission filters применить.
Пример:
User:
"Напиши следующую лекцию."
Полезный retrieval:
- project facts о структуре курса;
- procedural workflow написания лекций;
- соседние lesson files;
- writing style preferences;
- content plan.
Неполезный retrieval:
- старые tool errors из другой задачи;
- личные preferences без отношения к writing;
- все эпизоды прошлого месяца;
- документы из другого проекта.
Retrieval - это не "найти похожее". Это "найти полезное для текущего шага".
Rank и filter
После retrieval обычно есть candidates. Их нужно отобрать.
Сигналы ранжирования:
- relevance to current task;
- scope match;
- source priority;
- confidence;
- recency;
- freshness;
- importance;
- permissions;
- conflict status;
- context cost;
- diversity.
Даже релевантная память может не попасть в prompt, если она занимает слишком много места или дублирует более важную запись.
Хороший ranking отвечает не только на вопрос "похоже ли?", но и на вопрос "стоит ли тратить на это context budget?"
Inject: вставка в working memory
Inject - это этап, где selected memories попадают в context window.
Инъекция может быть в разных формах:
- короткий список фактов;
- relevant snippets;
- system/developer style instructions;
- project context block;
- citations;
- tool result summary;
- warnings;
- current task state.
Плохая инъекция:
Вот 40 воспоминаний, возможно связанных с задачей...
Хорошая инъекция:
Relevant project memory:
- Course is written in Russian.
- guide/content_plan.md is source of truth for structure.
- Full lectures should include terms, diagram, examples, risks, summary and self-check questions.
Memory injection должна быть компактной, scoped и понятной модели.
Generate / act
После context assembly модель рассуждает, отвечает или вызывает инструменты.
Память влияет на:
- понимание запроса;
- выбор плана;
- выбор инструментов;
- стиль ответа;
- safety checks;
- приоритет источников;
- решение, что спросить у пользователя;
- решение, что не делать.
Но память не должна полностью заменять reasoning. Даже retrieved memory может быть устаревшей, конфликтующей или неприменимой. Агент должен уметь проверять ее против текущего контекста.
Update: память меняется
После действия появляются новые наблюдения:
- пользователь подтвердил или исправил ответ;
- тесты прошли или упали;
- документ оказался устаревшим;
- old fact получил противоречие;
- workflow сработал или нет;
- новая версия источника заменила старую.
Update может:
- подтвердить existing memory;
- повысить или снизить confidence;
- создать новую версию;
- пометить запись как stale;
- заменить active fact;
- добавить relation;
- создать reflection;
- обновить summary;
- инициировать deletion.
Память без update быстро становится источником ошибок.
Forget: забывание как часть дизайна
Forget - это не только физическое удаление.
Формы забывания:
- TTL истек, запись перестала быть активной;
- старый факт помечен superseded;
- эпизод ушел в archive;
- importance decay снизил шанс retrieval;
- sensitive data удалены;
- пользователь запросил deletion;
- summary заменил длинный лог;
- duplicate merge убрал лишние копии.
Забывание нужно не потому, что storage дорогой. Оно нужно, чтобы активная память оставалась полезной, безопасной и актуальной.
Сквозной пример
Рассмотрим один путь памяти.
1. Observation
User:
"Для этого курса финальный отчет после правок делай коротким,
но саму лекцию пиши подробно."
2. Should remember
Это не временная фраза. Она относится к будущим writing tasks в проекте. Можно сохранить как project/user preference.
3. Extract
Preference 1:
- Final reports after edits should be concise.
Preference 2:
- Lecture content should remain detailed.
Scope:
- AI Agent Memory Guide course-writing tasks.
4. Normalize
type: semantic_preference
scope:
project: ai-agent-memory-guide
task_type: lecture_writing
source:
kind: user_instruction
confidence: high
status: active
5. Store and index
Запись сохраняется в project/user memory и индексируется по:
- "final report";
- "lecture writing";
- project scope;
- user preference.
6. Retrieve
Через неделю пользователь просит:
"Напиши лекцию 3.2."
Retrieval находит preference.
7. Inject
В context assembly попадает краткий блок:
Relevant preference:
- For this course, write lecture content in detail but keep final edit reports concise.
8. Act
Агент пишет подробную лекцию, а в финальном ответе дает короткое summary.
9. Update
Если пользователь говорит "да, так хорошо", memory может получить last_confirmed_at.
10. Forget или adjust
Если позже пользователь скажет "для следующих лекций делай финалы подробнее", старая запись не должна оставаться активной без уточнения. Ее нужно обновить, version или supersede.
Где чаще всего ломается lifecycle
| Этап | Типичная поломка | Последствие |
|---|---|---|
| Observe | Система не видит важный tool result | Память не знает outcome. |
| Should remember | Сохраняется все подряд | Retrieval noise и privacy risk. |
| Extract | Фраза превращается в слишком общий факт | Агент применяет ее вне scope. |
| Normalize | Нет source или timestamps | Невозможно проверить и обновить. |
| Deduplicate | Дубли не объединяются | Контекст получает повторяющиеся факты. |
| Store | Не тот storage для типа данных | Поиск или update становятся сложными. |
| Index | Нет keyword/entity/time индекса | Запись трудно найти. |
| Retrieve | Ищется только semantic similarity | Находится похожее, но бесполезное. |
| Rank | Не учитывается confidence | Слабые записи вытесняют надежные. |
| Inject | Вставляется слишком много | Context window шумит. |
| Update | Конфликты игнорируются | Старые и новые факты активны одновременно. |
| Forget | Нет TTL или deletion | Память устаревает и нарушает privacy. |
Типичные ошибки
Ошибка 1: считать память только storage.
Хранилище важно, но lifecycle включает политики записи, extraction, indexing, retrieval, update и forgetting.
Ошибка 2: писать раньше, чем решена политика сохранения.
Если система сохраняет raw data без фильтров, потом трудно исправить privacy и noise проблемы.
Ошибка 3: не различать write path и read path.
Хорошая запись бесполезна, если ее нельзя найти. Хороший retrieval опасен, если он достает старые или запрещенные записи.
Ошибка 4: не хранить metadata.
Память без source, scope, confidence и timestamps почти невозможно надежно обновлять.
Ошибка 5: забывать про context budget.
Memory retrieval заканчивается не в базе, а в prompt. Context window ограничен.
Ошибка 6: не проектировать update.
Факты, предпочтения и policies меняются. Если update не предусмотрен, память деградирует.
Ошибка 7: не проектировать forgetting.
Память без забывания становится архивом всего, а не инструментом действия.
Краткое резюме
Memory lifecycle описывает полный путь данных через memory layer: observe, should remember, extract, normalize, deduplicate, store, index, retrieve, rank, inject, act, update и forget.
Главная идея: память агента - это не база данных, а управляемый pipeline. На каждом этапе есть политики, trade-offs и failure modes.
В следующих лекциях мы разберем lifecycle глубже: сначала запись памяти, затем retrieval, затем update, consolidation и forgetting.
Вопросы для самопроверки
- Почему memory layer нельзя свести к операции
store? - Что происходит на этапе
Should remember? - Зачем memory record нужны
scope,source,confidenceи timestamps? - Почему retrieval должен заканчиваться ranking и context budgeting?
- Какие формы forgetting существуют кроме физического удаления?
Что дальше
В следующей лекции мы подробно разберем Memory Write: как решить, что сохранять, как выделять atomic facts и events, как учитывать importance, confidence, consent, PII и синхронную или асинхронную запись.