Память сводки и усечение с учётом токенов
Используйте ConversationSummaryMemory для автоматического суммирования старых реплик, сохраняя диалог компактным и одновременно не теряя важные факты, упомянутые пользователем ранее.
«Память сводки и усечение с учётом токенов» — бесплатный урок AI Engineering Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения AI Engineering Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс AI Engineering Academy содержит 4 уроков всего.
Стоимость токенов полной истории
Память буфера разговора сохраняет каждое когда-либо отправленное сообщение, быстро расходуя окно контекста. В разговоре из 100 обменов только история может занимать 20 000 токенов, оставляя мало места для самого ответа. Память сжатого содержания решает эту проблему, заменяя старые обмены сжатым резюме.
Как работает память сжатого содержания
Когда общее количество токенов превышает порог, ConversationSummaryMemory передаёт самые старые обмены разговора LLM и просит её обобщить ключевые моменты. Полные обмены удаляются и заменяются этим компактным резюме. Последующие обмены накапливаются поверх резюме.
- Старые обмены: заменяются резюме
- Недавние обмены: сохраняются без изменений
- Итог: существенное сжатие при минимальной потере информации
Память сжатого содержания ConversationSummaryMemory в LangChain
LangChain предоставляет ConversationSummaryMemory, которая автоматически создаёт резюме, когда буфер становится слишком большим. Вы передаёте LLM объекту памяти, чтобы он мог по запросу вызывать модель для создания резюме.
from langchain.memory import ConversationSummaryMemory
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model='gpt-4o-mini')
memory = ConversationSummaryMemory(
llm=llm,
return_messages=True
)
# Add messages manually
memory.save_context(
{'input': 'My name is Alice and I am building a RAG system.'},
{'output': 'Great, I can help you build a RAG system, Alice.'}
)
print(memory.load_memory_variables({}))Память буфера с резюме: лучшее из двух подходов
ConversationSummaryBufferMemory — это гибридный подход: он сохраняет самые последние обмены без изменений для точности, а обобщает только более старые обмены, превышающие max_token_limit. Это даёт точное воспроизведение недавнего контекста и сжатое воспроизведение более старого.
from langchain.memory import ConversationSummaryBufferMemory
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model='gpt-4o-mini')
memory = ConversationSummaryBufferMemory(
llm=llm,
max_token_limit=500, # Summarize when older turns exceed 500 tokens
return_messages=True
)
# As the conversation grows, old turns get summarized automatically
print('Moving summary:', memory.moving_summary_buffer)Подсчёт токенов перед усечением
Чтобы принимать разумные решения об усечении, нужно знать, сколько токенов занимают Ваши сообщения. Библиотека tiktoken позволяет подсчитывать токены для любой модели OpenAI. Это позволяет реализовать усечение с учётом токенов, которое строго укладывается в заданный бюджет.
import tiktoken
def count_tokens(messages: list, model: str = 'gpt-4o') -> int:
encoding = tiktoken.encoding_for_model(model)
total = 0
for msg in messages:
# Each message has overhead tokens for role framing
total += 4
total += len(encoding.encode(msg.get('content', '')))
total += 2 # Reply primer
return total
messages = [
{'role': 'user', 'content': 'Explain RAG to me.'},
{'role': 'assistant', 'content': 'RAG stands for Retrieval-Augmented Generation...'}
]
print('Token count:', count_tokens(messages))Ручное усечение с учётом токенов
Иногда Вам нужен полный контроль над усечением без классов памяти LangChain. Простой подход: сохранять все сообщения, а затем по одному удалять самые старые сообщения, кроме системных, пока общее количество токенов не уложится в Ваш бюджет.
def truncate_to_budget(messages: list, budget: int, model: str = 'gpt-4o') -> list:
'''Remove oldest non-system messages until under budget.'''
import tiktoken
encoding = tiktoken.encoding_for_model(model)
def token_count(msgs):
total = 2
for m in msgs:
total += 4 + len(encoding.encode(m.get('content', '')))
return total
result = list(messages)
while token_count(result) > budget and len(result) > 1:
# Never remove the system prompt at index 0
if result[0]['role'] == 'system':
del result[1]
else:
del result[0]
return resultСоздание запроса для формирования резюме
Создавая собственную память сжатого содержания, составьте запрос, который просит LLM выделить ключевые факты. В запросе следует указать модели, чтобы она сохраняла предпочтения пользователя, именованные сущности и нерешённые вопросы — факты, которые с наибольшей вероятностью окажутся важными в последующих обменах.
from openai import OpenAI
client = OpenAI()
def summarize_history(old_summary: str, new_turns: list) -> str:
turns_text = '\n'.join(
f'{m["role"].capitalize()}: {m["content"]}' for m in new_turns
)
prompt = f'''Current summary:\n{old_summary}\n\nNew conversation turns:\n{turns_text}\n\nWrite an updated summary that captures key facts, user preferences, and open questions.'''
resp = client.chat.completions.create(
model='gpt-4o-mini',
messages=[{'role': 'user', 'content': prompt}]
)
return resp.choices[0].message.contentВстраивание резюме в системный запрос
Получив резюме, вставьте его в системный запрос, чтобы LLM всегда имела контекст истории разговора. Добавьте резюме в начало в виде краткого блока контекста перед основными инструкциями, задающими образ модели.
def build_messages_with_summary(summary: str, recent_turns: list, user_input: str) -> list:
system_content = (
'You are a helpful AI assistant.'
+ ('\n\n[Conversation summary]\n' + summary if summary else '')
)
messages = [{'role': 'system', 'content': system_content}]
messages.extend(recent_turns)
messages.append({'role': 'user', 'content': user_input})
return messagesАвтоматический запуск создания резюме
Распространённый подход — запускать создание резюме, когда разговор превышает порог по токенам, например когда накопленная история достигает 2 000 токенов. В этот момент создайте резюме для всех обменов, кроме последних двух, и замените их этим резюме.
class SummaryBufferChat:
def __init__(self, max_tokens=2000):
self.summary = ''
self.recent_turns = []
self.max_tokens = max_tokens
def chat(self, user_message: str) -> str:
from openai import OpenAI
client = OpenAI()
messages = build_messages_with_summary(self.summary, self.recent_turns, user_message)
resp = client.chat.completions.create(model='gpt-4o', messages=messages)
reply = resp.choices[0].message.content
self.recent_turns.append({'role': 'user', 'content': user_message})
self.recent_turns.append({'role': 'assistant', 'content': reply})
if count_tokens(self.recent_turns) > self.max_tokens:
to_summarize = self.recent_turns[:-2]
self.recent_turns = self.recent_turns[-2:]
self.summary = summarize_history(self.summary, to_summarize)
return replyСохранение именованных сущностей в резюме
Качество резюме во многом зависит от запроса для обобщения. Если пользователи упоминают своё имя, местоположение, предпочтения или сроки, в запросе необходимо явно указать модели, что эти факты нужно включить. В обобщённых резюме часто теряются имена собственные, которые особенно важны для персонализации.
- Включайте: имена, даты, принятые технические решения, открытые вопросы
- Исключайте: пустые реплики, подтверждения, повторяющиеся любезности
Компромиссы: память сжатого содержания и память окна
Выбор между памятью сжатого содержания и памятью окна зависит от Вашего сценария. Память окна сохраняет точные формулировки, что важно для точного воспроизведения, но тратит токены на не относящийся к делу контекст. Память сжатого содержания агрессивно сжимает историю, но требует дополнительного вызова LLM и может потерять детали редких случаев. В большинстве рабочих чат-ботов используется гибрид: последние точные обмены и постоянно обновляемое резюме более старых.
Быстрая проверка
Проверьте, насколько Вы понимаете концепции памяти сжатого содержания и усечения с учётом токенов.
Итоги урока
В этом уроке Вы узнали, что память сжатого содержания сжимает старые обмены с помощью вызова LLM, ConversationSummaryBufferMemory объединяет точные недавние обмены с обобщёнными старыми, а tiktoken позволяет выполнять усечение с учётом токенов, чтобы разговоры укладывались в бюджет. Далее мы рассмотрим сохранение истории чатов в Redis и PostgreSQL для надёжного и масштабируемого хранения.
Изучай Python с ИИ-репетитором — бесплатно
Пиши и запускай код прямо в браузере, получай мгновенную помощь от ИИ-репетитора 24/7 и продолжи учиться на сайте или в приложении.
- Курсы
- 30
- Уроки
- 120
Часто задаваемые вопросы
Урок «Память сводки и усечение с учётом токенов» бесплатный?
Да — полный текст урока «Память сводки и усечение с учётом токенов» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс AI Engineering Academy, подпишись на CoddyKit PRO. Курс AI Engineering Academy содержит 4 уроков всего.
Чему я научусь в уроке «Память сводки и усечение с учётом токенов»?
Используйте ConversationSummaryMemory для автоматического суммирования старых реплик, сохраняя диалог компактным и одновременно не теряя важные факты, упомянутые пользователем ранее. Ты практикуешь AI Engineering Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать AI Engineering Academy?
Предыдущий опыт не требуется. AI Engineering Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.
Сколько времени занимает урок «Память сводки и усечение с учётом токенов»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке AI Engineering Academy?
Да. Каждый урок AI Engineering Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Зачем бессостояниным LLM нужна внешняя память
- Память буфера и окна
- Память сводки и усечение с учётом токенов
- Сохранение истории чата в Redis и PostgreSQL