前五篇立的是骨架:成本阶梯、异步整理、回忆机制。但两套架构相同的压缩系统,跑出来的效果可以天差地别------差距不在架构,在参数和细节。这篇是压缩篇的收官,讲肌理:阈值怎么定、参数怎么联动、坑怎么避。
架构决定下限,参数决定上限
压缩系统最常见的死法不是"没有设计",而是"设计对了、参数拍脑袋":阈值抄一个、tail 拍一个、各层阈值互不知情。架构图都长得差不多,功力全在参数族里。先讲最大的一颗参数:阈值。
阈值选择:1M 时代的双轨制
旧逻辑是"防爆窗":阈值 = 窗口 − 输出预留 − 缓冲,撞到之前压。CC 就是这个公式(有效窗口 − 13k,外加 warning 20k / error 20k / blocking 3k 多档告警),Codex 是窗口 90%。200K 时代这是对的------物理撞窗是主要矛盾。
1M 改变了前提 :物理撞窗变难了,但另外两件事没变------注意力稀释 (塞得下不等于用得好,中段信息利用率随长度劣化是实测规律)和成本线性增长(每轮都带全量前缀,cache miss 一次 prefill 天价)。阈值继续贴着窗口顶走,等于让模型长期在"塞满但变笨"的区间工作。
所以阈值变双轨:

- 信噪比阈值(主轨):远低于物理窗口,由注意力有效区间和预算决定,常态触发主动压缩------它的目标不是"别炸",是"保持模型在高质量决策区间";
- 硬阈值(辅轨):窗口安全线,兜底防爆,理想情况永远不触发。
推导要素四个:注意力有效区间(主约束)、prefill 成本曲线(越长越贵,缓存 miss 的代价随长度平方级感受)、缓存 TTL(决定原位清理窗口)、输出预留(硬阈值的唯一扣减项)。注意权重变了:200K 时代输出预留是主角,1M 时代注意力区间是主角。
阈值联动:阈值是参数族,不是常数
这是业界几乎没人讲透的一块。一个压缩系统里有七八个阈值,它们不是独立常数,是一张有向联动网:

- 单调性约束:pointer 阈值 < 信噪比阈值 < 硬阈值。序关系破了系统就精神分裂------pointer 阈值比压缩阈值还高,等于"大结果永远不折,等整体爆了再说";
- tail 预算 ← 阈值:tailKeep = min(上限, 阈值/5)。阈值调低,tail 跟着缩------否则压完剩下的 tail 又把阈值顶穿,陷入"压了白压"的抖振;
- 预压缩触发 ← 阈值 × 0.8(第四篇):提前量大了浪费算力,小了救不回来,系数跟着主阈值走;
- L1 时间窗 ← 供应商缓存 TTL:CC 实证 60 分钟对齐 1h 缓存 TTL------窗口必须取自供应商事实,不是拍一个"差不多";
- 判定数据源唯一:所有阈值判定共用上一轮真实 Usage,一个口径。两个口径就会有两个"真相",阈值之间互相打架。
工程结论:把阈值族收敛成一个派生体系------一个主阈值 + 一组派生规则,改主阈值全族跟着走;新增任何阈值,先回答"它和现有阈值的序关系是什么"。
话题折叠:从按时间切到按语义切
L2 的切分单位是时间前缀:早的折、晚的留。单线程任务没问题,但 C 端长会话是多话题交错的------上午聊部署、中午聊生日礼物、下午又回到部署。按时间切会把"部署"切散:前半进了摘要,后半留在 tail,话题的完整语境被劈成两半。
改进方向是话题折叠 :已明确结束的话题整体降级为一张话题卡------结论 + 未兑现承诺 + 相关文件/产物指针。三条纪律:
- 只折明确结束的(用户明示、或长期未触及且已有交付)。把进行中的话题折了就是失忆,拿不准的一律不折------第五篇的回忆机制兜底,保守的代价只是多占体积,不是丢信息;
- 话题卡结构就是回忆线索卡:指针栏(路径、时间范围)恰好是回忆检索最有效的线索;
- 话题卡是异步整理的产物(第四篇阶段二):安全点上后台生成,不占决策路径。
坑位清单:七条学费
架构看得懂,坑得摔过才知道。以下每条都是真实学费(含别家的,注明出处):
① 静态估算当裁判。 字符数估算 token 对 JSON/代码/中文混杂负载系统性失真------我们踩过估算差 3 倍的坑:四分钟空压三次,缓存命中率从 99% 打到 10%。解法:估算只做下界,裁决一律用上一轮真实 Usage 当轮校准。
② Usage 口径坑。 有的供应商 total 返回 null,要 input + cacheRead + cacheCreation 加和。漏了就是"用量永远为零,压缩永远不触发"。
③ 落库格式断缓存。 消息落库用了 JSON 列类型,读取时键序重排,投影字节跨 run 不一致,prompt 缓存全断------落库格式也是字节确定性的一环,用纯文本列。
④ 摘要自身 PTL。 压缩请求自己撞 prompt_too_long:按轮分组丢最旧的组重试,预算耗尽跳过本轮(历史不动)。不做逃生通道,压缩会把自己压死。
⑤ 压缩调用太长断连接。 摘要调用 5~10 秒起步,远端 bridge 的 WebSocket 会被服务端当空闲断开------CC 的解法是会话保活信号(30s 间隔)。
⑥ fork 参数失配断缓存。 摘要 fork 想共享主前缀缓存,cache-key 参数必须全等------CC 源码注释专门警告:多设一个 maxOutputTokens,thinking 配置失配,缓存当场作废。
⑦ 摘要与 tail 双重计费。 with-tail 的摘要 prompt 不明说"最近原文逐字附后",摘要会把 tail 内容再写一遍------同一段内容付两份钱。prompt 必须与保留策略联动(第三篇摘要语义通路)。
三个容易被漏掉的优化点
缓存基线监控重置。 压缩后前缀重建,cacheRead 必然跳水------如果不重置监控基线,压缩本身会被误报成缓存事故。CC 漏过这步,20% 的缓存断裂告警是误报。监控信号永不说谎的前提,是你帮它排除"自己人"。
压缩后预热。 换投影后的第一轮是全量 prefill------压缩省了钱,但用户在这一轮能感知到慢。主动 warm-up(换完立刻发一次轻量调用重建前缀缓存)把这笔账从用户路径上挪走,与第四篇的异步哲学一脉。
restoration 预算制。 恢复清单是把折叠抹掉的上下文加回来,没预算就白压了。CC 的定额可参考:文件最多 5 个、总 50k、每个 5k;Skill 总 25k、每个 5k。数字可以调,"有硬顶"这件事不能省。
收尾
压缩四篇下来,图景完整了:成本阶梯是骨架,异步整理是节奏,回忆机制是底气,而这篇的参数族是肌理。收个尾:
架构决定压缩系统的下限,参数决定上限。阈值双轨定方向,参数联动定秩序,坑位清单定生死------压缩系统最后拼的,全是这些说不出口的细节。
系列预告:压缩篇到此收官。下一篇进入工具篇《工具系统》------Schema 是合同,披露分三级:工具的协议怎么定,模型才用得又准又省。
智创者社区:apmen.cn