Цель лекции
Объяснить память одной беседы или ограниченной сессии и ее отличие от долгосрочного профиля пользователя.
Зачем это нужно
В предыдущей лекции мы разобрали working memory: текущий контекст, который попадает в context window перед одним LLM-вызовом. Но большинство полезных агентских сценариев не заканчиваются одним вызовом. Пользователь уточняет задачу, агент задает вопросы, вызывает инструменты, получает ошибки, меняет план и возвращается к уже обсужденным деталям.
Для этого нужна память текущего взаимодействия: conversation memory и session memory. Она помогает агенту не терять нить разговора, помнить выбранные настройки, не задавать одни и те же вопросы, продолжать workflow и корректно интерпретировать короткие реплики вроде "сделай так же, но короче".
При этом session memory опасно путать с долгосрочной памятью. То, что пользователь сказал в текущей беседе, не всегда должно становиться постоянным фактом. "Сегодня отвечай коротко" - это часто настройка сессии. "Я всегда предпочитаю короткие ответы" - кандидат в user profile. Различие кажется тонким, но для продукта оно критично.
Основная идея
Conversation memory - это память диалога: последние сообщения, предыдущие вопросы и ответы, уточнения, выбранные варианты, локальные договоренности. Session memory шире: она хранит временное состояние ограниченного взаимодействия или workflow, даже если оно не выражено только в сообщениях.
Session memory помогает не терять нить текущего взаимодействия, но не должна автоматически становиться постоянным знанием. Ее время жизни ограничено: пока длится разговор, support ticket, голосовая сессия, IDE-задача, checkout flow или другой workflow.
Технически session memory может быть реализована через сырую историю сообщений, sliding window, rolling summary, structured session state, временные key-value поля, task state или комбинацию этих подходов.
Главный практический вопрос этой лекции: какие данные должны жить только в рамках текущей сессии, а какие стоит вынести в долгосрочную память?
Ключевые термины
| Термин | Короткое определение |
|---|---|
Conversation memory |
Память текущего диалога: сообщения, уточнения, ответы, локальные договоренности. |
Session memory |
Временная память ограниченного взаимодействия или workflow. |
Conversation history |
Сырая последовательность сообщений между пользователем, агентом и иногда инструментами. |
Sliding window |
Подход, при котором в контекст включаются последние N сообщений или токенов. |
Rolling summary |
Подход, при котором старая часть диалога сжимается в обновляемое summary. |
Session state |
Структурированные временные переменные сессии: выбранные опции, текущий шаг, статусы. |
TTL |
Time to live: срок жизни записи до автоматического удаления или истечения. |
Expiration |
Механизм завершения действия сессионных данных после времени, события или окончания workflow. |
Summarization drift |
Накопление искажений при многократном пересказе старой истории. |
User profile |
Долгосрочная память о пользователе: устойчивые предпочтения, ограничения, настройки. |
Conversation memory и session memory
Эти два термина близки, но не полностью совпадают.
Conversation memory обычно относится к текстовой или мультимодальной истории общения. Она отвечает на вопросы: что пользователь уже сказал, что агент уже ответил, какие уточнения были сделаны, какие варианты обсуждались.
Session memory относится к состоянию текущего взаимодействия. Она может включать conversation history, но также хранит то, чего в сообщениях может не быть в явном виде: выбранный режим, активный объект, текущий шаг формы, временный токен, результаты инструментов, список уже проверенных гипотез.
| Критерий | Conversation memory | Session memory |
|---|---|---|
| Основной объект | История диалога. | Состояние текущего взаимодействия. |
| Форма | Сообщения, реплики, summaries. | Сообщения плюс structured state. |
| Время жизни | Обычно одна беседа. | Одна беседа, задача, ticket, workflow или voice call. |
| Пример | "Пользователь уже выбрал второй вариант." | selected_plan = "pro", current_step = "billing". |
| Риск | Длинная история становится шумной. | Временные данные ошибочно становятся постоянными. |
В простом чат-боте conversation memory и session memory могут быть почти одним и тем же. В агенте с инструментами они расходятся: агенту нужно помнить не только слова, но и состояние работы.
Conversation history как простейшая память
Самый простой способ дать агенту память диалога - включать в prompt предыдущие сообщения.
User: Хочу составить план лекции.
Assistant: Давай начнем с цели и структуры.
User: Пусть будет для инженеров.
Assistant: Тогда сделаем акцент на архитектуре.
User: Теперь напиши вступление.
Без истории последняя реплика "Теперь напиши вступление" почти бессмысленна. С историей модель понимает, что речь о вступлении к лекции для инженеров с архитектурным акцентом.
Conversation history хорошо работает для коротких диалогов. Она сохраняет точные формулировки и не требует сложной инфраструктуры. Но при длинной беседе возникают проблемы:
- история перестает помещаться в
context window; - старые детали вытесняют новые;
- prompt становится дороже и медленнее;
- случайные реплики начинают конкурировать с важными решениями;
- модель может учитывать уже отмененные варианты.
Поэтому сырая история - хороший старт, но плохая стратегия для длинных сессий.
Sliding window
Sliding window хранит последние N сообщений или последние N токенов диалога. Старые сообщения постепенно выпадают из контекста.
Преимущество sliding window - простота. Он не требует суммаризации, схем данных или сложного retrieval. Для многих коротких чатов этого достаточно.
Недостаток - слепота к старым, но важным деталям. Если пользователь в начале сессии сказал "не предлагай платный тариф", а через 40 сообщений это выпало из окна, агент может нарушить договоренность.
Sliding window особенно полезен, когда:
- сессии короткие;
- последние сообщения важнее старых;
- контекст быстро устаревает;
- цена ошибки от забывания невысока;
- нужно сохранить точные последние формулировки.
Rolling summary
Rolling summary решает проблему длинной истории иначе. Старая часть диалога сжимается в summary, а последние сообщения остаются в сыром виде.
Такой подход позволяет удерживать нить длинной беседы без передачи всей истории. Summary может содержать цели, принятые решения, ограничения, открытые вопросы и текущее состояние.
Пример rolling summary:
Пользователь готовит сравнительный обзор memory architectures для AI-агентов.
Выбрана структура: working memory, session memory, episodic memory, semantic memory.
Стиль: русский язык, инженерная аудитория, без низкоуровневого кода.
Открытый вопрос: добавить ли отдельный раздел про privacy в каждой лекции.
Проблема rolling summary - summarization drift. При каждом обновлении summary часть деталей может теряться, упрощаться или искажаться. Через много итераций система может уверенно помнить то, чего пользователь не говорил, или забыть важную оговорку.
Sliding window vs rolling summary
| Критерий | Sliding window | Rolling summary |
|---|---|---|
| Что хранит | Последние сообщения целиком. | Сжатое содержание старой истории плюс свежие сообщения. |
| Простота | Очень высокая. | Средняя: нужен механизм обновления summary. |
| Точность свежих деталей | Высокая. | Высокая, если свежие сообщения оставлены сырыми. |
| Память старых решений | Низкая, если они выпали из окна. | Выше, если summary качественное. |
| Риск | Забыть важную старую деталь. | Накопить искажения в summary. |
| Лучший сценарий | Короткий чат, быстрые уточнения. | Длинная сессия, support ticket, многошаговая задача. |
На практике часто используют гибрид: последние сообщения хранятся как sliding window, старая история - как rolling summary, а важные структурированные данные - в session state.
Session state
Session state - это структурированная временная память. В отличие от conversation history, она не обязана быть текстом сообщений. Это может быть набор полей, которые runtime обновляет по ходу workflow.
Пример:
session_id: support_48291
user_intent: refund_request
current_step: verify_purchase
selected_order_id: ord_7712
known_constraints:
- user wants email response
- refund policy window may be expired
open_questions:
- confirm purchase email
- check regional policy
expires_at: 2026-08-04T18:00:00+03:00
Session state помогает агенту быть устойчивее, чем простая история сообщений. Агент может явно знать текущий шаг, выбранный объект, временные ограничения и открытые вопросы.
Типичные поля session state:
current_goal: текущая цель;current_step: шаг workflow;selected_entity: выбранный заказ, файл, документ, пользователь, проект;temporary_preferences: настройки только на эту сессию;tool_results_summary: краткое состояние результатов инструментов;open_questions: что еще нужно уточнить;blocked_by: что мешает продолжить;expires_at: когда состояние должно устареть.
Session state особенно полезен в продуктах, где агент ведет пользователя через процесс: support, onboarding, checkout, booking, диагностика, IDE-задачи, голосовые сценарии.
TTL и expiration
Сессионная память должна иметь конец. Иначе временные настройки начинают жить слишком долго и превращаются в ошибочные долгосрочные факты.
TTL задает срок жизни записи. Expiration определяет, когда запись перестает применяться. Это может быть время, событие или завершение workflow.
| Тип expiration | Как работает | Пример |
|---|---|---|
| По времени | Запись удаляется или игнорируется после заданного срока. | Голосовая сессия истекает через 30 минут неактивности. |
| По событию | Запись завершает действие после конкретного результата. | Checkout state удаляется после оплаты или отмены. |
| По workflow | Данные живут до завершения задачи. | IDE-агент хранит план только пока чинит конкретный баг. |
| По смене scope | Запись сбрасывается при переходе к другому проекту или пользователю. | Настройка текущего репозитория не переносится в другой repo. |
| По ручному действию | Пользователь или система явно очищает сессию. | "Начнем заново" сбрасывает выбранные параметры. |
TTL не обязательно означает физическое удаление сразу. Иногда запись остается в audit log, но перестает участвовать в context assembly. Важно различать хранение для аудита и активную память агента.
Session memory vs user profile
Одна из главных ошибок - автоматически превращать все сессионные наблюдения в долгосрочный профиль пользователя.
| Ситуация | Session memory | User profile |
|---|---|---|
| "Сегодня отвечай коротко, я спешу." | Да: временный стиль ответа. | Нет, если нет признака постоянного предпочтения. |
| "Всегда присылай мне сначала краткое резюме." | Может начаться в сессии. | Да, если пользователь явно формулирует устойчивое предпочтение. |
| "Для этого проекта не используй внешние зависимости." | Да, в текущем workflow. | Скорее project memory, не общий профиль. |
| "Сейчас выберем тариф Pro." | Да: состояние checkout. | Нет: это действие, а не предпочтение. |
| "Мой рабочий язык - русский." | Может быть подтверждено в сессии. | Да, если нужно помнить между сессиями. |
Критерии для переноса в долгосрочную память:
- пользователь явно говорит о постоянном предпочтении;
- факт будет полезен в будущих сессиях;
- scope понятен: user, project, team, organization;
- нет признака временности;
- запись разрешено сохранять;
- есть источник и timestamp;
- систему можно обновить или удалить позже.
Если хотя бы часть этих условий не выполнена, безопаснее оставить данные в session memory.
Summarization drift
Summarization drift - это накопление ошибок при сжатии истории. Оно возникает, когда summary многократно обновляется и постепенно отходит от исходного диалога.
Типичные формы drift:
- потеря отрицаний: "не использовать Redis" превращается в "использовать Redis";
- потеря условий: "только для демо" становится общим правилом;
- потеря uncertainty: "возможно, проблема в timezone" становится "проблема в timezone";
- смешивание ролей: мнение агента записывается как решение пользователя;
- исчезновение источников: непонятно, откуда взялся факт.
Снижать drift помогают несколько практик:
- хранить рядом ссылки на исходные сообщения или events;
- явно выделять решения, предположения и открытые вопросы;
- не переписывать summary бесконечно без доступа к исходникам;
- использовать structured fields для критичных данных;
- периодически пересобирать summary из первичных событий;
- помечать временные утверждения и scope.
Summary должно быть рабочим инструментом, а не единственным источником истины.
Схема session memory
Внутри одной сессии полезно сочетать несколько представлений: свежие сообщения, summary, structured state и временные результаты инструментов.
Эта схема показывает, что session memory - не один буфер сообщений. Это временный слой состояния, который помогает context assembly собрать правильный рабочий контекст для следующего шага.
Пример: длинный support conversation
Представим support agent для SaaS-продукта. Пользователь пишет:
У нас не работает импорт CSV. Вчера все было нормально, а сегодня половина строк пропадает.
Диалог длится долго. Агент уточняет формат файла, проверяет лимиты тарифа, просит пример строки, смотрит логи импорта, предлагает workaround, затем передает ticket инженерам.
Если агент хранит только последние сообщения, он может потерять важные детали из начала:
- проблема началась сегодня;
- вчера импорт работал;
- пропадает примерно половина строк;
- файл CSV связан с конкретным workspace;
- пользователь просит ответить по email;
- temporary workaround уже был предложен.
Хорошая session memory может выглядеть так:
Session summary:
- User reports CSV import dropping about half of rows.
- Regression: import worked yesterday, fails today.
- Workspace: acme-prod.
- User wants follow-up by email.
- Workaround suggested: split file into smaller batches.
Session state:
- intent = "support_csv_import_issue"
- current_step = "escalate_to_engineering"
- selected_workspace = "acme-prod"
- severity = "high"
- open_questions = ["attach sample CSV", "confirm timezone of import"]
- expires_at = ticket_closed + 7 days
Relevant tool observations:
- Import logs show validation failures for rows with empty external_id.
- No global incident currently active.
Это не обязательно долгосрочный user profile. Большая часть данных относится к конкретному support ticket. После закрытия ticket активная session memory должна истечь, хотя часть сведений может остаться в audit log или issue tracker.
Пример: IDE-ассистент
IDE-агент работает над задачей:
Найди, почему сборка падает после обновления TypeScript.
Session memory хранит:
- текущую цель: исправить сборку после обновления TypeScript;
- уже проверенные файлы:
tsconfig.json,package.json, build script; - команды, которые уже запускались;
- последнюю ошибку компилятора;
- гипотезы, которые не подтвердились;
- временное решение, которое пользователь отклонил;
- следующий шаг: проверить generated types.
Эта память должна жить, пока длится задача. Но после завершения не все нужно сохранять. Успешный вывод "падение было из-за старого generated type file" может стать episodic memory. Процедура "после обновления TypeScript перегенерировать types" может стать procedural memory проекта. А весь рабочий список проверенных файлов обычно остается только session state.
Пример: голосовой агент
В голосовом интерфейсе session memory особенно важна, потому что пользователь часто говорит короткими фразами:
User: Закажи столик на завтра вечером.
Agent: На сколько человек?
User: На четверых.
Agent: В каком районе?
User: Там же, где в прошлый раз.
Working memory текущего вызова может содержать последнюю реплику, но session memory должна удерживать:
- цель: забронировать столик;
- дату: завтра вечером;
- количество людей: 4;
- открытый параметр: район или ресторан;
- возможную ссылку на прошлое бронирование, если есть разрешение использовать историю.
В голосе session memory должна быть особенно компактной и устойчивой к ошибкам распознавания. Неверно услышанная деталь не должна автоматически становиться долгосрочным фактом.
Что сохранять в session memory
Хорошая session memory избирательна. В нее стоит помещать сведения, которые нужны для продолжения текущего взаимодействия:
- текущую цель;
- выбранный объект или scope;
- последние важные решения;
- временные предпочтения;
- открытые вопросы;
- уже выполненные шаги;
- релевантные результаты инструментов;
- блокеры;
- условия завершения workflow.
Не стоит сохранять как session memory:
- каждую реплику, если она уже не влияет на ход работы;
- случайные фразы без связи с задачей;
- чувствительные данные без необходимости;
- устаревшие tool results;
- предположения агента как подтвержденные факты;
- временные настройки как постоянный профиль.
Как session memory попадает в working memory
Session memory не обязательно целиком передается модели. Перед каждым шагом context assembly выбирает релевантную часть.
Например, если support agent уже знает selected_workspace, severity и current_step, в prompt можно передать краткий блок:
Current session:
- Intent: troubleshoot CSV import issue.
- Workspace: acme-prod.
- Current step: escalate to engineering.
- Important: user wants follow-up by email.
- Open questions: sample CSV, timezone of import.
Этого достаточно для следующего ответа. Полная история сообщений, все логи и все промежуточные вопросы могут остаться вне prompt.
Так session memory работает вместе с working memory: session memory хранит временное состояние, а working memory получает только нужный slice для текущего LLM-вызова.
Типичные ошибки
Ошибка 1: считать последние N сообщений полноценной session memory.
Sliding window полезен, но он не хранит структурированное состояние и может забыть важное старое решение.
Ошибка 2: сохранять summary без источников.
Если summary искажает факт, а исходные сообщения недоступны, ошибку трудно обнаружить и исправить.
Ошибка 3: превращать временные настройки в user profile.
Сессионная фраза "сейчас отвечай коротко" не должна становиться постоянной характеристикой пользователя без явного сигнала.
Ошибка 4: не задавать expiration.
Если session state живет бесконечно, агент начинает применять старые временные данные к новым задачам.
Ошибка 5: смешивать сессии и scopes.
Данные из support ticket одного workspace нельзя автоматически использовать в другом workspace или для другого пользователя.
Ошибка 6: хранить только текст, когда нужен structured state.
Для workflows лучше явно хранить current_step, selected_entity, open_questions, expires_at, чем каждый раз извлекать их из длинной истории.
Краткое резюме
Conversation memory помогает агенту помнить ход текущего диалога. Session memory шире: она хранит временное состояние ограниченного workflow, включая историю, summary, выбранные параметры, результаты инструментов и открытые вопросы.
Основные техники - sliding window, rolling summary и structured session state. Sliding window прост и точен для свежих реплик, rolling summary удерживает длинную историю, а session state делает workflow управляемым.
Session memory не равна user profile. Ее данные должны иметь scope, TTL или expiration. Только устойчивые, полезные и разрешенные сведения стоит переносить в долгосрочную память.
Вопросы для самопроверки
- Чем
conversation memoryотличается отsession memory? - В чем сильные и слабые стороны
sliding window? - Почему
rolling summaryможет приводить к summarization drift? - Какие данные лучше хранить в structured session state, а не только в истории сообщений?
- По каким признакам можно понять, что сессионный факт стоит перенести в долгосрочную память?
Что дальше
В следующей лекции мы перейдем к Episodic Memory: памяти событий и опыта. Там мы разберем, что считается эпизодом, зачем агенту timeline действий, как tool calls и ошибки превращаются в журнал опыта и почему эпизодическую память нельзя заменить профилем пользователя.