Цель лекции
Дать обзор классов хранилищ, которые могут использоваться для разных типов памяти агента.
Ожидаемый результат
Читатель умеет сопоставлять тип памяти с подходящим классом storage и понимает, почему зрелая memory system почти всегда комбинирует prompt, files, SQL, document stores, vector indexes, search indexes, graph, object storage и cache.
Зачем это нужно
В Module 03 мы разобрали lifecycle памяти: наблюдение, запись, retrieval, injection, update и forgetting. Следующий вопрос естественный: где все это хранить?
Наивный ответ звучит так:
Положим память в vector database.
Это частый старт, но плохая универсальная архитектура. Vector database полезна для semantic retrieval, но не решает все задачи памяти:
- session state часто лучше хранить в key-value store;
- project facts удобнее моделировать структурно;
- audit log лучше хранить append-only;
- документы и артефакты могут жить в object storage;
- точный поиск по error codes требует search index;
- зависимости между сущностями лучше выражаются graph;
- system instructions иногда живут прямо в prompt или files;
- permissions и deletion часто требуют SQL-like структуры.
Storage design должен следовать типу данных и паттерну доступа, а не моде на один инструмент.
Основная идея
Не существует одного универсального хранилища для всей памяти агента.
Разные виды памяти требуют разных свойств:
- скорость чтения;
- скорость записи;
- структурированность;
- полнотекстовый поиск;
- semantic retrieval;
- связи между сущностями;
- versioning;
- auditability;
- access control;
- TTL;
- deletion;
- дешёвое хранение больших артефактов;
- удобство ручного редактирования.
Хорошая memory architecture обычно polyglot: использует несколько классов хранилищ, а сверху имеет единый memory layer, который скрывает детали storage от agent loop.
Ключевой принцип:
Выбирай storage по форме памяти и способу доступа к ней.
Ключевые термины
| Термин | Короткое определение |
|---|---|
Storage class |
Класс хранилища: prompt, files, KV, SQL, document store, vector DB, search index, graph, object storage, cache. |
Persistence |
Способность данных сохраняться между сессиями и перезапусками. |
Latency |
Время чтения или записи. |
Query pattern |
Как система обычно ищет данные: по ключу, тексту, вектору, связи, времени, metadata. |
Index |
Структура, ускоряющая retrieval. |
Hot storage |
Быстрый активный слой для часто используемых данных. |
Cold storage |
Более дешевый или медленный слой для архивов и больших данных. |
Source of truth |
Авторитетное место, где считается актуальная версия данных. |
Cache |
Быстрое временное хранилище производных или часто используемых данных. |
Polyglot persistence |
Использование нескольких типов хранилищ под разные задачи. |
In-prompt memory
In-prompt memory - это память, которая прямо включается в prompt или system/developer instructions.
Подходит для:
- коротких устойчивых инструкций;
- high-priority policies;
- текущего task state;
- кратких summaries;
- выбранных preferences;
- правил поведения агента;
- небольших project notes.
Плюсы:
- сразу доступна модели;
- не требует отдельного retrieval;
- хорошо работает для критичных инструкций;
- легко контролировать при context assembly.
Минусы:
- ограничена context window;
- увеличивает стоимость и latency;
- не масштабируется;
- может конфликтовать с другими инструкциями;
- не является полноценным storage;
- требует аккуратного обновления.
Пример:
Relevant project memory:
- Course is written primarily in Russian.
- guide/content_plan.md is source of truth for structure.
- Keep final edit reports concise.
In-prompt memory полезна как active view, но не как единственное долговременное хранилище.
Files: Markdown, JSON и YAML
Файлы - один из самых простых и полезных способов хранения памяти, особенно в проектах и coding agents.
Форматы:
- Markdown для human-readable instructions, plans, summaries;
- JSON для structured records;
- YAML для конфигураций и policy-like данных;
- plain text для небольших notes.
Подходит для:
- project memory;
- procedural instructions;
- style guides;
- lecture plans;
- ADR;
- TODO и checklists;
- lightweight user/project facts;
- manually reviewed memory.
Плюсы:
- читаемо человеком;
- хорошо версионируется в git;
- удобно редактировать;
- прозрачно для команды;
- не требует инфраструктуры;
- подходит для documentation-first проектов.
Минусы:
- плохая конкурентная запись;
- слабые permissions на уровне отдельных records;
- поиск нужно строить отдельно;
- сложно делать fine-grained deletion;
- трудно масштабировать на миллионы записей;
- нет встроенного semantic retrieval.
Файлы хороши, когда memory должна быть видимой и управляемой человеком. Но для высокочастотных событий, больших логов и персональной памяти многих пользователей нужны другие storage classes.
Key-value stores
Key-value store хранит данные по ключу.
Примеры паттернов:
session:{session_id}:state -> current session state
user:{user_id}:settings -> user settings
task:{task_id}:status -> active task status
cache:{query_hash}:retrieval -> cached retrieval results
Подходит для:
- session memory;
- temporary state;
- feature flags;
- user settings;
- active task state;
- TTL-based records;
- cache;
- locks и coordination signals.
Плюсы:
- очень быстрый доступ;
- простая модель;
- хороший TTL;
- подходит для hot state;
- удобно для agent loop.
Минусы:
- плохо выражает сложные relationships;
- ограниченные query capabilities;
- не подходит для rich retrieval;
- не дает semantic search;
- может стать свалкой opaque blobs.
KV-store хорош для "быстро получить текущее состояние", но не для "найти все события, связанные с сущностью и похожие по смыслу".
SQL databases
SQL database хорошо подходит для структурированной памяти.
Подходит для:
- user profiles;
- project facts;
- memory records с metadata;
- scopes и permissions;
- audit tables;
- versioning;
- task state;
- entity tables;
- deletion tracking;
- relationships умеренной сложности.
Плюсы:
- строгая структура;
- транзакции;
- constraints;
- joins;
- access control patterns;
- auditability;
- mature tooling;
- удобство для updates и deletes.
Минусы:
- не лучший выбор для raw documents;
- semantic retrieval требует отдельного embeddings/index слоя;
- graph traversal сложнее, чем в graph DB;
- schema migrations требуют дисциплины;
- плохо хранить огромные blobs прямо в таблицах.
SQL часто становится backbone memory layer: там удобно хранить authoritative records, metadata, scopes, source, confidence, statuses и links на внешние индексы.
Document stores
Document store хранит гибкие JSON-like документы.
Подходит для:
- heterogeneous memory records;
- episodic logs;
- tool observations;
- flexible metadata;
- records с меняющейся схемой;
- nested structures;
- drafts и intermediate states.
Плюсы:
- гибкая схема;
- удобно хранить разные типы memory records;
- natural fit для JSON;
- проще эволюционировать модель на ранней стадии;
- можно хранить вложенные fields.
Минусы:
- сложнее поддерживать строгие invariants;
- risk schema drift;
- queries могут стать хаотичными;
- joins слабее, чем в SQL;
- semantic search всё равно требует отдельного индекса.
Document store часто полезен для early-stage memory systems, где representation еще меняется. Но по мере зрелости часть данных может переехать в более строгую модель.
Vector databases
Vector database хранит embeddings и позволяет искать по semantic similarity.
Подходит для:
- RAG по документам;
- semantic memory snippets;
- episodic similarity search;
- retrieval по notes и summaries;
- поиск похожих incidents;
- long-form knowledge base.
Плюсы:
- находит смысловые совпадения;
- работает с paraphrases;
- хорошо масштабируется на большие текстовые корпуса;
- полезна для unstructured memory.
Минусы:
- похожее не всегда полезное;
- плохо работает с exact IDs, paths, error codes;
- требует metadata filters;
- требует reranking;
- deletion и updates могут быть сложнее, чем кажутся;
- не заменяет source of truth;
- не решает permissions самостоятельно.
Vector DB - это индекс для retrieval, а не вся memory system. Часто authoritative record живет в SQL/document store, а vector DB хранит embedding и ссылку на record id.
Search indexes
Search index нужен для keyword и full-text search.
Подходит для:
- error codes;
- file names;
- symbols;
- API endpoints;
- ticket IDs;
- exact phrases;
- documentation search;
- logs;
- mixed text corpora.
Плюсы:
- точный поиск по словам;
- BM25 и full-text ranking;
- хорошо работает с редкими терминами;
- объяснимее, чем vector similarity;
- можно комбинировать с filters.
Минусы:
- не понимает paraphrases так хорошо, как embeddings;
- требует нормализации текста;
- может пропустить смысловой match без общих слов;
- нуждается в metadata и reranking.
Search index особенно важен для coding agents. Если агент ищет invoice_totals.test.ts, vector similarity не должен быть единственным механизмом.
Graph databases
Graph database хранит сущности и связи.
Подходит для:
- entity memory;
- dependency graph;
- organization/team/project relationships;
- document links;
- service dependencies;
- user-account access;
- causal links между events;
- knowledge graph;
- path finding.
Плюсы:
- естественно выражает relations;
- удобно искать соседей сущности;
- полезно для multi-hop reasoning;
- помогает объяснять связи;
- хорошо подходит для scopes и ownership graphs.
Минусы:
- требует entity extraction и linking;
- сложнее поддерживать качество графа;
- не заменяет full-text и vector search;
- может быть overkill для простых систем;
- нужны правила conflict resolution.
Graph полезен, когда вопрос звучит не "найди похожий текст", а "что связано с этой сущностью и через какие отношения?"
Object storage
Object storage хранит большие объекты:
- raw logs;
- full documents;
- transcripts;
- artifacts;
- screenshots;
- datasets;
- exported reports;
- backups;
- long audio/video files;
- large tool outputs.
Плюсы:
- дешево хранить большие данные;
- хорошо для архивов;
- удобно ссылаться из metadata records;
- масштабируется;
- подходит для immutable artifacts.
Минусы:
- не дает rich query сам по себе;
- нужны индексы и metadata отдельно;
- deletion может быть сложной из-за backups;
- не подходит для low-latency fine-grained retrieval.
Частый паттерн:
SQL record -> object_storage_uri -> raw artifact
Vector/search index -> points to SQL record
Так active memory работает с metadata и summaries, а raw artifacts доступны при необходимости.
Cache
Cache хранит временные производные данные для ускорения.
Подходит для:
- recent retrieval results;
- assembled context blocks;
- embeddings cache;
- summaries;
- tool results;
- expensive permission checks;
- compiled prompts;
- current task state.
Плюсы:
- снижает latency;
- снижает стоимость;
- разгружает backing stores;
- полезен для hot memory.
Минусы:
- может устареть;
- может нарушить permissions, если key неправильно scoped;
- не должен быть source of truth;
- требует invalidation;
- sensitive data в cache опасны.
Cache должен иметь TTL и понятный scope. Нельзя кэшировать retrieval result пользователя A и показать его пользователю B.
Таблица: тип памяти и storage
| Тип памяти | Подходящие storage classes | Комментарий |
|---|---|---|
| Working memory | Prompt / context assembly | Не долговременное хранилище, а активный контекст. |
| Session memory | KV, cache, document store | Нужны TTL и быстрый доступ. |
| Episodic memory | Document store, SQL, object storage, temporal index | Важны timestamp, outcome, audit trail. |
| Semantic memory | SQL, document store, vector index, graph | Факты требуют structure, source, confidence и retrieval. |
| Procedural memory | Files, prompt, SQL/document store | Policies и workflows должны быть human-reviewable. |
| Reflection memory | Document store, SQL, vector index | Нужны evidence, applicability, confidence. |
| World memory / RAG | Object storage, vector DB, search index, metadata DB | Документы и индексы должны быть связаны с source attribution. |
| Shared memory | SQL/document store, KV для active state, graph для ownership | Нужны permissions, owner, statuses, conflict state. |
Комбинированная архитектура
В этой схеме агент не должен напрямую знать, где физически лежит каждая запись. Он обращается к memory layer API, а memory layer решает, какие хранилища читать и как объединять результаты.
Source of truth и индексы
Важно отличать source of truth от индекса.
Пример:
Authoritative memory record:
- SQL table memory_records
Indexes:
- vector embedding index
- full-text search index
- graph edges
Если запись обновилась в SQL, индексы должны быть обновлены или инвалидированы. Если запись удалена, embeddings и search documents тоже должны быть удалены или помечены.
Ошибка: считать vector DB source of truth, если в ней хранится только chunk text без status, source, permissions и deletion semantics.
Мини-кейс: personal assistant
Personal assistant может использовать:
- KV для текущей session;
- SQL для user preferences и reminders;
- calendar/email connectors как world memory;
- vector index для notes;
- object storage для attachments;
- cache для recent retrieval;
- prompt для активного краткого профиля.
Если пользователь говорит:
"Запомни, что рабочие встречи я предпочитаю утром."
Это может стать SQL/user preference record с source и scope. Для semantic retrieval может быть создан embedding. Для prompt может быть добавлена короткая active memory строка, если задача связана с scheduling.
Одна и та же память может иметь authoritative record, search index и prompt representation.
Мини-кейс: coding agent
Coding agent может использовать:
- files для
AGENTS.md, docs, plans; - SQL/document store для project facts и events;
- search index для file paths, symbols, error codes;
- vector index для semantic code/docs retrieval;
- graph для imports и dependencies;
- object storage для CI logs и artifacts;
- KV для текущего task state.
Если тест падает:
invoice_totals.test.ts failed after discount_helper.ts edit
Система может сохранить:
- event record в document store;
- file entities в SQL/graph;
- exact test name в search index;
- summary embedding в vector DB;
- raw test log в object storage;
- active task state в KV.
Это не избыточность, если каждый слой имеет свою роль.
Типичные ошибки
Ошибка 1: искать одно хранилище для всей памяти.
Разные memory types требуют разных storage и query patterns.
Ошибка 2: считать vector database source of truth.
Vector DB чаще является retrieval index, а не authoritative memory store.
Ошибка 3: хранить structured facts только как text chunks.
Без fields вроде scope, source, confidence и status update становится сложным.
Ошибка 4: игнорировать deletion в индексах.
Удалить запись из основной таблицы недостаточно, если embeddings, search index и cache остались.
Ошибка 5: класть большие логи в SQL без причины.
Raw artifacts лучше хранить в object storage, а в structured store держать metadata и ссылки.
Ошибка 6: использовать cache как память.
Cache может ускорять, но не должен быть единственным source of truth.
Ошибка 7: забывать про permissions на storage level.
Access control нужно учитывать в schema, metadata, indexes и cache keys.
Ошибка 8: выбирать storage до модели данных.
Сначала нужно понять representation и lifecycle, потом выбирать базу.
Краткое резюме
Память агента редко живет в одном хранилище. In-prompt memory, files, KV, SQL, document stores, vector DB, search indexes, graph databases, object storage и cache решают разные задачи.
Зрелая система обычно хранит authoritative records отдельно от retrieval indexes и raw artifacts. Memory layer объединяет эти хранилища в единый API и следит за scope, permissions, source, update, deletion и context assembly.
Главная мысль: storage должен следовать типу памяти и паттерну доступа.
Вопросы для самопроверки
- Почему vector database не является универсальным memory store?
- Какие данные хорошо хранить в key-value store?
- Чем source of truth отличается от retrieval index?
- Зачем coding agent может одновременно использовать search index, vector DB и graph?
- Какие проблемы возникают при deletion, если данные продублированы в индексах?
Что дальше
В следующей лекции мы разберем Memory Representation: как выглядит сама запись памяти, какие поля ей нужны и почему модель данных важнее выбора конкретной базы.