context-budget 表
Day 41 立了「context 是有限 token 预算」的命题,Day 43 把 context-token 列成指标树输入层的一个叶子。
阶段: B5 · tool/context engineering + 指标树(Day 41-50) 标签: #context-budget #compaction #offload #token-quota
今日导引(由浅入深)
Day 41 立了「context 是有限 token 预算」的命题,Day 43 把 context-token 列成指标树输入层的一个叶子。
今天把这个叶子做实——context-budget 表:把窗口拆成 system / tools / 检索 / 历史四类配额,任一超额就触发裁剪策略。这是 B1→B18 曲线里第一次把「预算」从口号变成一张带配额列、实测列、超额标红的可提交表。
它紧接 Day 43,因为没有指标树先把 token 列为可测叶子,预算表就无处挂载;它通向 Day 45,因为 tools 这一类配额的超额,正是 Day 45 重设计(合并 + 收窄 schema)要削减的。
今天的「最小可判定产出」:对 AML Copilot 一次 SAR 流程,用已绿 tokenizer 实测四类 token,填出 3 行(或四类)budget 表,超额行标红——离线可出。
1. 机理精读
定义。 context budget 把模型上下文窗口拆成四类配额:system(系统提示)、tools(工具 schema/描述)、检索(retrieved evidence)、历史(对话/步骤历史)。
每类预先分一个 token 上限;任一类超额即触发裁剪策略。预算法的本质是逼迫显式取舍,而非默认把窗口塞满到模型自己开始丢信息。参考 Anthropic《Effective context engineering》(2025-09)的 budget / compaction 段落。
三类裁剪策略。 超额时有三种处理:
- 压缩(summarize / compaction):把长历史摘要成短摘要,保语义丢冗余——主流 agent 框架(Claude Agent SDK)已内建。
- 外置(offload):把大块内容写到文件/外部存储,context 里只留指针,用到再取。
- 丢弃(prune):直接删掉低信号片段(如过期的中间步骤)。
三者权衡是「信息保真 vs token 节省」:
- compaction 保真度高但有摘要损失(可能丢细节);
- prune 最省但可能误删(删错了无法恢复);
- offload 最保真但加一次取回延迟(多一跳 IO)。
选哪个取决于「被裁内容的可恢复性与信号密度」:高信号难摘要的(如关键证据)宜 offload,低信号冗余的(如过期中间步骤)可 prune,长但语义可压的(如多轮历史)宜 compaction。
为什么按这四类分。 因为四类的可压缩性与增长性不同:
system通常固定、最不该动;tools随工具数线性增长,是 Day 45 重设计的削减对象;- 检索按 query 波动,可用 top-k 截断;
- 历史随轮次单调增长,是 compaction/prune 的首要目标。
按类切开,才能对不同类用不同策略,而不是一刀切截断尾部。
关键权衡。 配额总和应留出余量给输出(completion)与「中段不被忽略」的安全垫(呼应 Day 41 的 lost-in-the-middle)。
配额过紧会频繁触发裁剪、丢约束;过松等于没预算、回到塞满模式。所以预算不是静态死数,而是「按这次任务的信噪比动态分配」。
与相邻概念的边界。 预算表是 Day 43 指标树「输入层 token 叶子」的执行细化:指标树告诉你「要测 token」,预算表告诉你「测完按四类配额判超额并裁剪」。
它也不同于单纯统计 token——预算表的价值在「配额 vs 实测」的差,以及超额触发的动作(裁哪一类、用哪种策略)。
2. 推导 / 手算 / 代码走读
代码日:走读 src/agent/eval/tokenizer.ts(实测 token)与 src/agent/mcp/contextAudit.ts(预算表实现)。
src/agent/eval/tokenizer.ts的tokenReport(texts, model):- 对一组文本逐条
encode().length计 token,给totalTokens / meanCharsPerToken; - 今天把四类组件文本(system / tools / 检索 / 历史)各作为一条喂进去,即得各类实测 token;
- tokenizer 已绿(vocab=456、2.01 c/t)。
- 对一组文本逐条
src/agent/mcp/contextAudit.ts的contextBudget(components, merges=200)——这就是 Day44 的预算表实现:- 入参是
Array<{label, text, quota}>,先trainBpe出模型; - 再对每个组件
encode().length算tokens,算overBy = max(0, tokens - quota); - 汇总
totalTokens / totalQuota / overBudget = rows.some(overBy>0); overBy>0的行即「超额标红」的判据。
- 入参是
- 同文件
auditToolContext(tools, merges=200):- 单独算
tools这一类配额的逐工具细分(descTokens + sigTokens); - 是预算表里
tools行的下钻来源——也直接喂 Day 43 指标树的「context tokens / tool」叶子。
- 单独算
- 诚实 CAVEAT(代码注释明写):
- BPE 每次调用按传入 corpus 现拟合,所以逐组件计数是该次调用内的相对值,跨调用不可比,也不等于生产分词器(tiktoken/cl100k);
- 要稳定跨调用数字,需
trainBpe()一次固定参考语料再复用; - 今天的预算表因此是相对配额审计,不是绝对计费——这条限制必须写进产出表的脚注。
预算表骨架(今天要填的产出形状,配额为示意):
| 类别 | 配额 quota | 实测 tokens | overBy | 超额? | 裁剪策略 |
|----------|-----------|-------------|--------|------|----------|
| system | 400 | 380 | 0 | | — |
| tools | 600 | 720 | 120 | 🔴 | →D45 收窄 |
| 检索 | 1200 | 1100 | 0 | | top-k 截断 |
| 历史 | 800 | 950 | 150 | 🔴 | compaction |
手算示例:设 tools 配额 600、实测 720,则 overBy = max(0, 720-600) = 120,该行 overBudget=true,标红(🔴),提示去 Day 45 削 tools;历史 超额则触发 compaction。注意上表 token 数为示意——真实实测来自对 AML SAR 流程跑 contextBudget(),且受「相对配额、非生产分词器」CAVEAT 约束。
3. 今日实战
- 取 AML Copilot 一次 SAR 流程作为被测样本(system prompt + 来自
toolRegistry的 tools schema + 检索到的证据 + 对话历史)。 - 用
src/agent/eval/tokenizer.ts的tokenReport()(或contextAudit.ts的contextBudget())对四类分别实测 token。 - 填一张 budget 表:每行
配额 quota | 实测 tokens | overBy,overBy>0的行标红。 - commit 产出的 context-budget 表,脚注注明「相对配额、非生产分词器」的 CAVEAT。
4. 今日实测 / 产出
- tokenizer 已绿,可离线测真实 token。
- 3 行 budget 表为「待跑(离线可出)」——产出 committed context-budget 表,含配额列、实测列、超额标红。
- tokenizer 真实基线已有:1760 tokens over 29 prompts。
(诚实状态:tokenizer 与 contextBudget() 已绿,预算表无 key 阻塞、纯待执行;真实基线 1760 tokens / 29 prompts 为已测数字,逐字保留。)
5. 常见误区 / 陷阱
- 拿本仓 BPE 数当生产计费 token:它是按本次 corpus 现拟合的相对值,≠ tiktoken/cl100k,也跨调用不可比(代码 CAVEAT 已警示)。
- 配额加满到窗口上限:要给 completion 输出与中段安全垫留余量,否则一超就丢信息。
- 四类一刀切截尾:不同类该用不同策略(system 别动、history 压缩/丢、tools 重设计削),无脑截尾会误删 system 约束。
- 只填实测列不填配额列:预算表的信息量在「配额 vs 实测」的差与触发的动作,单列 token 数等于没预算。
6. 学习资源(每条带 YYYY-MM)
- Anthropic, Effective context engineering for AI agents(2025-09)——budget / compaction / offload / prune 的主线来源。
- Liu et al., Lost in the Middle(2023-07,TACL)——为预算留中段安全垫的经验依据。
- Anthropic, Claude Agent SDK(2025-2026 持续更新)——compaction 内建于主流框架的现状参照。
- 本仓代码:
src/agent/mcp/contextAudit.ts(contextBudget/auditToolContext+ CAVEAT 注释)、src/agent/eval/tokenizer.ts(tokenReport)。
SOTA检查 (2026-06 更新)
- 当前主流方案:compaction(summarize)/ offload / prune 三策略在 2025-09 提出后,2026 仍是 SOTA,并已被主流 agent 框架(Claude Agent SDK)内建为默认。
- 是否仍 SOTA:是。四类配额 + 超额裁剪是 2026 经营长上下文的标准动作。
- 过时黑名单(AVOID):默认塞满窗口、靠模型自己丢信息;用相对 BPE 数冒充生产分词器计费;history 无上限单调增长不压缩。
- 下次复查点:是否出现更细的 KV-aware budget 工具(按 KV cache 占用而非纯 token 数做预算)——若出现,本预算表应升级到 KV 维度。
衔接
- 昨天:Day 43 — 指标树与 North Star(把 context-token 列为输入层叶子)。
- 今天:context-budget 表把窗口拆 system/tools/检索/历史四配额,超额触发 compaction/offload/prune。
- 明天:Day 45 — tool 重设计(合并 + 收窄),削减预算表里
tools这一类的超额。