Agent Memory

Модуль 03 · Урок 3.3

Урок 3.3. Memory Retrieval: как агент вспоминает нужное

На этой странице
  1. Цель лекции
  2. Ожидаемый результат
  3. Зачем это нужно
  4. Основная идея
  5. Ключевые термины
  6. Схема retrieval pipeline
  7. Memory read policy
  8. Query construction
  9. Vector search
  10. Keyword search и BM25
  11. Graph search
  12. Temporal search
  13. Metadata filters
  14. Hybrid retrieval
  15. Reranking
  16. Context budget
  17. Negative retrieval
  18. Retrieval noise
  19. Мини-кейс: написание лекции
  20. Мини-кейс: debugging agent
  21. Типичные ошибки
  22. Краткое резюме
  23. Вопросы для самопроверки
  24. Что дальше

Цель лекции

Показать, как агент ищет полезную память с учетом смысла, слов, сущностей, времени и прав доступа.

Ожидаемый результат

Читатель понимает, почему поиск памяти требует нескольких сигналов и финального отбора: read policy, query construction, vector search, keyword search, graph search, temporal search, hybrid retrieval, reranking, context budget и negative retrieval.

Зачем это нужно

В предыдущей лекции мы разобрали запись памяти. Но хорошая запись бесполезна, если агент не может найти ее в нужный момент.

Retrieval часто воспринимают слишком узко:

text
Сделаем embeddings, найдем похожие chunks, вставим в prompt.

Это работает для некоторых задач, но быстро ломается в агентской памяти. Агенту нужно найти не самое похожее, а самое полезное для текущего шага.

Пример:

text
User:
"Напиши следующую лекцию."

Семантически похожие воспоминания могут включать все тексты прошлых лекций, обсуждения Markdown и разные заметки про writing. Но полезные записи гораздо уже:

  • текущий content plan;
  • план нужного урока;
  • соседний урок;
  • project writing conventions;
  • preference о кратком финальном отчете;
  • procedural workflow для lecture writing.

Retrieval должен учитывать задачу, scope, тип памяти, источник, свежесть, confidence, permissions и context budget.

Основная идея

Memory retrieval - это управляемый поиск и отбор памяти для текущего действия агента.

Он отвечает на вопросы:

  • нужно ли обращаться к памяти;
  • какие слои памяти искать;
  • как сформулировать запрос;
  • какие filters применить;
  • какие индексы использовать;
  • как объединить результаты;
  • как убрать шум;
  • сколько записей можно вставить в context;
  • что делать, если лучше ничего не вспоминать.

Retrieval - это не один алгоритм. Это pipeline, где semantic search, keyword search, graph traversal, temporal search, metadata filters и reranking работают вместе.

Ключевые термины

Термин Короткое определение
Memory retrieval Извлечение релевантных записей памяти под текущую задачу.
Read policy Правила, когда и какие слои памяти искать.
Query construction Формирование поискового запроса из user task, plan, entities и current state.
Vector search Поиск по смысловой близости через embeddings.
Keyword search Поиск по точным словам, именам, путям, ошибкам и терминам.
BM25 Классический алгоритм полнотекстового ранжирования по словам.
Graph search Поиск через связи между сущностями.
Temporal search Поиск с учетом времени, recency и порядка событий.
Hybrid retrieval Объединение нескольких видов поиска.
Reranking Повторная сортировка кандидатов более точной моделью или правилами.
Context budget Ограничение на объем памяти, который можно вставить в context window.
Retrieval noise Память, которая похожа на запрос, но не помогает текущему действию.
Negative retrieval Решение не извлекать память или не вставлять найденное в контекст.

Схема retrieval pipeline

flowchart TD T[Current task] --> P[Read policy] P --> Q[Query construction] Q --> V[Vector search] Q --> K[Keyword / BM25 search] Q --> G[Graph search] Q --> M[Metadata filters] Q --> R[Temporal search] V --> C[Candidate pool] K --> C G --> C M --> C R --> C C --> F[Permission / scope filtering] F --> D[Deduplicate] D --> RR[Rerank] RR --> B[Context budget selection] B --> I{Useful enough?} I -->|Yes| X[Inject selected memory] I -->|No| N[Negative retrieval]

Схема показывает, что retrieval состоит из нескольких стадий. Важно не только найти кандидатов, но и отфильтровать их, убрать дубли, оценить полезность и уложиться в context budget.

Memory read policy

Read policy решает, когда агент обращается к памяти.

Обращение к памяти полезно, если:

  • задача зависит от прошлых предпочтений;
  • нужен project context;
  • есть риск повторить прошлую ошибку;
  • задача многошаговая;
  • требуется continuity между сессиями;
  • пользователь ссылается на прошлый разговор;
  • нужно проверить policies;
  • нужно найти связанные entities;
  • нужно использовать world memory или docs.

Обращение к памяти может быть лишним, если:

  • задача полностью self-contained;
  • пользователь просит простую одноразовую операцию;
  • retrieval почти наверняка даст шум;
  • вопрос требует только текущего файла или текущего сообщения;
  • sensitive scopes не разрешены;
  • context budget лучше сохранить для источников.

Пример:

text
User:
"Сколько будет 2 + 2?"

Long-term memory не нужна.

text
User:
"Продолжи писать курс в том же стиле."

Memory retrieval нужен: стиль, структура, project facts, соседние лекции.

Query construction

Хороший retrieval начинается с хорошего запроса.

Запрос к памяти не обязан совпадать с пользовательской фразой. Агент может расширить его:

  • определить task type;
  • выделить entities;
  • добавить project scope;
  • добавить нужный memory type;
  • добавить temporal constraints;
  • добавить source priority;
  • включить текущий plan step.

Пример:

text
User:
"Почини тест."

Слабый retrieval query:

text
"Почини тест"

Лучший query construction:

text
task_type: coding_debug
entities:
  - failing test name
  - changed files
  - error message
memory_types:
  - episodic failures
  - project testing procedures
  - reflection lessons
scope:
  - current repository
temporal:
  - recent related failures first

Чем больше агент понимает текущий шаг, тем точнее retrieval.

Vector search полезен, когда нужно найти смыслово похожие записи.

Примеры:

  • пользователь формулирует тему другими словами;
  • нужно найти похожий прошлый incident;
  • нужно найти docs section по описанию проблемы;
  • нужно извлечь related lessons learned;
  • нужно найти концептуально близкие project notes.

Плюсы:

  • находит paraphrases;
  • хорошо работает с естественным языком;
  • полезен для больших текстовых коллекций;
  • не требует точного совпадения слов.

Ограничения:

  • похожее не всегда полезное;
  • плохо работает с exact identifiers;
  • может пропустить filenames, IDs, error codes;
  • может вернуть устаревший, но похожий фрагмент;
  • требует reranking и metadata filters.

Пример: запрос "ошибка при входе" может найти записи про login failure, authentication issue, session expiration. Но если нужен конкретный ERR_AUTH_403, keyword search будет надежнее.

Keyword search и BM25

Keyword search важен для точных совпадений.

Хорошо работает для:

  • file paths;
  • function names;
  • class names;
  • API endpoints;
  • error codes;
  • ticket IDs;
  • customer names;
  • product terms;
  • exact phrases;
  • configuration keys.

Пример:

text
Error:
ERR_ENTITLEMENT_CACHE_STALE

Vector search может понять смысл "устаревший кеш прав", но keyword search по exact code почти всегда нужен.

BM25 и полнотекстовый поиск особенно полезны, когда:

  • корпус большой;
  • важны редкие термины;
  • нужно искать по документации;
  • нужно комбинировать title, heading и body;
  • нужно объяснимое ranking по словам.

В агентской памяти keyword search часто дополняет vector search. Один ищет смысл, другой держит точность.

Graph search полезен, когда память содержит entities и relations.

Пример graph:

text
User -> works_on -> Project
Project -> contains -> Module 03
Module 03 -> includes -> lesson_03_03_memory_retrieval.md
lesson_03_03 -> follows -> lesson_03_02
Project -> has_source_of_truth -> guide/content_plan.md

Graph search отвечает на вопросы:

  • какие entities связаны с текущей задачей;
  • какие файлы зависят от измененного helper;
  • какие decisions относятся к этому сервису;
  • какие пользователи имеют доступ к account;
  • какие уроки входят в модуль;
  • какие прошлые incidents связаны с feature.

Для coding agents graph может быть dependency graph, import graph или call graph. Для enterprise agents - knowledge graph организаций, команд, документов и продуктов.

Graph search особенно полезен, когда похожий текст не содержит нужной связи. Например, два файла могут не быть семантически похожими, но один импортирует другой.

Память существует во времени.

Temporal search учитывает:

  • recency;
  • event order;
  • last confirmed;
  • valid_from и valid_until;
  • session timeline;
  • incident timeline;
  • staleness;
  • version history.

Примеры:

text
"Что мы уже пробовали в этой задаче?"

Нужен recent episodic timeline.

text
"Какое предпочтение пользователя сейчас активно?"

Нужна последняя подтвержденная active запись, а не все старые preferences.

text
"Почему решение было принято тогда?"

Нужна историческая версия, действовавшая в момент события.

Свежесть зависит от вопроса. Иногда нужен самый новый факт. Иногда нужна версия на конкретную дату.

Metadata filters

Metadata filters ограничивают поиск до допустимых и релевантных записей.

Типичные filters:

  • user_id;
  • project_id;
  • organization_id;
  • account_id;
  • memory_type;
  • source;
  • status;
  • confidence threshold;
  • permission scope;
  • language;
  • created_at / updated_at;
  • tags;
  • related entities;
  • visibility;
  • freshness.

Без filters retrieval может смешать данные разных пользователей, проектов или организаций.

Пример:

text
Query:
"export feature access"

Required filters:
- account_id = current customer
- source_type in [CRM, docs, incidents]
- status != deprecated
- permission: readable by current support role

Metadata filtering - это не удобство, а safety requirement.

Hybrid retrieval

Hybrid retrieval объединяет несколько сигналов.

Пример pipeline:

text
1. Metadata filter by project and permissions.
2. Vector search for semantic candidates.
3. BM25 search for exact terms.
4. Graph expansion through related entities.
5. Temporal boost for recent or active records.
6. Merge candidates.
7. Deduplicate.
8. Rerank.

Почему hybrid нужен:

  • vector search находит смысл;
  • keyword search держит точность;
  • graph search находит связи;
  • temporal search учитывает время;
  • metadata filters защищают scope и permissions;
  • reranking выбирает полезное.

Таблица:

Сигнал Лучше всего подходит для Ограничение
Vector Смысловая похожесть, paraphrases Может вернуть похожий шум.
Keyword / BM25 Имена, ID, пути, error codes Не понимает paraphrases.
Graph Связи entities, dependencies Требует структуры и entity linking.
Temporal Последовательность, recency, версии Самое новое не всегда самое важное.
Metadata Scope, permissions, source Не решает semantic relevance.

Reranking

Reranking - повторная сортировка кандидатов после первичного поиска.

Первичный retrieval обычно дешевле и шире. Reranking может быть дороже, но точнее.

Reranker может учитывать:

  • текст текущей задачи;
  • current plan step;
  • role агента;
  • memory type;
  • source reliability;
  • confidence;
  • staleness;
  • conflict status;
  • context cost;
  • diversity;
  • novelty;
  • user intent.

Пример:

text
Candidates:
1. Old note about Jest in this project.
2. Current package.json showing Vitest.
3. Reflection about checking test runner before commands.

Reranking должен поднять current package.json и reflection, а old note пометить как stale или снизить.

Context budget

Retrieval не заканчивается списком кандидатов. Нужно выбрать, что попадет в context window.

Context budget ограничен:

  • token cost;
  • latency;
  • model attention;
  • risk of distraction;
  • instruction hierarchy;
  • room for user request и tool results.

Хороший memory context:

  • компактный;
  • scoped;
  • не дублируется;
  • содержит source или confidence;
  • отделяет факты от гипотез;
  • сохраняет важные constraints;
  • не вытесняет task instructions.

Плохой memory context:

text
20 старых эпизодов, 8 похожих фактов, 5 длинных summaries, 3 устаревших процедуры.

Лучше:

text
Relevant memory:
- Active project fact: current test runner is Vitest. Source: package.json.
- Procedure: before changing shared helpers, run dependent focused tests.
- Reflection: previous failure came from checking only local tests.

Negative retrieval

Иногда правильное решение - ничего не вспоминать.

Negative retrieval нужен, когда:

  • найденные записи слабые;
  • нет scope match;
  • записи устарели;
  • confidence низкий;
  • permissions не позволяют использовать данные;
  • context budget лучше отдать current source;
  • memory может навязать неверную framing;
  • задача не требует long-term memory.

Пример:

text
User:
"Переведи это предложение на английский: ..."

Не нужно доставать project memory о предыдущих задачах, если пользователь не просил стиль проекта.

Другой пример:

text
User:
"Какая текущая цена тарифа?"

Если long-term memory содержит старую цену, лучше не использовать ее. Нужен свежий внешний источник.

Negative retrieval - признак зрелой системы. Агент не обязан вспоминать ради самого факта вспоминания.

Retrieval noise

Retrieval noise - это память, которая попала в контекст, но не помогает.

Источники шума:

  • слишком широкий query;
  • нет scope filter;
  • vector similarity без reranking;
  • старые записи без staleness;
  • дубли;
  • длинные summaries;
  • смешанные memory types;
  • weak confidence records;
  • извлечение слишком большого top-k;
  • отсутствие negative retrieval.

Последствия:

  • модель фокусируется не туда;
  • старые факты конфликтуют с текущими;
  • важные инструкции вытесняются;
  • ответ становится более уверенным, но менее точным;
  • агент повторяет прошлые ошибки.

Retrieval noise опасен тем, что выглядит как полезный контекст. На самом деле он ухудшает reasoning.

Мини-кейс: написание лекции

Задача:

text
User:
"Напиши лекцию 3.3."

Read policy:

text
Need project memory, writing procedure, target lesson plan, content plan, adjacent lessons.

Query construction:

text
task_type: lecture_writing
project: ai-agent-memory-guide
module: 03
lesson: 03_03
memory_types:
  - semantic project facts
  - procedural writing workflow
  - world memory docs

Useful retrieval:

  • guide/content_plan.md section for Memory Retrieval;
  • lesson_03_02_memory_write.md;
  • target plan lesson_03_03_memory_retrieval.md;
  • style from Module 02 full lectures;
  • preference for Russian technical Markdown.

Noise:

  • old frontend screenshot workflow;
  • unrelated support CRM examples;
  • all previous event logs;
  • every mention of retrieval across the repo.

Context budget should include enough style and plan context, not the entire course.

Мини-кейс: debugging agent

Задача:

text
User:
"Тест invoice_totals.test.ts снова падает после изменения скидок."

Good retrieval:

  • keyword search: invoice_totals.test.ts;
  • graph search: files related to discount helper;
  • episodic memory: previous failures involving invoice totals;
  • procedural memory: run focused tests for pricing rules and invoice totals;
  • reflection memory: previous failure came from too narrow test scope;
  • temporal search: most recent related attempts.

Bad retrieval:

  • generic docs about testing;
  • old unrelated auth test failures;
  • semantic facts about user style;
  • all pricing docs without reranking.

This is where hybrid retrieval matters. Exact test names, graph dependencies and previous episodes are more useful than generic semantic similarity.

Типичные ошибки

Ошибка 1: искать только embeddings.

Vector search полезен, но для filenames, error codes, IDs и permissions нужны другие сигналы.

Ошибка 2: считать похожее полезным.

Semantic similarity не знает текущего plan step, scope, confidence и context budget.

Ошибка 3: не применять permissions до context assembly.

Запрещенная память не должна попадать в prompt.

Ошибка 4: забывать про negative retrieval.

Иногда лучший результат retrieval - пустой результат.

Ошибка 5: вставлять слишком много.

Большой top-k может ухудшить ответ сильнее, чем отсутствие памяти.

Ошибка 6: не учитывать time.

Старая активная запись может быть хуже новой, но иногда нужна именно историческая версия.

Ошибка 7: не различать memory types.

Fact, event, procedure и reflection должны использоваться по-разному.

Ошибка 8: не делать reranking.

Первичный retrieval часто возвращает кандидатов, но не финальный контекст.

Краткое резюме

Memory Retrieval - это не просто поиск похожего текста. Это pipeline, который решает, когда обращаться к памяти, как построить query, какие индексы использовать, как объединить vector, keyword, graph, temporal и metadata signals, как rerank candidates и что вставить в ограниченный context window.

Главная цель retrieval - найти самое полезное для текущего шага агента. Иногда это semantic match. Иногда exact error code. Иногда свежий project fact. Иногда прошлый episode. Иногда правильное решение - ничего не извлекать.

Вопросы для самопроверки

  1. Почему vector search недостаточен для memory retrieval?
  2. Что такое query construction, и почему пользовательская фраза не всегда хороший retrieval query?
  3. Какие задачи лучше решает graph search?
  4. Зачем нужен reranking после первичного поиска?
  5. Что такое negative retrieval?

Что дальше

В следующей лекции мы разберем Memory Update, Consolidation и Forgetting: что происходит с памятью после записи и retrieval, как устаревшие факты заменяются, эпизоды обобщаются, summaries сжимаются, а лишние записи архивируются или удаляются.

Обновлено 08.08.2026