上下文即预算:八个杠杆与三种工作流模式
一周内就能收回成本的八种杠杆和三种工作流模式。
一个五十人的开发团队每个月可能在AI编码助手上默默烧掉三万美元,根本没人注意到。高级请求配额到第三周就告警了。账单来了,没人说得清钱花在了哪里。
成本是显而易见的痛点。另外两个则更隐蔽:
- 延迟。 更大的上下文需要更长时间。模型思考更多,你的等待也更久。
- 上下文腐化。 这是最出人意料的一点。Anthropic 和 Chroma 都曾表明,随着上下文窗口被填满,模型的回忆和推理能力会退化——即使远未达到标称的窗口上限。200K 令牌的模型在 150K 标记时的表现确实不如在 20K 标记时。更多的上下文并非免费;超过某个点后,它反而会带来损害。
能同时解决这三个问题的思维模型是:停止将上下文当作免费自助餐。把它看作每次对话中需要花费的预算。
本文是一份实用指南,教你如何精打细算:令牌实际流向了哪里,八种可以改变局面的杠杆,以及在此基础上叠加增效的三种工作流模式。
[LOADING...]
令牌实际上去了哪里
每次向编码助手发出的请求都是一叠桶。不同工具和会话的形状各不相同,但大致如下:
值得注意的几点:
- 工具模式的占比远超预期。 五个连接的 MCP 服务器很容易在每请求产生 5,000–10,000 令牌,你还没输入一个字呢。模型不一定使用该工具——模式无论如何都会发送。
- 对话历史无界增长。 一个 30 轮次的聊天,每提一个新问题都要为前 29 轮付费,再加上你新提交的。
- 输出量虽小,但每令牌成本高。 在大多数直接 API 中,输出令牌的成本是输入令牌的三到五倍。一条回复写着“当然!让我先解释一下我打算做什么……”然后再做正事——这纯粹是开销。
经验法则: 在优化之前,先分析你自己的流量。主导你会话的那个桶很少是你直觉以为的那个。
在 Copilot 上下文中,你不能直接看到令牌计数——但你能看到症状。打开 Output → “GitHub Copilot Chat”,观察 ccreq 行:每一行显示模型、延迟和每次对话的请求类型。当同一个问题在第二段聊天里耗时是第一次的三倍时,你就亲眼看到了令牌计量表在运行。
[LOADING...]
八大杠杆
这些不是按优先级排列的——而是按你在一次会话中自然遇到的顺序。前三个(上下文、缓存、工具)关乎请求的形状。接下来三个(指令、模型、输出)关乎你如何与助手对话。最后两个(仓库、可观测性)是让其他所有杠杆生效的基础。
[LOADING...]
A. 上下文工程——限定你的请求
大多数AI工作流中最大的浪费是:在 agent 模式的聊天中,带着完整代码库的访问权限提出模糊问题。agent 尽职尽责地探索,读取十个文件,找到它需要的两个,全部总结一遍,然后回答。每一步你都要付费。
比较一下:
糟糕: “重构订单确认邮件,使用新的模板引擎。”
agent 打开
src/main/java/com/example/demo/email/下的四个文件,读取WelcomeEmailService.java获取它不需要的上下文,考虑是否应该存在templates/资源目录,然后提出一个庞大的 diff,顺便还把某个方法重命名了。良好: “重构
#file:src/main/java/com/example/demo/email/OrderConfirmationService.java,使其调用#file:src/main/java/com/example/demo/email/TemplateEngine.java的render方法,而不是renderLegacy。保持行为一致。”agent 打开两个文件。diff 只有三个有意义的代码行。整个轮次的成本大约是十分之一。
明确是免费的。你提供的每一个 #file:(Copilot)或显式路径(Claude Code),都是 agent 不用去寻找的块。每一句“保持行为一致”都是一道护栏,防止出现200行的旁支任务。
周一做这件事: 把 #file: 作为默认习惯。只有在你确实不知道你不知道什么的时候,才使用带有广泛检索的 agent 模式。
B. 提示缓存——顺序很重要
现在所有主流提供商都支持提示缓存。Anthropic 和 OpenAI 对缓存命中收取约 基本输入成本的10%。Google 的 Gemini 则明确实现。机制相同:提示开头的一个稳定前缀在首次请求后被缓存,后续请求可以廉价读取。
因此,成本规范的关键在于顺序:
静态在上,动态在下。你能构造的最长稳定前缀就是最可缓存的前缀。
典型的反模式看起来无害却代价惨重:
将时间戳放在系统提示的开头会在每次请求时破坏缓存。你将整天为相同的10KB前导内容支付全价。解决办法是将动态内容推送到用户消息或提示的尾部。
周一做这件事: 审计系统提示的前200个令牌。任何每请求变化的内容都应该放在更靠后的位置。
C. 工具与 MCP 卫生——每个模式都是一笔开销
每个连接的工具都会将其完整的 JSON 模式随每次请求发送。一个典型的 MCP 服务器有 8–15 个工具,每轮对话成本 400–2,500 令牌。连接了五个服务器?你每轮对话可能要为模型从未调用的工具定义支付 5,000–10,000 令牌。
把 MCP 服务器当作浏览器扩展:有用,但只保留你今天真正需要的。
同样的规范也适用于你自己构建的工具。一个返回 { id, summary } 的工具是廉价的。一个返回 50 字段 JSON 对象的工具是昂贵的——模型每轮引用它时都要重新处理所有 50 个字段。默认使用紧凑的响应,并附带可选的 ?expand=... 参数供少数需要完整数据的调用者使用。
周一做这件事: 打开 MCP 服务器列表,禁用所有你本周没有主动用过的东西。按需重新启用。
D. 自定义指令与技能——一次固化
任何你在聊天中反复输入的内容都应该放在一个指令文件中。具体文件名可能不同——.github/copilot-instructions.md、CLAUDE.md、AGENTS.md、Cursor Rules——但原则相同:将你的团队约定写一次,提交,让仓库中的每次聊天都继承它们。
一个小例子胜过千言万语:
[LOADING...]
一共六行。从此,这个仓库里的任何聊天都不会再提议使用 Jest,不会在 diff 就能解决问题时抛出一个全文件重写,也不会用“当然!让我先解释一下我打算做什么……”作为开场白。
对于特定技术栈的规则,使用路径作用域指令。在 Copilot 中:
只有当匹配的文件在作用域内时才会加载此文件。仓库级规则放在全局指令中;特定技术栈的规则放在作用域指令中。两者都提交,都版本化,都是团队资产——而不是埋在某人 IDE 设置中的个人偏好。
周一做这件事: 检查你上周在聊天窗口中输入的内容。任何出现超过两次的东西都适合放入一个指令文件。
E. 模型路由——从便宜的起步,卡住时升级
日常任务默认使用最贵的模型,如果你不加干预的话。你可能刚刚为了同一个答案支付了 10 倍的代价。
一个可靠的默认路由表:
规则是:从便宜的起步,只在卡住时升级。 “卡住”意味着你已经在良好上下文下尝试了中档模型,但它显然没抓住要点——而不是“我想要更确信”,也不是“我有时间浪费”。
数学效果会叠加。一个 50 人团队,每天每人运行 20 次 agent,使用 10× 模型比使用 2× 模型成本高五倍——在大多数日子里,生成的 diff 却是一样的。
周一做这件事: 将默认模型固定为中档。让 Opus 成为一个带有明确理由的刻意选择。
F. 输出规范——diff 而非长篇大论
每个模型都有“让我先解释一下我打算做什么”的本能。这很礼貌,但也纯粹是成本。
同样的修复,两种问法:
“在
templateEngine.js中,welcome模板缺少一个感叹号。给我看更新后的文件。”→ 返回 30 行。(如果是 600 行文件,则返回 600 行。)
“在
templateEngine.js中,welcome模板缺少一个感叹号。只回复一个统一 diff,不要任何评论。”→ 返回 5 行。
在直接 API 上,输出令牌的价格通常是输入令牌的三到五倍。在像 Copilot 这样的按请求付费模型下,冗长输出同样有害:它增加延迟,为后续对话填充上下文,并更快地将较早的有用内容逐出。
杠杆在系统提示中。copilot-instructions.md 里的两行代码能让仓库中的每次聊天从此表现更好:
- 简洁,不要开场白。
- 优先使用 diff 而非完整文件。
周一做这件事: 添加这两行。
G. 仓库卫生——索引器看到什么
驱动检索的索引器遵循 .gitignore。收紧它。
重要陷阱: 如果一个文件已经被 git 跟踪,将其路径添加到 .gitignore 并不会解除跟踪——索引器仍然能看到它。你还需要:
对于密钥、测试夹具和供应商依赖,请使用组织/仓库级别的内容排除(大多数编码助手提供商都暴露此功能)。
仓库卫生的另一半是在每个模块的顶部添加摘要注释:
三行,约 50 令牌。现在“模板引擎做什么?”这个问题无需读取文件其余部分就能回答。每个模块顶部的 200 令牌摘要胜过每次重新读取 5,000 令牌的代码。
周一做这件事: 对不应被索引的内容执行 git rm --cached;为你最关心的模块添加三行摘要。
H. 可观测性——延迟就是你的令牌计量表
你看不到 Copilot 的令牌数量。你也不需要。使用你已有的代理:
当你第四个聊天的同一个问题比在全新聊天中耗时三倍时,你已经实时看到了上下文的膨胀。解决办法是“带摘要的新聊天”,而不是“等它完成”。
你还可以像 lint 包体积一样 lint 上下文膨胀。CI 中一个 30 行的脚本足以捕获最常见的退化:
将其接入 CI,上下文膨胀就不会在 PR 之间悄悄累积。
[LOADING...]
周一做这件事: 在你的编辑器旁放一个秒表,用一天时间数“一、二、三”(而不是千字文)。你会知道哪些聊天需要轮换。## 三种能产生协同效应的工作流模式
以上八个杠杆降低了单次交互的成本。而以下三种模式则能减少昂贵交互的次数。将它们叠加运用。
[LOADING...]
1. 拉尔夫·威格姆循环
以《辛普森一家》中那位以不懈愚蠢为超能力的角色命名。这个配方刻意显得朴实无华:
- 创建一个包含复选框任务的
TODO.md文件。 - 以廉价模型开启代理模式对话。
- 告诉它:“读取
TODO.md。选中第一个未勾选的项目。仅实现该任务。运行npm test。如果通过,勾选该框并提交。选中下一个。重复。”
就这样。代理逐个任务地遍历整个列表。
为何有效:
- 每次迭代从一个小而新的上下文开始。 聊天历史不会像在自由对话中那样不断膨胀。
- 状态存储在磁盘上(
TODO.md和 git 提交),而非对话令牌中。 - 廉价模型就足够了,因为每个任务都很小且独立。
- 可随时重启。 中途关闭聊天,开启新对话,再次运行提示——它会从上次中断处继续。
运行之后,git log --oneline 读起来就像一份变更日志:每个任务一个提交,提交信息以任务标题开头,可以轻松回退任何一步。与那种典型的“修复一切”的巨型提交相比,你再也回不去了。
[LOADING...]
2. 自动压缩
大多数助手不会主动进行激进压缩。你需要主动推动。
当对话达到上下文窗口的 60%–80% 时(你会知道的——回复开始变得缓慢),停下来并提问:
总结我们讨论过的内容:目标、我们接触过的文件、做出的决策、未解决的问题以及下一步行动。控制在 300 字以内,使用项目符号。
将输出保存到 plan.md。开启一个全新的对话。附上该文件:
从
#file:plan.md继续。下一步是……
新对话的第一个请求远比旧对话的最后一个请求要小得多。模型能够毫无障碍地接过主线。大致而言:一份 4KB 的摘要保留了 95% 的信号,却只花费了 3% 的成本。
额外的模式:这份摘要文件成为了一个稳定、可缓存的前缀。任何引用它的未来对话都能在压缩之上享受提示缓存的好处。一次总结带来两个叠加的胜利。
如果你对压缩的实现感兴趣,可以查看这个技能,它被一些自定义代理所使用。
经验法则: 每个任务一个对话。新任务 → 新对话,附上摘要。
3. 规划者 → 实现者 → 审查者(代理交接)
这是改变功能构建方式的一种模式。三个简短、聚焦的对话,三种不同的模型选择,以及一个共享的产物:
[LOADING...]
- 规划者 —— 昂贵模型,仅一次调用。读取功能需求,生成
plan.md,包含目标、验收标准、任务、预计会修改的文件、范围外项目以及风险。尚未编写代码。 - 实现者 —— 廉价模型,代理模式,全新对话。只看到
plan.md。在其上运行一个拉尔夫循环:选中第一个未勾选任务,实现,测试,勾选框,提交,重复。 - 审查者 —— 昂贵模型,全新对话。只看到
plan.md和差异。标记每个验收标准为通过或失败,列出错误、代码异味、范围外的修改。最后给出判定:通过或判定:需要修改。
三个对话,一个端到端功能大约需要 5–8 次优质请求。相比之下,一个全程使用最昂贵模型的巨型对话:轻松超过 30 次请求,且乘数高达 10 倍。
关键纪律:交接产物(plan.md、差异、审查笔记)是唯一跨越边界的东西。绝不传递聊天历史。这样你才能保持每个代理的上下文小巧、集中且廉价。
周一清单
将此固定到你的团队维基上。取有用的部分,忽略其余部分。
仓库设置
- 添加一个顶层指令文件(
copilot-instructions.md、AGENTS.md、CLAUDE.md或你工具对应的等效文件),包含构建、测试、代码检查、约定和输出风格规则。 - 为栈特定规则添加路径限定的指令文件(例如
src/下的测试约定)。 -
.gitignore忽略构建输出、快照和大型固件。对已跟踪的内容执行git rm --cached。 - 为你的前 10 个模块添加三行的“此模块做什么”的摘要注释。
- 添加一个持续集成代码检查,如果指令文件超过约 150 行或提示文件超过约 250 行则失败。
每次会话的习惯
- 关闭本次会话中不需要的 MCP 服务器。按需重新启用。
- 默认使用中档模型。仅在遇到困难时升级到顶级模型——并且要有理由。
- 对于范围明确的任务,使用
#file:(或你工具的等效方式)代替广泛检索/代理模式。 - 要求差异,而非完整文件。
- 每个新任务都在全新对话中开始。
- 当回复开始变慢时(约 60% 上下文),总结到
plan.md并在新对话中继续。
本周尝试的工作流模式
- 对一个包含杂务小任务的
TODO.md运行拉尔夫循环。 - 对一个真正的功能使用规划者/实现者/审查者拆分。留意请求数量。
- 将延迟视为你的令牌计。在一天中数一数阿姆斯特丹。
结语
思维转变很小,但收获不容小觑。
提示工程曾经是关于巧妙的措辞。上下文工程——本文真正讨论的内容——是关于窗口里有什么、没有什么。更小的提示、更少的工具、限定的检索、摘要而非历史、廉价模型做廉价工作、昂贵模型处理罕见的困难部分。
这些都不是新奇的。这些都不难。大多数团队实际上没有令牌问题,他们有的是纪律问题。这些杠杆很无聊。但协同效应是真实的:一个采用上述做法哪怕一半的团队,都会看到延迟下降、优质请求消耗显著降低,而且反直觉的是,回答质量会提高,因为模型不再被无关上下文淹没。
请记住这一句话:
最糟糕的令牌是你正在付费却没有注意到的那些。
留意你的 ccreq 行。数一数阿姆斯特丹。像花自己的钱一样使用预算。
本文《上下文即预算——八个杠杆与三种工作流模式》首发于 foojay。