第一章 账单到底花在哪
一条简短需求,为什么会产生远多于输入框字数的消耗?先拆开一次完整请求。
本章关键词 · 量价分开你敲进输入框的那句话,从来不是请求的全部。系统提示、工具说明、项目规则、会话历史——这些东西跟着你的问题一起塞进模型。想看懂账单,先搞清楚这支随行队伍有多大。
我翻过一次自己的实际请求明细:新开一个会话,只发一句「Hello」。第一次请求的输入就有 28,358 Token。具体数字会随环境变,但「基础上下文是笔大钱」这件事是通用的。你自己的环境,也值得看一眼。
1.1 一次请求里,除了你的问题还有什么
在这个案例中,用户的问候只占很小一部分。把这份基础上下文拆成七类,方便判断哪些由客户端提供、哪些自己能调。
| 构成部分 | 大约规模 | 费用能不能省下 |
|---|---|---|
| 核心系统提示 | 4,000–5,000 | 通常由客户端提供,用户可控范围有限 |
| 内置工具说明(Read、Bash 等参数 Schema) | 10,000–14,000 | 依赖客户端配置,部分可延迟加载 |
| 外部扩展 MCP 服务与插件 | 随已加载定义与配置变化 | 不用的插件能关掉 |
| 项目规则文件 (CLAUDE.md / .cursorrules) | 500–800 | 能够自主删减精简 |
| 电脑运行环境与路径信息 | 500–1,000 | 自动生成,基本不能省 |
| 预先挂载的专项技能 (Skills) | 1,000–2,000(示例估值) | 区分常驻摘要与按需加载的正文 |
| 你敲进去的那句「Hello」 | 约 4 | 占比不到万分之二 |
只在输入框里抠两三个字,改变不了整项任务的成本。真正该查的是:哪些上下文每轮都跟着走,它们还在帮模型干活吗?该说清楚的需求,反而要写明白。
1.2 历史如何累积为重复输入
模型本身无状态。它这次能看到什么,完全取决于这次请求里实际塞进去的上下文。
点一次发送,后台可能触发多次模型调用。每一轮调用前,客户端都会把系统提示、工具定义、会话历史重新拼装成完整上下文。如果模型调用了工具,拿到工具返回结果之后,还会再发起一轮模型请求。自动压缩、裁剪会话历史、工具延迟加载这些机制,都会改变模型实际读到的上下文。
这解释了下图的“滚雪球”现象:历史越长,后续调用需要重复处理的输入就越多。这里讨论的是上下文累积机制。
第 N 次调用的输入量,约等于基础上下文 + 仍保留的历史 + 本次新增。累计输入要逐次相加——调用次数越多,前面的历史被重复计费的次数也越多。这才是滚雪球真正的来源。
假设同一任务先查状态、再改代码、最后跑测试,触发了 3 次模型调用。每次输入约 2 万 Token,累计输入就约为 6 万 Token。工具执行次数与模型调用次数也要分开统计:独立工具请求能合并在同一轮。存在依赖的步骤,必须顺序进行。
1.3 把 Token 数量与实际费用分开看
算账的第一性原理,可以用一个核心公式概括:成本 = 量 × 价 × 次。量是每次请求带进多少 Token(前缀、历史、代码切片、工具回显);价是每个 Token 算多少钱(依赖缓存命中率与模型档位);次是同样的内容被重复计费了多少轮(交互轮数与失败重试)。三个因子是相乘关系,任何一项失控都会被另外两项成倍放大。看账单时,先区分以下四类用量:
| 计费类型 | 单价差距 | 对应内容 |
|---|---|---|
| 缓存命中读取 | 0.1×(示例) | 满足缓存条件的重复前缀,按模型缓存价计算 |
| 普通未命中输入 | 1.0× 基准 | 本次新发给模型的全新内容 |
| 缓存初次写入 | 1.25×(5 分钟写入示例) | 第一次写进短时缓存的新内容 |
| 模型生成回复 | 5.0×(示例) | 模型生成的计费输出;推理用量的归类依平台而定 |
在同一模型的价目下,缓存读取 0.1× 与输出 5× 意味着两者单价相差 50 倍。数量占比与费用占比必须分开看,不能把不同模型的最低输入价和最高输出价拼在一起比较。
即便大量内容命中缓存,输入总量上去之后,累计读取成本依旧不容小觑。输出虽然字符看上去不多,但单价更高,同样可以成为开销大头。工具返回、人工输入的占比随任务差异巨大。优先查看自身用量分类与账单再确定优化方向;字符只能定位大块文本,无法换算真实花费。 知道了量价分离的道理,再回头看一个最常见的疑问:同样的请求发第二次,为什么有时候便宜很多?
1.4 前缀缓存:哪些内容可以复用
Prompt caching 让重复前缀的处理结果得以复用,降低符合条件的重复输入成本。它缓存的是前缀处理结果,回复仍需要生成。
拿 Anthropic 的前缀缓存举例。想要命中缓存,前缀内容必须完全一致,同时满足最小长度、有效期、缓存控制等条件。只要靠前的内容发生改动,后面一大段前缀就会缓存失效。只有位置靠后、且内容完全不变的短前缀,才能够继续复用。缓存读取实际折扣,请以对应模型价目表为准。
拿盖楼打个比方:请求上下文就像从地基往上盖的一串严格依赖链——系统提示 → 工具定义 → 项目规则 → 偏好记忆 → 历史消息 → 本轮新增。地基越稳固,上层就越容易被缓存复用。一旦改动靠前的内容,后面一大段前缀就会立刻失效。这也是为什么绝不要在任务排查中途频繁改配置:排查到第 20 轮时随手改动前部的 Rules,不仅导致规则本身需要重新写入,后面整整 20 轮原本可以 0.1× 命中的历史前缀,全得当场重新按全价算一遍。
能控制请求组织方式时,从两点入手:
- 稳定内容前置,易变信息后置:在可配置的范围内保持系统提示与核心工具说明稳定,将动态时间戳等易变内容放在适当的后部位置;
- 综合评估稳定与精简:删改前缀可能带来一次缓存重建,但更短的上下文也可能节省后续费用,需要按整个任务周期比较。
Anthropic 默认缓存有效期为 5 分钟(可配置为 1 小时),每次命中会自动刷新倒计时。但在实际开发中,如果中途离开去倒杯咖啡或长时间思考,一旦超过 5 分钟,回来后的下一轮请求就会退化为全额冷启动。在长耗时任务中保持连贯交互,也是守住缓存收益的细节习惯。
第二章 使用习惯治理
把目标、范围和验收标准说清楚,让每一次往返都推动任务向前。
本章关键词 · 验收先行随口抛出一句「把这个下单接口优化一下」,模型就得自行揣测改动目标:究竟是查询性能、参数校验,还是防重复提交逻辑。一旦判断方向出错,后续全部模型调用,都在为这种猜测付出成本。把需求描述到位,这部分开销原本就可以避免。
上一章讲清楚了:历史和工具结果都会跟着进下一轮。把需求说清楚的价值,就是让模型少走弯路、更快拿到做对事情所需的信息。下面八个习惯覆盖提问、材料、规则、规划、会话、重试、交付和输出约束,一个个往日常里加就行。
2.1 验收条件和需求写在同一条消息里
要求模糊,模型判断目标的成本就高。只说一句”优化下单接口”,它只能瞎猜你是要加参数校验、改 SQL 索引,还是做分布式防重提交。猜错一次,所有试探性的改动都照样计费;后面推倒重来,花掉的钱一分不退。
更好的做法是同一条消息里把行为和验收点都说清楚。以下单接口为例:直接写清防重提交、错误码、并发测试要求,Redis 锁作为约束一起交代。先说什么算完成,再谈锁时长、事务边界和释放。
版本 A:模糊的提问要求
随口发一句:“把这个下单接口优化一下。”
模型只能凭空猜测你是要改 SQL 索引、补参数校验,还是做分布式防重提交。它猜错一次,所有的试探性修改都要计费,后续推倒重来的成本一分不退。
版本 B:同一条消息交代验收点
一次性给出行为和验收点:“为下单接口增加防重提交;沿用现有 Redis 锁方案,Key 为 order:submit:{userId},先评估 3 秒锁时长能否覆盖事务。冲突返回 ORDER_DUPLICATED;核对锁释放与事务提交顺序,并补齐并发扣库存、锁过期和失败重试测试。”
多写几句验收要求,能大幅减少后续补充条件的往返沟通。
检验要求清不清楚,问自己一句就够了:模型交活的时候,我能不能凭最开始那句话判断它做完了?把已知的验收条件提前写出来,探索和验证才有方向。没想清楚的部分,也明确标成"待讨论",别留着让它猜。
如果需求还没想透,先列出待定问题,把大方向沟通对齐。这种探索性质的简短沟通成本很低。最怕的是直接上手实现,写完又整体推倒重来——多出的开销,本质就是不断膨胀的会话历史带来的代价。
目标:希望改变什么行为,当前问题是什么。
入口:相关文件、函数或已有证据。
约束:需要保留的接口、业务规则与兼容要求。
验收:如何判断完成,需要哪些测试。
待定:目前还不清楚、需要先核实的部分。
2.2 给出入口文件,范围按需扩大
如果你已经知道问题发生在哪个文件,就直接给出具体路径和函数名:“从 OrderServiceImpl.java 的 createOrder 方法开始排查,重点看扣库存前分布式锁的加锁时机,必要时再看 FeignClient 调用的库存微服务接口。”模型拿到确切的门牌号,省掉的是漫无目的的全盘扫描和各种误读。
一个上千行的代码文件,通常真正要改的只有其中三五十行。看病拍胸片就行,别让模型每次都做全身 CT:养成让模型用行号切片(offset/limit)读取的习惯,而不是整本翻开。用编辑器的代码选中引用功能时也要留个心眼:界面上看似只高亮了 3 行,有的工具后台却静默偷渡了整个文件,账单可能差出十倍。
范围不能一味收得过小:函数依赖的核心接口、关键调用方,该读取依旧要读取。如果强行砍掉关键上下文换来少量 Token 节省,一旦模型理解错误触发返工,额外开销会把这点节省全部吞噬。
2.3 日志只贴能定位问题的那一段
粘贴运行报错时,挑出最关键的三样信息即可:执行的失败命令、关键报错提示与相关堆栈。跑测试失败时,先把失败用例的名字和报错差异给它。几百行顺利通过的废话留在本地,模型需要时再补充。
遇到超长的完整日志,存成本地文件,把路径给它,让模型自己去读相关段落。筛选报错时要保留真实的退出状态,终端回显显示得短,不代表命令真的跑通了。遇到异步任务失败,原因往往出现在很早的记录里,按请求编号去找,别只截取最末尾的连锁报错。
2.4 常驻规则只放每轮都要用的东西
配置要按生命周期分层:越高频、越短越适合常驻;越低频、越重越必须按需触发。
很多开发者把所有约定一股脑塞进全局规则,导致每轮调用的系统底噪飙升。现代 AI 编程工具通常有五层配置载体,它们的加载时机与缓存代价截然不同:
- Memory(偏好记忆):全量常驻 System Prompt。只适合放单句稳定偏好(如“统一 4 空格缩进”);位于前缀链前端,中途改一条整条缓存链断裂。
- Rules(规范约定):高频命令与核心红线常驻;低频专用规范(如数据库迁移、发版清单)应设为按需触发,不触发时零开销。
- Skills(能力工作流):存在单向流入陷阱。未触发前仅占几十 Token 描述;但一旦被触发,整篇流程与文档永久注入对话历史,后续每轮都要带着走且无法卸载,切忌随意预加载。
- MCP 工具(外部扩展):这就好比去餐馆看菜单,菜单上只印菜名就行,千万别把每道菜的做法火候全印在上面。每个工具 Schema 占 200~500 Token 常驻底噪;调用结果还会不断沉淀进历史。不用的 MCP 插件务必及时关掉。
- 项目文档(长篇背景):用路径引用代替全文内联。规则里只写“规范参见 docs/api.md”,让模型按需读取,坚决避免将上千行文档直接内联进规则。
算一笔常驻成本账:一份 2,000 Token 的常驻规则,在 30 轮调用中累计参与计算就达 60,000 Token。将缩进、引号等格式交给格式化工具,把业务细节分流到子文档,根规则只留全局红线与关键命令。
规则不仅要分类型,还要分层级。根规则管住全局,子目录再按需挂载细则,实现局部隔离。
以开源项目常见的规则目录组织为例,可以借鉴的是它的分层结构:根文件只放构建测试命令与核心业务约束;架构原理、测试政策和发布流程通过链接放入 docs 与 .agents,需要时再由模型按需读取。
目录级规则继续细分适用范围即可。图中标出 22 份嵌套 AGENTS.md 作为组织示例。不同客户端对嵌套文件的发现与加载方式并不一样。在 packages/web 工作时,通常仍需遵守上层适用规则。是否只加载当前目录的额外细则,要以实际行为核对。
整理规则后一定要观察实际加载了什么。详细文档如果依然被自动全量塞入,拆成十个小文件也没有减少输入。
2.5 跨模块任务先要方案再放行
涉及多个模块联动的复杂改动,一旦做到一半发现方向偏了,前面消耗的调用成本完全无法追回。先让模型花少量 Token 梳理调用链路,讲清楚准备改哪几个地方、打算怎么验证。方案合理再让它动手写代码。
如果只是修改实体字段注释,可以直接交给模型改动。只有涉及多服务 RPC、状态机联动这类复杂改动,才需要分步规划。不必对每一处微小改动都生成长篇方案,同样会消耗时间成本。执行过程一旦发现方向偏离:比如明确要求兼容旧接口,但模型准备大规模修改数据结构,要立刻叫停。等到整套代码全部写完再推翻,返工代价会高出一个量级。
方案阶段的投入,应与改动复杂度和返工风险相匹配。把接口、改动范围与验证路径提前讲清楚,能减少实现完成后才发现方向错误的损失。
2.6 在任务交界处换会话
判断标准只有一条:旧记录对下一件事还有没有用,跟聊了多少轮没关系。还在查同一个 Bug,前面摸清楚的调用链值钱,就留着。当前任务已经验收通过,下一件事完全不沾边,就果断开新会话。
很多人新开会话的第一句话就是“把整个项目读一遍 / 读一下 README”,一次冷启动直接烧掉上万 Token。别让新会话每次从头查户口。中途更换会话前,留下一张 200 字的简短交接卡:“订单防重切面已调整,改动尚未提交;单机并发测试通过,Redis 超时场景待测;下一步检查 git diff 并补齐单测。”新会话踩在便签上直接起跑,既避免携带冗余旧历史,又省掉了重新通读全库的冷启动费用。
2.6.1 会话治理四大手段分工罗盘
面对不断增长的会话,很多开发者分不清何时该换会话、何时该压缩。记住这四个动作的硬性分工边界:换需求果断 /new,开全新会话彻底清空包袱;延续当前任务用 /compact,裁剪历史保留核心;面对脏活和大日志摸底,派出带回传契约的 Sub-Agent 充当防火墙;只有需要并行开发无冲突的独立模块时,才用 Git Worktree。手段各司其职,切忌混用乱套。
2.7 重试必须携带新证据
报错后只说“还是不行,再试一次”,通常不能帮助模型修正判断。一次有效的重试,应当带来新的证据、一个更具体的假设,或一项可观察的验证。否则调用次数与历史长度增加了,问题却没有缩小。
有效的反馈包含三件事:具体在哪一步挂了、当前的精确报错、上一次的假设到底哪里不对。最贵的账单往往不是你主动聊出来的,而是你说了一句“把报错全修好再叫我”,结果它改了 A 坏了 B,在后台死循环重试了几十轮。一定要给自动化设个止损线:连续重试 3 次要是没有拿到新证据,强制停机喊人,绝不让它自己在死循环里烧钱钻牛角尖。暂时没有新证据时,先加几行打印缩小范围;同一个错误反复出现,停下来让模型把试过的思路整理成短备忘,下次从未解决的地方接着来。
2.8 按交付方式约束输出
代码已经落盘时,如果你直接看 diff,回复里只说关键变更和验证结果就行。再贴一次全文会增加输出,并可能进入后续历史;实际费用取决于输出量、后续引用和缓存情况。
习惯在编辑器里看代码 diff,就提前约好:修改文件后只做两句话总结。说明关键改动和验证结果,测试失败时保留报错。不仅落盘的代码别全量重贴,长篇的架构方案、排查报告也一样:别让模型在聊天框里倒垃圾。几千字的详细分析一旦打在聊天窗里,后续每一轮都得背着它算钱。直接命令它:“把完整报告写入本地 analysis.md,聊天框里只回两句话结论和文件路径”。会话干干净净,历史永远不超重。当然底线依然是保留必需信息:如果输出过度压缩导致多追问两三轮,省下的输出费用会被后续对话成本完全吞噬。
第三章 模型路由策略
按任务需要选择能力,再把失败尝试、验证时间与最终交付一起计入成本。
本章关键词 · 总账为准用旗舰大模型写 Git 提交说明,或者照着现成逻辑补两行注释,是账单虚高最隐蔽的原因。
模型路由,说白了就是把活派给能力、价格、推理深度都对得上的模型。改文案、写业务逻辑、排查并发死锁,对推理的要求完全不在一个量级。先稳住一个主力模型,再给明确的场景找替补,比天天换来换去更容易管好成本。
3.1 常见任务的模型分工矩阵
先选定一个能稳定完成日常编码的主力模型。如果一个模型经常需要反复纠正或手动重写,这些返工成本必须合并计入评估。
主力模型定下来后,再把边界清晰的任务拆分出去。下面是一份分工参考。
| 任务特点 | 推荐模型档位 | 典型工作示例 |
|---|---|---|
| 输入极其明确,结果一眼看穿 | 轻量跑腿模型(如 Haiku 4.5 / Flash) | 根据 diff 提取提交说明、补充文档、批量格式化 |
| 涉及业务逻辑,改动范围明确 | 默认主力模型(如 Sonnet 5.5) | 日常功能开发、已知报错排查、模块级重构 |
| 涉及深层推理,出错代价极高 | 专家攻坚模型(如 Fable 5.1 / Opus 5.5) | 并发死锁排查、分布式状态机设计、复杂底层重构 |
判断任务难度,看推理深度,和代码行数多少没有关系。修复一个高并发重复扣款的 Bug,最终改动可能只有两行配置。背后却需要把整套请求重试机制与网络并发竞争理清楚。只按改动行数派发模型,很容易低估这种工作的推理门槛。
翻几千行日志找报错、照着实体类写 20 个转换函数,本质上是纯苦力活,根本用不着高智商。别让博导去打印店排队:把大文件通读和机械样板代码丢给几分钱的轻量跑腿模型(Haiku/Flash),几十块钱的主力模型只负责最后审查提炼出的成果。遇到修改卡壳,先看报错日志给没给够;要是关键堆栈缺失,换再贵的模型也是瞎猜。只有输入材料完整、当前模型仍反复给出荒谬方案时,才考虑升级强模型。
面对边界模糊的常规任务,大可先用主力或轻量模型低成本试探;但涉及并发死锁、分布式状态机这类高风险骨架,从一开始就别省钱,直接上顶级模型。代码逻辑允许试错,但系统可用性不能拿来赌。
3.2 推理档位按需调节
不少模型分低/中/高推理档位。模型内部思考过程同样消耗 Token 计费,这笔用量和屏幕输出给你看到的文字字数,不是一回事。具体计费规则,以对应平台说明为准。
常规的代码修改从默认或较低档位起步即可。只有在需要梳理复杂的多层调用、或者权衡底层架构取舍时,才值得拉高推理档位。一个任务已经能够稳定完成,可以试着调低推理强度,看看返工次数有没有增加。对于原因不明的隐蔽死锁,则应当留足充裕的思考预算。
评估花费时,同时查看输出与推理用量的定义。有些平台把推理 Token 包含在输出统计内,此时不能再加一次。即便模型输出回复很短,也不代表本次调用成本更低。
3.3 任务与阶段边界切换
任务进展顺利,别为了某条短回复临时换模型。切换模型会影响缓存复用,还要重新组织背景。划不划算,得把这些开销和单价差放一起算。
遇到真正的技术瓶颈,中途升级就行。把当前目标、已查明的事实和失败的假说整理成三两句,交给更强的专家模型。让它从现有进展往下推,别从头再来。
大型任务可以按阶段分工。先请能力更强的模型敲定系统重构方案,把模块接口契约和验证条件写清楚。再让主力模型按部就班完成具体代码实现。写代码时发现最初的设想不成立,再停下来重新核对。
3.4 算清包含重试的综合总账
单次调用的单价便宜,绝不等于做完这件事的总花费便宜。
轻量模型如果需要连续重试,累计花费可能迅速超过能力更强的模型一次完成任务的费用。必须比较完整任务的累计成本,才能判断哪种选择更划算。
廉价模型 × 连续重试
假设模型连续尝试三次,前两次的失败输出、工具结果与修复过程都会增加开销。仍保留的材料还可能进入后续调用。记录三次实际用量,才能看清低单价是否抵消了额外往返。
匹配模型 × 一次过关
能力匹配的模型若一次完成任务,可以减少重试与重复探索。它是否更省钱,仍需根据实际单价、调用用量和验证结果计算;一次成功也应包含必要的测试。
评估模型选得对不对,永远看做完这件事的总账,把所有失败尝试的开销都算进去。拿一组自己熟悉的日常任务做横向对比:相同的代码起点、相同的需求材料,记下各自花了多少钱、用了多少时间。自己的分工边界,只能从自己的数据里长出来。
这里有个常见统计误区:部分评测直接累加多项优化的单项降幅,算出接近百分之百的亮眼数字。不同优化手段处理对象、统计基准完全不一样,各项降幅根本不能直接相加。看到这类汇总数字,先确认每一项对应的统计分母。
第四章 上下文压缩与工具装配
从终端输出到模型回复,在数据进入上下文的位置减少冗余,并保留验证所需的信息。
本章关键词 · 按需装配除了用户输入,测试、构建、接口、检索工具也会吐出大量文本。几百条绿色通过、重复的日志行、长长的 JSON——这些东西一旦进了会话,就跟着往下游走,越堆越厚。这类高频噪音,适合交给工具自动收拾。
先看数据流过哪里,再决定用哪种处理。这里按命令执行、外部材料、请求发包和模型回复分成四个关口。它们各管各的问题,按需组合就行;用之前先想清楚:哪些错误、数值和原文回查路径必须保留。
4.1 第一关 命令执行端的终端过滤 (RTK)
模型后台跑测试、构建、看仓库状态时,经常吐出几百行绿色通过和颜色控制码。这些东西一进会话,后面每轮都要再读一遍。这一关常用的是命令行过滤器,比如 RTK。
4.1.1 声明式过滤:每条命令一份清单
测试、编译命令输出大量刷屏日志是很常见的噪音。工具 RTK 的思路不搞全局通用压缩,而是为每条命令配置一份 TOML 声明式过滤清单。先用正则识别当前执行的命令,再按清单精准执行:
- 清洗 ANSI 颜色控制码与空行;
- 将成百上千行批量通过项折叠为一行摘要;
- 完整保留失败用例的断言报错与退出状态码。
以 mvn test 为例:上百个通过用例的 [INFO] 行折叠为一行摘要,只保留失败断言、错误堆栈与退出状态。全部通过时,最终只返回 BUILD SUCCESS。仓库内置 60+ 份清单,覆盖 Maven、Gradle、Spring Boot 等常见命令。
4.1.2 效果评估与防吞底线
过滤在本地运行,通过客户端的 PreToolUse 钩子接管终端命令;被包装的构建、下载命令本身仍可能访问网络。
示例:50 个测试用例,800 行输出压缩为 3 行摘要 + 失败详情,可以看到折叠重复通过项的效果。具体比例取决于命令与日志结构;需要分别测量原始文本、过滤后文本,以及模型最终收到的 Token。
终端过滤上手简单,随时可以关闭回退。验收配置必须核验:退出码、失败用例、关键堆栈,同时确认原始日志可以回溯。输出变短只是表象;过滤之后依旧可以定位问题,这套配置才算合格。
4.2 第二关 外部材料端的沙箱隔离 (Context Mode)
生产环境日志、接口响应和大型数据对象动辄数万行。任务往往只需要核对其中的某一段报错或几个字段。如果把几十万字完整读进对话,窗口会瞬间被塞满,并在后续每轮交互中持续存在。处理这种庞大材料的办法,是把文件放在会话外面查。代表工具是 Context Mode。
4.2.1 双道闸门与沙箱机制
遇到几万行的大日志、大 JSON,不适合完整灌入会话。工具 Context Mode 的工作逻辑可以分成拦截、建索引、执行三部分理解:
- PreToolUse 拦截:如果模型准备用
cat/Read读取超大日志文件,就直接拦住,引导改用检索查询; - 本地 FTS5 知识库:把大文件拆块存入 SQLite 本地索引,模型通过关键词,按需读取片段;
- 沙箱子进程:在隔离环境跑分析代码,只有提炼后的结论才传回主会话,原始大文件不会灌入对话。
大日志的实际 Token 量需要测量,不能直接从行数推算。使用会话外分析时,原文留在本地文件或索引中,主会话只接收检索片段与结论。省下来的,是原文少进主上下文的那些次。还要检查其他读取入口是否绕过了这条路径。
4.2.2 适用边界与开启纪律
日常以业务编码为主、很少碰大文件的人,务必按需开启、用完即关。最大风险是长期闲置常驻:即便不干活,工具接口定义每轮都会计入上下文,常驻开销甚至会超过它偶尔节省的 Token。只在重度日志分析与长 JSON 排查这类场景才启用。
4.3 第三关 请求发包端的网关修剪 (Headroom)
随着会话推进到几十轮,早期试错历史越积越厚,请求中保留的材料可能持续变多。客户端自带的压缩命令需要单独花钱重写且会破坏前缀缓存。在发包端卡位的是本地代理网关,代表是 Headroom。
4.3.1 三通道分流压缩管线
会话轮次变多,早期试错历史会越堆越厚。想要在发包阶段做压缩,可以用本地代理网关工具 Headroom,它部署在开发工具与模型接口中间,按不同内容做分流压缩:
- 日志:把 800 行重复日志,压缩成一套模板 + 变量表;
- diff:一份 200 行的 diff,如果只改动 3 行,只保留
+/-实际变更行,剔除多余上下文、lockfile 和空行; - JSON:针对大量重复字段做去重,过滤掉信息量很低的行。
每种变换都带臃肿度评分,不够臃肿的原样放过,不做无谓加工。
4.3.2 CCR 本地可逆缓存
Headroom 敢于激进压缩的核心保障是 CCR(可逆压缩)。被压掉的原文完整缓存在本地,模型需要全文时,可凭句柄通过 headroom_retrieve 无损取回。
使用该工具需要在本地运行代理,将开发工具的模型接口指向代理,由代理完成转换再转发给目标模型服务。文档里“一万 Token 压到一千二”只是局部日志场景下的压缩极值。接入前务必核对工具版本、鉴权配置,确认原文回取功能稳定可用。
4.4 第四关 模型回复端的输出规约 (Caveman & Ponytail)
前三关都是在数据流动的路径上加外部滤网。第四关不一样,它直接约束模型自身的输出行为,从源头上减少废话生成。
模型输出回复是按输出 Token 计费,单价一般比输入更高。模型返回的全部内容,还会存入会话历史,下一轮请求继续当作输入重复扣费。社区曾流行一种民间偏方:在提示词里声称“我有严重多动症(ADHD),请只说核心代码、严禁废话”。真机对账表明,模型回复在总账单中往往只占很小比例;盲目逼它闭嘴不仅省不下几毛钱,反而把模型的思维链自检和边界推导直接阉割掉了。代码漏掉一个判空,后续返工排错的代价高出百倍。压输出有两个方向,别搞混了:一个是压缩表达风格,一个是压制过度设计。前者砍输出废话,后者砍架构返工。
4.4.1 表达风格规约:Caveman(压输出字数)
模型输出啰嗦、铺垫寒暄太多,可使用输出风格规约工具 Caveman,核心目标是让模型少说废话。口号是 compress STYLE, never RIGOR(只压缩风格,绝不压缩严谨度)。
它在 Claude Code 里通过原生 Output Style 生效,核心要求是:
- 结论先行:前置答案,解释放后;
- 删除冗余:剔除冠词、寒暄、铺垫、对冲词与结尾复述;
- 碎片句模板:允许以
[东西] [动作] [原因]。[下一步]极简交付; - 技术细节不动:术语、代码、路径、JSON 与报错一字不删;
- 例外恢复:涉及安全与不可逆操作时,自动恢复完整自然语言。
相关工具材料里有约 40% 输出 Token 降幅的案例。这个比例跟原来的回复风格、任务和评测方法都有关系。它测的是输出侧,还要连同后续追问次数和任务质量一起看。
4.4.2 设计原则规约:Ponytail(压方案复杂度)
模型容易过度设计、写一堆不必要代码,可用规约工具 Ponytail,核心是让模型像“房间里最懒的资深架构师”一样思考,拒绝过度设计。口号是 think expensive, write cheap。
它通过一条 7 层决策阶梯严格约束模型做事的深度:
- 这东西真的需要存在吗? 臆想需求直接不做 (YAGNI);
- 仓库里已经有现成的吗? 先找再写,严禁重复造轮子;
- 标准库能解决吗? 优先使用标准库;
- 平台原生特性能覆盖吗? 原生特性优于引入类库;
- 已装依赖能搞定吗? 绝不为几行代码增加新依赖;
- 能一行写完吗? 绝不写五十行;
- 以上都不行,才编写能工作的最少必要代码。
一条铁律:修 Bug 修根因,不修表面症状。在共享函数里加一道防线,胜过在每个调用点各打一块补丁。
4.4.3 规约执行底线
表达规约重点是减少重复和铺垫;设计规约重点是约束不必要的实现。遇到复杂架构与深层排障,仍要保留必要分析。如果过强的简化要求使方案遗漏边界,就应调整或关闭相应规约。
压输出的前提永远是保证质量。如果输出压缩得过简,需要额外多追问两三轮才能理清逻辑,省下的输出开销会被后续多轮对话的成本完全吞噬。
4.5 按需装配,并验证实际效果
工具并不是装得越多越好。多个网络代理叠在一起容易打架,额外加载的工具说明也可能增加基础上下文。
| 关口节点 | 常见痛点 | 拦截形态与代表工具 | 核心底线 |
|---|---|---|---|
| 命令执行端 | 编译与测试大量刷屏 | 命令行过滤器 (RTK) | 真实退出状态与报错堆栈必须原样透传 |
| 外部材料端 | 上万行日志灌满上下文 | 本地沙箱与知识库 (Context Mode) | 保持阻断,重度排查任务才开启 |
| 请求发包端 | 请求体松散与长历史膨胀 | 本地代理分流压缩 (Headroom) | CCR 本地可逆,数值精度不可破坏 |
| 模型回复端 | 寒暄客套与过度设计 | 格式与设计规约 (Caveman / Ponytail) | 保留关键推导,复杂排障主动关闭 |
4.5.1 推荐装配方案
日常开发(极简两件套):命令执行端挂 RTK 拦截控制台噪音,回复端配三行输出规约直奔主题。这套组合不碰复杂链路,以极小代价解决日常最频繁的两类噪音。
重度排障(按需启用):生产日志排查、大型数据对象分析时,挂载 Context Mode 沙箱。任务完成后立即关闭,不让额外工具定义常驻底噪。
4.5.2 两项验收要求
任何工具引入都必须经受两项客观要求的检验:
- 严格同任务对照:选一个有明确验收标准的功能修改,在相同代码起点下用不同配置各跑一次,对比真实账单;
- 核对总费用与完成质量:分别记录字符、Token 与金额;任务通过同等验收,才能比较成本。
公开案例中的系统级优化,与单个工具输出的压缩率,往往采用不同统计范围。7%~15% 和 80%~90% 这样的数字,只有连同来源、分母、任务和配置才有比较意义。局部改善对总费用的影响,需要结合它原本占多少费用,以及是否产生了额外调用来计算。
第五章 代码检索与索引选型
从路径搜索、符号定位到语义索引,依据真实的定位困难选择工具。
本章关键词 · 代码即索引如果模型为找一个调用方读了 27 个文件,大概率是定位路径太长了。文件读取次数不等于模型调用次数:批量读取、返回大小、历史保留策略,一起决定了后续开销。先定位符号和依赖,再读必要的实现,通常更容易把范围控住。
找代码这件事,真正该省的是无效候选和来回瞎摸。证据要留够,函数、调用方、相关测试都得确认,不然省了读取、多了返工,反而更贵。这一章讲的是:怎么选最合适的定位方式。
5.1 先判断项目是否需要额外检索工具
代码行数仅作参考线索,不能单独用来判断检索工具是否值得引入。目录清晰、入口已知的小项目,直接使用编辑器自带的搜索能力即可,盲目引入复杂的检索工具反而大概率亏钱。
检索工具本身也有成本:工具说明、索引构建、更新维护、查询开销。客户端如果支持延迟加载,固定上下文成本会低一些。结构简单的项目,节省的探索时间可能盖不过这些成本。定位确实困难的项目,才值得做对照试验。
可以用两个信号判断是否值得试验:
- 规模与结构信号:例如十万行以上、模块关系复杂的项目,需要花较多时间理解跨模块关系;
- 定位行为信号:例如同一排查任务读了十个以上文件仍未找到核心路径,值得检查检索方式。
例如,十万行项目或一次排查读了十个以上文件,可以提醒你检查定位效率;它们仍只是线索。先提供已知入口与函数名,再记录工具引入前后的调用量、准确性和耗时,判断收益。
5.2 找代码的三种姿势
开发者在代码库里找东西,本质上只有三种需求,对应三种完全不同的技术路线。选错了路线,花了钱还办不好事。
5.2.1 精确找人:语言服务协议 (LSP)
如果你已经知道函数名称,需要定位定义与全部调用处,优先用 LSP(语言服务协议),这是该场景最高效的手段。
它就像 IDE 里的“跳转到定义”和“查找所有用法”。查找 OrderService.createOrder() 时,LSP 直接把模型带到定义与实现类的精准行号。不需要全局 grep,也就不会把 DTO、测试 Mock 和日志里的同名词卷入上下文。
函数定义、类型和引用关系,优先尝试可靠的语言服务。文本搜索则适合字符串、配置键、日志与语言服务未覆盖的文件。两者可以配合使用:缩小候选范围,再读取源码验证。
5.2.2 追溯波及面:代码图谱 (Code Graph)
你准备改底层一个模块,想知道上面哪些业务会受影响。这时候你要的不是某一个点,而是一张依赖关系图。代码图谱把整个项目解析成一张模块调用网络,就像顺着电路管网找哪些房间会因为总闸改动而跳闸。
代码图谱好不好用,取决于三点:语言支持程度、索引是否是最新、依赖关系解析能力,另外还要看项目的调用透明度:
- 高透明度工程:标准三层架构(Controller → Service → Mapper),包路径与接口实现一一对应,目录本身就是活索引,图谱带来的额外收益有限;
- 低透明度工程:深度依赖事件发布、AOP 动态代理、反射 RPC 等动态调用的系统,调用链被动态解耦切断,文本搜索找不出谁发布事件、谁消费消息。这类系统才是图谱的主战场,但必须先核对图谱对动态调用的解析覆盖。
公开的 CodeGraph 基准中,Java/OkHttp 与 Rust/Tokio 的成本降幅分别约为 2% 和 82%。差距主要来自仓库的调用透明度,而非语言本身。动态调用越多的系统,图谱潜在收益越大,也越需要核对图谱解析是否完整。
5.2.3 模糊意图:语义向量索引 (Embeddings)
你记不清函数名,也不知道在哪个模块,只大概知道有个功能是做某件事的。这是最模糊的一类需求,对应的是语义向量索引。它把代码按含义切片存起来,你用自然语言描述你想找的东西,它把最相关的代码片段捞出来给你。
使用语义索引时,先明确索引范围与数据处理位置:
- 排除第三方依赖:给依赖库建向量索引,等于花钱请人把一整本电话簿背下来,毫无用处;
- 确认数据处理位置:语义索引可能涉及本地或远端嵌入服务。根据项目的数据要求选择方案,确认代码片段的发送范围与存储位置。
5.3 选工具的一条总原则
判断要不要引入一个新的检索工具,不要看它宣称的命中率,算一笔账就够了。选工具的核心原则,就是对照实验说了算。
选一组熟悉且有明确验收标准的排查任务。固定代码起点,记录不用新工具时的用量、读取范围和时间。再使用工具做对照,计入建索引、查询和后续维护成本。总开销没降,就去查任务类型、索引质量和配置,别拿仓库大小说事。
阅读基准测试数据,要警惕多手转述陷阱。很多文章复制粘贴一模一样的优化比例,看上去像是多方验证有效,实际全部摘抄自项目官方文档,缺少可复现的独立实测记录。碰到这类数据优先找到原始出处,不要误以为经过多方验证。 说到底,检索工具是用来弥补代码组织不够清晰的。越规范的代码库,目录、命名和调用关系本身就越容易找,越不需要复杂的检索工具。代码自己就是最好的索引。
第六章 多 Agent 与上下文隔离
清楚的子任务边界、可验证的交付与简洁回传,决定分工是否值得。
本章关键词 · 结论回传会话聊的轮次越多,携带的历史内容也会越多。但是不存在所谓"会话满 20 轮就会明显变慢"这种铁律。实际开销受每轮上下文大小、缓存、压缩策略、任务类型共同影响。真正要关注两件事:上下文体积是不是持续膨胀,哪些工作可以拆出去独立执行。
多 Agent 的思路很直接:把探索过程丢在子会话里,主会话只收结论和证据定位,这样主上下文就不会被撑爆。隔离效果好不好,取决于子任务到底继承了什么、回传了什么。子会话的记录留着备查就行,不用全灌回主会话。
6.1 高低搭配:主子模型的双重价格压缩
多 Agent 最直接的降本手段是价格分工。主会话使用旗舰主力模型(如 Sonnet 5.5 / Opus 5.5),负责架构设计与核心代码审查。跑腿的子 Agent 指定单价便宜数倍至数十倍的轻量模型(如 Haiku 4.5 / Flash)。繁杂的摸索留在子会话,主会话只接收提炼后的结论,实现上下文体积与模型单价的双重压缩。
在 Java 后端日常开发里,下面三类场景最适合交给轻量子 Agent 处理:
- 摸排配置与定位线索:排查未知故障时,往往需要在多个微服务工程中翻阅各类
application.yml、Nacos 规则或长串异常日志。让轻量子 Agent 独立去翻,即便在子会话里消耗了几万 Token,最终也只需向主会话汇报出问题的具体类名与配置项。 - 大报文切片与局部提取:面对动辄数千行的银行支付回包 XML、或臃肿的 MyBatis SQL 映射文件,如果只为了提取其中的两三个状态字段,直接让轻量子 Agent 读取并输出字段摘要,避免把整个大文件灌入主会话。
- 批量样板代码与单测编写:核心领域模型与接口入参已在主会话中定稿,编写批量 DTO 转换类或基于 Mockito 补充常规单元测试,属于模式明确的体力活。派发给轻量子 Agent 在独立会话中编写并直接落盘,产出的冗长样板代码完全不需要经过主会话。
6.2 把交接成本算进任务拆分
拆分子任务并不会天然省 Token,反而常常更贵。从底层缓存机制来看,子 Agent 的工具集(Schema)和系统指令通常与主 Agent 不一致,天生无法复用主会话已经建立的 0.1× 缓存前缀。当主会话进行到第 8 轮时,哪怕带着 3 万 Token 历史,凭借 0.1× 热缓存读取可能只需结算几千等价 Token;而新派发的子 Agent 哪怕只分流了一个小任务,第 1 轮启动几乎必定遭遇 1.25× 的全价冷写入惩罚。
评估多 Agent 方案,必须把全部 Agent 的冷启动写入、输入输出、重复读取以及结果回传合并计算。子 Agent 的本质是“上下文防火墙”而非“省钱代金券”:只有当任务涉及脏活、大文件探索、或海量日志需要彻底隔离出主上下文时,付出的冷启动与交接代价才算值得。
6.2.1 用简短交接检查任务边界
强拆给多个 Agent
多个 Agent 反复理解同一段连续推理,各自重读文件并频繁交接,沟通税很快超过任务本身。把这类协同成本单独列出,才能看清分工是否划算。
单 Agent 一气呵成
连续推理留在同一会话,省掉重复同步背景的开销。先确认子任务能否在短篇幅内交接、并能独立验证,再决定是否拆分。
判断一个任务该不该拆,可以先用“能否简短说清”检查边界,再看依赖关系与协调成本:
- 适合试行拆分:前置背景能在 约 200 字内 交代清楚,且产出物能被独立验证(如“根据接口写 5 个单测并运行通过”);
- 需要谨慎拆分:需要花费大篇幅解释之前的试错过程与推导假设,说明任务属于高耦合连续推理,应优先保持单会话推进。
面对分布式事务、并发故障等高危场景,轻量模型还容易漏掉线程安全问题,且委派会增加 10~30 秒延迟。做方案取舍时,这些代价都要纳入考量。
6.3 严格限制回传契约
启用子 Agent 之后,保护主上下文的关键在于严防结果全量回灌。绝不能让子 Agent 把几千行内部推导过程和长篇执行日志原样倒回主会话。
调用前强制约束以下三项回传契约,其余细节留在本地磁盘日志中:
- 修改文件路径;
- 核心变更摘要(控制在两三句话内);
- 需要主会话留意的潜在风险点。
辨析一个常见误区:Git 工作区(worktree)并行 ≠ 省 Token。多工作区并发确实能缩短等待时间,但每个 Agent 的调用都计入总账,还会增加合并验证开销。并发省的是时间,不省 Token。
先做减法,后做分工。让主力模型统筹核心逻辑,让轻量子任务跑腿搬运,严格限制回传内容,才能守住多 Agent 的上下文红利。
结语 建立可验证的成本治理习惯
回到自己的任务与账单,把优化变成一次能够复查的对照实验。
No. 002 · 你的下一张账单回到开篇第一章提出的核心问题:一次 AI 编程任务的消耗,来自一轮轮叠加的模型调用。系统提示、工具定义和规则构成基础上下文;历史消息与工具结果会在后续请求被重复携带;输出、推理、缓存各自拥有独立的计价逻辑。账单中哪一项开销最高,只能从你自己真实数据里寻找答案。
实践可以围绕六件事展开:减少无关历史,选对模型,整理工具返回,提高代码定位效率,谨慎拆多 Agent 任务,核对完成任务的真实成本。每次先改一个有证据的问题。
方法都在前面了。真正管用的只有一件事:拿自己的真实账单去验证,别信别人宣传的百分比。
十秒自查清单
操作层面的很多失误,源于对底层无状态与计费机制的直觉偏差。遇到账单异常时,对照下表快速过一遍。
| 常见直觉偏差 | 底层计费真相 | 工程解法 |
|---|---|---|
| 认为上下文贴得越多越好 | 上下文每多留一轮,后续就可能多一份重复输入,费用受缓存命中影响 | 只给入口路径,范围按需扩大 |
| 扩展工具装得越多越强 | 已加载的工具定义会增加基础上下文,延迟加载可减少常驻量 | 只保留高频工具,善用延迟加载 |
| 所有任务全上最强模型 | 机械性模式化任务溢价严重,开销成倍虚高 | 主力模型兜底,跑腿派发轻量子任务 |
| 把聊天记录当永久数据库 | 历史或摘要由会话层维护,持续累积会增加重复输入 | 长期共识提炼为规则,任务交界换会话 |
| 只看单价低,不看总账单 | 推理能力不足导致多次返工,累积支出反超 | 按完成任务的综合累计支出核算 |
| 认为提问语句越短越省 | 缺乏约束导致盲目猜测,引发多轮无用往返 | 预期行为与验收标准一次性说透 |
工程师一页速查卡
把全篇的方法浓缩为一张随手查阅的电报便签:
| 治理维度 | 核心工程口诀与防线要点 |
|---|---|
| 底层定律 | 成本 = 量 × 价 × 次;前缀稳定压倒一切;数量与费用坚决分开算 |
| 提问与会话 | 需求验收一次说透;看病拍胸片只读切片;任务交界开新窗留便签 |
| 规则与模型 | 菜单只印菜名清单;苦力别让博导干;自动化连续报错设 3 次止损 |
| 工具与隔离 | 终端挂过滤;大文件进沙箱;聊天框不倒垃圾;子 Agent 严守回传契约 |
| 测量与核算 | 大日志是外伤,重复读是内伤;算总账不看单价;无分母百分比皆套路 |
今晚就能验证的三件事
不要为了节约少量 Token 牺牲交付健壮性,也不要盲目相信缺少统计分母的惊人优化比例。今晚不妨在你的开发工具里做三件立刻见效的对照实验:
第一件 · 测底噪:空白会话只发「Hello」,记录首次调用的输入与缓存用量;逐一开关扩展配置,摸清你环境里真实的系统底噪。
第二件 · 查来源:翻看一段历史长会话,统计人工输入、工具回显与历史滚雪球的各自体积;搞清楚过去哪一处在真正泄露 Token。
第三件 · 做对照:固定代码起点与验收标准,拿真实任务对比当前流程与「写交接卡 + 换会话」的成本差异。如果所在平台拿不到细分账单,可以用完整任务的总耗时和总花费做粗粒度对照。
把这三件事做完,这些方法就不再是别人文章里的口号,而是你日常工程习惯里的肌肉记忆。
鉴别降本宣传的三条底线
最后,怎么判断网上传播的降本神话值不值得信?记住这三条试金石:
- 明确标注统计分母:讲清楚降幅统计对象,是单条命令输出、某类工具返回,还是完整任务总开销。
- 写明测试限定条件:说明项目语言、代码规模、运行环境,切勿把大型单体仓库的个别效果,当作普适结论。
- 分项效果可与总账核对:即便局部压缩收益可观,如果该部分原本占总开销比重很低,对整体账单改善也有限。新增模型调用还会抵消节省,评测必须同步提供任务质量与耗时。
