Agent Memory

Модуль 04 · Урок 4.2

Урок 4.2. Представление памяти: запись, факт, событие, навык, граф

На этой странице
  1. Цель лекции
  2. Ожидаемый результат
  3. Зачем это нужно
  4. Основная идея
  5. Ключевые термины
  6. Базовый MemoryRecord
  7. Content: текст и структура
  8. Type: зачем памяти нужен тип
  9. Scope
  10. Source и provenance
  11. Confidence и importance
  12. Temporal metadata
  13. Fact representation
  14. Event representation
  15. Skill representation
  16. Reflection representation
  17. Links между записями
  18. Soft delete и superseded records
  19. Представление как graph
  20. MemoryRecord schema: пример
  21. Мини-кейс: user preference
  22. Мини-кейс: coding event
  23. Типичные ошибки
  24. Краткое резюме
  25. Вопросы для самопроверки
  26. Что дальше

Цель лекции

Объяснить, в каком виде память существует внутри системы и почему модель данных важнее выбора базы.

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

Читатель понимает, какие поля нужны воспоминанию, чтобы оно было управляемым: content, type, scope, source, timestamp, confidence, importance, provenance, temporal metadata, links, status, soft delete и superseded records.

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

В предыдущей лекции мы обсуждали, где хранить память: prompt, files, KV, SQL, document store, vector DB, search index, graph, object storage и cache. Но выбор storage не спасает систему, если сама запись памяти плохо спроектирована.

Плохая запись:

text
Пользователь любит краткость.

На первый взгляд это полезно. Но для memory layer не хватает почти всего:

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

Хорошая память - это не просто текст. Это структурированная запись с жизненным циклом.

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

Качество памяти сильно зависит от representation: как система моделирует записи, факты, события, навыки, связи, источники, время и статусы.

Storage отвечает на вопрос "где лежит память?".

Representation отвечает на вопрос "что именно мы храним и как этим управлять?".

Если representation слабая, появляются проблемы:

  • retrieval не может фильтровать по scope;
  • update не знает, что заменить;
  • confidence не учитывается;
  • source теряется;
  • deletion не затрагивает derived records;
  • facts и hypotheses смешиваются;
  • old и active versions попадают в один context;
  • permissions невозможно применить точно.

Memory record должен быть достаточно структурированным, чтобы поддерживать весь lifecycle: write, retrieve, inject, update, consolidate и forget.

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

Термин Короткое определение
MemoryRecord Базовая единица памяти в системе.
Content Текстовое или структурированное содержание записи.
Type Вид записи: fact, event, skill, reflection, document chunk, summary, policy.
Scope Область применимости: user, session, project, team, organization, agent.
Source Откуда появилась запись: user, tool, document, model extraction, human review.
Provenance История происхождения и преобразований записи.
Confidence Насколько система доверяет записи.
Importance Насколько запись важна для будущего поведения.
Temporal metadata Временные поля: created_at, observed_at, valid_from, valid_until, last_confirmed_at.
Link Связь между memory records или entities.
Status Состояние записи: active, draft, superseded, stale, archived, deleted.
Soft delete Логическое удаление без немедленного физического удаления.
Superseded record Запись, замененная более новой или scoped версией.

Базовый MemoryRecord

Концептуальная запись может выглядеть так:

text
MemoryRecord
  id: mem_123
  type: semantic_fact
  content: "Project uses Vitest as test runner."
  scope:
    project: billing-service
  source:
    kind: file
    reference: package.json
  confidence: high
  importance: medium
  status: active
  created_at: 2026-08-07T12:00:00+03:00
  observed_at: 2026-08-07T11:58:00+03:00
  last_confirmed_at: 2026-08-07T12:00:00+03:00
  entities:
    - billing-service
    - Vitest
    - package.json
  links:
    - relation: supersedes
      target: mem_098
  permissions:
    visibility: project

Это не универсальная схема для всех систем. Это mental model. В конкретной реализации часть полей будет таблицами, часть JSON, часть индексами, часть derived metadata.

Главная мысль: запись должна быть управляемой.

Content: текст и структура

Content может быть natural language, structured data или оба варианта.

Текст:

text
User prefers concise final reports after file edits.

Структура:

text
subject: user
predicate: prefers_response_style
object: concise_final_reports
scope:
  task_type: file_edit_final_response

Текст удобен модели. Структура удобна системе.

Практичный подход часто комбинирует оба:

text
summary: "User prefers concise final reports after file edits."
structured:
  subject: user_123
  relation: prefers
  object: concise_final_reports
  applies_to: file_edit_final_response

Так запись можно вставить в prompt и одновременно искать, обновлять, фильтровать и проверять.

Type: зачем памяти нужен тип

type определяет, как запись использовать.

Примеры:

Type Что хранит Как используется
semantic_fact Устойчивый факт Context, reasoning, project/user profile.
episodic_event Событие и outcome Debugging, audit, replay, reflection.
procedural_skill Workflow или навык Планирование действий.
policy Обязательное правило Ограничение поведения.
reflection Lesson learned Warning, strategy adjustment.
document_chunk Фрагмент внешнего источника RAG и grounding.
summary Сжатое состояние Session continuity, handoff.
entity Объект системы Linking и graph retrieval.

Если type не задан, retrieval может смешать event, fact и procedure. Модель получит "что произошло" как "что всегда делать" или hypothesis как verified fact.

Scope

Scope говорит, где запись применима.

Примеры:

text
scope:
  user: user_123
text
scope:
  project: ai-agent-memory-guide
  task_type: lecture_writing
text
scope:
  organization: acme
  policy_domain: security

Без scope агент вспоминает правильные данные в неправильном месте. Preference одного пользователя применяется к другому. Workflow одного репозитория используется в другом. Временная session instruction становится долговременной привычкой.

Scopes подробно разберем в следующей лекции. Здесь важно: scope должен быть частью representation, а не внешним комментарием.

Source и provenance

Source отвечает на вопрос: откуда взялась запись?

Примеры source:

  • direct user instruction;
  • tool result;
  • project file;
  • official documentation;
  • CRM record;
  • model extraction;
  • human review;
  • consolidation of episodes;
  • imported knowledge base.

Provenance шире source. Она показывает историю:

text
Raw conversation -> extracted fact -> human confirmed -> indexed -> superseded older fact

Пример:

text
source:
  kind: user_instruction
  conversation_id: conv_2026_08_07
  message_id: msg_42
provenance:
  extracted_by: memory_writer_v2
  reviewed_by: user
  derived_from:
    - msg_42

Provenance нужна для:

  • проверки;
  • объяснимости;
  • conflict resolution;
  • deletion;
  • audit;
  • confidence scoring;
  • human correction.

Запись без source со временем становится опасной: агент помнит, но не знает, почему.

Confidence и importance

Confidence и importance отвечают на разные вопросы.

Confidence:

text
Насколько запись надежна?

Importance:

text
Насколько запись важна для будущего поведения?

Примеры:

Запись Confidence Importance
"Пользователь сказал 'ок'." High Low
"Возможно, причина бага в кешировании." Low Medium
"Security policy запрещает раскрывать secrets." High Critical
"Тест упал один раз." High как событие, low как причина Medium
"Проект использует Vitest согласно package.json." High Medium

Retrieval и action должны учитывать оба поля. Low-confidence memory может быть полезной как hypothesis, но не как fact. High-importance policy должна иметь высокий приоритет в context assembly.

Temporal metadata

В memory systems важно различать несколько моментов времени.

Поле Что означает
created_at Когда запись создана в memory store.
observed_at Когда событие было замечено агентом.
event_time Когда событие реально произошло, если известно.
valid_from С какого момента факт считается действительным.
valid_until До какого момента факт действителен.
last_confirmed_at Когда запись последний раз подтверждалась.
last_used_at Когда запись последний раз использовалась retrieval/action.
expires_at Когда запись должна перестать быть active.

Пример:

text
created_at: 2026-08-07
observed_at: 2026-08-07
valid_from: 2026-07-20
last_confirmed_at: 2026-08-07

Агент мог узнать сегодня, что проект перешел на Vitest 20 июля. Это разные даты.

Temporal metadata нужна для freshness, historical retrieval, contradiction detection, TTL и decay.

Fact representation

Факт удобно представлять как relation:

text
subject -> predicate -> object

Пример:

text
subject: ai-agent-memory-guide
predicate: primary_language
object: Russian
scope:
  project: ai-agent-memory-guide
source:
  kind: project_instruction
confidence: high

Или:

text
subject: user_123
predicate: prefers
object: concise_final_reports
scope:
  project: ai-agent-memory-guide
  task_type: file_edit

Такая форма помогает:

  • находить противоречия;
  • обновлять object;
  • связывать entities;
  • строить graph;
  • объяснять факт;
  • фильтровать по subject или predicate.

Не каждый факт нужно превращать в строгий RDF-like triple. Но mental model subject-predicate-object помогает избегать расплывчатых записей.

Event representation

Event record отвечает на вопрос "что произошло?"

Поля:

  • actor;
  • action;
  • target;
  • result;
  • time;
  • context;
  • artifacts;
  • source;
  • importance;
  • related entities.

Пример:

text
type: episodic_event
actor: coding-agent
action: ran_tests
target: invoice_totals.test.ts
result: failed
event_time: 2026-08-07T16:10:00+03:00
context:
  changed_file: src/pricing/discount_helper.ts
artifacts:
  - test_log_uri: object://logs/test_run_123
source:
  kind: tool_result
importance: medium

Event representation важна для audit, replay, debugging и reflection.

Ошибка: сохранять event как semantic fact.

text
"invoice_totals.test.ts fails"

Это может быть true в конкретный момент, но не обязательно всегда. Лучше:

text
"invoice_totals.test.ts failed after change X at time Y."

Skill representation

Procedural memory требует другой структуры.

Skill или workflow может иметь:

  • name;
  • trigger или applies_when;
  • goal;
  • steps;
  • constraints;
  • required tools;
  • expected outcome;
  • failure modes;
  • source;
  • scope;
  • priority;
  • status.

Пример:

text
type: procedural_skill
name: write_full_markdown_lecture
applies_when:
  - user asks to write or expand a lesson
scope:
  project: ai-agent-memory-guide
steps:
  - read target lesson plan
  - read adjacent course files
  - preserve title, goal and expected result
  - add terms, diagram, examples, risks, summary and self-check questions
constraints:
  - write in Russian
  - keep the guide conceptual
expected_outcome:
  - complete Markdown lecture
source:
  kind: project_instruction

Если хранить skill как один text chunk, агенту труднее понять trigger, constraints и priority.

Reflection representation

Reflection record должен отличать outcome, evidence и lesson.

Пример:

text
type: reflection
summary: "Lesson plans should be checked against final lecture sections."
trigger:
  kind: draft_review
evidence:
  - first draft missed SOUL.md from source bullet list
lesson:
  When expanding lesson plans, verify that required bullets are represented or intentionally omitted.
applicability:
  project: ai-agent-memory-guide
  task_type: lecture_writing
confidence: high

Так representation не сохраняет chain-of-thought, но сохраняет полезный урок.

Память редко состоит из независимых строк.

Links могут выражать:

  • derived_from;
  • supersedes;
  • conflicts_with;
  • supports;
  • contradicts;
  • related_to;
  • mentions_entity;
  • caused_by;
  • part_of;
  • depends_on.

Пример:

text
reflection_123 derived_from event_456
fact_789 supersedes fact_101
procedure_222 supported_by reflection_123
document_chunk_333 mentions_entity service_billing

Links помогают:

  • объяснять происхождение;
  • делать graph search;
  • удалять derived records;
  • разрешать конфликты;
  • строить summaries;
  • проводить audit.

Soft delete и superseded records

Не каждая запись удаляется физически сразу.

Soft delete:

text
status: deleted
deleted_at: 2026-08-07
delete_reason: user_request

Superseded:

text
status: superseded
superseded_by: mem_456

Разница:

  • deleted запись не должна использоваться и может подлежать физическому удалению из индексов и derived records;
  • superseded запись остается историей, но не должна быть active;
  • archived запись может быть доступна для audit или historical retrieval;
  • stale запись требует проверки перед использованием.

Статус - обязательная часть representation, если memory layer поддерживает update и forgetting.

Представление как graph

Даже если storage не graph database, полезно думать о памяти как о графе.

flowchart TD U[User] -->|prefers| P[Concise final reports] U -->|works_on| PR[Project: AI Agent Memory Guide] PR -->|has_source_of_truth| CP[guide/content_plan.md] PR -->|contains| M4[Module 04] M4 -->|includes| L42[Lesson 4.2] L42 -->|uses_skill| SK[write_full_markdown_lecture] RF[Reflection: check source bullets] -->|supports| SK

Граф помогает увидеть связи между user, project, documents, lessons, skills и reflection. Даже если физически данные лежат в SQL и JSON, relation model улучшает retrieval и update.

MemoryRecord schema: пример

text
MemoryRecord
  id: string
  type: enum
  status: enum
  summary: string
  content: text_or_json

  scope:
    user_id: optional
    session_id: optional
    project_id: optional
    team_id: optional
    organization_id: optional
    agent_id: optional

  source:
    kind: enum
    reference: string
    observed_by: optional

  scores:
    confidence: low | medium | high
    importance: low | medium | high | critical

  temporal:
    created_at: timestamp
    observed_at: optional timestamp
    event_time: optional timestamp
    valid_from: optional timestamp
    valid_until: optional timestamp
    last_confirmed_at: optional timestamp
    expires_at: optional timestamp

  entities:
    - entity_id

  links:
    - relation: string
      target_id: string

  permissions:
    visibility: enum
    read_roles: list
    write_roles: list

Это учебная схема, не готовая миграция базы. В реальной системе поля будут зависеть от продукта, privacy requirements и storage choice.

Мини-кейс: user preference

Плохая запись:

text
User likes short answers.

Управляемая запись:

text
id: pref_001
type: semantic_fact
status: active
summary: User prefers concise final reports after file edits.
structured:
  subject: user_123
  predicate: prefers
  object: concise_final_reports
scope:
  project: ai-agent-memory-guide
  task_type: file_edit_final_response
source:
  kind: user_instruction
confidence: high
importance: medium
created_at: 2026-08-07T13:00:00+03:00
last_confirmed_at: 2026-08-07T13:00:00+03:00

Теперь агент может правильно применить preference: кратко ответить после редактирования файла, но не сокращать саму лекцию.

Мини-кейс: coding event

Плохая запись:

text
Tests failed.

Управляемая запись:

text
id: event_401
type: episodic_event
status: active
summary: invoice_totals.test.ts failed after editing discount_helper.ts.
actor: coding-agent
action: ran_tests
target: invoice_totals.test.ts
result: failed
context:
  changed_file: src/pricing/discount_helper.ts
source:
  kind: tool_result
confidence: high
importance: medium
event_time: 2026-08-07T16:10:00+03:00
entities:
  - file:src/pricing/discount_helper.ts
  - test:invoice_totals.test.ts

Такую запись можно использовать для debugging, reflection и future retrieval.

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

Ошибка 1: хранить только text blob.

Текст удобен, но без type, scope, source и status память трудно обновлять.

Ошибка 2: не различать content и metadata.

Metadata не должна прятаться внутри произвольной фразы.

Ошибка 3: не хранить source.

Факт без источника трудно проверить, объяснить и удалить.

Ошибка 4: смешивать event и fact.

"Тест упал" - событие. "Тест всегда падает" - другое утверждение и обычно неверное.

Ошибка 5: не хранить temporal fields.

Без времени невозможно понять freshness, TTL и historical validity.

Ошибка 6: не моделировать links.

Без связей трудно понять, какие records derived from source и что удалить при correction.

Ошибка 7: не иметь status.

Active, stale, superseded, archived и deleted записи должны вести себя по-разному.

Ошибка 8: проектировать representation только под одну базу.

Модель памяти должна отражать lifecycle, а не ограничения первого выбранного storage.

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

Memory Representation определяет, чем является запись памяти внутри системы. Хорошая запись содержит content, type, scope, source, provenance, confidence, importance, temporal metadata, entities, links, permissions и status.

Факты, события, навыки и reflection требуют разных структур. Text summary полезен для LLM, но structured fields нужны для retrieval, update, conflict detection, deletion и governance.

Хорошая representation делает память управляемой. Плохая representation превращает память в набор заметок, которые невозможно надежно искать, обновлять и забывать.

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

  1. Почему memory record не должен быть только текстовой строкой?
  2. Чем confidence отличается от importance?
  3. Какие временные поля могут быть нужны записи памяти?
  4. Почему event representation отличается от fact representation?
  5. Зачем memory records нужны links и status?

Что дальше

В следующей лекции мы разберем Memory Scopes: как определить, кому и где применима запись памяти, как защищать multi-tenant системы и как решать конфликты между user, session, project, team и organization memory.

Обновлено 08.08.2026