长对话不烧钱:用 Prompt 缓存与摘要压缩降低 Token 成本的实战方法
长对话一跑就是几十轮,账单往往不是被某一次回答撑大的,而是被每一轮都重新带上的历史、系统提示和参考资料慢慢拖大的。本文给出一套可以直接落地的组合方法:用 Prompt 缓存复用不变部分,用摘要压缩控制增长部分,两者配合,先把成本降下来,再谈体验。
一、先算账:长对话的 Token 到底花在哪
一次长对话的输入通常由四部分组成:
- 系统提示与角色设定:每轮基本不变,却每轮都重复计费。
- 历史对话:轮数越多越长,是最主要的增长项。
- 检索到的参考资料:同一份资料可能在多轮中反复出现。
- 本轮用户问题:真正变化的部分,往往只占很小比例。
所以优化目标很明确:不变的尽量只算一次缓存价或只传一次,变化的尽量只传必要部分,历史则用摘要代替全文。先统计再优化,否则很容易在不该省的地方省错。
二、Prompt 缓存:把不变部分一次写好、多次复用
1. 缓存生效的关键是“前缀稳定”
多数厂商的 Prompt 缓存按前缀匹配。也就是说,开头一段内容完全相同,才更容易命中缓存;中间插一句不同的内容,后面即使相同也可能重新计费。
推荐的拼接顺序是:
- 系统提示、角色定义、输出格式要求;
- 长期不变的业务规则、术语表、常用参考资料;
- 本轮检索到的资料;
- 对话摘要;
- 最近几轮原文;
- 本轮用户问题。
把最稳定的内容放最前面,把最易变的内容放最后面。
2. 示例:拆分静态部分与动态部分
def build_messages(system_prompt, knowledge, summary, recent_turns, question):
# 前两段尽量保持稳定,是缓存命中的关键
static_prefix = [
{"role": "system", "content": system_prompt},
{"role": "system", "content": knowledge},
]
# 动态部分放在后面,每轮都会变化
dynamic_part = [
{"role": "system", "content": f"对话摘要:{summary}"},
*recent_turns,
{"role": "user", "content": question},
]
return static_prefix + dynamic_part
注意:不同厂商的缓存字段、最小缓存长度和过期时间不同,上面是通用结构示意,接入前请以所用模型厂商的官方文档为准,不要照抄字段名。
3. 缓存不是免费
缓存通常是折扣价,不是零成本;缓存还有过期时间,长时间不用的会话再次提问可能需要重新建立缓存。评估时要同时看命中率和缓存单价,不要只看“命中一次省多少”。
三、摘要压缩:历史不是越全越好,而是越准越好
1. 分层保留,不要一刀切
直接把全部历史删掉,模型会丢失决策背景;全部保留,成本又失控。实用的分层做法是:
- 最近 6 到 10 轮:保留原文,保证语气、细节和正在讨论的任务不丢失。
- 更早的历史:压缩成结构化摘要。
- 关键事实:单独抽取成清单,摘要里也不能丢。
2. 摘要模板示例
【对话摘要】
- 用户目标:为客服场景搭建长对话助手,重点是降成本而不是换模型。
- 已确定:系统提示放缓存前缀;摘要每 20 轮或输入超过阈值时触发一次。
- 未决事项:缓存过期时间、摘要模型的选型仍在评估。
- 关键数字:基线单轮输入约 20000 Token,目标降到 8000 Token 以内。
- 约束:不得把用户手机号、订单号等敏感信息写入长期摘要。
摘要要写“结论和约束”,不要只写“聊了什么”。模型下一轮需要的是能继续干活的信息,而不是流水账。
3. 触发条件要固定
建议同时设两个触发条件,任一满足就压缩:
- 轮数触发:例如每 20 轮压缩一次;
- 长度触发:例如输入 Token 超过 8000 就压缩。
压缩后要做一次自检:摘要是否保留了待办事项、已做决策、关键数字和未解决问题;缺一项就补一项,再继续对话。
四、两者组合的完整流水线
落地时可以按下面六步走:
- 统计基线:记录 10 轮对话的平均输入 Token、缓存命中率和单轮成本。
- 拆分消息:把系统提示和长期资料固定在前缀,把问题和最新上下文放末尾。
- 开启缓存:先在小流量上验证命中率,确认前缀没有被随机内容打断。
- 接入摘要:超过阈值时自动生成结构化摘要,替换更早的原文。
- 保留最近上下文:摘要之外,始终保留最近几轮原文,避免模型“失忆”。
- 定期复盘:每周看一次命中率、摘要质量和用户投诉,调整阈值和模板。
五、效果测算示例与常见避坑
下面是一组示意数据,用于说明测算方法,不是任何厂商的承诺价格:
| 方案 | 单轮输入 Token(示例) | 说明 |
|---|---|---|
| 基线:全文历史 | 20000 | 每轮都带全部历史 |
| 仅 Prompt 缓存 | 14000 | 不变部分命中缓存,仍按缓存价计费 |
| 仅摘要压缩 | 11000 | 历史变短,但系统提示仍重复计费 |
| 缓存 + 摘要组合 | 7000 | 不变部分复用,历史只保留摘要和最近轮次 |
常见避坑清单:
- 前缀里混入时间戳、随机 ID 或每轮不同的检索结果,会导致缓存命中率骤降。
- 摘要丢了数字、日期和决策结论,后续回答容易出现事实错误。
- 把敏感信息写进可长期复用的缓存或摘要,等于扩大了泄露面,敏感字段要先脱敏或排除。
- 只看单轮价格不看总成本:摘要本身也要花 Token,压缩频率太高反而可能不划算。
结语
长对话降成本没有银弹,关键是结构:稳定部分用缓存复用,增长部分用摘要控制,变化部分只传必要内容。先把消息顺序固定下来,再把摘要模板和触发阈值固定下来,最后用命中率和单轮成本两个指标持续验证,这套方法才能在真实业务里长期生效。
- 点赞
- 收藏
- 关注作者
评论(0)