Как вы реализуете память агента (Memory) на разных уровнях?
Краткий тезис
Память агента — это многоуровневая система, имитирующая человеческое запоминание. Я комбинирую краткосрочную память (буфер последних сообщений в Redis) для поддержания контекста диалога, долгосрочную память (векторное хранилище важных фактов) для хранения знаний о пользователе, семантическую память (эмбеддинги обобщённых выводов) и рабочую память (переменные текущей сессии). В фреймворках вроде LangChain это реализуется через ConversationBufferMemory и VectorStoreRetrieverMemory, но на продакшене требуется кастомная интеграция с учётом времени жизни данных, сжатия контекста и механизмов забывания.
1. Зачем агенту память и какие бывают уровни
В AI-агентах память необходима, чтобы:
- Поддерживать связный диалог (не терять нить беседы).
- Обучаться на прошлых взаимодействиях (запоминать предпочтения пользователя).
- Принимать решения на основе накопленного опыта (например, повторно используя успешные стратегии).
Выделяют четыре основных уровня памяти, аналогичных когнитивным процессам человека:
| Уровень | Аналог человека | Пример данных |
|---|---|---|
| Краткосрочная (Short‑term) | Рабочая память, удержание нескольких секунд | Последние 5 сообщений чата |
| Долгосрочная (Long‑term) | Факты, хранящиеся годами | День рождения пользователя, его любимый жанр книг |
| Семантическая (Semantic) | Обобщённые знания, концепции | «Пользователь предпочитает короткие ответы» |
| Рабочая (Working / Episodic) | Переменные текущей задачи | Выбранная категория товара в процессе покупки |
В продакшен-системах обычно комбинируют все уровни, управляя их размером и временем жизни (TTL).
2. Краткосрочная память (Conversation Buffer)
Термин: Conversation Buffer — хранит последние k сообщений в порядке их поступления.
Реализация:
- Чаще всего используют Redis (in‑memory key‑value store) с TTL (например, 30 минут).
- Для каждого сеанса (session_id) сохраняем список сообщений.
- При каждом новом запросе отправляем буфер в prompt или в messages (ChatML).
Пример кода на Python:
import redis
import json
r = redis.Redis(host='localhost', port=6379, decode_responses=True)
def get_buffer(session_id: str, max_tokens: int = 2000) -> list:
key = f"agent:buffer:{session_id}"
messages = json.loads(r.get(key) or "[]")
# оставить последние N сообщений, не превышающих лимит токенов
return messages[-5:] # например, последние 5
def append_to_buffer(session_id: str, role: str, content: str):
key = f"agent:buffer:{session_id}"
messages = json.loads(r.get(key) or "[]")
messages.append({"role": role, "content": content})
r.setex(key, 1800, json.dumps(messages)) # TTL 30 минут
Плюсы: быстрый доступ, простота.
Минусы: ограниченный размер, потеря контекста при длинных диалогах (проблема «lost in the middle»).
Для решения проблемы длинного контекста применяют суммаризацию (сжатие предыдущих сообщений в одно саммари) и замену буфера на гибрид: последние N сообщений + саммари старой истории.
3. Долгосрочная память (Vector Store Memory)
Термин: Long‑term memory — хранит факты, извлечённые из разговоров, в виде эмбеддингов в векторной БД.
Принцип работы:
- После каждого витка диалога агент решает, какую информацию стоит запомнить (например, «пользователь любит научную фантастику»).
- Кандидаты в память превращаются в эмбеддинги (через ту же модель, что используется в RAG) и сохраняются в векторное хранилище (ChromaDB, Pinecone, Qdrant, FAISS).
- При новом запросе извлекаются наиболее релевантные воспоминания (top‑k) и подмешиваются в контекст.
Инструменты:
- LangChain VectorStoreRetrieverMemory — удобная обёртка.
- Mem0 — специализированная библиотека для управления долгосрочной памятью агентов.
from langchain.memory import VectorStoreRetrieverMemory
from langchain.vectorstores import Chroma
from langchain.embeddings import OpenAIEmbeddings
embeddings = OpenAIEmbeddings()
vectorstore = Chroma(collection_name="agent_memory", embedding_function=embeddings)
memory = VectorStoreRetrieverMemory(
retriever=vectorstore.as_retriever(search_kwargs={"k": 5}),
input_key="input", # ключ ввода
output_key="output",
memory_key="history"
)
# Сохранение опыта
memory.save_context({"input": "как тебя зовут?"}, {"output": "Меня зовут Ассистент."})
# Извлечение релевантных воспоминаний
relevant = memory.load_memory_variables({"input": "напомни своё имя"})
Важно: нужно настроить механизм запоминания (какие части диалога сохранять) и забывания (удалять устаревшие факты по TTL или при неиспользовании).
4. Семантическая память
Термин: Semantic memory — хранит обобщённые выводы, а не конкретные диалоги. Например: «Пользователь предпочитает технические ответы с формулами» или «Пользователь всегда просит примеры кода».
Отличие от долгосрочной:
- Долгосрочная память — сырые факты (например, «любит научную фантастику»).
- Семантическая память — агрегированные паттерны (например, «все вопросы пользователя связаны с Python и ML»).
Реализация:
- Используем ту же векторную БД, но данные предварительно обобщаются (например, через LLM: «Из последних 10 диалогов выдели 3 устойчивых характеристики пользователя»).
- Ключи могут быть не просто текстом, а концептами (например, эмбеддинг фразы «стиль общения: краткий»).
Пример агрегации через LLM:
def summarize_to_semantic(memory_facts: list[str]) -> str:
prompt = f"Обобщи следующие факты в 2-3 кратких вывода о пользователе:\n{chr(10).join(memory_facts)}"
# вызов LLM
return llm.invoke(prompt)
Семантическая память помогает агенту адаптировать свой тон, глубину ответа и стиль без явных инструкций.
5. Рабочая память (Working / Session Memory)
Термин: Working memory — временные переменные, относящиеся к текущей сессии или задаче.
Примеры:
- Текущий выбранный товар в корзине.
- Шаг процесса (например, «пользователь проходит аутентификацию»).
- Результаты предыдущих вызовов инструментов.
Реализация:
- Простое хранилище в памяти процесса (словарь Python) или Redis с коротким TTL.
- В LangChain — через ConversationTokenBufferMemory или кастомный класс, наследующий
BaseMemory.
from dataclasses import dataclass, field
from typing import Any
@dataclass
class WorkingMemory:
session_id: str
variables: dict = field(default_factory=dict)
def set(self, key: str, value: Any):
self.variables[key] = value
def get(self, key: str) -> Any:
return self.variables.get(key)
# Использование в цепочке
working = WorkingMemory("session_123")
working.set("current_step", "checkout")
Рабочая память живёт только до конца сессии (или timeout) и не сохраняется между сессиями.
6. Реализация в LangChain: основные типы памяти
LangChain предоставляет готовые классы для разных уровней:
| Класс | Уровень | Особенности |
|---|---|---|
ConversationBufferMemory | Краткосрочная | Хранит все сообщения, может переполниться. |
ConversationSummaryMemory | Краткосрочная сжатая | Суммаризирует старые сообщения, буфер содержит саммари + последние N. |
VectorStoreRetrieverMemory | Долгосрочная | Хранит факты в векторной БД, извлекает по релевантности. |
ConversationEntityMemory | Семантическая | Извлекает именованные сущности и их атрибуты. |
ConversationTokenBufferMemory | Краткосрочная | Ограничивает память по количеству токенов (отбрасывает старые). |
Как комбинировать:
memory = CombinedMemory(
memories=[
ConversationBufferMemory(k=5), # последние 5 сообщений
VectorStoreRetrieverMemory(retriever=...), # долгосрочные факты
ConversationSummaryMemory() # саммари истории
]
)
Продакшен-советы:
- Устанавливайте TTL на все уровни.
- Для краткосрочной памяти используйте Redis Cluster, чтобы избежать потери при сбое одного узла.
- Для долгосрочной — регулярная дедупликация и реранжирование фактов по важности.
7. Продвинутые техники
7.1. Рефлексия (Reflective Memory)
Агент периодически пересматривает свою память, выделяет противоречия, делает новые выводы. Реализуется через отдельный цикл «reflection», запускаемый после N диалогов.
7.2. Синтез воспоминаний (Memory Synthesis)
Несколько близких фактов объединяются в один обобщённый, чтобы уменьшить шум и экономить токены. Например:
- Факт 1: «Пользователь купил книгу по Python».
- Факт 2: «Пользователь спросил про асинхронность».
- Синтез: «Пользователь изучает продвинутый Python».
7.3. Иерархическая память (Hippocampal‑inspired)
По аналогии с гиппокампом человека: краткосрочная память (быстрая, нестабильная) постепенно консолидируется в долгосрочную (медленная, устойчивая). В программной реализации — асинхронная запись из буфера в векторную БД с проверкой повторений.
8. Инструменты и библиотеки для памяти агентов
| Инструмент | Описание |
|---|---|
| MemGPT (Letta) | Система с иерархической памятью, автоматическим сжатием и «разрывами» контекста. |
| Mem0 | Библиотека для управления долгосрочной памятью с поддержкой профилей пользователей. |
| Zep | Open‑source сервис памяти для чатов (сохраняет историю, извлекает релевантные фрагменты). |
| LangChain Memory | Готовые классы для быстрого прототипирования. |
| Cassandra / ScyllaDB | Можно использовать как долгосрочное хранилище с временными метками. |
9. Пет-проект для закрепления
Задача: Разработать Telegram-бота-ассистента, который запоминает предпочтения пользователя и поддерживает контекст между сессиями.
Инструменты:
- Python,
python-telegram-bot - LangChain (Memory)
- Redis (краткосрочная память)
- ChromaDB (долгосрочная память)
- OpenAI API (LLM, эмбеддинги)
Шаги:
- Реализовать
ConversationBufferMemoryна Redis для каждогоchat_id. - Добавить
VectorStoreRetrieverMemory, куда после каждого диалога отправляется обобщение (через LLM summary). - При получении сообщения — собрать буфер + top‑5 релевантных фактов из Chroma и отправить в LLM.
- Реализовать команду
/forget_me, очищающую долгосрочные воспоминания пользователя.
Ожидаемый результат:
- Бот помнит, что пользователь просил называть его «Алексей» и отвечать кратко, даже если прошло несколько дней.
- При длинном диалоге — автоматически сжимает старые сообщения в саммари (не теряя важных деталей).
- Возможность инспекции памяти (команда
/memoryвыводит текущие факты).
10. Связь с другими вопросами
| Вопрос | Тема |
|---|---|
| 47 | Как управлять состоянием (state) агента? |
| 44 | Как спроектировать архитектуру агента? |
| 45 | Как агент выбирает и вызывает инструменты? |
| 50 | Как масштабировать агента до тысяч параллельных сессий? |
| 32 | Как реализовать механику «chain of thought» в агенте? |
| 20 | Как вы оцениваете качество работы RAG-системы (связь через векторное хранение)? |
Навигация
- Предыдущий: 47
- Следующий: 49
- Индекс: 00. Индекс разборов