会话记忆与上下文预算
多轮对话里历史记录同样占用上下文预算,而且它会持续膨胀。常见策略是保留最近若干轮原文、更早的轮次压缩成摘要;当摘要与检索片段争抢窗口时,优先保证本轮检索片段与系统约束,因为答案的依据来自片段而不是闲聊历史。摘要本身也是有损压缩,涉及精确引用编号的场景必须单独保留编号映射,否则多轮引用会断链。
基本信息
| 预算构成 | 系统提示、历史摘要、最近轮原文、检索片段、输出预留 |
|---|---|
| 典型策略 | 保留最近 3 到 5 轮原文,更早的压缩为摘要 |
| 优先级 | 检索片段与系统约束优先 |
| 摘要风险 | 丢掉编号映射与限定条件 |
| 观测方式 | 统计上下文各部分的 token 占比 |
| 兜底 | 超预算时按时间顺序截断最旧内容 |
典型使用场景
- 客服多轮排查问题,需要保留前几轮的现象描述
- 长会话中历史把检索片段挤出窗口,答案越来越差
- 用户反复追问同一件事,说明摘要丢掉了关键限定
- 需要引用编号可回溯的多轮问答
- 按会话设置成本上限,控制单次调用预算
历史裁剪策略
历史裁剪策略
recent = turns[-4:] # 最近 4 轮保留原文
older_summary = summarize(turns[:-4]) # 更早的压缩为摘要
messages = [{"role": "system", "content": system_prompt},
{"role": "system", "content": "历史摘要:" + older_summary},
*recent,
{"role": "user", "content": question}]
# 摘要里保留引用编号映射,多轮引用才回指得到原文预算构成读法
| 部分 | 可压缩程度 | 注意 |
|---|---|---|
| 系统提示与约束 | 低,只能精简措辞 | 约束被压掉后模型行为不可控 |
| 历史摘要 | 高 | 容易丢编号映射与限定条件 |
| 最近轮原文 | 中 | 指代信息主要靠这里承载 |
| 检索片段 | 低,是答案依据 | 被挤出窗口时答案质量直接下降 |
| 输出预留 | 不可占用 | 不留空间会导致答案尾部被截断 |
摘要本身也会丢信息:依赖精确引用编号的场景,摘要生成时就要把编号映射保留下来,否则后续轮次的引用无法回溯。
多轮评测要按轮次分组看:第一轮正常、第五轮下滑,通常就是预算被历史吃掉,而不是模型能力问题。