Aivaro
  • Оглавление
  • Вопросы
  • Практика
  • Вики
  • Материалы сообщества
  • Тесты
  • Поиск
✈Telegram @ai_varo
RUEN中文
…
Оглавление/Вопросы/#936

Как вы храните историю чата для long-term памяти агента (сжатие, суммаризация, векторная память)?

Краткий тезис

Long-term память агента решает проблему выхода за лимиты контекста и потери знаний о предыдущих взаимодействиях. Основные подходы — in-context memory (всё в одном окне), compression (суммаризация старых сообщений), vector memory (векторный RAG по истории) и иерархическая память (short-term + long-term). Выбор зависит от требований к временной глубине, релевантности, латентности и стоимости.

2. Сжатие (compression): суммаризация старых сообщений

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

Методы реализации:

  • Периодическая суммаризация — после каждых K сообщений агент пишет summarizer_llm, который извлекает ключевые факты, решения, предпочтения.
  • Итеративное сжатие — при каждом добавлении нового сообщения сжимается самая старая часть.
  • Иерархическое сжатие — сначала сжимаются отдельные блоки (10 сообщений), затем их резюме — в глобальный сценарий.

Проблемы:

  • потеря деталей (конкретные даты, цитаты)
  • необходимость отдельной LLM-компоненты (дополнительные токены и latency)
  • сложность с инкрементальным обновлением при изменении контекста

Пример с периодическим сжатием (Python-псевдокод):

def summarize_history(messages, summary_so_far=""):
    if len(messages) > COMPRESSION_THRESHOLD:
        old = messages[:-COMPRESSION_THRESHOLD]
        summary_prompt = f"Existing summary: {summary_so_far}\nNew messages: {old}\nUpdate summary:"
        new_summary = summarizer(summary_prompt)
        return new_summary, messages[-COMPRESSION_THRESHOLD:]
    return summary_so_far, messages

Инструменты:

  • LangChain — ConversationSummaryMemory, SummaryBufferMemory
  • LlamaIndex — ChatSummaryMemory

3. Векторная память (vector memory): retrieval по истории

Каждое сообщение (или chunk диалога) эмбеддируется и сохраняется в векторной БД для поиска по семантической близости. При каждом новом запросе выполняются RAG-извлечение наиболее релевантных фрагментов истории, которые добавляются в контекст.

Компоненты:

  • Эмбеддер (OpenAI text-embedding-3-small, Sentence Transformers all-MiniLM-L6-v2)
  • Векторное хранилище (Chroma, Qdrant, Pinecone, FAISS)
  • Retriever (similarity search + возможный реранжинг)
  • Формирование контекста — извлечённые chunks оформляются в системное сообщение.

Стратегии разбиения:

  • одно сообщение → один вектор
  • диалоговый turn (user + assistant) → один вектор
  • chunk по N токенов со сдвигом (sliding window)

Преимущества:

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

Минусы:

  • потеря контекстной связности (извлечённые куски — «лоскуты»)
  • эмбеддинги не всегда точно отражают релевантность
  • добавочная латентность на retrieval
from langchain.memory import VectorStoreRetrieverMemory
from langchain_community.vectorstores import Chroma

embeddings = OpenAIEmbeddings()
db = Chroma(collection_name="chat_history", embedding_function=embeddings)
retriever = db.as_retriever(search_kwargs={"k": 3})

memory = VectorStoreRetrieverMemory(retriever=retriever, memory_key="chat_history")

Развитие: использование агентных паттернов, где retrieval выполняется не для каждого входа, а по решению агента (через tool-call).


4. Иерархическая память: short-term + long-term

Комбинирует краткосрочную память (in-context buffer) и долгосрочную (сжатие или векторы). Агент держит ближайший диалог в контексте, а когда достигается лимит — старые фрагменты архивируются и индексируются.

Типичная архитектура:

  1. Short-term buffer — последние ~20 сообщений (или ~8K токенов) подаются непосредственно модели.
  2. Long-term store — после вытеснения из short-term сообщения:
    • суммаризируются и кладутся в текстовый файл или БД
    • или эмбеддятся и добавляются в векторное хранилище
  3. Поиск — агент решает, обращаться ли к long-term (через специальный инструмент).

Пример (LangGraph):

  • нода remember — читает state, если буфер переполнен, вызывает summarizer и сохраняет summary в отдельное поле.
  • нода recall — извлекает релевантные куски из long-term через RAG или запрос summary.

Плюсы:

  • баланс между скоростью (short-term) и охватом (long-term)
  • гибкость: можно выбрать степень сжатия или детализации
  • подходит для долгоживущих агентов (недели, месяцы)

Минусы:

  • сложность настройки триггеров и миграции
  • необходимость управления несколькими хранилищами (SQLite + Vector DB)
  • агент может не знать, когда что recall

Паттерн «Memory Sandbox»:

  • каждое сообщение имеет метку времени и source (user/assistant)
  • при добавлении в long-term запускается summarization с сохранением ключевых фактов
  • retrieval учитывает временную дистанцию (с weighting по recency)

5. Пет-проект для закрепления

Задача: Реализовать агента-помощника по личным заметкам с долгосрочной памятью, который запоминает пользовательские предпочтения и предыдущие обсуждения.

Инструменты:

  • Python, LangChain / LangGraph
  • OpenAI API или локальная модель (например, LLaMA через Ollama)
  • Chroma или FAISS для векторов
  • SQLite для хранения raw-messages

Шаги:

  1. Создайте цикл диалога с буфером на 10 последних сообщений (in-context).
  2. При достижении лимита запускайте суммаризацию через отдельный LLM-узел.
  3. Сохраните summary в SQLite с тегами (дата, тема).
  4. Добавьте эмбеддинг для каждого summary и положите в Chroma.
  5. Перед формированием ответа ищите в векторной БД топ-3 записи, похожих на текущий вопрос, и добавляйте их в системный промпт.
  6. Сделайте визуализацию: показывайте, какие сообщения были сжаты, а какие извлечены.

Ожидаемый результат:
Агент помнит факты из диалога недельной давности («ты просил напоминать о покупке кофе каждую пятницу») и не требует полной истории в контексте. Метрики: среднее число токенов на запрос сокращено в 3-5 раз по сравнению с in-context version.


Связь с другими вопросами

ВопросТема
48RAG — общий паттерн извлечения знаний, который применяется и для истории диалога.
105Управление контекстом — базовые техники обрезания, sliding window, attention-based compression.

Навигация

  • Предыдущий: 935
  • Следующий: 937
  • Индекс: 00. Индекс разборов