数据截至 (上游 commit 7538cc96774b)
缓存优先:上下文工程与省钱三件套
30 秒导读: 本章只回答一个问题——一次 model step 到底把什么字节发给模型、为什么必须这么发。答案是:请求被硬切成两段,前面那段(system prompt + 工具 schema + few-shot)必须逐字节不变,后面那段(对话历史 + 工具结果)可以随便修、随便砍、随便折叠。前段不变,provider 的 prompt cache 才能复用;后段被压住,请求才不会无限膨胀。
本章不讲控制流(见 02-agent-loop)、不讲工具目录怎么生成(见 04-tools-and-gates)、也不讲 HTTP 请求体最终长什么样(见 05-model-layer)。本章只讲装进请求的内容,以及装之前做了什么手脚。
1. 这是什么:为什么"前缀"值钱
1.1 一句话背景
主流大模型 provider 都提供 prompt cache(提示缓存):如果这次请求的开头一段字节和上次完全一样,这段就不重新算,按更便宜的价格计费。
关键在"开头一段"和"完全一样"这两个词:
- 缓存是前缀匹配,不是集合匹配。第 1 个字节变了,后面全废。
- 匹配的是字节,不是语义。把工具 schema 里两个字段换个顺序,语义没变,缓存全丢。
1.2 所以 Kun 的做法
Kun 把每次请求物理切成两段,并给前段起了个名字叫 ImmutablePrefix(不可变前缀):
发给模型的字节,从头到尾
══════════════════════════════════════
① systemPrompt ┐
② tools[](名字排序) ├─ 稳定前缀:指纹上锁,逐字节不变 ← 想被缓存
③ few-shot 示例 ┘
─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
④ modeInstruction / contextInstructions ┐
⑤ history(压缩摘要 + 最近若干轮) ├─ 易变尾巴:每回合都在变
⑥ 本轮输入 / 附件 / 工具结果 ┘
这张图的读法:越靠上越该一动不动,越靠下越自由。Kun 的全部上下文工程,就是在保证"上面三层不动"的前提下,把下面三层压进预算。
1.3 项目自己把这条规矩写进了 system prompt
不是外部推断,而是 Kun 的 system prompt 正文里就有一节 Cache behavior,明说稳定指令与稳定工具 schema 要跨回合逐字节稳定,可变内容必须排在稳定前缀之后(kun/src/prompt/kun-system-prompt.ts:41-46,常量 KUN_SYSTEM_PROMPT)。
它甚至在开头自我说明"这份契约刻意保持稳定,放在每个请求最前面,好让 provider 的缓存在 Code / Write / Claw / plan / 工具续跑之间复用同一段前缀"(同文件 :4)。
2. 顶层全景:从磁盘上的历史到发出去的请求
一次 modelStep 里,历史要过六道工序才变成请求体。先看流水线,再逐道拆:
磁盘 session log
│
▼
① 治愈 healLoadedHistoryItems 补 id / 丢坏项(每 turn 只做一次)
│
▼
② 截断 effectiveHistoryAfterLatestCompaction 只留最后一次压缩点之后
│
▼
③ 配对修复 repairModelHistoryItems 孤儿 tool_result 不发
│
▼
④ 按需压缩 compactIfNeeded 超阈值就把老的折成一条摘要
│
▼
⑤ 瘦身 图片封顶 → token economy → 历史卫生
│
▼
⑥ 装配 baseRequest ← 稳定前缀 + 上面这坨
各道工序的落点:
| 工序 | 干什么 | 入口符号 | 文件 |
|---|---|---|---|
| ① 治愈 | 补缺失 id、丢掉结构非法的 item | healLoadedHistoryItems | kun/src/loop/history-healing.ts:9 |
| ② 截断 | 跳到最后一次有效压缩点 | effectiveHistoryAfterLatestCompaction | kun/src/loop/compaction-history.ts:3 |
| ③ 配对修复 | 保证 tool_call / tool_result 严格配对 | repairModelHistoryItems | kun/src/domain/model-history-repair.ts:11 |
| ④ 压缩 | 超阈值折叠成摘要 item | ContextCompactor.planCompaction / compact | kun/src/loop/context-compactor.ts:96,142 |
| ⑤ 瘦身 | 截图封顶、描述压缩、工具结果限额 | capToolResultImages / applyTokenEconomyToRequest / applyRequestHistoryHygiene | tool-result-image.ts:144 / token-economy.ts:84 / request-history-hygiene.ts:70 |