Память AI-агента: sessions, long-term state и retrieval
Что такое память AI-агента?
Память AI-агента — управляемое приложением состояние между steps, turns или sessions, которое помогает продолжить работу и найти релевантные факты. Оно включает thread history, workflow checkpoints, durable user/project facts и извлечённый прошлый опыт с разными scope и lifecycle.
TL;DR
- -Conversation history, workflow checkpoints, long-term facts и document retrieval решают разные задачи; единый vector index делает их неоднозначными
- -Memory нужны scope, provenance, timestamps, sensitivity и lifecycle, а не только текст и embedding
- -Записывайте explicit user statements и verified outcomes; model-extracted facts остаются candidates, пока их не примет policy
- -Сначала фильтруйте retrieval по identity и task relevance, затем применяйте semantic similarity и укладывайте результат в фиксированный context budget
- -Измеряйте write precision, useful recall, contradiction rate, cross-user leakage, staleness и deletion completion на фиксированных scenarios
«Добавить агенту память» звучит как одна feature. В production это минимум четыре разные системы данных:
current run state
conversation or workflow checkpoint
long-term facts and preferences
retrieval over documents and prior experiences
Если смешать их, агент начнёт считать старый chat summary текущим account state, приватную preference — organization policy, а неудачную попытку — проверенной процедурой.
Memory — не увеличенный prompt и не vector database со всеми разговорами подряд. Это управляемый путь event → candidate → stored record → retrieval → context → correction or deletion.
Здесь разобран именно этот путь. Общий гайд по context engineering показывает, как memory конкурирует с instructions, tools и retrieved documents внутри context window. Для нескольких cooperating agents пригодится гайд по multi-agent architecture.
Разделите четыре задачи состояния
| Слой | Scope | Пример | Storage shape |
|---|---|---|---|
| Working state | Один run или step | Текущий plan, intermediate IDs, retry count | Typed in-memory state |
| Thread state | Один conversation или workflow | Messages, approvals, checkpoint, pending tool call | Ordered log и checkpoints |
| Long-term memory | User, project, agent или organization | Preference, verified fact, reusable experience | Structured records с lifecycle |
| Knowledge retrieval | Corpus и access domain | Product docs, tickets, repository files | Source documents плюс index |
Границы важнее названий. OpenAI Agents SDK, например, использует Session для
conversation history одной session. Актуальный
гайд по state management
разделяет client-managed sessions и server-managed conversations и предупреждает: если
смешать обе стратегии persistence в одном run, context может задублироваться.
LangGraph проводит похожую границу: checkpoints сохраняют thread state, Store — данные для recall между threads. В memory overview они называются short-term и long-term memory. Framework можно сменить; scopes смешивать не стоит.
Храните records, а не свободный prose
Единое поле memory_text быстро запускается и плохо эксплуатируется. Record должен
отвечать, кому он принадлежит, откуда взялся, действует ли сейчас и где может
использоваться:
{
"memory_id": "mem_01...",
"subject_id": "usr_internal_42",
"namespace": ["user", "travel_preferences"],
"kind": "preference",
"fact": {
"field": "seat_preference",
"value": "aisle"
},
"source": {
"type": "explicit_user_statement",
"event_id": "evt_01..."
},
"confidence": "confirmed",
"sensitivity": "personal",
"valid_from": "2026-08-21T10:00:00Z",
"valid_until": null,
"created_at": "2026-08-21T10:00:02Z",
"supersedes": null
}
Embedding остаётся производным index от source record, а не source of truth. Тогда correction, смена access и deletion не требуют восстанавливать смысл из вектора.
Осознанно выбирайте memory type
Полезно разделять три long-term типа:
- Semantic: facts — язык пользователя или deployment region проекта.
- Episodic: предыдущая попытка, actions и verified outcome.
- Procedural: instructions по выполнению задачи.
Procedural memory требует самого строгого gate. Если агент может переписать свои общие instructions, одна poisoned conversation закрепит вредное поведение. Organization policy и high-impact procedures должны быть versioned, reviewed и read-only для runtime. Агент может предложить изменение, но не тихо опубликовать его.
Сначала спроектируйте write path
Большинство memory failures начинается с лишних записей. «Пользователь это упомянул» — не retention policy.
Используйте три write paths.
1. Explicit и immediate
Пользователь говорит: «запомни, что я предпочитаю место у прохода». Проверьте, можно ли хранить этот data class, при необходимости покажите будущую запись и сохраните confirmed record.
2. Deterministic outcome
Application code фиксирует завершённое бронирование, approved decision или successful tool result. Сохраните verified state или ссылку на system of record. Не просите модель перефразировать identifier, чтобы затем доверять пересказу.
3. Inferred candidate
Модель выводит preference или lesson из нескольких событий. Сохраните candidate с provenance, а не accepted fact. Background job может выполнить deduplication, policy check, сравнение с текущими records и запросить user review.
Background consolidation не добавляет latency в основной ответ и видит несколько events. Но появляются lag и races. Выдавайте candidate event ID, делайте writes idempotent и не позволяйте старой job перезаписать новый confirmed record.
Текущая sandbox memory в OpenAI Agents SDK использует похожее разделение: conversation
extracts консолидируются в компактные memory files, а обычная Session остаётся
conversation history. В
agent memory documentation
сохранённая memory считается guidance, а при конфликте приоритет получает current
environment.
Разрешайте conflicts, а не добавляйте бесконечно
Memory меняется: пользователь переехал, проект мигрировал, preference была временной, либо extraction оказался неверным.
Задайте precedence policy в коде. Например:
current system of record
> explicit current user statement
> approved organization or project record
> recent verified outcome
> model-inferred candidate
> old summary
Не склеивайте несовместимые values в prose. Храните versions или supersession link, выбирайте active record детерминированно и показывайте conflict, если policy его не разрешает. «Нашлись два billing contacts; какой актуален?» лучше, чем выбор ближайшего embedding.
Для естественно устаревающих facts используйте validity intervals и TTL. Recency сама по себе не является truth: более новая заметка не должна переписать approved policy.
Сначала scope, потом similarity
Retrieval pipeline должен сначала сузить authority:
verified principal
→ allowed namespace and tenant
→ memory kind and validity
→ task filters
→ lexical or semantic retrieval
→ reranking
→ context budget
Не ищите по глобальному index с последующей фильтрацией уже в model context. Identity и
tenant boundaries исполняются в storage query. Namespace выводится из verified runtime
context, а не из user_id в prompt.
Structured lookup нужен для точных facts:
- current timezone;
- approved language;
- active workflow ID;
- policy version;
- object ownership.
Semantic search нужен для fuzzy experiences и notes: похожих incidents, прошлых подходов или preferences в разных формулировках. Добавляйте metadata filters и lexical search, когда важны identifiers или exact phrases.
Возвращайте небольшой typed packet с provenance:
{
"fact": "Prefers aisle seats",
"status": "confirmed",
"source_date": "2026-08-21",
"memory_id": "mem_01..."
}
У memory должен быть фиксированный token budget. Если помещаются десять records, retrieval не должен возвращать пятьдесят в надежде, что модель отбросит сорок. Логируйте candidates, selected records и rejection reasons для debugging.
Summary — lossy index
Conversation compaction полезен, но summary не должен оставаться единственным record approvals, tool results или user commitments.
Сохраняйте append-only event log или source messages согласно retention policy. У summary фиксируйте:
- source range;
- prompt или summarizer version;
- creation timestamp;
- unresolved items;
- ссылки на важные source events.
После correction или deletion summary нужно пересобрать. Иначе исходный факт исчезнет, а его paraphrase продолжит попадать в каждый будущий prompt.
Возобновляйте workflow из checkpoint
Durable agent нужна точная state для side effects:
workflow_id
current_step
completed_steps
pending_approval
tool_call_id and idempotency key
artifacts produced
last verified outcome
Это thread state, а не long-term memory. Сохраняйте её transactionally вокруг tool effects и авторизуйте каждый resume. Model-generated summary «платёж, вероятно, прошёл» не может решать, списывать ли деньги повторно.
Persistence model LangGraph пишет checkpoints per thread и использует отдельный Store для cross-thread memory. Это хорошая architecture и без LangGraph.
Privacy и deletion входят в schema
До хранения memory class решите:
- purpose и allowed readers;
- может ли model писать, читать или только предлагать;
- sensitivity и encryption requirements;
- default TTL и maximum retention;
- export, correction и deletion paths;
- может ли запись пересекать user, project или organization boundaries.
Не храните passwords, access tokens, recovery codes, payment data, raw government IDs и secrets как conversational memory. Используйте подходящий system of record и отдавайте агенту только минимально нужный факт.
Delete должен охватить source record, vector и lexical indexes, summaries, caches, нужные checkpoints и asynchronous replicas. Используйте deletion job со status и retry. Content-free tombstone не даст запоздавшему index event создать запись снова. Проверяйте завершение через read path, а не только успешную постановку в queue.
Оценивайте memory как write-and-retrieval system
Соберите fixed scenarios из реальных failure shapes:
| Метрика | Что проверяет scenario |
|---|---|
| Write precision | Сохранены только facts, достойные retention? |
| Write recall | Сохранён explicit permitted fact? |
| Useful retrieval | Task получил релевантный active record? |
| Noise | Irrelevant memories заняли context или изменили ответ? |
| Contradiction handling | Новые или более authoritative data победили? |
| Isolation | Может ли principal получить чужой record? |
| Staleness | Исключены expired и superseded records? |
| Deletion | Удалённый content исчез со всех read surfaces? |
Добавьте adversarial cases: indirect instructions в remembered note, prompt с попыткой сменить namespace, poisoned shared procedure и race удаления с background consolidation. Memory store одновременно является untrusted input для модели и sensitive data для приложения.
Production checklist
- Working state, thread checkpoints, long-term memory и knowledge retrieval разделены.
- У durable memory есть owner, scope, provenance, timestamps и sensitivity.
- Explicit facts и inferred candidates используют разные write paths.
- Conflicts и supersession разрешаются deterministic policy.
- Identity и tenant filters выполняются до semantic search.
- Retrieval имеет фиксированный context budget и возвращает provenance.
- Workflow resume использует checkpoints и idempotency, а не summaries.
- Shared procedures проходят review и versioning.
- Correction и deletion распространяются на indexes, summaries и caches.
- Fixed tests проверяют quality, isolation, staleness и deletion.
Хорошая memory избирательна и скучна. Агент находит нужный факт, показывает его источник, забывает его по команде и не превращает вчерашний chat в сегодняшнюю authority.