Цель лекции
Объяснить политику записи памяти и показать, почему сохранять все подряд опасно.
Ожидаемый результат
Читатель понимает, как проектировать входной фильтр для долгосрочной памяти: какие данные сохранять, какие оставлять в session, какие отбрасывать, как выделять atomic facts, events и entities, как учитывать importance, confidence, consent, PII и режим записи.
Зачем это нужно
В предыдущей лекции мы увидели общий lifecycle памяти. Теперь увеличим масштаб одного этапа: Memory Write.
Запись кажется простой:
new information -> save to memory
Но именно здесь часто возникают самые дорогие ошибки. Если система сохраняет все сообщения, tool logs, гипотезы и промежуточные выводы, она быстро получает шумную память. Retrieval начинает доставать случайные фразы. Устаревшие сведения конфликтуют с новыми. Личные данные сохраняются без необходимости. Модель получает контекст, который мешает, а не помогает.
Хорошая память начинается не с базы данных, а с отбора.
Memory write отвечает на вопросы:
- стоит ли это сохранять;
- в какой слой памяти;
- на какой срок;
- с каким scope;
- с каким source и confidence;
- нужно ли согласие пользователя;
- есть ли sensitive data;
- нужно ли писать сразу или можно фоном;
- что делать, если новая запись конфликтует со старой.
Основная идея
Memory write policy - это набор правил, которые определяют, какие наблюдения становятся памятью.
Главный принцип: сохранять нужно не все, а только то, что с высокой вероятностью поможет будущему поведению агента и безопасно для хранения.
Хорошая запись памяти должна быть:
- полезной для будущих задач;
- scoped;
- проверяемой;
- достаточно стабильной;
- разрешенной к сохранению;
- очищенной от лишних чувствительных данных;
- представленной маленькими единицами смысла;
- связанной с source и confidence;
- пригодной для update и deletion.
Слабая запись памяти звучит как случайная цитата из диалога. Сильная запись выглядит как управляемый memory record.
Ключевые термины
| Термин | Короткое определение |
|---|---|
Memory write |
Процесс превращения наблюдения в запись памяти. |
Write policy |
Правила, которые определяют, что сохранять, куда, когда и с какими ограничениями. |
Atomic fact |
Маленькое самостоятельное утверждение, которое можно проверить, обновить или заменить. |
Event extraction |
Выделение события: что произошло, когда, при каких условиях и с каким результатом. |
Entity extraction |
Выделение сущностей: пользователь, проект, файл, сервис, организация, документ. |
Importance scoring |
Оценка важности записи для будущих задач. |
Confidence scoring |
Оценка надежности записи и источника. |
Consent |
Разрешение пользователя или политики на сохранение данных. |
PII filtering |
Фильтрация персональных данных. |
Secrets filtering |
Защита tokens, passwords, keys и credentials от сохранения. |
Add-only |
Подход, где новые записи добавляются или версионируются, а не молча перезаписывают старые. |
Synchronous write |
Запись во время текущего взаимодействия. |
Asynchronous write |
Фоновая запись, consolidation или indexing после ответа. |
Схема write pipeline
Важный порядок: privacy и secrets filtering должны происходить до долговременного сохранения. Нельзя сначала записать все, а потом надеяться очистить память позже.
Что стоит сохранять
Сохранять стоит информацию, которая:
- может повлиять на будущие действия агента;
- относится к устойчивому предпочтению пользователя;
- описывает project convention;
- фиксирует важное событие или outcome;
- помогает объяснить прошлое решение;
- задает policy или workflow;
- уточняет entity или relation;
- отражает user feedback;
- нужна для continuity между сессиями;
- имеет понятный scope и source.
Примеры хороших кандидатов:
- User prefers concise final reports for this course.
- guide/content_plan.md is the source of truth for course structure.
- In task X, test Y failed after changing shared helper Z.
- For Markdown-only edits in this repo, there is no build step.
- Customer account A has feature export disabled according to CRM record B.
Эти записи разные по типу, но у них есть общее: они могут изменить будущую работу агента.
Что не стоит сохранять
Не стоит сохранять информацию, если она:
- важна только для текущей фразы;
- является временным настроением;
- основана на непроверенной догадке;
- содержит secret;
- содержит sensitive data без необходимости;
- не имеет scope;
- дублирует уже существующую запись;
- быстро устареет и не будет проверяться;
- является chain-of-thought;
- представляет raw logs без фильтра;
- может причинить вред при future retrieval.
Примеры плохих кандидатов:
- Пользователь сказал "ок".
- Агент подумал, что проблема, возможно, в API.
- Сегодня пользователь торопится.
- Полный terminal log с token.
- Весь текст личного письма без явной необходимости.
- "Нужно быть внимательнее."
Эти данные могут быть полезны в текущей session или audit log, но не обязательно должны попадать в активную долгосрочную память.
Atomic facts
Atomic fact - маленькая единица смысла, которую можно проверить и обновить отдельно.
Плохая запись:
User likes short answers, the course is in Russian, module 02 is about memory taxonomy,
and TODO should not be updated unless requested.
Лучше:
Fact 1:
- User prefers concise final answers.
Fact 2:
- AI Agent Memory Guide is written primarily in Russian.
Fact 3:
- Module 02 covers taxonomy of agent memory.
Fact 4:
- Do not update TODO files unless the user requests tracking changes.
Почему atomic facts лучше:
- их проще искать;
- проще обновлять;
- проще задавать scope;
- проще обнаруживать конфликт;
- проще удалять отдельную запись;
- проще объяснять source;
- меньше риск, что один неверный фрагмент испортит весь блок.
Но не нужно доводить atomization до абсурда. Если разделить знание слишком мелко, потеряются связи. Хорошая запись маленькая, но не бессмысленная.
Event extraction
Event extraction выделяет из наблюдений конкретные события.
Хорошая event record отвечает:
- что произошло;
- когда;
- кто или что участвовало;
- в каком scope;
- какое действие было выполнено;
- какой outcome;
- какие artifacts связаны;
- насколько событие важно.
Пример:
Raw observation:
The command npm test failed after editing src/pricing/discount_helper.ts.
The failing test is invoice_totals.test.ts.
Event memory:
type: event
summary: invoice_totals.test.ts failed after discount_helper.ts edit.
timestamp: 2026-08-07T16:10:00+03:00
actor: coding-agent
action: edited src/pricing/discount_helper.ts
outcome: test failure
related_files:
- src/pricing/discount_helper.ts
- tests/invoice_totals.test.ts
importance: medium
source: tool_result
Event extraction особенно важна для debugging, auditability, replay и reflection.
Entity extraction
Entity extraction выделяет объекты, о которых память должна знать.
Типичные entities:
- user;
- project;
- repository;
- file;
- service;
- document;
- team;
- customer;
- account;
- ticket;
- feature;
- API endpoint;
- dataset.
Пример:
Raw:
"В billing-service discount_helper.ts влияет на invoice totals."
Entities:
Service: billing-service
File: src/pricing/discount_helper.ts
Concept: invoice totals
Relation:
discount_helper.ts -> affects -> invoice totals
Entity extraction помогает retrieval. Если в будущем агент работает с invoice totals, он может найти не только точную фразу, но и связанные файлы, tests, decisions и incidents.
Importance scoring
Не вся память одинаково важна.
Importance scoring помогает решить:
- сохранять ли запись вообще;
- в какой слой ее положить;
- как часто извлекать;
- стоит ли выполнять synchronous write;
- нужна ли consolidation;
- когда применить decay или archive.
Сигналы importance:
- пользователь явно сказал "запомни";
- запись влияет на будущие задачи;
- запись связана с ошибкой или incident;
- запись касается policy или safety;
- запись часто используется;
- запись подтверждена несколькими источниками;
- запись относится к active project;
- запись имеет high business impact;
- запись нужна для continuity.
Пример шкалы:
| Importance | Пример | Действие |
|---|---|---|
| Low | "Пользователь сказал спасибо." | Не сохранять или session only. |
| Medium | "Тест упал в текущей задаче." | Episodic memory, возможно TTL. |
| High | "Пользователь изменил постоянное предпочтение." | Long-term semantic memory. |
| Critical | "Новая security policy запрещает действие." | Policy/procedural memory с высоким приоритетом. |
Importance не равно confidence. Запись может быть важной, но ненадежной. Тогда ее нужно сохранить как hypothesis или запросить подтверждение.
Confidence scoring
Confidence отвечает на вопрос: насколько можно доверять записи.
Источники confidence:
- явная инструкция пользователя;
- canonical project file;
- официальный источник;
- tool result;
- repeated pattern;
- single episode;
- model inference;
- third-party document;
- outdated source.
Пример:
| Источник | Типичный confidence | Комментарий |
|---|---|---|
| Прямая инструкция пользователя | High | Если scope понятен. |
| Canonical file проекта | High | Пока файл актуален. |
| Tool result | High для observed outcome | Но интерпретация результата может быть medium. |
| Один эпизод | Low или medium | Может быть случайностью. |
| Повторяющиеся эпизоды | Medium или high | Если pattern стабилен. |
| Вывод модели | Low | Не сохранять как факт без проверки. |
Confidence должен влиять на retrieval и action. Агент может использовать high-confidence fact прямо, а low-confidence hypothesis должен проверить.
Consent и user control
Не все полезное можно сохранять.
Memory write должен учитывать:
- явное согласие пользователя;
- настройки продукта;
- организационные policies;
- privacy requirements;
- legal constraints;
- право на просмотр и удаление памяти;
- чувствительность данных;
- ожидания пользователя.
Примеры:
"Запомни, что я предпочитаю краткие ответы."
Это явное разрешение сохранить preference.
"Сегодня у меня встреча с врачом, напомни мне позже."
Это может быть sensitive context. Система должна понимать scope, purpose и retention. Не нужно превращать это в общий long-term profile без необходимости.
User control должен включать возможность:
- посмотреть, что сохранено;
- исправить запись;
- удалить запись;
- отключить memory;
- ограничить scope;
- задать retention.
PII и secrets filtering
PII и secrets должны фильтроваться до записи.
PII может включать:
- email;
- phone;
- address;
- government ID;
- payment data;
- medical data;
- employment data;
- customer identifiers;
- private account notes.
Secrets:
- API keys;
- tokens;
- passwords;
- private keys;
- session cookies;
- credentials;
- internal access links.
Правила:
- secrets не должны сохраняться в memory layer;
- sensitive data сохраняется только при необходимости, с scope и retention;
- raw logs нужно очищать;
- retrieved sensitive memory нельзя вставлять в context без permission;
- deletion должен быть технически возможен.
Плохой подход:
Save entire terminal output to memory.
Лучше:
Save sanitized event:
- Command failed because environment variable OPENAI_API_KEY was missing.
Do not store the key value.
Add-only подход
В memory systems часто полезен add-only или append-oriented подход.
Идея: новая информация не молча перезаписывает старую. Вместо этого система:
- добавляет новую запись;
- помечает старую как superseded;
- создает новую версию;
- хранит provenance;
- запускает contradiction detection;
- обновляет active view.
Пример:
Old memory:
- Project uses Jest. Status: active.
New observation:
- package.json uses Vitest.
Update:
- Old memory: status = superseded.
- New memory: Project uses Vitest. Source: package.json. Status: active.
Add-only полезен для аудита и conflict resolution. Но active retrieval не должен доставать все версии сразу. Нужен слой, который выбирает актуальную active запись.
Синхронная и асинхронная запись
Не все записи должны происходить в один момент.
Synchronous write полезна, когда:
- пользователь явно сказал "запомни";
- запись нужна в текущей задаче;
- событие критично;
- policy или permission требует немедленного учета;
- нужно сохранить state перед handoff.
Asynchronous write подходит, когда:
- нужно обработать длинный лог;
- нужно сделать consolidation;
- нужно построить embeddings;
- нужно deduplicate много похожих записей;
- нужно извлечь entities из большого документа;
- reflection можно выполнить после ответа.
Сравнение:
| Режим | Плюсы | Минусы |
|---|---|---|
| Synchronous | Сразу доступно, лучше continuity | Увеличивает latency, риск поспешной записи. |
| Asynchronous | Можно обработать качественнее, дешевле для ответа | Память не сразу доступна, нужен retry и monitoring. |
Хорошая система часто использует оба режима: критичное пишет сразу, тяжелую обработку делает фоном.
Decision tree: should remember?
Decision tree не обязан быть буквально реализован как код. Это mental model для write policy.
Мини-кейс: writing agent
Пользователь говорит:
"Напиши лекцию 3.2. И вообще для этого курса держи стиль:
русский язык, структурно, с таблицами, схемами и вопросами в конце."
Что можно извлечь:
Project preference:
- Course lectures should be written in Russian.
Procedural writing rule:
- Full lectures should include structure, tables or diagrams, examples, summary and self-check questions.
Scope:
- AI Agent Memory Guide course.
Source:
- User instruction.
Confidence:
- High.
Что не нужно сохранять:
- Сам факт, что пользователь сейчас открыл IDE.
- Все промежуточные рассуждения агента.
- Полный текст текущей лекции как user preference.
Запись должна быть маленькой, scoped и пригодной для future retrieval.
Мини-кейс: coding agent
Наблюдение:
Tool result:
pytest tests/test_auth.py failed:
AssertionError: expected 401, got 403
Возможные записи:
Event:
- test_auth.py failed after auth change. Outcome: expected 401, got 403.
Entity:
- File: tests/test_auth.py
- Domain: auth
Reflection candidate:
- Auth error-code behavior may have changed or test expectation may be stale.
Что не стоит сохранять как факт:
- "Auth should return 403."
Почему? Потому что это пока не подтвержденный доменный факт. Это наблюдение о failed test. Агент должен проверить код, docs или user intent, прежде чем обновлять semantic memory.
Типичные ошибки
Ошибка 1: сохранять весь диалог.
История полезна для session continuity, но long-term memory должна быть отфильтрована и структурирована.
Ошибка 2: превращать временную просьбу в постоянное предпочтение.
"Сегодня отвечай кратко" не равно "всегда отвечай кратко".
Ошибка 3: сохранять inference как факт.
Если модель предположила причину, это не значит, что причина доказана.
Ошибка 4: не фильтровать secrets.
Секреты не должны попадать в memory store даже временно, если этого можно избежать.
Ошибка 5: сохранять большие смешанные блоки.
Большой блок трудно обновлять, удалять и искать. Лучше atomic facts и structured events.
Ошибка 6: не задавать scope.
Правило одного проекта может быть вредным в другом.
Ошибка 7: не различать importance и confidence.
Важная запись может быть ненадежной. Надежная запись может быть неважной.
Ошибка 8: делать все записи синхронными.
Это увеличивает latency и подталкивает к поспешному extraction. Часть работы лучше делать асинхронно.
Краткое резюме
Memory Write - это входной фильтр memory layer. Его задача не сохранить все, а выбрать стабильные, полезные, разрешенные и безопасные данные.
Хорошая write policy учитывает atomic facts, events, entities, importance, confidence, consent, PII, secrets, deduplication, conflicts, scope и режим записи.
Если write path плохой, downstream retrieval уже не спасет систему: агент будет вспоминать шум, устаревшие догадки и лишние чувствительные данные.
Вопросы для самопроверки
- Почему сохранять все подряд опасно?
- Что такое
atomic fact, и почему он полезен для update? - Чем importance отличается от confidence?
- Какие данные нужно фильтровать до записи?
- Когда memory write лучше делать асинхронно?
Что дальше
В следующей лекции мы разберем Memory Retrieval: как агент вспоминает нужные записи, почему semantic similarity недостаточно и как combine vector, keyword, graph, temporal search, reranking и context budget.