跳转至

Conversation Lifecycle · 会话状态与多轮对话工程

Explanation · 原理资深

一句话定位

LLM 天然无状态 · 每次请求都从零开始。多轮对话是工程"骗出来的"——把历史消息 / 工具结果 / 用户上下文 / 记忆检索 拼成新 prompt · 每轮重来一次。问题是:历史越长越贵越慢越遗忘重点。本页讲会话生命周期契约:state 怎么存 · history 怎么裁 · 何时总结 / 检索 / 丢弃 · short-term 和 long-term memory 的分工。

TL;DR

  • 会话状态 ≠ LLM 状态:LLM 无状态 · 状态全在你的应用层
  • 6 类消息组件:system prompt · 历史对话 · tool 结果 · 检索 context · 用户画像 · scratchpad
  • 3 种 history 策略Full(短对话)· Sliding Window(保最近 N 轮)· Summary + Recent(超长会话主流)
  • 2026 Memory 分层:LIGHT 框架经典分层 · episodic(长期 · 全对话检索)+ working(近期完整)+ scratchpad(推理笔记)
  • Letta / ReMe 框架:OS 风格分层 memory · 主 context 作 RAM · 外部存储作 disk
  • 工程要点:Prompt Caching 命中率 · 裁剪触发点(70-80% context capacity)· 中断恢复 · checkpoint
  • Agent Patterns Memory 分工:Agent Memory 讲"Agent 要不要记住" · 本页讲"会话怎么组织"

边界

  • Agent 的 Memory 机制(Short/Long/Episodic/Procedural 四类)→ Agent Patterns §3 Memory
  • Prompt 模板版本化(存哪 · 谁改 · 评估)→ Prompt 管理
  • Prompt Caching(KV cache 级缓存)→ Semantic Cache
  • 本页专注会话级 state 组装 + 多轮 prompt 组装 + 长对话 history 管理

1. 业务痛点 · LLM 无状态的现实

朴素实现的崩溃

# 朴素 · 只发当前消息
for user_msg in user_inputs:
    reply = llm.chat([{"role": "user", "content": user_msg}])
  • LLM 每次都从零开始 · 不知道"刚刚你说的"
  • 体验:用户问 "它(上轮提到的某产品)多少钱" → LLM 不知道"它"是啥

真实多轮 · 状态全在你这边

history = []  # 你的责任 · 不是 LLM 的
for user_msg in user_inputs:
    history.append({"role": "user", "content": user_msg})
    reply = llm.chat([system_msg] + history)
    history.append({"role": "assistant", "content": reply})

问题马上来: - 10 轮后 · history 可能 5000 tokens · 成本累加 - 50 轮后 · history 超 context · 报错或丢信息 - 100 轮后 · 即使装得下 · "Lost in the Middle" · LLM 忽略中间信息 - 一天后回来继续 · 状态在哪?Redis?数据库?如何恢复?

这些都是会话生命周期工程要回答的问题。

2. 会话状态构成

6 类组件 · 每次 LLM 调用时组装

┌──────────────────────────────────┐
│ 1. System Prompt(角色 · 禁令 · 工具声明)│
├──────────────────────────────────┤
│ 2. Few-shot / 业务规则示例(可选)  │
├──────────────────────────────────┤
│ 3. 长期 Memory 检索结果(用户偏好 / 历史结论)│
├──────────────────────────────────┤
│ 4. 近期 History(最近 N 轮 user/assistant)│
├──────────────────────────────────┤
│ 5. Tool Results(当轮检索到的 docs · SQL 结果 · API 返回)│
├──────────────────────────────────┤
│ 6. User Query(当前一问)           │
└──────────────────────────────────┘

每个组件有不同的生命周期 · 不同的存放 · 不同的剪裁策略

组件 生命周期 典型存放 每轮重取?
System Prompt 版本化 · 部署级 Git / Prompt Registry ❌ 不变
Few-shot 版本化 Git / Prompt Registry ❌ 不变
长期 Memory 持久 Vector store / KV DB ✅ 检索
History 会话级 Redis / Postgres ✅ 全部或裁剪
Tool Results 当轮 In-memory ✅ 新生成
User Query 一次性

3. History 裁剪 · 三种策略

策略 A · Full History(完整历史)

messages = system + full_history + [{"role": "user", "content": query}]
  • :最全 · LLM 看得见一切
  • :tokens 爆 · 成本高 · 长对话超 context
  • 适用:短对话(< 20 轮)· 不差钱场景

策略 B · Sliding Window(滑动窗口)

WINDOW = 10  # 最近 10 轮
messages = system + history[-WINDOW*2:] + [user_query]
  • :tokens 稳定 · 成本可预测
  • :远程信息丢失 · 用户说过的约束被遗忘
  • 适用:短上下文相关(问答 / 客服)· 长程依赖弱

策略 C · Summary + Recent(总结 + 近期)· 主流

[summary of early conversation (LLM-generated)]
+
[last N turns in full fidelity]
+
[current query]
  • 触发点(常用启发):达到 70-80% context capacity 时 · LLM 生成前 M 轮的 summary · 用 summary 替代 M 轮 · 保留最近 N 轮全文
  • :兼顾长短期 · tokens 可控
  • :summary 有损 · summary 质量依赖 LLM
  • 适用:长对话应用(教练 / 研究助手 / 长工单)· 2026 主流路径

策略 D · 混合(Summary + Retrieval + Recent)· LIGHT 框架

[relevant past conversations retrieved by vector similarity]  ← Episodic memory
+
[summary of mid-session]
+
[last N turns full]
+
[current query]
  • LIGHT 框架(学术 / 2025+):三层记忆 · episodic(长期检索)+ working(近期完整)+ scratchpad(推理笔记)
  • :远程语义相关的片段也能拉回来 · 不靠粗糙 summary
  • :实现复杂 · 需要向量化所有历史
  • 适用:高级会话 agent · 重度生产应用

4. 2026 Memory 框架

实现策略 C / D 的几个框架:

框架 层级架构 特色 开源
LangChain Memory ConversationBufferMemory · SummaryMemory · EntityMemory · KnowledgeGraphMemory 4 种 memory 类型 · 每种单独选择
LangGraph Checkpointing State 自动持久化 · time travel 支持 恢复 / 回放友好
Letta(原 MemGPT) OS 分层:main context(RAM)+ archival(Disk)· LLM 自己决定 paging "无限"context 感 · 主流实现
ReMe 自动压缩 / 召回 / 持久化旧会话 轻量 · 透明集成
Mem0 User-centric memory · 跨会话学习用户偏好 个人助手场景
Zep 长期 memory + 知识图谱 商业 + 开源版 部分

选型

  • 简单应用:LangChain ConversationSummaryMemory 足够
  • 需要 checkpoint / 可回放:LangGraph Checkpointing
  • 长对话 · 要"无限记忆"感:Letta
  • 用户级 memory(助手记住"我是 vegetarian"):Mem0 / Zep
  • 自己造:基础 Redis + LLM summary + 向量库足以起步

5. 多轮对话工程要点

Prompt Caching 命中率(关键省钱)

System prompt / 工具声明放最前 · 这部分每轮完全相同 · 命中 Anthropic / OpenAI Prompt Caching

┌─ [可缓存前缀]
│  System prompt
│  Tool schemas
│  Few-shot examples
│  长期 memory(本次不变)
├─ [每轮变]
│  近期 History
│  Tool results
│  User query
└─
  • Anthropic 2024-08 Prompt Caching · 命中减 90% input token
  • 设计 prompt 时稳定内容放前 · 动态内容放后 · 命中率飙升

Context 容量规划

模型 context = 200k tokens(Claude / GPT-4)
预算分配:
  system + tools + few-shot    ~5k
  长期 memory 检索              ~3k
  近期 history                  ~20k
  当轮 tool results / context   ~10k (RAG 时更大)
  user query                    ~1k
  LLM response 预留             ~4k
  ─────────────────
  共计                          ~43k(留 80% 头空间)

70-80% 触发 history 压缩 / summary。

中断恢复 / Checkpoint

生产场景: - 用户对话到一半关机 · 第二天回来要接上 - Agent 长任务跑到一半挂了 · 要 resume

解法:每轮对话后原子持久化完整 state:

# LangGraph 自带
from langgraph.checkpoint.postgres import PostgresSaver

checkpointer = PostgresSaver(...)
graph = workflow.compile(checkpointer=checkpointer)

# 每次 invoke 自动存 · 用 thread_id 恢复
config = {"configurable": {"thread_id": "user-42"}}
result = graph.invoke(state, config=config)

自建:Redis / Postgres + 版本化 state schema · 关键是schema migration(state schema 变了 · 旧会话怎么办)。

用户画像 / User State

  • 独立于 conversation · 跨会话持久
  • 存:偏好(语言 / 详细度 / 领域)· 历史重要事实 · 权限 / 租户
  • 组装 prompt 时注入相关部分
  • Mem0 / Zep 是这个场景的专用框架

6. 典型生产架构

flowchart TB
  user[用户] --> api[Conversation API]
  api --> load[Load State]
  load --> redis[(Redis · hot session)]
  load --> pg[(Postgres · 长会话持久)]

  api --> mem[Memory Retrieval]
  mem --> vdb[(Vector store · 长期 memory)]

  api --> assemble[Assemble Prompt<br/>按 6 类组件]
  assemble --> llm[LLM Call · Gateway]
  llm --> parse[Parse response + tool calls]
  parse --> save[Save State Atomically]
  save --> redis
  save --> pg

  parse --> |定期| summary[Trigger Summary<br/>达 70-80% context]
  summary --> assemble

  api --> response[Return response]

7. 陷阱与反模式

  • 把 history 全塞 prompt · 长对话必崩 · 必须裁剪或总结
  • 只用 Sliding Window · 用户说"记住我叫 Alice"几轮后就忘 · 需要 summary 或 user profile
  • Summary 质量不监控 · 用小模型总结丢关键信息 · 下游回答错 · 关键信息丢失需告警
  • System prompt 放 history 里 · 不享受 Prompt Caching · 每轮都重算
  • User state 和 conversation state 混存 · 跨租户泄漏风险 · 一定分开
  • 无 thread_id / session_id · 多用户并发搞混 · 必须唯一标识
  • 不做 schema migration · state 结构改了 · 旧会话 deserialize 崩
  • 裁剪触发点固定(如"20 轮后")· 不看 token 实际占比 · 触发过早或过晚 · 应按 token 百分比
  • Memory 无限堆 · 长期 memory 越长召回质量反降 · 必须淘汰 / 压缩
  • Checkpoint 不原子:存了 user message 没存 assistant reply · 恢复时重复回答
  • LLM 自己 summarize 没做 eval · summary 越来越偏 · 定期抽查
  • 把 scratchpad / 推理笔记也 persist · 浪费存储 · scratchpad 是当轮的

8. 和其他章节分工

主题 章节
会话 lifecycle · history 裁剪 · state 组装 本页 canonical
Agent Memory 四类(Short/Long/Episodic/Procedural) Agent Patterns §3
Prompt 版本 · 模板管理 · DSPy Prompt 管理
Prompt Caching(KV 级)· Semantic Cache Semantic Cache
LLM context window 限制 · 工程影响 LLM Inference · Long Context 段
评估 session 质量 RAG 评估 + 自定义

9. 延伸阅读

相关