Стратегии истории: обрезка и суммаризация

Урок про то, как держать историю в рамках лимита контекста и бюджета.

Суммаризация истории — приём, при котором старые сообщения заменяют их кратким изложением, чтобы сэкономить токены.

Почему историю надо ограничивать

Контекст модели ограничен числом токенов, а каждый токен в запросе стоит денег и времени. Если слать всю историю диалога, рано или поздно вы упрётесь в лимит, а ответы станут дорогими и медленными. Поэтому историю урезают одной из стратегий.

СтратегияСутьМинус
Окно последних Nхранить только последние N сообщенийтеряется давний контекст
Обрезка по токенамдержать историю в пределах бюджета токеновграница может разрезать мысль
Суммаризациястарое сжать в краткое резюмелишний вызов модели, потеря деталей

Окно последних сообщений

Простейшую стратегию «оставить последние N» легко показать на Python:

def trim_window(history, n):
    return history[-n:]

history = [f"msg{i}" for i in range(1, 8)]
print(trim_window(history, 3))

Вывод:

['msg5', 'msg6', 'msg7']

Обрезка по токенам

В LangChain есть утилита trim_messages, которая обрезает историю по бюджету токенов, при этом умеет сохранять system-сообщение и не разрывать пары «вопрос — ответ».

from langchain_core.messages import trim_messages

trimmer = trim_messages(
    max_tokens=2000,
    strategy="last",
    token_counter=model,
    include_system=True,
)
# trimmer вставляют в цепочку перед промптом
chain = trimmer | prompt | model

Как работает под капотом

Окно и токен-обрезка просто отбрасывают лишние сообщения с начала. Суммаризация сложнее: когда история превышает порог, отдельный вызов LLM сжимает старые реплики в абзац-резюме, и дальше в промпт идёт это резюме плюс последние свежие сообщения. Так бот «помнит» суть давнего разговора, не таская его дословно. Выбор стратегии — компромисс между точностью памяти, стоимостью и сложностью.

Частые ошибки

  • Урезать system-сообщение. Инструкция о поведении должна оставаться — указывайте include_system=True.
  • Разрывать пары сообщений. Обрывок «вопрос без ответа» путает модель; используйте готовые утилиты обрезки.
  • Суммаризировать слишком агрессивно. Резюме теряет детали; не сжимайте то, что ещё может понадобиться дословно.

Итог

  • Историю ограничивают из-за лимита контекста и стоимости токенов.
  • Три стратегии: окно последних N, обрезка по токенам, суммаризация.
  • trim_messages обрезает по бюджету, сохраняя system и целостность пар.
  • Выбор стратегии — баланс точности, цены и сложности.
Проверьте себя
1. Почему нельзя бесконечно наращивать историю диалога?
ALangChain запрещает более 10 сообщений
BКонтекст модели ограничен токенами, а длинная история дороже и медленнее
CИстория портит качество эмбеддингов
DЭто требование лицензии OpenAI
2. В чём идея суммаризации истории?
AУдалить всю историю целиком
BЗаменить старые сообщения их кратким резюме, чтобы сэкономить токены
CДублировать каждое сообщение
DПеревести историю на английский
3. Что важно сохранить при обрезке истории по токенам?
AТолько самое первое сообщение пользователя
BSystem-сообщение и целостность пар «вопрос — ответ»
CПустые сообщения
DМетаданные о стоимости