AI Coding Agent Token 成本控制 把额度花在刀刃上。
月初看账单会吓一跳 —— 没问多少问题,Token 怎么烧成这样?拆开看一次完整请求才会发现一个反直觉的事实: 您输入的那句提问,在每次请求里可能连 1% 都不到。真正的成本大头,藏在系统替您拼接的上下文里。
心智模型 — 账单的真实结构
把「Token 烧太快」归因为「我问得太多」是一种误诊。真正决定账单的,不是您敲进去那几十个字, 而是系统为了让模型「看起来懂上下文」自动带上的一整包背景。不先看清成本结构,所有优化都是猜。
「它记得」是错觉
大模型 API 是无状态的 —— 不是模型无记忆,而是 API 层每次请求独立。 「它记得」实际上是 Agent / CLI 层在每轮请求前,把历史、规则、工具、文档重新拼一遍再发出去。三个直接后果:
- 会话越长,后续每一轮越贵 —— 历史每轮被重新带过去
- 工具越多,常驻定义越重 —— 每个 Tool / MCP 都要让模型每轮「读一遍」它的描述
- 工具调用是回路 —— 一次任务往往是「请求 → 工具返回 → 再请求」的连环计费
五种 Token 开销
| 类型 | 解释 | 容易被低估的原因 |
|---|---|---|
| 输入 Token | 拼进 prompt 的所有内容 | 每轮都可能重复携带 |
| 输出 Token | 模型生成的回答 | 啰嗦回答 = 直接溢价 |
| 推理 Token | reasoning / thinking 内部消耗 | 简单任务走高档位会显著溢价 |
| 工具往返 | 工具描述 + 参数 + 返回值都进上下文 | 一次工具调用常比原问题长 |
| 重试 | 第一次输出不合格再来一轮 | 整包上下文被反复付款 |
今天就能改的 7 个使用习惯
零工程投入,按效果排序。这七条不需要写一行代码,改的是使用方式本身。
把「修 Bug / 重构 / 写文档 / 查线上」塞进同一个会话,是最常见的隐性烧钱。切换任务时 /clear。会话的本质不是「记录」,而是「上下文负债」。
会话超过 30-50 轮或跨越多个子任务时,主动用 /compact。模型不需要完整试错过程,只需要:现在要干什么、做完了什么、哪条路不通、卡在哪、下一步怎么做。
会话不是数据库。项目背景 → CLAUDE.md / AGENTS.md;决策记录 → 独立 markdown;代码地图 → Repo Map。会话只承载「当前工作状态」。
只写文件名 → AI 要 grep / find 整个项目 → 多消耗一轮工具调用 + 返回值。
src/config/config.go 的问题 · 帮我改 @src/utils/parser.ts聊天式拆碎成四轮(看一下 → 有 Bug 吗 → 帮我修 → 加个单测),每轮都要重新带历史。换成一次说清:「看 @service.go 的 CreateOrder,找潜在 bug、修复、并补单测。」省掉中间三轮的上下文重传。
很多回答最贵的不是「错」,是「废」—— 复述、铺垫、然后才给结论。只要 diff 就说「只输出 diff」;要结论就说「一句话结论」。省两次:输出更短 + 第一次就可用 → 不重试。
每个常驻 Tool / MCP / Skill 都在每轮请求里占位置。高频通用的常驻,低频长说明的按需加载或卸载。能用 CLI 完成的(gh、git、docker)优先 CLI。判断标准只有一个:有没有必要常驻。
一句话版
一会话一目标 → 长会话压缩 → 长期信息外置 → 引用带路径 → 意图一次说完 → 输出硬约束 → 工具精简。七条全是零成本,通常能拿到第一波最大收益。
模型路由 — 贵模型只做高价值推理
默认所有任务都用最强模型 = 放弃路由。判断标准是任务需要的能力,不是「哪个最近发布」。 悬停下方任意一档,查看它适合的任务类型。
级联升级:先便宜后贵
便宜模型先跑
├── 输出可用 → 完成
└── 输出不达标 → 升级到强模型重做
典型场景:让便宜模型先分类任务(重构?Bug?文档?)再分发;先做初筛(PR 有没有高风险点)命中再交强模型;先做摘要(20 页 → 1 页)强模型只看摘要做推理。
控制「思考」档位(按 2026-06 官方文档)
| 厂商 | 参数名 | 取值 |
|---|---|---|
| Anthropic Claude | thinking.budget_tokens | 整数 token 数(显式预算) |
| OpenAI(推理系列) | reasoning_effort | none / minimal / low / medium / high / xhigh(取值模型相关) |
| Google Gemini | thinking_level | low / medium / high(旧版 thinkingBudget 已废弃) |
简单任务默认起步用最低档,需要时再升档。让推理模型用高档位做格式化,等于拿推土机扫地。
把模型选择固化到执行单元
模型路由要落到执行单元:Skill / Subagent 头部声明默认模型;斜杠命令(/commit、/gen-ut)绑定便宜模型;多 Agent 工作流里 Planner 强、Coder 中档、Reviewer 强、Formatter 便宜。一旦固化,成本治理从「靠人记得切」变成「系统默认更省」。
Prompt Cache — 把前缀写「稳」,不是写「短」
Prompt Cache 是所有优化的基础 —— 您为同一段前缀重复付款的钱,本来就该省掉。前提是先搞清它的真实命中条件。
三家厂商的命中条件
| 厂商 | 启用方式 | 门槛 | TTL / 定价 |
|---|---|---|---|
| Anthropic | 显式 cache_control | 按模型 512 ~ 4096 tokens | 5 分钟 / 1 小时;写入 1.25×~2×,命中读取 0.1× |
| OpenAI | 自动 | ≥ 1,024 tokens | 5-10 分钟失效,扩展最长 24 小时;命中按折扣 |
| Google Gemini | 显式 / 隐式两种 | 各模型独立门槛 | 可指定 TTL;命中大幅折扣 |
短于门槛的请求即使标了 cache_control 也不会被缓存(不报错)。
四个常见误解
- 「缓存的是答案」 —— 缓存的是 prompt 前缀的处理结果(KV cache),不是输出
- 「差不多的前缀也命中」 —— 必须精确匹配到某个前缀边界,差一个字符就 miss
- 「缓存是免费的」 —— Anthropic 写入比正常贵,命中读取才便宜;OpenAI 写入按正常价
- 「用了就赚」 —— 缓存有 TTL,低频访问的前缀过期就白存了
哪些内容适合放前缀
[ 适合缓存:放在 prompt 最前面 ]
① System Prompt(项目通用规则)
② Tool / MCP 定义
③ Skill 定义
④ 长期项目文档(架构说明、API 规范)
⑤ 稳定的 few-shot 示例
[ 不要放前缀 ]
⑧ 会话历史(每轮都变)
⑨ 本轮检索结果
⑩ 用户最新提问
Anthropic 官方的「缓存前缀建立顺序」是 tools → system → messages。
三条具体的工程动作
- 静态在前,动态在后 —— 任何一段稳定文档放到变化内容后面,整段都用不上缓存
- 前缀写「稳」不是写「短」 —— 每天改 System Prompt / Skill 描述,缓存形同虚设
- Anthropic 显式埋点(最多 4 个 breakpoint) —— 按变化频率给 system / tools / project context / history 分段标记
怎么验证缓存确实在工作
| 厂商 | usage 关键字段 |
|---|---|
| Anthropic | cache_creation_input_tokens / cache_read_input_tokens / input_tokens |
| OpenAI | prompt_tokens_details.cached_tokens |
| Gemini | usageMetadata.cachedContentTokenCount |
cached / total_input 应长期 > 50%。低于 20% 说明前缀在抖 —— 回头查是不是有不该变的内容混进了前缀。Prompt Cache 不是让模型更聪明,是让您别为同一段前缀反复买单。
上下文压缩 — 先看您的「Token 黑洞」在哪
不要先选工具,先量。一次中等开发会话结束后,看 usage 拆解,定位最大黑洞再对症下药。
| 黑洞类型 | 怎么发现 | 对应压缩方向 |
|---|---|---|
| 命令输出 | 跑一次测试 / 构建后 token 暴涨 | 终端输出过滤 |
| 大文件读取 | Read / cat 工具调用频繁 | 只读需要的片段 |
| 工具返回值 | 浏览器 / 截图 / 批量拉取返回字节大 | 工具结果沙箱化 |
| AI 回复啰嗦 | 输出 token 占比 > 30% | 输出格式约束 |
| 会话历史 | 会话超 30 轮后每轮都贵 | 会话压缩 / 摘要 |
四个压缩方向,各自的零成本做法
方向 1 · 终端命令输出
测试只跑改动相关子集;加 --quiet / -q;pipe 给 tail -n 200;失败优先 pytest -x --tb=short。进阶可接一层终端输出过滤工具,压缩率因命令类型差异很大,选用前在自己项目里实测。
方向 2 · 只读需要的文件片段
优先用 Grep / Glob 定位行号再精读;用 Read offset=N limit=M 只读相关段;也可以让 Agent 写脚本(如 wc -l *.ts)而不是逐个读文件。
方向 3 · 工具返回值沙箱化
工具调用时指定 limit / fields;长返回值先存文件再按需 grep;二进制 / 截图走外部存储。进阶方案用中间处理层把原始数据留在本地、只把摘要进上下文,但会引入额外一层,规模小时先用零成本手段。
方向 4 · AI 输出压缩(最高 ROI)
在 System Prompt / Skill 里硬约束「不复述、不铺垫、直接给结果」;指定输出 schema。风格化的极限压缩更适合机器消费的输出,给人看的文档不建议这么压。
选择顺序
1. 输出格式硬约束(写到 System Prompt) ← 5 分钟,立刻见效
2. 命令输出加 --quiet / tail / head ← 10 分钟,立刻见效
3. Read 改用 Grep + 精读片段 ← 1 天,改提示词和 Skill
4. 评估压缩工具填补剩余黑洞 ← 1-2 周,要做 A/B
代码图谱 — 让 AI 先查图、再读文件
真正贵的不是「读代码」,是「找代码」。项目稍大,AI 就会陷入「grep 一圈 → 读几个文件 → 发现漏了 → 再 grep」的循环,反复几轮才定位完,还容易漏掉跨文件依赖。代码图谱让 AI 在读文件之前就知道该读哪里。
收益和项目规模强相关
| 项目规模 | 跨文件查询频率 | 建议 |
|---|---|---|
| < 50 文件 | 任意 | 不需要,Grep + Glob 够用 |
| 50-300 文件 | 偶尔 | 不必常驻,按需生成 Repo Map 摘要 |
| 50-300 文件 | 频繁 | 值得建,但不必上重型方案 |
| 300+ 文件 | 频繁 | 强烈建议,ROI 很高 |
| 多语言 + 跨服务 | 任意 | 强烈建议 |
经验规律:千文件量级开始有真实 ROI,数千文件以上效果显著。类型系统强、跨文件依赖密集的项目收益最明显;纯脚本类、单体小项目收益有限。
两类主流方案
类型一 · 一次性扫描 + 静态产物
基于 Tree-sitter 等静态解析,扫一次生成图数据文件给 AI 查阅。零配置、可挂 git hook 增量更新;但静态文件较大时每次查询都要把图加载进上下文。适合个人项目、中型仓库、快速验证。
类型二 · MCP Server + 持久化图数据库
解析结果存入图数据库,通过 MCP 暴露查询接口,AI 按需查询而非加载整图。可做精细影响分析(trace / impact);但要持续维护索引。适合团队、大型仓库、长期使用。
不建图谱的零成本替代
- 手写
REPO_MAP.md放仓库根,列出各目录职责、关键入口、跨模块依赖 —— 50-200 行就够,还能进缓存前缀 CLAUDE.md/AGENTS.md写明常用查询路径- 建立「先看文档再 grep」的提示词约束
多 Agent 编排 — 边界清晰才省钱
单 session 很容易演变成「什么都塞一个会话」:规划、写代码、跑测试、Review 全在同一上下文,任务 A 的历史到任务 D 还在每轮重传。 根因:职责混 → 上下文胖 → 成本高。
.agent/findings.json.agent/fix.json单 Agent 跑长任务时每一轮都背着全程历史 —— 哪怕当前只是改一个函数。Orchestrator-Worker 让每个 Agent 只看「当前步骤相关」的内容。这一模式在业界已有公开实践,是标准工作流之一。
上下文隔离后,信息怎么流转
最常见的陷阱:拆了 Agent 却不知道怎么传数据,又把所有历史塞回去 —— 白拆了。正解:通过文件系统传,不通过会话历史。四条配套原则:
- 输出结构化 —— JSON 比自然语言紧凑精确,下游只读关心的字段
- 用
progress.json追踪状态 —— Orchestrator 每次唤醒只读这一个文件就知道全局进度 - Worker 的 context 包精心裁剪 —— 派遣时明确「只读什么」,不让 Worker 自己探索
- 临时文件及时归档 ——
.agent/是临时工作区,避免旧任务上下文带入新任务
并行与「什么时候不用」
适合并行:不同模块的修改、代码 + 测试 + 文档、多文件格式化、影响分析 + 方案设计。不适合并行:有顺序依赖、修改同一文件、依赖上一步输出。若 Worker 要并发改文件,加 worktree 隔离。
六个常见误区 — 很多「优化」其实在加成本
下面六条都是看起来合理、实际增加成本的做法。对照自查,中招的越多,优化空间越大。
噪音越多模型越分神。该读哪几个文件比读多少文件更重要。
每多一个常驻工具,模型每轮都要「读一遍它的说明书」。低频工具长挂等于持续付费。
这不叫保质量,叫放弃路由。本质是 80% 预算花在 20% 价值上。
会话不是数据库。长期信息该外置到文件、Memory、知识图谱里。
便宜模型如果导致更多重试、搜索、工具调用,端到端总成本可能更高。判断指标是「完成一次任务的总 Token + 总耗时」。
压掉必要的格式约束和 few-shot → 第一次输出不达标 → 重试 → 整包上下文再付一遍。正解:压前缀的抖动,不是压前缀的长度。
可量化的行动清单
按投入度分三档,从「今天就能做」开始,逐步往上累加。
今天就能做(30 分钟内见效)
- 切换任务时
/clear,一会话一目标;长会话主动/compact - 引用文件用
@完整路径;一次把意图说完 - 在 System Prompt 加输出格式硬约束(「不复述、不铺垫、直接给结果」)
- 命令加
--quiet/tail/head;清点 Skill / MCP,低频的卸掉
这周能做(1-2 天工程投入)
- 按任务给模型分档;把常用 Skill / 命令 / Subagent 绑定默认模型
- 调用推理模型时显式设
reasoning_effort/thinking_level/thinking.budget_tokens - 把稳定内容前置,让 Prompt Cache 命中率 > 50%;Anthropic 用户埋
cache_control - 看一次完整 usage 拆解,定位最大 Token 黑洞
这个月能做(工程项目)
- 项目级长期信息外置到
CLAUDE.md/AGENTS.md/REPO_MAP.md - 大型 / 跨文件项目评估是否引入代码图谱
- 长任务拆 Orchestrator-Worker,约定
.agent/目录传状态、progress.json跟踪进度 - 评估压缩工具填补剩余黑洞(先量后选);建 Token / 重试率 / 工具调用次数的观测面板
怎么验证您真的省了
省 Token 不能靠「感觉账单少了」。建一个能持续看的最小观测面板,用数据说话。
必看的 5 个指标
| 指标 | 怎么算 | 健康区间 |
|---|---|---|
| 单任务总 Token | 一次完整任务的 input + output + reasoning | 持续下降 |
| Cache 命中率 | cached_tokens / 总 input_tokens | > 50%,稳定任务可达 70%+ |
| 首次完成率 | 不需要返工的任务占比 | > 70% |
| 工具调用次数 / 任务 | 平均每次任务调用工具次数 | 引入图谱后明显下降 |
| 输出 / 输入比 | output_tokens / input_tokens | 通常 < 0.3,过高说明啰嗦 |
验证优化是否有效的最小方法
不要「上了就觉得有效」。对每个优化做 A/B:选 5-10 个有代表性的真实任务,优化前后各跑 1 次,记录总 Token / 耗时 / 首次完成率 / Tool Call 次数并对比。显著下降就保留,微小或反向就卸掉。
成本优化不是「少问一句话」,
是「让系统少重复搬运上下文」。
您的提问从来不是账单大头。
把额度花在刀刃上,从看清成本结构开始。