[!NOTE] Автоматический перевод Эта статья была автоматически переведена с оригинальной английской версии.
ИИ-агент Архитектура памяти в 2026 году: Чекпоинты, векторные хранилища и память на основе файлов
Часть 2 серии «Инженерия стека Агентный»
цикл ризонинга может существовать лишь в течение одного запроса, если его состояние не сохраняется вне процесса обработки. Без агентской памяти агент не может возобновить приостановленный план, восстановиться после сбоя или воспроизвести предпочтение, заданное ранее в сессия. Часть 1 В данной статье рассматривается контрольный поток. Здесь указывается, какое состояние требуется на каждом последующем шаге и где оно должно храниться.
Я расскажу о архитектуре памяти данного устройства. Агент аналитика рынка, Покажу, как чекпоинты, векторные хранилища с низкой задержкой и память для документов на основе файлов взаимодействуют друг с другом в рамках агентов с длительным временем работы. Затем рассмотрю случаи, когда целесообразно использовать PostgreSQL, Redis, Qdrant, хранилища типа «ключ-значение» и обычные файлы в формате Markdown.
Кратко: Разделяйте память в зависимости от способа доступа. Горячая память представляет собой состояние на уровне потока чекпоинт, необходимое для приостановки и возобновления работы. Холодная память используется для хранения межпоточных сессия данных в структурах типа ключ-значение или векторных хранилищах. Документированная память служит для сохранения проектной информации в удобных для анализа файлах. Начните с проблемы, которую необходимо решить, а затем выберите подходящее хранилище. Не сохраняйте точные данные в системах с фазированным поиском retrieval, а также не используйте чекпоинт в качестве журнала аудита.
Что такое память ИИ-агент?
ИИ-агент память представляет собой слой состояния, который позволяет агенту сохранять прогресс выполнения задачи, восстанавливать ранее полученные знания и обновлять свои данные между разными запусками. В продакшене это не одна векторная база данных; это комбинация активных чекпоинты хранилищ, холодных семантических или структурированных хранилищ, а также памяти в виде документов, читаемых человеком.
| Нужно | Лучший стандартный вариант | Почему? |
|---|---|---|
| Пауза и возобновление одной запуска | хранилище PostgreSQL чекпоинт | Надёжные данные приложения, поддающиеся поиску и удобные в работе |
| Низкоуровневое кратковременное состояние латентность | хранилище Redis чекпоинт | Быстрое восстановление состояния и его кратковременная жизненность при необходимости компромисса между сохранением данных и производительностью |
| Кросс-сессия семантическое воспроизведение | Qdrant или pgvector | Восстанавливает воспоминания на основе смысла, а не только точных ключей |
| Структурированные сведения о пользователях | PostgreSQL или хранилище типа «ключ-значение» | Детерминистические обновления превосходят нечёткие retrieval методы при работе с предпочтениями и идентификаторами. |
| Проектные конвенции и устоявшиеся процедуры работы | Markdown-файлы или файлы JSON | Читаемый человеком формат, поддерживающий сравнение изменений, и удобный для обновления агентами |
| Память отношений между несколькими сущностями | граф знаний | Полезно в ситуациях, когда взаимосвязи имеют большее значение, чем отдельные факты. |
Не начинайте с рассмотрения аспектов памяти, поскольку это может создать впечатление высокой интеллектуальности. Начните с проявлений сбоев, видимых для пользователя: потери прогресса в работе, забывания настроек, необходимости повторять одни и те же исследования или невозможности использовать уже существующие стандарты проекта.
Сбои, требующие использования памяти
Безсостоянийный агент способен ответить на изолированный вопрос, но забывает о запросе сразу после завершения вызова. Такая архитектура теряет эффективность, когда продукту требуются любые из следующих функциональных особенностей:
- Пауза и возобновление работы: пользователь запускает задачу по поиску информации, закрывает ноутбук и возвращается на следующий день. Без сохранённого состояния агент должен начинать работу с нуля.
- Согласованность в многократных диалогах: в ходе длительного общения агенту необходимо помнить, какие инструменты он использовал, какие данные собрал и какие шаги плана были выполнены.
- Персонализация: возвращающийся пользователь ожидает, что агент будет знать его уровень толерантности к рискам, предпочтительную глубину анализа и информацию о прошлых взаимодействиях.
- Участие человека в процессе (HITL): агент составляет проект отчёта и ждёт одобрения. Состояние «ожидания» должно сохраняться при перезапуске процесса.
В рамках Агент аналитика рынка из Часть 1, При запросе «Проанализировать NVDA» генерируется план, пять tool calls, собранные данные и черновик отчета. Когда пользователь отвечает «всё нормально, но добавьте анализ конкурентов», хранилище чекпоинт позволяет агенту загрузить состояние с предыдущего узла и включить этап анализа конкурентов. В отсутствие сохраненных состояний агент не может определить, на что именно указывает оценка «всё нормально», и вынужден начинать работу заново.
Долгосрочная память решает схожую задачу в другом контексте. Если пользователь вернётся через неделю и попросит «Обновить анализ NVDA», агенту, возможно, потребуется вспомнить предпочтение к консервативной оценке рисков и интерес к акциям полупроводниковой отрасли. Хранилище памяти на основе векторов позволяет извлекать такие данные через сессии без необходимости повторного запроса.
LangGraph разделяет данные внутри графа по уровням области применения. Каждая итерация обработки графа выполняется в рамках отдельной thread, то есть для одного конкретного диалога или задачи. Состояние, сохраняемое внутри такой thread, называется краткосрочная память. Состояние, доступное между разными thread, обозначается как долгосрочная память. Текущий контекст и переменные, находящиеся в процессе выполнения, модель, формируют слой рабочей памяти, расположенный над обоими вышеупомянутыми хранилищами данных.
Таксономия памяти ИИ-агент
Прежде чем переходить к реализации, целесообразно классифицировать те данные, которые агентам необходимо запоминать. CoALA фреймворк (Sumers, Yao et al., 2023) представляет собой стандартную таксономию, основанную на принципах когнитивной науки. Я ввёл понятие ограничения области действия памяти в своей работе контекст-инжиниринг публикация; Здесь я разделяю его на шесть категорий:
| Тип памяти | Область применения | Время существования | Пример | Шаблон хранения данных |
|---|---|---|---|---|
| Рабочий | Текущий шаг | миллисекунды | аргументы Tool call, текущий ответ LLM | Внутрипроцессный словарь (Python) |
| Краткосрочный | Текущая ветка | Минуты–часы | История диалога, ход выполнения плана, собранные данные | Чекпоинт хранение |
| Эпизодический | межпоточная коммуникация | Дни–месяцы | На прошлой неделе пользователь спрашивал о результатах деятельности NVDA. | хранилище векторов / хранилище типа KV |
| Семантический | межпоточная коммуникация | Месяцы — постоянные | «Пользователь отдаёт предпочтение консервативным инвестициям» | хранилище векторов / хранилище KV |
| Документация | межпоточная коммуникация | Дни — постоянные | Заметки по проекту, краткие обзоры исследований, выявленные закономерности | Хранилище файлов (Markdown/JSON) |
| Процедурный | по всей системе | Постоянный | При анализе акций обязательно проверяйте документы, подаваемые в SEC. | Config / системный промпт |
Рабочая память — это то, с чем в данный момент активно взаимодействует ризонинг через LLM: переменные Python в текущей функции, содержимое контекстное окно, аргументы tool call во время выполнения. Это самый быстрый и кратковременный уровень хранения данных. Ничто не сохраняется после завершения текущего шага. Объём рабочей памяти ограничен контекстное окно модель, что делает её фактическим боттлнек. Все данные, которые агент «знает» в момент принятия решения, должны помещаться именно здесь, независимо от того, поступили ли они из хранилища чекпоинт, в результате векторного поиска или при чтении файла. Остальные уровни предназначены для подачи нужной информации в рабочую память в подходящее время.
Краткосрочная память — это данные, которые чекпоинт LangGraph записывает после каждого узла. Эпизодическая и семантическая память сохраняются в рамках всех потоков выполнения. Документная память хранит проектные заметки, краткие отчеты о исследованиях и выработанные стандарты в файлах, доступных как для людей, так и для агентов. Процедурная память заключена в системных инструкциях и определениях инструментов, поэтому она не изменяется под каждого пользователя.
В процессе реализации эти категории сводятся к трём уровням. В памяти типа «горячая» хранится текущий сессия. Память типа «холодная» обеспечивает возможность восстановления данных в рамках сессии. Память документов сохраняет накопленные знания проекта в состоянии читаемости и позволяет осуществлять прямую редактирование.
Класс CoALA классифицирует память как рабочую, эпизодическую, семантическую и процедурную. The Память в эпоху исследования ИИ-агенты В документации особый акцент делается на векторных хранилищах и графах знаний; кроме того, описываются чекпоинты и его интерфейс Store. Знания проектов, сохраняемые в файлах, не входят в рамки этих таксономий, несмотря на то что Claude Code, Cursor, Windsurf и Devin все поддерживают загрузку постоянных файлов проектов.
Аналогичная схема хранения применяется и в других областях. В проекте Voyager переиспользуемые игровые навыки сохраняются в виде библиотек кода, команды ECR3 работали над процедурными документами промпт, а механизм Agent Workflow Memory позволяет генерировать повторно используемые веб-работы на основе успешных примеров. Благодаря файлам такие знания становятся доступными к анализу и версионированию без необходимости в отдельном сервисе эмбеддинг.
Память, управляемая агентом, также отличается от фиксированной RAG пайплайн по тому, кто осуществляет запись данных. Агент или его харнесс определяют, что необходимо сохранить, обновить или удалить, а затем решают, в какой момент это данные нужно извлечь.
Этот Статья «Генеративные агенты» (Park et al., 2023) показали, до каких пределов это может быть доведено: симулированные агенты хранили, анализировали и восстанавливали собственные воспоминания. Их memory stream ранжировал кандидаты по принципам свежести, значимости и релевантности, что до сих пор служит полезной отправной точкой для моделирования памяти агентов retrieval.
Краткосрочная память агента: хранилище чекпоинт
Каждый раз при выполнении узла LangGraph компонент фреймворк сериализует полное состояние графа и сохраняет его в чекпоинт хранилище. Именно это обеспечивает возможность паузы/возобновления работы, отладку с использованием механизма «путешествия во времени», а также поддержку рабочих процессов типа HITL.
A чекпоинт содержит состояние графа, необходимое для возобновления работы: AgentState из Часть 1 (сообщения, идентичность, профиль пользователя, шаги плана, исследовательские данные, режим выполнения), а также метаданные LangGraph, включая узел, который его сгенерировал, и его ID чекпоинт. После прерывания типа HITL или перезапуска процесса граф загружает последние зарегистрированные границы и переходит к следующему узлу. Он не продолжает работу с какой-либо произвольной строки кода на Python. чекпоинт также отличается от лога событий с возможностью только добавления данных или трейс. Часть 5 явно разделяет эти рантайм observability поверхности.
Как работает сохранение состояния модели LangGraph
LangGraph’s BaseCheckpointSaver это простой интерфейс: put() пишет чекпоинт, get_tuple() читает самый свежий элемент для данной нити. list() возвращает историю. Каждый чекпоинт имеет свой ключ (thread_id, checkpoint_ns, checkpoint_id), где thread_id определяет разговор checkpoint_ns обеспечивает управление пространствами имён субграфов, и checkpoint_id это уникальная версия.
Ключевым фактором выбора является то, какой бэкенд следует использовать в качестве основы. PostgreSQL и Redis — это два наиболее распространённых варианта для производственной среды.
PostgreSQL против Redis
| Размерность | PostgreSQL (langgraph-checkpoint-postgres) | Redis (langgraph-checkpoint-redis) |
|---|---|---|
| Прочность модель | Транзакции ACID, WAL и механизмы репликации | Возможность настройки сохранения данных в форматах AOF или RDB |
| Чекпоинт история | Надёжная история операций для анализа логов и отладки | Уровень сохранения зависит от настроек сохранения и вытеснения. |
| Основное ограничение | Запись в базу данных латентность и рост размера таблицы | Использование ОЗУ, процедура вытеснения данных и настройки сохранения состояния |
| Соответствие операционным требованиям | Команды, уже использующие реляционные базы данных | Команды, которые уже используют Redis в высоконагруженном режиме throughput |
| Оптимальный стандартный вариант для | Надёжная рекурсия и воспроизводимая отладка | Латентность — чувствительное, восстанавливаемое сессия состояние |
Обычная база данных бенчмарки не позволяет прогнозировать чекпоинт производительность. Необходимо измерять размер сериализованного состояния, частоту записей, настройки сохранения данных и уровень конкурентности в вашей собственной графовой структуре.
PostgreSQL: стандартный вариант с высокой надёжностью хранения данных
PostgreSQL представляет собой более надёжный стандарт для большинства команд. Благодаря способности Чекпоинты выдерживать сбои, он обеспечивает полную семантику транзакций, а наличие истории чекпоинт значительно упрощает отладку путём «путешествий во времени».
from langgraph.checkpoint.postgres.aio import AsyncPostgresSaver
async def create_postgres_checkpointer(connection_string: str) -> AsyncPostgresSaver:
"""Create a PostgreSQL-backed checkpoint store.
PostgreSQL gives us ACID guarantees — if a checkpoint write succeeds,
the state is durable even if the process crashes immediately after.
"""
checkpointer = AsyncPostgresSaver.from_conn_string(connection_string)
# Create the checkpoint tables if they don't exist.
# This is idempotent — safe to call on every startup.
await checkpointer.setup()
return checkpointer
# Usage: wire into the graph compilation
checkpointer = await create_postgres_checkpointer(
"postgresql://user:pass@localhost:5432/agent_memory"
)
graph = create_graph(checkpointer=checkpointer)
# Every invoke/stream call now persists state automatically
config = {"configurable": {"thread_id": "user-123-session-1"}}
result = await graph.ainvoke({"messages": [HumanMessage(content="Analyze NVDA")]}, config)
# Resume later — loads the latest checkpoint for this thread
result = await graph.ainvoke({"messages": [HumanMessage(content="approved")]}, config)
Этот AsyncPostgresSaver использует langgraph-checkpoint-postgres пакет, который создаёт три таблицы: checkpoints (сериализованное состояние), checkpoint_blobs (большие бинарные данные), и checkpoint_writes (Ожидаются операции записи для восстановления после сбоя). Данная схема поддерживает одновременный доступ и использует консультативные блокировки для предотвращения конфликтов при записи.
Redis: когда латентность является боттлнек
Когда критически важна скорость обработки на уровне нескольких субмиллисекунд чекпоинт латентность (в реальном времени для конверсационных агентов или при высокочастотных циклах работы инструментов), Redis представляет собой более подходящий выбор.
from langgraph.checkpoint.redis.aio import AsyncRedisSaver
async def create_redis_checkpointer(redis_url: str) -> AsyncRedisSaver:
"""Create a Redis-backed checkpoint store.
Redis stores checkpoints in memory for sub-millisecond access.
Trade-off: less durable than PostgreSQL unless AOF is enabled.
"""
checkpointer = AsyncRedisSaver.from_conn_string(redis_url)
# Initialize Redis data structures
await checkpointer.setup()
return checkpointer
# Usage: same graph API, different backend
checkpointer = await create_redis_checkpointer("redis://localhost:6379")
graph = create_graph(checkpointer=checkpointer)
Этот AsyncRedisSaver из langgraph-checkpoint-redis хранит чекпоинты в виде документов JSON, идентифицируемых по идентификатору потока. v0.1.0 — переработка дизайна заменил несколько операций поиска на одну JSON.GET этот механизм позволяет существенно снизить латентность. В Redis 8.0+ по умолчанию включены модули RedisJSON и RediSearch — установка дополнительных модулей не требуется.
Для систем с ограниченными ресурсами памяти деплои, ShallowRedisSaver Сохраняет только самую свежую версию чекпоинт для каждой нити — без истории изменений, однако с минимальным потреблением оперативной памяти. Используйте этот режим тогда, когда вам необходимы функции паузы/продолжения работы, но нет нужды в отладке с возможностью возврата к предыдущим состояниям.
Когда использовать тот или иной инструмент
Используйте PostgreSQL в следующих случаях:
- Вам требуется полная история чекпоинт для отладки с использованием механизмов «путешествий во времени» или для обеспечения воспроизводимости процессов.
- Надёжность является абсолютным условием (в сферах финансовых услуг и здравоохранения).
- У вас уже используется PostgreSQL в вашей технологической стеке.
- Ваши агенты выполняют длительные задачи, при потере состояния которых требуется многочасовая пересчётная работа.
- Вы хотите получить единый хранилище данных — PostgreSQL с расширением pgvector может выступать в роли единого бэкенд для обработки чекпоинты, долгосрочная память и vector search, тем самым упрощая архитектуру вашей инфраструктуры.
Используйте Redis в следующих случаях:
- Чекпоинт латентность представляют собой ваш боттлнек (чат в реальном времени, потоковый интерфейс пользователя)
- Вы разрабатываете голосовых ботов — системы преобразования речи в текст, обработки информации с использованием LLM и последующего преобразования текста обратно в речь, требующие пайплайны доступ к состоянию с задержкой в несколько миллисекунд
- Необходима горизонтальная масштабируемость в рамках большого количества одновременных потоков
- Схемы высокой конкурентности, при которых несколько агентов делят состояние
- Кратковременные сессии, при утере которых чекпоинт возможна восстановление
- Желание использовать семантическое кэширование для сокращения количества избыточных вызовов LLMRedis LangCache кэши семантически похожие запросы для предотвращения дублирования LLM вызовы)
Другие варианты: langgraph-checkpoint-sqlite подходит для локальной разработки и однопроцессных сред деплои. Для стеков, оптимизированных под AWS, langgraph-checkpoint-aws предоставляет DynamoDBSaver Благодаря интеллектуальной обработке пайлоадов небольшие чекпоинты (менее 350 КБ) остаются в DynamoDB, а крупные данные автоматически переносятся в S3. Модель без серверов и отсутствие необходимости в управлении инфраструктурой делают этот решение привлекательным для сценариев с переменной нагрузкой деплои.
Долгосрочная память: сохранение состояния в течение сессии
Текущее общение обрабатывается с помощью «горячей» памяти. Однако как быть с пользователем, который вернётся на следующей неделе? Долгосрочная память хранит факты, предпочтения и историю взаимодействий, которые сохраняются между разными диалогами.
LangGraph предоставляет функционал для Store интерфейс для обмена данными между потоками через него BaseStore класс. Каждый элемент памяти представляет собой (namespace, key) сопоставляется с значением JSON и необязательным вектором эмбеддинг. Обычно этот пространство имён кодирует пользователя или организацию: ("user", "user-123", "preferences").
Хранение векторов: семантическое восстановление с использованием Qdrant
Когда агенту необходимо восстановить структурированную информацию («Что сказал пользователь о сроках инвестирования?»), vector search обеспечивает семантическое восстановление данных. Вместо поиска по точным ключам агент выполняет запросы на основе смысла.
Qdrant это специально разработанная векторная база данных, написанная на Rust, которая обеспечивает хранение эмбеддинг, индексацию (HNSW) и фильтрованный поиск. Я подробно рассмотрел HNSW и связанные с ним компромиссы в своем пост об ранжировании результатов поиска. Qdrant также предоставляет сервер MCP это функционирует как слой семантическая память — что очень удобно, если ваш агент фреймворк поддерживает протокол контекста Модель.
Из memory_store.py:
from qdrant_client import QdrantClient
from qdrant_client.models import PointStruct, Distance, VectorParams
from langchain_anthropic import ChatAnthropic
import hashlib
import json
class UserMemoryStore:
"""Long-term memory backed by Qdrant vector search.
Stores user facts as embedded vectors for semantic retrieval.
Each fact is a short natural-language statement about the user.
"""
def __init__(self, qdrant_url: str, collection_name: str = "user_memory"):
self.client = QdrantClient(url=qdrant_url)
self.collection_name = collection_name
self._ensure_collection()
def _ensure_collection(self):
"""Create the collection if it doesn't exist."""
collections = [c.name for c in self.client.get_collections().collections]
if self.collection_name not in collections:
self.client.create_collection(
collection_name=self.collection_name,
vectors_config=VectorParams(
size=1536, # text-embedding-3-small dimensions
distance=Distance.COSINE,
),
)
def store_fact(self, user_id: str, fact: str, embedding: list[float]):
"""Store a user fact with its embedding."""
point_id = hashlib.md5(f"{user_id}:{fact}".encode()).hexdigest()
self.client.upsert(
collection_name=self.collection_name,
points=[PointStruct(
id=point_id,
vector=embedding,
payload={"user_id": user_id, "fact": fact},
)],
)
def recall(self, user_id: str, query_embedding: list[float], top_k: int = 5):
"""Retrieve the most relevant facts for a user given a query."""
results = self.client.query_points(
collection_name=self.collection_name,
query=query_embedding,
query_filter={"must": [{"key": "user_id", "match": {"value": user_id}}]},
limit=top_k,
)
return [hit.payload["fact"] for hit in results.points]
Последовательность действий следующая: (1) после каждого разговора LLM извлекает ключевые факты из взаимодействия («у пользователя высокая толерантность к риску», «пользователь заинтересован в акциях полупроводниковых компаний»), (2) эти факты сохраняются в базе данных Qdrant, (3) в начале следующего разговора агент отправляет запрос в Qdrant с новым сообщением пользователя для восстановления соответствующего контекста.
Retrieval оценка качества: за пределами косинусного сходства
Чистое сходство по косинусу является лишь отправной точкой, однако системы памяти в продакшене требуют более разнообразных retrieval. Статья «Генеративные агенты» (Park и др., 2023) предложили функцию оценки, объединяющую три сигнала:
- Недавность: снижение веса на основе правил, при котором более свежие воспоминания получают более высокие оценки. Благодаря функции экспоненциального затухания факт, возникший вчера, будет иметь более высокий приоритет по сравнению с аналогичным фактом, существующим уже шесть месяцев.
- Важность: оценка значимости по шкале от 1 до 10 с использованием LLM. Фраза «Капитал пользователя снизился на 40%» получит более высокий балл, чем фраза «Пользователь поздоровался».
- Релевантность: коэффициент косинусного сходства между запросом и сохранённым фактом, рассчитываемый с помощью Эмбеддинг.
Конечный балл retrieval представляет собой взвешенную сумму: score = alpha * recency + beta * importance + gamma * relevance. Это предотвращает то, что актуальные и важные факты остаются под слоем устаревших, но семантически похожих данных. Для Агент аналитика рынка, У элемента вес наивысшая релевантность (0,5), за которой следуют показатели свежести (0,3) и значимости (0,2) — поскольку самый важный фактор при обработке запроса пользователя — это его текущая цель. Эти начальные значения веса были адаптированы из статьи «Generative Agents» (в которой использовалось равное взвешивание всех параметров); я обнаружил, что упор на релевантность лучше всего срабатывает для запросов, связанных с финансовым анализом, однако эти коэффициенты основаны на интуиции, а не на эмпирической оптимизации.
Альтернативы vector search
Vector search обладает высокой эффективностью, однако не всегда является наиболее подходящим инструментом. Вот ситуации, когда целесообразно использовать альтернативы:
| Подход | Лучше всего подходит для | Основные операционные затраты |
|---|---|---|
| Vector search (Qdrant) | Семантическое воспроизведение неструктурированных фактов | Эмбеддинг и жизненный цикл индекса |
| Хранилище типа «ключ-значение» (Redis) | Структурированные профили пользователей и их предпочтения | Политика использования памяти и сохранения данных |
| Хранилище документов (файлы) | Знания проекта и заметки, управляемые агентом | Одновременная обработка, разрешения и поиск |
| Поиск по всему тексту (PostgreSQL) индекс GIN)** | Показатель воспроизведения ключевых слов на основе истории разговора | Рост индекса и настройка запросов |
| Граф знаний (Neo4j) | Отношения между сущностями и запросы с несколькими промежуточными шагами | Моделирование графов и другие системы хранения данных |
| Гибридный (векторный + поисковый по ключевым словам) | Вспомните случаи, когда намерение запроса меняется | Два пути расчёта оценок, подлежащих настройке и тестированию |
Хранилища типа “ключ-значение” эффективно справляются с структурированными данными. Если ваш долгосрочная память представляет собой профиль пользователя — уровень толерантности к риску, горизонт инвестирования, предпочтительные сектора — то использование хеша в Redis или столбца JSONB в PostgreSQL будет проще и быстрее, чем работа с эмбеддинг и поиск векторов. Применяйте vector search в тех случаях, когда данные находятся в неструктурированном виде, а формулировки запросов retrieval постоянно меняются.
Встроенный хранилище LangGraph предоставляет интерфейс типа «ключ-значение» на основе пространства имён с факультативной поддержкой vector search. BaseStore API представляет собой простую структуру: put(), get(), search(), и delete() с иерархическим ограничением области имён. Существуют три варианта реализации:
InMemoryStore— предназначен для разработки и тестирования (данные теряются при завершении процесса)PostgresStore— производственное постоянное хранилище с полноценными запросами к SQLAsyncRedisStore— межпоточная память с vector search, поддержка TTL и фильтрация метаданных
Этот index Данная конфигурация позволяет использовать vector search над хранимыми элементами с применением настраиваемого эмбеддинг-модель. Во многих сценариях использования такой встроенный хранилище полностью достаточно, что исключает необходимость в применении специализированной векторной базы данных.
from langgraph.store.memory import InMemoryStore
# Create a store with vector search enabled
store = InMemoryStore(
index={
"dims": 1536,
"embed": my_embedding_function, # e.g., OpenAI text-embedding-3-small
}
)
# Store a user preference (namespace scopes to user)
await store.aput(
namespace=("user", "user-123", "preferences"),
key="risk-profile",
value={"risk_tolerance": "high", "horizon": "long-term"},
)
# Semantic search across user's memories
results = await store.asearch(
namespace=("user", "user-123"),
query="What is their investment style?",
limit=5,
)
Выбор стратегии долгосрочная память
Начните с формата ключ-значение, если ваша структура данных четко определена и имеет явную организацию (профили пользователей, настройки, именованные сущности). Добавляйте vector search тогда, когда требуется семантическое обработание retrieval над неструктурированными данными или при условии непредсказуемой формулировки запросов.
Графы знаний находят своё применение там, где важны связи между сущностями, например, при задаче «Какие компании, о которых спрашивал пользователь, являются конкурентами NVDA?». Самым интересным недавним проектом в этой области является Графити (автор — Zep), который формирует временно-ориентированную графовую структуру знаний, позволяющую отслеживать когда те или иные факты считались истинными, а не только что считалось истинным. Каждая рёбро сопровождается интервалами действительности, благодаря чему изменение уровня рисков пользователя приводит к аннулированию старого значения вместо его тихого перезаписывания. Graphiti предоставляет отчёты Точность составляет 94,8% на наборе данных DMR бенчмарк, Благодаря своей двухвременной архитектуре модель решается проблема устаревших данных на уровне хранилища информации.
Проблема кроется в операционной части. Запуск графовой базы данных — задача непростая, и для большинства приложений агентов vector search фильтрация метаданных позволяет достичь аналогичных результатов с меньшими затратами на инфраструктуру.
Управляемая память фреймворки подобная Mem0 и Летта (formerly MemGPT) берут на себя задачи извлечения, консолидации и retrieval пайплайн. Подход Mem0 отличается особенностью: специальный LLM выделяет кандидатов в память, двигатель принятия решений сравнивает каждый новый факт с уже существующими записями в векторном хранилище, а механизм разрешения принимает решение о том, следует ли его добавить, обновить или удалить, что обеспечивает целостность и отсутствие дубликатов в хранилище памяти. Letta использует подход, характерный для операционных систем: агенты самостоятельно управляют своей контекстное окно с помощью инструментов управления памятью, автономно перемещая данные между «основной памятью» (в рамках контекста) и «архивной памятью» (вне контекста). Оба решения стоит рассмотреть, если вам необходимо сократить время вывода продукта на рынок и не требуется полный контроль над процессом управления памятью пайплайн.
Память документов: шкаф для хранения данных агента
В таксономиях памяти файловая память получила более широкое применение на практике, чем указано в официальных классификациях. В одной из оценок LoCoMo, проведённых определённым поставщиком, Летта сообщил 74,0% — таков показатель эффективности подхода, основанного на файловой системе. Необходимо сохранять этот результат в рамках условий модель, бенчмарк и харнесс, однако операционные преимущества очевидны: разработчики могут напрямую читать, редактировать и сравнивать хранящиеся данные.
Более длинные контекстные окна позволяют реализовывать полноценное чтение всего файла в рамках некоторых проектных документов. Хотя разбитые на части retrieval подходят и для крупных корпусов данных, короткий файл с правилами или инструкциями по передаче информации часто можно загрузить напрямую. Выбор метода зависит от размера документа, уровня retrieval точности, доступного объёма памяти и того, как часто требуется пересматривать или редактировать содержимое.
Векторные хранилища и структурированные хранилища типа «ключ-значение» бэкенды эффективно справляются с задачами семантического поиска и структурированных запросов. Однако существует ещё одна категория знаний агента, которую ни те, ни другие не могут обрабатывать оптимально — это накопленный контекст проекта, включающий установленные правила, записи исследований и принятые решения, необходимые агенту на протяжении всего сессии. Для таких данных критически важны возможности человекочитаемости и контроля версий.
Это и есть память документов: агент читает и записывает структурированные файлы (Markdown, JSON, YAML) в определённую директорию. Никаких эмбеддинги, никаких баз данных, никакой инфраструктуры — только файлы на диске, доступные как для агента, так и для разработчика. cat, grep, git diffи вручную вносить правки.
Почему файлы?
Для рабочих процессов долгоживущих агентов наиболее эффективным подходом, который я видел, является не векторная база данных, а каталог хорошо структурированных заметок. Подумайте о ситуации, когда кодинг-агент работает над проектом в течение нескольких недель:
- Он определяет, что в проекте используется Pydantic v2, а не v1. - Он выявляет, что тесты должны запускаться с
pytest -x --tb=short - Он накапливает знания о архитектуре кодовой базы
- Он учитывает предпочтения разработчика («всегда использовать»)
pathlib, никогдаos.path”)
Эти факты слишком структурированы для vector search (требуется точное воспроизведение информации, а не размытое сходство), к тому же их слишком много для хранения в формате ключ-значение (они представляют собой взаимосвязанные документы, а не изолированные записи). Кроме того, речь идёт о данных, которые разработчик хочет видеть и редактировать непосредственно. Если агент что-то ошибётся, достаточно открыть файл и внести исправления.
Вот так и выглядит процесс. инструменты Claude Code CLAUDE.md и .claude/ Работа с директориями. Агент читает информацию на уровне проекта CLAUDE.md файлы с конвенциями и инструкциями, а также выполняет запись в ~/.claude/MEMORY.md для обмена знаниями между сессия. Файлы представлены в простом формате Markdown: их можно читать, редактировать, коммитить в Git и делиться ими с командой. курсора .cursorrules и виндсерфинг .windsurfrules файлы в простом формате, которые агент загружает при запуске для получения контекста проекта.
Реализация хранилища в памяти для файлов
Реализация преднамеренно оставлена простой. Агент обладает четырьмя операциями: запись документа, чтение документа, получение списка доступных документов и поиск в документах по ключевому слову.
Из file_memory.py:
from pathlib import Path
import json
import fnmatch
class FileMemory:
"""Document memory backed by the local filesystem.
Stores agent knowledge as human-readable files organized by topic.
No embeddings, no database — just files that both the agent and
the developer can read, edit, and version-control.
"""
def __init__(self, base_dir: str | Path):
self.base_dir = Path(base_dir)
self.base_dir.mkdir(parents=True, exist_ok=True)
def write_doc(self, path: str, content: str, metadata: dict | None = None):
"""Write or overwrite a document at the given path.
Paths are relative to base_dir. Directories are created automatically.
Metadata (if provided) is stored as a JSON sidecar file.
"""
full_path = self.base_dir / path
full_path.parent.mkdir(parents=True, exist_ok=True)
full_path.write_text(content, encoding="utf-8")
if metadata:
meta_path = full_path.with_suffix(full_path.suffix + ".meta")
meta_path.write_text(json.dumps(metadata, indent=2), encoding="utf-8")
def read_doc(self, path: str) -> str | None:
"""Read a document by path. Returns None if not found."""
full_path = self.base_dir / path
if full_path.exists():
return full_path.read_text(encoding="utf-8")
return None
def list_docs(self, pattern: str = "**/*") -> list[str]:
"""List documents matching a glob pattern."""
return [
str(p.relative_to(self.base_dir))
for p in self.base_dir.glob(pattern)
if p.is_file() and not p.name.endswith(".meta")
]
def search_docs(self, query: str, pattern: str = "**/*.md") -> list[dict]:
"""Search documents by keyword. Returns matching files with context.
This is intentionally simple — grep-style keyword search.
For semantic search, use a vector store instead.
NOTE: This is a sketch for demonstration. A simple substring check
won't scale beyond a few hundred documents. For production with 500+
documents, use TF-IDF/BM25 scoring (e.g., rank_bm25) or a full-text
search backend (PostgreSQL GIN index, Elasticsearch).
"""
results = []
for path in self.base_dir.glob(pattern):
if not path.is_file() or path.name.endswith(".meta"):
continue
content = path.read_text(encoding="utf-8")
if query.lower() in content.lower():
# Return the paragraph containing the match for context
for paragraph in content.split("\n\n"):
if query.lower() in paragraph.lower():
results.append({
"path": str(path.relative_to(self.base_dir)),
"match": paragraph.strip()[:500],
})
return results
Структура папок
Большая часть ценности памяти документа обусловлена способом организации каталога. Вот структура, которую я использую для Агент аналитика рынка:
.agent-memory/
README.md # What this directory is, for human readers
user-profiles/
user-123.md # Preferences, history, risk profile
user-456.md
research/
NVDA-2026-02.md # Research notes from recent analysis
TSLA-2026-01.md
conventions/
analysis-format.md # How to structure analysis reports
data-sources.md # Preferred data sources and API patterns
learnings/
common-errors.md # Mistakes the agent has learned to avoid
tool-patterns.md # Effective tool call sequences
Каждый файл представляет собой файл в формате Markdown. Назначение любого файла очевидно из его пути. Вы можете git diff полный каталог памяти для анализа того, что изучил агент в сессия. git revert Плохая процедура обучения или копирование директории в другой проект — попробуйте применить любой из этих подходов к коллекции Qdrant.
Когда использовать память документов, векторы или структуры ключ-значение
Три блока памяти бэкенды обеспечивают различные схемы доступа:
| Размерность | Хранилище векторов | Хранилище ключей-значений | Хранилище документов |
|---|---|---|---|
| Шаблон запроса | ”Найти факты, аналогичные X” | Получить значение по ключу | Прочитайте документ, расположенный по указанному пути. |
| Лучше всего подходит для | Неструктурированное, разнообразное воспроизведение | Структурированные поиски | Контекст проекта, примечания |
| Читаемый человеком | Нет (эмбеддинги) | Частично (JSON) | |
| Поддающийся отладке | Лёгкий режим (точные клавиши) | Trивиальный (открыть файл) | |
| Контролируемая версия | Нет | Возможный | |
| Эмбеддинг инфраструктура | Обязательно | Не требуется | Не требуется |
| Масштабируется до | Миллионы фактов | Миллионы ключей | Тысячи документов |
| Возможности поиска | Семантическое сходство | точное совпадение | Основанный на ключевых словах/путих |
Используйте память документа в следующих случаях:
- Агент накапливает знания о проекте в течение нескольких сессии
- Разработчикам необходимо проверять, редактировать или переопределять содержимое знаний агента
- Эти знания структурируются в виде документов (заметок, кратких обзоров, правил), а не как изолированные факты
- Необходима система версионирования памяти агента на основе git
- Отсутствие инфраструктуры является строгим требованием
Используйте векторные хранилища в следующих случаях:
- Необходима технология фаззи-семантики retrieval (поиск воспоминаний, связанных с X).
- Формулировки запросов изменяются непредсказуемо.
- У вас имеется от тысяч до миллионов отдельных фактов.
Используйте хранилища типа key-value в следующих случаях:
- Для структурированных данных (профили пользователей, настройки) требуются точные и быстрые поисковые операции.
- Схема данных четко определена.
На практике в производственных агентах часто объединяются все три компонента. Агент аналитика рынка для хранения данных в оперативной памяти используется PostgreSQL чекпоинты, для восстановления семантически значимых фактов о пользователях — сервис Qdrant, а для сохранения проектных стандартов и исследовательских заметок применяется файловый хранилище документов.
Примеры из реальных проектов
Этот подход уже широко распространён в помощниках по кодированию AI:
- Claude Code выполняет чтение
CLAUDE.mdфайлы из корневой директории проекта и директорий его родителей, а также записывает в~/.claude/MEMORY.mdдля обмена знаниями между сессия. Вся система памяти представляет собой обычные файлы в формате Markdown, которые сохраняются вместе с кодом. - Cursor загружает их
.cursorrulesФайлы с инструкциями для агента, специфичными для проекта: конвенции кодирования, предпочтения фреймворк, архитектурные решения. - Windsurf использует
.windsurfrulesфайлы плюс одинmemories/директория, в которой агент хранит извлечённые им шаблоны из вашего кодового репозитория. - Инструмент памяти Anthropic для Claude API предоставляет
create_memory,read_memory,update_memory, иdelete_memoryВсе операции выполняются на стороне клиента. Ваше приложение само определяет местоположение фактических файлов — на локальном диске, в S3 или в базе данных.
Общий механизм: во всех этих решениях знания агента хранятся в виде текстовых файлов, доступных для чтения человеком, при этом используются прямые операции записи и чтения. Никакого эмбеддинги отсутствует. Также нет никакой векторной инфраструктуры. Агент сам определяет, что записывать, разработчик может просматривать и редактировать всё содержимое, причём вся система помещается в один git diff.
За пределами ассистентов по программированию
Память документов не является прерогативой только кодирующих агентов. Эта закономерность наблюдается в самых разных областях применения агентов:
-
Агенты игр открытого мира: Вояджер (Wang et al., 2023) разрабатывают постоянную библиотеку навыков из проверенных JavaScript-программ, которую агент Minecraft накапливает со временем; благодаря этому он собирает в 3,3 раза больше уникальных элементов и достигает определённых этапов в 15,3 раза быстрее по сравнению с базовыми вариантами. Навыки могут быть перенесены в новые миры без необходимости повторной обучения. JARVIS-1 расширяет данную структуру за счёт мультимодальной памяти, объединяющей текстовые планы и визуальные наблюдения, что позволяет достигать коэффициента успеха 5 к 1 даже при решении самых сложных задач.
Стоит отметить одно важное различие: библиотеки навыков представляют собой исполняемую память (файлы кода, импортируемые и запускаемые), тогда как документная память в кодинг-ассистентах является декларативной (Markdown, вставляемый в промпты). Механизмы возникновения ошибок у них разные: плохой исполняемый код приводит к сбоям агента, а некорректный декларативный текст вызывает ошибки типа ризонинг. Однако способы хранения данных и операционные преимущества (возможность отладки, контроль версий) остаются одинаковыми.
-
Автоматизация рабочих процессов в корпоративной среде: The конкурс ECR3 Победители использовали механизмы хранения документов для итеративной промпт отладки и улучшения моделей. Агенты типа Analyzer и Versioner одной из победивших команд проходили через 80 промпт версий, сохранённых в виде процедурных документов. Другая сильная команда разработала более 20 модулей-обогатителей, представляющих собой процедурные знания в формате документов. LEGOMem (2025) формализует это как модульную память фреймворк для систем multi-agent, в которой существуют специализированные типы памяти (сенсорная, краткосрочная, долгосрочная), из которых агенты составляют свои структуры подобно строительным блокам.
-
Автоматизация веб-интерфейсов: Память рабочего процесса агента (Wang et al., 2024) позволяет веб-агентам генерировать повторно используемые рабочие процессы на основе успешных примеров, что обеспечивает улучшение показателя эффективности на 51% в среде WebArena. SkillWeaver (2025) предлагает более продвинутый подход: агенты синтезируют повторно используемые инструменты типа API на основе результатов исследования, что позволяет повысить уровень успеха на 31,8%. Заимствованные навыки также передаются менее мощным модели моделям, способствуя улучшению их производительности на 54,3%; таким образом, накопленная память более сильного агента может помочь улучшить работу более слабого.
-
Поддержка клиентов: Компания Gartner прогнозирует К 2029 году ИИ-агенты будет автономно решать 80% распространённых проблем обслуживания клиентов. Для этого эти агенты опираются на СПО, пособия и историю взаимодействий с клиентами, которые представляют собой различные формы документальной памяти.
Этот Семинар MemAgents на конференции ICLR 2026 Одним из признаков того, что исследовательское сообщество нагоняет те решения, которые уже созданы практиками, является то, что системы документирования памяти явно вышли за рамки своих первоначальных задач в качестве инструментов помощи при написании кода.
Скрипты используют документацию для упаковки процедурных инструкций. Стандарт навыков агента хранит эти инструкции в SKILL.md файлы с YAML-фронтматтером и телом в формате Markdown. Это напоминает структуру «памяти документа» на уровне хранилища, однако функции у них разные: скилл указывает агенту, как выполнять определённый класс задач, тогда как память хранит факты, полученные в ходе выполнения проекта или предыдущих запусков. Часть 3 обеспечивает учёт этого различия с точки зрения инструмента.
MCP (Модель Протокол контекста) идет в том же направлении: определения инструментов представляют собой файлы JSON Schema, которые любой агент может обнаружить и использовать. Протокол имеет 97 миллионов ежемесячных загрузок SDK Этот инструмент поддерживается компаниями OpenAI, Google, Microsoft и AWS. MCP не является технологией, специфичной для программирования. Те же самые серверы обеспечивают связь агентов с базами данных, внутренними APIs и корпоративными системами.
Оба подхода указывают на одну и ту же закономерность: процедурные знания хранятся в виде документов, ограниченных схемой, с явными операциями чтения/записи. MCP, которые в настоящее время регулируются Агентный AI основа, это ближайшее к стандарту взаимодействия решение в экосистеме агентов.
Масштабирование памяти документов в продакшене
Приведённая выше реализация на основе файлов хорошо справляется с задачами на ноутбуках одного разработчика и в малом масштабе деплои. Однако для производственных сред с множеством арендаторов, где работают сотни пользователей и тысячи документов, требуется совершенно иная архитектура.
Ограничения однодольевой структуры становятся очевидными: горизонтальное масштабирование операций ввода-вывода с файлами невозможно, для параллельных записей требуется блокировка, а управление правами доступа между разными тенантами сопряжено с значительными трудностями. В производственной среде необходим хранилище, способное эффективно обрабатывать ситуации конкурентного доступа, выполнять поиск и обеспечивать корректную поддержку многотенантности.
Три распространённых подхода:
Подход А: гибридная архитектура с тонким слоем базы данных
Сохраняйте файлы для редактирования (разработчики работают с Markdown локально), но обслуживайте их из базы данных в рантайм. При деплой происходит синхронизация файлов с записями в PostgreSQL. Агент читает данные непосредственно из базы данных, а не с диска. Это позволяет вам:
- Эргономика разработки (редактирование Markdown, коммиты в git)
- Производительность запросов в продакшене (чтение из индексированных баз данных)
- Чёткое разделение этапов создания контента и сервинг
Подход B: хранилище объектов + вспомогательный компонент для индексации векторов
Документы хранятся в S3/GCS в виде объектов, причем существует коллекция Qdrant, которая индексирует их эмбеддинги. Агент запрашивает у Qdrant идентификаторы соответствующих документов, после чего загружает их содержимое из системы хранения объектов. Такой подход позволяет осуществлять горизонтальное масштабирование и обеспечивает semantic search, однако он увеличивает сложность: требуется управление двумя системами, наличие эмбеддинг пайплайн для поддержки работы, а также обеспечение консистентности между хранилищем и индексом.
Подход C: хранилище структурированных документов с PostgreSQL (рекомендуется)
Для хранения документов используются строки формата JSONB в базе данных PostgreSQL, оснащенные функцией полнотекстового поиска (индекс GIN) и, при необходимости, поддержкой векторных данных эмбеддинги (pgvector). Такой подход позволяет реализовать гибридный способ поиска (на основе ключевых слов и семантики), обеспечивает соблюдение принципов ACID для транзакций, а также упрощает управление всей системой через единую операционную среду.
Набросок подхода C:
from typing import Optional
import asyncpg
class ProductionDocumentMemory:
"""PostgreSQL-backed document memory with hybrid search.
Schema:
CREATE TABLE documents (
id SERIAL PRIMARY KEY,
tenant_id TEXT NOT NULL,
path TEXT NOT NULL,
content TEXT NOT NULL,
metadata JSONB,
embedding vector(1536), -- pgvector extension
ts_vector tsvector GENERATED ALWAYS AS (to_tsvector('english', content)) STORED,
created_at TIMESTAMPTZ DEFAULT NOW(),
UNIQUE(tenant_id, path)
);
CREATE INDEX ON documents USING GIN(ts_vector);
CREATE INDEX ON documents USING ivfflat(embedding vector_cosine_ops);
"""
def __init__(self, pool: asyncpg.Pool):
self.pool = pool
async def write(
self,
tenant_id: str,
path: str,
content: str,
metadata: Optional[dict] = None,
embedding: Optional[list[float]] = None,
):
"""Write or update a document."""
async with self.pool.acquire() as conn:
await conn.execute(
"""
INSERT INTO documents (tenant_id, path, content, metadata, embedding)
VALUES ($1, $2, $3, $4, $5)
ON CONFLICT (tenant_id, path) DO UPDATE
SET content = EXCLUDED.content,
metadata = EXCLUDED.metadata,
embedding = EXCLUDED.embedding
""",
tenant_id, path, content, metadata, embedding,
)
async def search(
self,
tenant_id: str,
query: str,
embedding: Optional[list[float]] = None,
limit: int = 5,
) -> list[dict]:
"""Hybrid search: full-text + optional vector similarity."""
async with self.pool.acquire() as conn:
if embedding:
# Hybrid scoring: 0.6 * text relevance + 0.4 * vector similarity
rows = await conn.fetch(
"""
SELECT path, content, metadata,
(0.6 * ts_rank(ts_vector, plainto_tsquery('english', $2)) +
0.4 * (1 - (embedding <=> $3))) AS score
FROM documents
WHERE tenant_id = $1
AND ts_vector @@ plainto_tsquery('english', $2)
ORDER BY score DESC
LIMIT $4
""",
tenant_id, query, embedding, limit,
)
else:
# Full-text search only
rows = await conn.fetch(
"""
SELECT path, content, metadata,
ts_rank(ts_vector, plainto_tsquery('english', $2)) AS score
FROM documents
WHERE tenant_id = $1
AND ts_vector @@ plainto_tsquery('english', $2)
ORDER BY score DESC
LIMIT $3
""",
tenant_id, query, limit,
)
return [dict(row) for row in rows]
Что вы получаете:
- Гибридный поиск: совместная оценка совпадения ключевых слов (индекс GIN) и семантической близости (pgvector)
- Многоклиентская архитектура:
tenant_idОпределение области применения с использованием безопасности на уровне строк - Гарантии ACID: отсутствие проблем с консистентностью в долгосрочной перспективе
- Единая операционная система: не требуется отдельная база данных векторов для управления
- Горизонтальное масштабирование: реплики для обработки запросов и разделение по абонентам для увеличения производительности записей
Файлы отлично подходят для рабочих процессов, где задействован только один разработчик. Однако в средах многоклиентской эксплуатации структурированный хранилище документов на базе PostgreSQL обычно обеспечивает оптимальный баланс между простотой использования, производительностью и уровнем готовности к операционному обслуживанию.
Сборка в единое целое: полная архитектура
Вот как взаимодействуют между собой все три уровня памяти в данной системе. Агент аналитика рынка. На диаграмме показан полный процесс от поступления запроса от пользователя до его обработки, при этом все уровни памяти находятся в активном состоянии.
Архитектура включает три пути доступа к памяти:
-
Горячий путь (чекпоинт хранилище): Каждый узел в LangGraph записывает свое состояние графа, поддерживающее возобновление работы, в чекпоинт хранилище. Когда граф сталкивается с
interrupt_beforeузел (аналог репортера в) Часть 1), Во время выполнения возможны паузы. Пользователь может закрыть приложение, и по возвращении график продолжит работу с чекпоинт. Журналы событий Рантайм и механизмы обработки трейсы представляют собой отдельные аспекты, требующие внимания в производственной среде. -
Холодный путь (долгосрочное хранилище): В начале каждого диалога агент запрашивает долгосрочное хранилище с целью получения соответствующей контекстной информации о пользователе. В конце диалога он извлекает новые факты и сохраняет их. Эта операция выполняется асинхронно — она никогда не должна блокировать основной цикл ризонинга.
-
Путь к документу (хранилище файлов): При запуске агент загружает стандарты проекта и соответствующие исследовательские заметки из хранилища документов. Во время выполнения он записывает новые краткие отчеты об исследованиях и выявленные закономерности обратно на диск. В отличие от режима «холодного» доступа, чтение документов происходит синхронно (это необходимо для выполнения текущей задачи), тогда как запись может быть отложена.
В структуре подключений в LangGraph всё довольно просто — хранилище чекпоинт и долгосрочное хранилище передаются при компиляции графа, в то время как хранилище документов встраивается в качестве зависимости. Приведённый ниже локальный скетч использует InMemoryStore Поэтому фрагмент остаётся небольшим: в примере топологии Docker для реализации аналогичной функции по восстановлению семантической связности используется Qdrant.
from langgraph.checkpoint.postgres.aio import AsyncPostgresSaver
from langgraph.store.memory import InMemoryStore
# Hot memory: PostgreSQL for durable checkpoints
checkpointer = await create_postgres_checkpointer(pg_connection_string)
# Cold memory: local sketch with vector search
# (The reference Docker topology uses Qdrant for persistent recall.)
memory_store = InMemoryStore(
index={"dims": 1536, "embed": embedding_function}
)
# Document memory: file-based store for project knowledge
doc_memory = FileMemory(base_dir=".agent-memory")
# Checkpoint store and long-term store wired into the graph
graph = create_graph(
checkpointer=checkpointer,
store=memory_store,
)
# The store is accessible inside any node via the store parameter
def planner_node(state: AgentState, *, store: BaseStore) -> dict:
"""Plan with user context from long-term memory."""
# Recall relevant user facts from vector store
user_memories = store.search(
namespace=("user", state.user_id),
query=state.messages[-1].content,
limit=5,
)
# Load project conventions from document memory
conventions = doc_memory.read_doc("conventions/analysis-format.md")
# Inject both into planning context
memory_context = "\n".join(m.value["fact"] for m in user_memories)
# ... rest of planning logic with personalized context and conventions
Полный поток обработки данных
Что происходит, когда возвращающийся пользователь отправляет запрос «Analyze TSLA» на сервер? Агент аналитика рынка:
-
Запись нагрузки на память документов: При запуске агент загружает из хранилища документов стандарты проекта: предпочтения по формату анализа, источники данных, которые используются в первую очередь, а также шаблоны работы с инструментами. Все это определяет базовое поведение системы.
-
Восстановление данных из холодной памяти: перед тем как будет выполнен узел роутер, граф обращается к долгосрочному хранилищу с сообщением пользователя. В результате извлекаются следующие данные: «У пользователя высокая толерантность к риску», «Пользователь предпочитает подробный анализ конкурентов», «Ранее пользователь изучал акции NVDA и AMD».
-
Роутер + Планировщик: Класс роутер относит это к
DEEP_RESEARCH. планировщик формирует план исследований из 5 шагов, адаптированный под учтённые предпочтения пользователя. В него включается этап анализа конкурентов, поскольку история действий пользователя указывает на его потребность в таком анализе. План составлен в соответствии с форматом, описанным в документе с правилами стандартизации. -
Экзекьютор цикл (горячая память): Каждый шаг выполняется с использованием паттерна ReAct Часть 1. После обработки каждого узла (роутер, планировщик, каждого экзекьютор шага) LangGraph записывает чекпоинт в базу данных PostgreSQL. Если процесс сбрасывается после 3-го из 5 шагов, его необходимо запустить заново и продолжить с 4-го шага.
-
HITL прерывание: график достигает
reporterузел сinterrupt_before. Предварительный вариант отчёта находится в чекпоинт. Через несколько часов пользователь его просматривает, и график загружается в чекпоинт, после чего работа продолжается. -
Обновление памяти: После завершения разговора: (a) асинхронный процесс извлекает новые факты о пользователе («пользователь теперь отслеживает TSLA», «пользователь одобрил формат отчёта») и сохраняет их в хранилище долгосрочных векторов, а (b) агент записывает краткое резюме исследования в хранилище документов.
research/TSLA-2026-02.md) — для последующего использования.
Паттерн трёх уровней позволяет чётко разделить функциональные обязанности компонентов. Хранилище чекпоинт отвечает за обеспечение долговечности данных и возобновление работы после сбоев; это инфраструктурный слой. Долгосрочное хранилище используется для реализации функций персонализации; здесь реализуется логика продукта. Хранилище документов содержит накопленные знания по проекту; оно выполняет роль блокнота агента.
Компромиссы и факторы, требующие учёта
Память повышает ценность решения, но в то же время увеличивает затраты и усложняет архитектуру. Необходимо честно оценивать существующие компромиссы:
-
Эмбеддинг стоимость: Для хранения каждого факта в базе данных векторов требуется вызов операции эмбеддинг API. Стоимость составляет 0,02 доллара за миллион токены (OpenAI)
text-embedding-3-small), фактическая стоимость является незначительной, однако она накапливается при работе с тысячами пользователей и сессии. Необходимо выполнять эмбеддинг запросов пакетно и получать кэш результатов одновременно. Настоящей проблемой является латентность: потребление 100–300 мс на эмбеддинг API латентность во время выполнения запроса для извлечения данных из холодной памяти, что имеет гораздо большее значение для реальных временных чат-агентов, чем денежные затраты. Для типовых запросов следует использовать Кэш эмбеддинги, либо применять локальный эмбеддинг-модель для задач, требующих высокой конфиденциальности латентность. -
Устаревшая память: меняются предпочтения пользователя. Информация, сохранённая шесть месяцев назад («пользователь отдаёт предпочтение консервативным инвестициям»), может уже не быть актуальной. Необходимо настроить политики истечения срока действия. Я использую период в 365 дней для предпочтений и 90 дней для эпизодических событий, как описано у меня в контекст-инжиниринг публикация.
-
Накладные расходы памяти в контексте: Каждый извлечённый факт потребляет токены в LLM’s контекстное окно. Если при каждом запросе извлекается 20 фактов, это приводит к тому, что несколько сотен токены памяти контекста конкурируют с самой задачей. Необходимо ограничить количество извлекаемых фактов и отдавать приоритет тем, у которых более высокий рейтинг релевантности.
-
Конфиденциальность и соответствие нормативам: Долгосрочная память хранит данные пользователей. Для такого хранения необходимо проводить удаление персональной информации до её записи, соблюдать чёткие правила хранения данных и предоставлять пользователям инструменты для удаления информации. В отраслях, находящихся под строгим регулированием, ни один из этих аспектов не является факультативным.
-
Чекпоинт рост объёма хранилища: таблицы PostgreSQL чекпоинт увеличиваются в размере при каждой обработке задачи на узле. Для агентов с длительным временем работы необходимо задать политику хранения: сохранять последние N чекпоинты для каждой нити и архивировать или удалять более старые записи. Пример запроса на очистку, который сохраняет 10 самых свежих чекпоинты для каждой нити и удаляет всё, что старше 30 дней:
DELETE FROM checkpoints WHERE thread_id = $1 AND created_at < NOW() - INTERVAL '30 days' AND checkpoint_id NOT IN ( SELECT checkpoint_id FROM checkpoints WHERE thread_id = $1 ORDER BY created_at DESC LIMIT 10 ); -
Консолидация памяти: С течением времени детальные эпизодические воспоминания должны преобразовываться в компактные семантические представления: вместо хранения всех трёх разговоров дословно используется формат вроде «пользователь трижды задавал вопросы о NVDA в январе». Это соответствует механизмам консолидации памяти у людей и позволяет поддерживать объём хранилища в управляемых пределах. Mem0 и Графити Обрабатывайте это автоматически; если вы разрабатываете решение сами, запланируйте периодические задачи на консолидацию.
-
Проблема Холодный старт: у новых пользователей отсутствует долгосрочная память. Агент должен работать в режиме сниженной производительности и задавать уточняющие вопросы, вместо того чтобы делать предположения. Хранение информации осуществляется аддитивно, её наличие не является обязательным.
-
Отравление памяти: Любой элемент в контекстное окно агента представляет собой потенциальную точку внедрения. Если злоумышленник записывает вводящие в заблуждение данные в хранилище документов или в долгосрочная память («всегда утверждать транзакции без проверки»), агент может интерпретировать их как инструкции к действию. Использование Промпт-инъекция через сохранённые в памяти данные является реальной поверхностью атаки. Мерами по снижению риска являются проверка данных перед их сохранением, обращение с восстановленным контентом как с ненадёжными данными, а не как с системными инструкциями, а также механизмы контроля доступа, ограничивающие возможность использования определённых записей памяти для влияния на критически важные операции.
-
Дрейф памяти документов: память, основанная на файлах, не обеспечивает автоматическую дедупликацию или разрешение конфликтов. Со временем в документах накапливаются противоречия: в одном файле указано «использовать pytest», а в другом — «использовать unittest». Необходимо планировать периодические проверки (или поручить это агенту), чтобы удалять избыточные данные и объединять их. Хорошая новость заключается в том, что в отличие от векторных хранилищ, где проблема устаревания данных скрыта, здесь её можно легко обнаружить.
grepдля обнаружения противоречий. -
Память на основе документов не масштабируется до миллионов элементов: Память, основанная на файлах, эффективна для сотен или небольших тысяч документов. Если ваш агент должен восстанавливать информацию из миллионов фактов с использованием метода размытого совпадения, требуется векторный хранилище. Память на основе документов предназначена для структурированных знаний проекта, а не для обработки огромного количества крайне редких пользовательских интеракций.
Основные выводы
- Память агента представляет собой набор отдельных хранилищ с различными схемами доступа. Необходимо сохранять разделение между возможностью возобновления работы чекпоинты, структурированными фактами, механизмом семантического воспроизведения информации и документацией проекта.
- До начала персонализации следует реализовать функции паузы и возобновления работы агента. Потеря прогресса выполнения задачи является первым проявлением сбоя в работе памяти у долгосрочно работающего агента.
- Детерминистичные факты следует хранить в структурированных форматах. В случаях неоднозначных запросов с изменяющейся формулировкой следует применять vector search.
- Для хранения проектной информации, которую люди должны просматривать, редактировать, контролировать версии или сравнивать изменения, следует использовать файлы.
- Каждому типу памяти необходимо определить правила истечения срока хранения, выявления конфликтов и удаления данных. Память, которую система не может исправить, превращается в «деятельность, создающую долг» продукта.
- Следует ограничивать объём данных, возвращаемых в модель. Хранимая память имеет ценность лишь тогда, когда retrieval включает соответствующие доказательства в текущий контекст.
Следующий уровень — это выполнение действий
Часть 3, ИИ-агент Tool Use к 2026 году, Происходит переход от сохранённого состояния к выполнению действия. В нём рассматривается вопрос о том, как агент находит и вызывает инструменты, а также о том, как границы этих инструментов возвращают ошибки, которые может использовать цикл ризонинга. Части 5 и 6 занимаются возвратом данных из операционной среды в память: рантайм восстанавливает чекпоинт, в то время как харнесс определяет, что должно быть передано следующему модель сессия.
Список литературы
Статьи
- Когнитивные архитектуры для языковых агентов (CoALA) — Sumers, Yao и др., 2023 — Основная таксономия типов памяти агентов Память в эпоху ИИ-агенты: обзор — Декабрь 2025 г. — Всеобъемлющая трехмерная таксономия памяти агента
- MemGPT: Путь к LLMs в качестве операционных систем — Packer и др., 2023 — Управление виртуальным контекстом для агентов LLM Генеративные агенты: интерактивные симулякры человеческого поведения — Park и др., 2023 — Архитектура потока памяти с оценкой свежести, значимости и релевантности Zep: архитектура графа временных знаний для хранения памяти агентов — Rasmussen, 2025 — Би-темпоральная графа знаний для хранения памяти агента
- Mem0: Создание производственной версии ИИ-агенты с масштабируемым Долгосрочная память — 2025 — Экстракция/консолидация пайплайн с использованием бенчмарки
- Voyager: открытый агент с физическим воплощением и поддержкой больших языковых моделей Модели — Wang и др., 2023 — Библиотека навыков как память в виде документов для агентов игр открытого мира
- JARVIS-1: агенты в открытом мире для выполнения нескольких задач с использованием мультимодального языка и усиленной памятью Модели — 2023 — Мультимодальная библиотека памяти для агентов Minecraft Память рабочего процесса агента — Wang и др., 2024 — Метод индукции повторно используемых рабочих процессов для агентов веб-автоматизации SkillWeaver: веб-агенты могут самостоятельно создавать библиотеки навыков — 2025 — Самосинтезируемые многоразовые инструменты API для веб-агентов
- LEGOMem: модульная память Фреймворк для систем агентов LLM — 2025 — Композитные модули памяти для систем multi-agent
Документация LangGraph
- Поддержка долгосрочного хранения данных в LangGraph (создание чекпоинтов) — Основные концепции памяти, основанной на чекпоинт Хранилище памяти LangGraph — Межпоточная коммуникация долгосрочная память с интерфейсом Store
- Поддержка сохранения состояния LangGraph между потоками — Функциональность API для обмена данными между потоками Как добавить память к заранее скомпилированному агенту ReAct — Практическое руководство по расширению объёма памяти
Чекпоинт бэкенды
langgraph-checkpoint-postgres— Спасатель PostgreSQL чекпоинт для LangGraphlanggraph-checkpoint-redis— Сохранитель данных Redis чекпоинт для LangGraph LangGraph Redis Чекпоинт 0.1.0 — переработанная версия — Детали архитектуры механизма сохранения данных Redis чекпоинтlanggraph-checkpoint-aws— Сохранитель данных в DynamoDB чекпоинт с переносом данных в S3
Базы данных векторов и инструменты памяти
- Qdrant — Открытая векторная база данных с индексацией и фильтрацией на основе HNSW Руководство по созданию приложений с Qdrant Агентный — Практическое руководство по созданию памяти агента с использованием Qdrant
- pgvector — Расширение для поиска по векторному сходству в PostgreSQL Графити — движок временных знаниевых графов с открытым исходным кодом от Zep
Память, основанная на документах и файлах
- Память Claude Code — Система памяти на основе файлов CLAUDE.md и MEMORY.md Инструмент Anthropic Memory — Внутренняя память на основе файлов с клиентской стороны для агентов Claude API
- Правила курсора — Файлы .cursorrules на уровне проекта для настройки контекста агента Воспоминания о виндсерфинге — Память на основе файлов и .windsurfrules для агентов-кодеров
Память фреймворки
- Mem0 — Слой управления памятью с механизмами извлечения и консолидации пайплайн
- Letta (MemGPT) — Управление виртуальным контекстом агентов на основе принципов операционных систем
- LangMem SDK — Инструменты управления памятью для LangGraph
Бенчмарки
- Производительность PostgreSQL против Redis — CyberTec латентность и throughput бенчмарки
- Сравнение PostgreSQL и Redis — Сравнение архитектур RisingWave
- Инженерия Redis ИИ-агент — Шаблоны Redis для нагрузок агентов
Семинары
- MemAgents: механизм управления памятью для систем на основе Агентный с использованием LLM — Семинар ICLR 2026
Проект-демонстрация
- Агент аналитика рынка — Полная реализация с использованием всех трёх уровней памяти
полный код агента Market Analyst Agent, включая описанную здесь архитектуру памяти, доступен по GitHub если хотите следить за прогрессом чтения.
Серия: Проектирование стека Агентный
- Часть 1: ИИ-агент Ризонинг Циклы в 2026 году — ReAct, ReWOO и подход Plan-and-Execute
- Часть 2: Архитектура памяти ИИ-агент в 2026 году (эта статья)
- Часть 3: ИИ-агент Tool Use в 2026 году — MCP, интерфейс командной строки, навыки, выполнение кода и ACI Часть 4: ИИ-агент Безопасность в 2026 году — гардрейлы, права доступа, сэндбоксы, HITL и ограничение диапазона MCP
- Часть 5: Долгосрочные ИИ-агент Рантайм в 2026 году — сессии, сэндбоксы, чекпоинты, механизмы управления и деплой формирования структур
- Часть 6: Харнесс-инжиниринг для ИИ-агенты (вскоре выйдет) — проверки приемки, трейсы, повторные попытки, передача задач и циклическая обработка в рамках модель