Перейти к содержанию

Автоматический перевод

Эта статья была автоматически переведена с оригинальной английской версии.

Память ИИ-агента: типизированное состояние с управлением схемой для долгосрочно работающих систем

Агенты редко терпят неудачу из-за того, что забывают всё. Они терпят неудачу потому, что запоминают старую информацию и рассматривают её как текущее состояние.

Представьте долгосрочно работающего ассистента, обслуживающего пользователя по имени Мира. В одном из разговоров Мира говорит, что крайний срок подачи её паспорта — 15 июля. Позже она корректирует эту информацию на 30 июня. Векторный поиск может найти старую запись. Однако он сам по себе не может определить, какой срок является актуальным. В этом и заключается разница между воспроизведением информации и памятью.

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


Ловушка контекстного окна

Контекстное окно представляет собой рабочий набор данных. Это не долговечная память и не база данных.

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

Теперь у агента могут быть два срока истечения действия «паспорта», два предпочтительных формата или два решения по проекту. Семантический поиск может выдать оба варианта. Краткая сводка может перезаписать один из них. Длинный контекст может содержать устаревшую информацию рядом с актуальной. Ни одно из этих поведений не обеспечивает четкого контракта на хранение памяти.

Контракт должен содержать ответы на конкретные вопросы:

  • Что верно в данный момент?
  • Что было верно 2 июня?
  • Кто это сказал?
  • Какому арендатору это принадлежит?
  • Какой старый факт заменил этот факт?
  • Могу ли я его удалить или ограничить срок действия?

Именно здесь начинается использование Schema-Guided Agent Memory (SGAM).


Что означает SGAM

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

Schema-Guided Dialogue (SGD) — это набор данных для задач-диалогов от Google 2019 года. Его схема описывает API-сервисов, намерения и поля данных, что позволяет модели диалога отслеживать состояние сервисов, которые она ранее не видела. Это полезный прецедент, но для другого уровня абстракции.

Schema-Guided Memory (SGM) — это исследовательский термин, используемый Mei и соавторами в работе According to Me: Long-Term Personalized Referential Memory QA. В этой статье сравниваются текстовые записи Descriptive Memory (DM) с элементами памяти в формате «ключ-значение» с фиксированной схемой. Исходная информация остается прежней; меняется только способ её представления.

Schema-Guided Agent Memory (SGAM) — это инженерный паттерн, о котором идет речь в данной статье: использование схем для управления процессами записи, обновления, поиска и удаления данных в долгосрочной памяти агента. Схема — это не просто более удобный формат записей; это контракт, определяющий состояние системы.

ATM-Bench делает эту концепцию более наглядной. Он использует примерно четыре года данных личной памяти в формате электронных писем, изображений и видео, затем задает вопросы, требующие личных ссылок, информации о местоположении, нескольких источников доказательств и обновлений со временем. Современные системы памяти показывают слабые результаты при решении подобных задач, тогда как SGM превосходит DM благодаря тому, что такие поля, как время, источник, местоположение, сущности и теги, предоставляются системе поиска и ответчику в структурированном виде, а не в виде простого текста.

Именно поэтому следующее сравнение касается SGAM и SGR. Разумование с использованием схемы — это не случайный отклонение от основного пути; это именно тот механизм записи, который обычно требуется SGAM.


SGR — это механизм записи

Разумование с использованием схемы (SGR) и Память агента с использованием схемы (SGAM) решают разные аспекты одной и той же задачи по обработке информации.

В этом блоге я регулярно использую SGR в качестве основного строительного блока. Изначальный... Статья о vLLM и XGrammar описали механизм. В последующих публикациях он был применён к структурированные судьи, планировщики и маршрутизаторы, и критерии оценки репродуцируемости RAG. Во всех этих случаях механизм SGR ограничивал вызов таким образом, чтобы ответ был достаточно корректным для обработки кодом.

Механизм SGAM заимствует эту же логику, но изменяет срок действия результата. Теперь выходной результат уже не является просто вердиктом, маршрутом или планом действий для текущего запроса; он превращается в потенциальную запись в память, которая может повлиять на будущие сессии и вызовы инструментов. Именно поэтому сходства и различия между ними имеют большое значение.

SGR ограничивает количество вызовов модели. Он заставляет модель генерировать корректный объект для текущего шага инференса, часто с использованием Pydantic, JSON Schema, структурированных выходных данных, специфичных для конкретного провайдера, или среды декодирования с руководством, такой как XGrammar.

SGAM определяет, что происходит после того, как объект существует. Следует ли его сохранять? Заменяет ли он более старый факт? Какой арендатор может его видеть? Является ли он актуальным или историческим? Какая эпизод из исходных данных его подтверждает?

Размер SGR SGAM
Область применения Один шаг инференса или вызов инструмента Цикл жизни надёжной памяти
Формат Pydantic или JSON Schema для вызова Заполненные записи, схемы и связи
Принудительное исполнение Структурированный вывод или ограничения по времени декодирования Проверка корректности данных, ограничения базы данных, правила разрешения конфликтов
Срок службы Обычно удаляется после генерации ответа Сохраняется между сессиями и выполняется
Режим сбоя Некорректная или семантически слабая экстракция Состояние с устаревшими данными, загрязнённостью, отсутствием определения области применения или невозможностью аудита

Шаблон выглядит следующим образом:

structured extraction on write -> typed memory at rest -> scoped retrieval on read

SGR обеспечивает достаточную надежность процесса извлечения данных для их последующей загрузки в память. SGAM делает эту память достаточно безопасной для повторного использования в дальнейшем.

from datetime import datetime
from pydantic import BaseModel, Field


class MemoryDelta(BaseModel):
    tenant_id: str = Field(description="Isolation boundary, e.g. acme")
    subject: str = Field(description="Normalized entity ID, e.g. mira")
    attribute: str = Field(description="Property being updated")
    value: str = Field(description="New value")
    valid_from: datetime
    source_episode_id: str

Этот объект не является системой памяти. Это граница между хаотичным диалогом и реестром памяти.


Два потока

В данном рабочем процессе существуют два независимых потока обработки. Их смешивание приводит к тому, что диаграммы становятся крайне запутанными.

Поток ввода представляет собой путь записи данных:

  1. Захватить необработанную информацию из сообщений, результатов работы инструментов или бизнес-событий.
  2. Извлечь соответствующие данные через структурированный вывод.
  3. Проверить соответствие шаблону и отклонить некорректные записи.
  4. Урегулировать конфликты, закрыть устаревшие записи и сохранить информацию о происхождении данных.
  5. Сохранить запись в хранилище SGAM.

Поток запросов представляет собой путь чтения данных:

  1. Начать с вопроса пользователя.
  2. Определить, требуется ли текущее состояние данных или состояние в определённый момент времени.
  3. Произвести фильтрацию по аренде, типу памяти, теме, атрибутам и окну действительности.
  4. Применить методы векторного или графового расширения только в том случае, если достаточно не является прямого поиска по состоянию.
  5. Собрать минимально необходимый контекст для передачи модели.

Архитектура памяти агента с руководством схемой

Читайте эту диаграмму слева направо по двум каналам. Верхний канал отвечает за запись в память, а нижний — за её чтение. Память является общей, но функции каналов различаются. text.

tenant_id
memory_id
subject
attribute
value
memory_type
schema_version
valid_from
valid_to
supersedes_memory_id
source_episode_id
confidence
retention_policy

Такая структура делает обычные операции более явными. Новый срок действия паспорта может заменить предыдущий срок, не удаляя историю. Запрос может требовать информации о текущем состоянии или состоянии в определённый момент времени. Ответ может указывать на исходную запись. Механизм миграции может определять, какая версия схемы была использована для создания записи. Процесс удаления может определять, какие индексы требуют очистки.

Именно здесь SGAM и RAG отличаются друг от друга: RAG отвечает за поиск документов, тогда как SGAM отвечает за хранение состояния.

SGAM не является антивекторным методом. Векторы полезны для фаззи-поиска, кластеризации и расширения результатов. Однако текущее значение mira.passport_deadline Эта информация должна браться из записи памяти с определённым диапазоном, а не из того фрагмента, который случайно оказался на первом месте.


Пример устаревшей информации

Самая простая полезная демонстрация SGAM — это реестр для приведённого выше примера Mira с двумя эпизодами.

e1: Mira prefers concise answers. Her passport deadline is 2026-07-15.
e2: Mira corrected the deadline. It is now 2026-06-30.

Поиск в текстовой памяти может вернуть e1 потому что в нём содержатся правильные слова. Система хранения данных, созданная с использованием программирования, должна возвращать e2 для текущего состояния и сохранять e1 для исторического запроса. Поведение на стороне записи минимально:

def close_previous_fact(db: sqlite3.Connection, fact: MemoryFact) -> int | None:
    row = db.execute(
        """
        select fact_id
        from memory_facts
        where tenant_id = ?
          and subject = ?
          and attribute = ?
          and valid_to is null
        order by valid_from desc
        limit 1
        """,
        (fact.tenant_id, fact.subject, fact.attribute),
    ).fetchone()
    if not row:
        return None

    db.execute(
        "update memory_facts set valid_to = ? where fact_id = ?",
        (fact.valid_from, row["fact_id"]),
    )
    return int(row["fact_id"])

Ожидаемая поведенческая модель и есть главная цель:

Naive text memory:
  returned episode: e1 -> passport deadline is 2026-07-15

SGAM current state:
  mira.passport_deadline = 2026-06-30
  valid_from=2026-06-03T10:00:00Z, source=e2

SGAM point-in-time state:
  on 2026-06-02, mira.passport_deadline = 2026-07-15

В производственной среде необходимо сочетать эту транзакцию с структурированным извлечением данных на этапе записи. База данных автоматически удаляет устаревшие состояния. Модели не должны самостоятельно определять, какая старая информация по-прежнему актуальна.

Инструмент или фреймворк Основной уровень хранения данных Обработка временных данных Механизм схемы Практическая ниша
Zep / Graphiti Поддержка Neo4j, FalkorDB, Neptune и устаревшей версии Kuzu Высокий Pydantic-сущности и типы рёбер, временные рёбра, происхождение данных Память временных графов
LangGraph / LangMem Хранилища LangGraph, хранилища на основе Postgres Средний JSON хранит профиль Pydantic или результат извлечения коллекции Приложения-агенты, уже созданные с использованием LangGraph
Mem0 Управляемая стек-архитектура с бэкендами Valkey / Redis / vector в средах OSS Средний Типы памяти, пользовательские категории, промпты для извлечения Память пользователя, агента и сессии как сервис
Letta / MemGPT Состояние агента и блоки памяти, хранящиеся в базе данных Низкий Редактируемые блоки памяти с метками Агенты с состоянием и механизмами управления контекстом в стиле операционных систем
Cognee Графовые, векторные и реляционные бэкенды Средний Экстракция и верификация, ориентированные на онтологии Память корпоративной графической сети знаний
Граф свойств LlamaIndex Графовые хранилища свойств и векторные хранилища Низкий до среднего SchemaLLMPathExtractor с разрешёнными сущностями и связями Извлечение графов из документов и трейсов

Graphiti представляет собой наиболее подробный открытый исходный пример реализации для сценариев, где память имеет реляционную и временную структуру. Эта библиотека отслеживает изменения фактов, сохраняет информацию о происхождении данных из исходных источников и поддерживает гибридные способы поиска. LangGraph отлично подходит в качестве слоя приложений, поскольку он разделяет точки контроля выполнения потоков от хранилищ данных между потоками. Mem0 полезен тогда, когда требуются управляемые операции с памятью вместо необходимости самостоятельной обработки всей инфраструктуры хранения. Letta ближе к концепции редактируемых блоков контекста, чем к SGAM на уровне полей, однако использование модели состояний агента здесь также имеет свою актуальность.

Не начинайте с самой сложной структуры данных в виде графа, если доменная среда этого не требует. Для многих команд первой версии достаточно реляционной таблицы с данными в формате JSON, столбцами для проверки корректности, индексами, предназначенными для отдельных тенантов, и векторного сервиса-помощника.


Плейбук реализации

Первое решение, связанное с реализацией, заключается не в том, «графовый хранилище или векторное?», а в том, что продукт имеет право запоминать.

Агент службы поддержки может хранить информацию о уровне аккаунта, открытых заявках и предпочтениях пользователя по контактам. Однако он не должен автоматически переводить каждую жалобу пользователя в состояние профиля. Агент, занимающийся кодингом, может запоминать правила структурирования репозиториев и нерешённые задачи. Тем не менее он не должен сохранять личные заметки бесконечно лишь потому, что они были извлечены один раз.

Начните с процесса записи данных, рассматривая память как небольшое изменение состояния:

  1. Укажите тип памяти, тему, диапазон применения и класс хранения данных.
  2. Извлеките кандидатские записи в структурированном виде.
  3. Проверьте содержимое записи с помощью Pydantic или слоя схем, уже используемого в вашей системе.
  4. Устраните конфликты перед сохранением, включая определение того, заменяет ли новая запись старую.
  5. Сохраняйте указатель на исходный источник — первоначальную запись, результат работы инструмента, файл, заявку или подтверждение пользователя, которые послужили основой для создания записи.
  6. Записывайте версию схемы вместе с записью, а не только в коде приложения.

Для многих команд первым вариантом хранения данных в рамках SGAM может стать реляционная таблица с колонкой в формате JSON и несколькими индексами. Не обязательно начинать с временной графовой структуры. Графовая модель становится полезной тогда, когда важны связи между элементами: от клиента к аккаунту, от аккаунта к политике, от задачи к результату её выполнения, от пользователя к его предпочтениям, от проекта к принятому решению.

Процесс записи в реальном времени и фоновая запись

Сразу же извлекать данные целесообразно, если следующее действие системы зависит от новых данных. Если пользователь просит «запомнить, что я предпочитаю краткие ответы», системе не нужна еженощная обработка, чтобы изменить своё поведение.

Большинство запросов не похожи на такие. Более дешевым стандартным решением является быстрое запись сырого эпизода, привязка метаданных арендатора/сессии/инструмента и последующая обработка кандидатских воспоминаний фоновым работником. Консолидация на основе рекурренции — это одна из версий такой политики: хранение запросов с низкой значимостью в буфере и выделение факта в качестве актуального только тогда, когда повторяются подобные доказательства или пользователь прямо это подтверждает. Недостатком является задержка в получении актуальной информации. Это приемлемо в случаях, когда «пользователь часто запрашивает экспорт в формате CSV», но менее приемлемо, если «клиент изменил адрес доставки».

Путь чтения должен быть проще, чем путь записи. Сначала следует ответить на вопрос «Какое состояние мне разрешено использовать?», затем спросить, может ли фаззи-поиск добавить полезный контекст.

  1. Фильтрация по арендатору, типу воспоминания и окну действительности.
  2. Получение точного структурированного состояния перед анализом семантических аналогов.
  3. Использование векторного или графового расширения для получения дополнительных доказательств, связанных сущностей и примеров, но не как источника авторитетных данных для текущих фактов.
  4. Сбор минимального необходимого контекста для ответа на вопрос.

Миграцию схем следует рассматривать как часть работы над продуктом. Когда структура записи воспоминания меняется, меняется и поведение агента: что он может вспомнить, что может цитировать, что может удалить, и какие старые факты по-прежнему считаются актуальными. Скрипты миграции, процедуры восстановления данных, двойные окна чтения и правила удаления должны входить в один план выпуска с изменениями продукта.

  • Предпочтения пользователя, которые можно обновить или отменить;
  • Данные о клиенте или аккаунте с требованиями к аудиту;
  • Статус задачи для долгосрочно работающих ассистентов;
  • Память проекта кодинг-агента;
  • Общее состояние многоклиентских систем;
  • Примечания по соответствию стандартам, где важна происхожденность данных;
  • Временные вопросы вроде «Что мы считали до миграции?»

Это избыточно, когда память имеет кратковременный характер, используется в исследовательских целях или её легко пересчитать. Если агенту нужно лишь несколько этапов поддержания контекста, достаточно чекпоинта и сокращённой истории сообщений. Для проверки статических документов может хватить технологии RAG. Если ваша схема меняется ежедневно из-за неопределённости области применения, использование SGAM замедлит работу.


Чек-лист оценки

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

Её структура близка к разделению критериев оценки, предложенному мной Статья об оценке архитектуры RAG: необходимо определять этап пайплайна, на котором может возникнуть сбой, а не только генерируемый в конце текст. Это также перекрывается с подходами трейсинга Статья об оценке агентов: Ошибка памяти часто проявляется в истории выполнения задач ещё до того, как становится заметной в результатах ответа.

Для SGAM наиболее эффективным тестом является повторная обработка данных. Необходимо подать фиксированную последовательность эпизодов в модуль записи в память, проверить содержимое журнала после каждого значимого хода, а затем сформулировать вопросы о текущем состоянии и состоянии в определённый момент времени на основе полученных данных.

Слой Искомая ошибка Показатели измерения
Выполнение операции извлечения Агент упустил какой-либо факт, выдумал его или сгенерировал недопустимую форму. Скорость записи с соблюдением схемы, точность/покрытие при извлечении, степень охвата исходных эпизодов
Обработка конфликтов Устаревший факт оставался актуальным, либо действительный старый факт подвергался перезаписи. Правильность замены данных, коэффициент дубликатов, правильность аннулирования устаревших данных
Изоляция и политики Утечка памяти между пользователями или её сохранение после истечения установленного срока использования Сбои изоляции тенантов, корректность удаления, соблюдение правил хранения данных
Запрос информации Запись существует, но считыватель не загрузил её. Точность в текущем состоянии, точность в определённый момент времени, воспроизводимость@k для записей в памяти
Ответ с привязкой к данным Ответ использовал память без соответствующей поддержки или сослался на неверный источник. Подайте заявку на поддержку по поводу исходных эпизодов, точности цитирования и корректности решения конфликтов.
Операции Путь к памяти слишком медленный, слишком устаревший или слишком дорогой в использовании. p95 задержка записи, задержка обновления данных, задержка чтения, стоимость за запрос

тесты производительности вроде LoCoMo, LongMemEval, и ATM-бенчмарк Предоставьте полезные внешние сигналы. Они не могут заменить собой набор тестов для проверки домена. Объём памяти зависит от характера нагрузки: кодинг-ассистенту, боту поддержки клиентов и копилоту для соблюдения регламентов требуются разные схемы обработки данных, фильтры, правила хранения информации и тесты на выявление сбоев.


Ограничения

SGAM — это мой собственный термин для описания определённого шаблона, а не стандарт. В отрасли уже используются перекрывающиеся названия для элементов, относящихся к одной и той же области дизайна: Память LangGraph и LangMem Рассмотрим краткосрочные и долгосрочные хранилища, профили, коллекции, операции записи в «горячие» пути, а также фоновые менеджеры памяти. Zep Graphiti называет версию в форме графа временным контекстным графом. Летта представляет систему в виде агентов с состоянием, обладающих блоками памяти с долгосрочным хранением. Mem0 называет себя слоем управления памятью. Microsoft GraphRAGLlamaIndex Property Graphs и Cognee используют язык знанийых графов для решения задач поиска связанных данных и работы с онтологиями.

Эти названия не являются взаимозаменяемыми. Некоторые системы отвечают за управление профилями пользователей, другие — за обработку эпизодов информации. Есть системы, которые формируют контекст графа на основе документов, а также те, что предоставляют агенту инструменты для редактирования собственной памяти. SGAM представляет собой более строгую версию этого подхода: когда постоянная память отражает текущее состояние приложения, необходимы схема структуры данных, механизмы проверки корректности, отслеживания происхождения информации, урегулирования конфликтов, правила хранения и миграции данных.

Даже в случае использования типизированной памяти возможны ошибки. Схема помогает легче выявлять некорректные записи, но не делает их достоверными. По-прежнему требуется доверие к источникам информации, подтверждение пользователем важных фактов, наличие политик разрешения конфликтов, возможность удаления записей и постоянный мониторинг.

Миграция схем — это сложная задача. Как только память становится частью состояния приложения, необходимо учитывать вопросы версионирования, восстановления старых данных, обработки устаревших записей и правил их удаления. Именно это является ценой получения надежного отражения текущего состояния вместо просто набора вероятных заметок.


Основные выводы

  1. Контекст представляет собой рабочий набор данных. Для устойчивой памяти агента требуется отдельный контракт состояния.
  2. SGR и SGAM дополняют друг друга: сначала выполняется проверка записи, затем обеспечивается сохранение типизированного жизненного цикла памяти в состоянии покоя.
  3. Векторное восстановление данных полезно, однако текущим фактам необходимы информации о диапазоне применимости, действительности, возможности замены и происхождении.
  4. Прежде чем переходить к графовым структурам, начните с простого реляционного или JSON-ориентированного реестра памяти.
  5. Оценивайте качество памяти по корректности записей, способности к временному поиску, связи с реальными данными, изоляции различных пользователей и поведению при удалении. По моему мнению: качественная проверка долгосрочной персонализированной референтной памяти - Статья Mei и соавторов, в которой представлены ATM-Bench и Schema-Guided Memory. К пути к масштабируемым мультидоменным конверсационным агентам: набор данных для диалогов с использованием схемы - Статья Rastogi и др. о наборе данных SGD. LongMemEval: тестирование чат-ассистентов с учётом долгосрочной интерактивной памяти - Бенчмарк Wu и др. для оценки способностей к долгосрочной памяти. Graphiti: создание графов временного контекста для ИИ-агентов

  6. Zep: архитектура временной графовой сети знаний для памяти агентов

  7. Обзор платформы Mem0
  8. Mem0: Создание агентов ИИ, готовых к эксплуатации в производственных условиях, с масштабируемой долгосрочной памятью
  9. Обзор памяти LangGraph
  10. Поддержание состояния LangGraph
  11. Документация LangMem
  12. Letta: Введение в агентов с состоянием
  13. Документация Microsoft GraphRAG
  14. LlamaIndex: использование индекса на основе графа свойств
  15. Документация Cognee
  16. Документация по валидации моделей Pydantic
  17. Документация к модулю sqlite3 в Python