
文章目录
-
- 1. 先说结论:第 8 轮是分水岭
- 2. 环境信息
- 3. 三种策略:谁在什么场景下赢
- 4. 成本曲线:crossover 在第 8 轮
- 5. 比成本更贵的事故:摘要把编号摘没了
- 6. 与 0830② 的关系:省的是两笔不同的钱
- 7. 踩坑与避坑
- 8. 总结
- 参考链接
1. 先说结论:第 8 轮是分水岭
多轮对话有一个隐藏的成本结构:每多聊一轮,历史就变长一点,而历史在每次调用时都要全额重发。本文用一段 20 轮的香港物业客服投诉线程(粤语、真实感长度、系统提示 1,500 tokens 常驻)实测三种记忆策略:全量重发、滚动摘要、摘要加事实保护层。结果:从第 8 次调用起,全量重发的单次成本开始反超滚动摘要——整段对话跑完,全量策略多花 79,392 tokens,滚动摘要省 19%,摘要加事实层省 15%。但省 4 个百分点的代价可能是个事故:滚动摘要把案件编号 A-4821 摘没了。这笔账怎么算、事实怎么保,全文拆开。
2. 环境信息
- Python 3.13(纯标准库 json/re,零第三方依赖)
- 对话样本:20 轮物业客服投诉线程(走廊灯/后楼梯杂物/停车场道闸/会所冷气,四案穿插,粤语真实感文本)
- token 估算:CJK 字符约 2.2 字/token、拉丁约 4 字符/token 的近似法——估算用于策略对比足够,计费请以官方 tokenizer 为准
- 模型部分零调用:三种策略的 token 数全部是确定性算术
3. 三种策略:谁在什么场景下赢
策略 A——全量重发。 每次调用把系统提示加全部历史塞进去。质量最好(模型看到一切),成本平方增长:第 20 次调用要发 2,225 tokens,40 次调用累计 79,392。对话短于 8 轮时它反而是最省的——短对话根本不需要记忆管理,这是很多人踩的反向坑。
策略 B——滚动摘要。 保留最近 4 轮原文,更早的压缩成一段摘要。成本线性化(每次调用约 1,600-1,700 tokens 稳定),全程省 19%。但它有个致命暗伤,见第 5 节。
策略 C——摘要加事实保护层。 在 B 的基础上加一个结构化事实表(JSON:客户资料/案件编号/各案状态),与摘要并列发送。比 B 多花 4%,换来的是编号、电话、承诺事项这类标识符永远不被压缩。
核心代码骨架:
# depends on: SYSTEM_TOKENS(常量), est_tokens(), SUMMARY_B, FACTS_C, TURNS
# full runnable version in the repo file conv_memory_manager.py
KEEP_LAST_K = 4 # recent turns kept verbatim
def ctx_tokens(i: int, with_facts: bool) –> int:
head_n = max(0, i – KEEP_LAST_K)
t = SYSTEM_TOKENS # resident, every call
if head_n:
t += est_tokens("SUMMARY: " + SUMMARY_B)
if with_facts:
t += est_tokens("FACTS: " + json.dumps(FACTS_C, ensure_ascii=False))
for r, c in TURNS[head_n:i]:
t += est_tokens(c) # recent turns, verbatim
return t
这套「阈值前全量、阈值后摘要、事实永不在摘要里」的三段式可直接抄进任何多轮对话应用,建议收藏。
4. 成本曲线:crossover 在第 8 轮

三条线的形态说明一切:红线(全量)持续爬坡——每多一轮就抬一截,永不回头;绿线(摘要加事实)第 8 轮后走平——它的成本由常驻的摘要、事实表和固定窗口决定,与对话总长无关。灰虚线标出的 crossover 第 8 轮,就是"该不该上记忆管理"的决策点:预计对话不超过 8 轮,全量重发既简单又省钱;可能超过 8 轮,立刻上滚动摘要。注意这个数字依赖系统提示长度(1,500 tokens)——系统提示越长,crossover 越早。
5. 比成本更贵的事故:摘要把编号摘没了

策略 B 全程省 19%,比 C 还多省 4 个百分点——但它有一个实测演示的事故模式:滚动摘要写的是"業主投訴多項設施問題……“,案件编号 A-4821 在压缩时丢了。对话进行到中段,客户问"我的案件编号是多少?”,模型的上下文里已经没有这串字符——它只能编一个或者承认失忆。物业客服场景里,编号是客户查询的唯一凭证,丢了它等于案件失联。
解法不是"把摘要写得更好"——摘要天然压缩事件、天然倾向于丢标识符,这是它的工作原理。解法是把标识符从摘要的职责里剥离:结构化事实表(策略 C 的 FACTS)与摘要并列发送,事件归摘要管,标识符归事实表管。两者失败模式不同,所以生产环境两个都要。事实表的维护规则也简单到不需要聪明:编号、电话、金额、日期、承诺事项——出现即入表,永不依赖摘要携带。这行纪律值得收藏在团队的开发规范里。
6. 与 0830② 的关系:省的是两笔不同的钱
0830② 讲过 Prompt Caching——缓存重复前缀省 66%。它和本文解决的是同一枚硬币的两面:caching 省的是"同一对话内重复发送历史"的钱(读 0.1 倍),记忆管理省的是"根本没有必要发送的历史"的钱。两者可以叠加:滚动摘要让每次调用变短,caching 再让常驻系统提示变便宜。先做记忆管理(结构决策),再开 caching(计费优化),顺序不要反。
7. 踩坑与避坑
| 短对话也上滚动摘要 | 每轮重复发摘要反而多花 4% | 先算 crossover(本文第 8 轮),短对话全量重发 |
| 摘要里丢标识符 | 客户问编号,模型失忆或编造 | 事实保护层:编号/电话/承诺进结构化 JSON,不进摘要 |
| token 估算当精确值 | 成本核算与账单对不上 | 近似法做策略对比,计费用官方 tokenizer |
| 摘要只在轮数触发、不看信息量 | 编号在压缩瞬间丢失 | 标识符出现即入事实表,与轮数无关 |
| 常驻系统提示不计入对比 | 低估全量策略的每轮底价 | SYSTEM_TOKENS 是每次调用都要付的,永远算进去 |
这张表建议收藏,上任何多轮对话应用前先对一遍。
8. 总结
20 轮粤语客服线程实测出的三个数字:crossover 第 8 轮、全程省 19%、事实层多花 4% 买一个"编号永不丢"。对话记忆管理的本质不是省钱技巧,是把"模型该记得什么"从隐式的上下文堆砌变成显式的信息架构——事件进摘要、标识符进事实表、近 4 轮保原文、其余全丢弃。这套分层在 20 轮的投诉线程里成立,在 200 轮的长期助理场景里更加成立。下一步顺理成章:把摘要步骤本身交给一个便宜的模型调用(mini 档),再和本文的算术对比一遍真实成本。这篇也收录进「开学季·九月创作之星博客挑战赛」——多轮对话的账,越早算越省。
参考链接
原创声明:本文为原创技术实践,token 数为本地确定性算术(估算近似,非官方 tokenizer),模型部分零调用、零计费,全部逻辑可复现。


