月初查看账单,确实让人大吃一惊。

明明没提几个问题,Token 消耗怎么会如此惊人?
后来专门花时间仔细拆解了一轮,才发现一个相当反直觉的现象:
你亲口说出的那句话,在每次 API 请求中可能连 1% 的占比都不到。
真正的成本重头戏,其实隐藏在别处。这篇文章的核心目标,就是彻底厘清那个“隐藏角落”,并分享一套无需安装任何额外工具、今天就能直接实践的高效省钱技巧。
第一章 你的Token究竟花在了哪里
许多朋友一开始会将优化重点放在打磨提问方式上:句子尽量精简,删掉冗余形容词,让问题看起来更像出自 Prompt Engineer 之手。
这个方向并非错误,但很容易抓不住主要矛盾。
因为在 AI Coding Agent 的实际运行中,真正决定账单大小的,往往不是你手动敲进去的那几十个字,而是系统为了让你产生“模型似乎理解上下文”的错觉,而自动附加的一大堆背景信息。
先把一次完整的请求结构拆解清楚,后续的优化才能有的放矢。否则,你可能一直在节省小钱,却忽略掉了真正的大头支出。
1.1 你提出的问题,其实是最便宜的环节
先来看一个典型的请求内部构成:
System Prompt 5K
项目说明文档 10K
Skill 定义 20K
Tool / MCP 定义 30K
历史会话 100K
代码文件 50K
用户问题 0.1K
这并非所有产品的精确账单,但它揭示了一种非常普遍的成本分布规律。
它传递的信息很明确:许多人本能地将优化方向定为“如何把问题写得更短”。这当然不是坏事,但它没有抓住核心。因为模型真正接收的,不是“你的问题”,而是“那个装满了各种上下文的大型包裹”。
我们可以把一次请求近似理解成这样一个公式:
总成本 ≈ 固定前缀 + 会话历史 + 运行时检索 + 工具往返 + 模型输出
这里面包含了三个层次:
固定前缀:System Prompt、Skill 定义、Tool / MCP 定义、稳定的背景文档
半固定上下文:项目说明、Repo Map、Memory、长期约束
动态上下文:聊天历史、代码片段、检索结果、工具返回值、你当前这一轮的新问题
你那句提问,往往只是最后一点“点火器”。它负责触发任务,但通常不是成本的主体。
这个结构可以用一张图来直观理解:
你主动输入
用户问题:0.1K
系统自动补充
System Prompt:5K
项目说明文档:10K
Skill 定义:20K
Tool / MCP 定义:30K
历史会话:100K
代码文件:50K
这也是为什么许多人会产生一种错觉:
我明明只问了一句话,怎么会这么贵?
答案其实很简单:你确实只问了一句话,但系统替你背了一整车的背景资料。
一旦理解了这一点,后面许多优化动作就会变得非常合理:为什么要开启新会话、为什么要压缩历史、为什么要少加载 Skill、为什么要构建代码图谱。这些看似零散的操作,本质都在做同一件事:
减少重复的上下文传输。
1.2 “它好像记得” 只是一种错觉
AI Coding Agent 用久了,很容易产生一种感觉:
它似乎一直记得我们聊过什么
但实际上,大模型本身通常是无状态的。
真正“记住”的,不是模型本身,而是包裹在模型外部的 Agent / CLI / 平台层。它在每一轮请求开始前,默默地将历史、规则、工具、代码、文档重新组合,再一股脑地发给模型。我们常说的“记忆”,很多时候只是“再次传入”。
这个过程可以简化为:
用户提问 → Agent/CLI(提取系统提示词 → 拼接历史消息或摘要 → 附加 Skill/Tool 定义 → 读取代码、文档、检索结果 → 组装完整请求) → LLM API → 输出答案/发起工具调用 → 结果再被塞入下一轮上下文
这件事为什么重要?因为它直接决定了成本结构。
第一,会话越长,后续每一轮就越贵。因为历史不是“搁在那等模型自己回忆”,而是大概率在每一轮都要重新携带一次。
第二,工具越多,常驻定义就越重。一个 Tool / MCP 不只是“多了一个按钮”,而是增加了一段需要让模型理解的说明、参数模式以及调用约束。
第三,工具调用会形成回路。模型先读取一大包上下文,然后调用工具;工具返回一段结果;结果又被塞回上下文,再进入下一轮判断。于是,一个任务不是一次计费,而是一个“请求—返回—再请求”的链条。
所以 AI Agent 最怕的不是问题复杂,而是:
- 会话越滚越长
- 工具越堆越多
- 背景越塞越满
- 每次都要从头开始找信息
- 输出不合格,导致反复重试
很多人说“它好像记得”。更准确的说法其实是:“它每次都得重新读一遍。” 这才是成本雪球式增长的真正根源。
1.3 五种成本类型,远不止是“输入字数”
进行成本优化,首先需要将 Token 这个概念从“字数”的简单认知中解放出来。
在 Agent 场景里,至少涉及五类开销,需要分开审视。
成本类型 | 它是什么 | 为什么会放大 |
|---|---|---|
输入 Token | 系统提示词、历史消息、代码片段、检索结果、工具定义 | 每轮都可能重复携带,是最大头 |
输出 Token | 模型最终生成的文字 | 回答越长、越啰嗦、越容易失控 |
推理 Token / thinking budget | 模型内部用于思考和规划的预算 | 简单任务如果设置高推理档位,会明显增加成本 |
工具往返成本 | 工具描述、调用参数、返回结果进入上下文 | 一次工具调用,通常比原问题本身还长 |
重试成本 | 第一次出错后需要重新来一轮 | 每次修正,都可能将整个上下文包再付费一次 |
这里面,最容易被低估的往往是后两项。
工具往返成本的问题在于:你以为自己只是“让它查个文件”,但模型实际经历的是:理解工具定义 → 生成参数 → 接收返回值 → 再结合返回值继续思考。对人来说只是一个动作,对系统来说可能是多段上下文交换。
重试成本则更加隐蔽。真正烧钱的,往往不是第一次调用太长,而是第一次不合格——格式不对、结构出错、找错文件、推理过度——于是又得重来一轮。
第一次没答对 → 重新描述问题 → 重新附带历史 → 重新拉取代码或工具结果 → 再跑一轮模型
所以很多“看起来只补了一句话”的修正,实际意味着:
错误的第一次调用 + 第二、第三次修正调用 = 整包上下文被反复付费
这也是为什么“减少重试”本身就是一种非常直接的成本优化手段。格式约束更清晰、任务边界更明确、上下文给得更精准,省下来的不只是一次输出,而是整条失败链路的所有成本。
1.4 Prompt Cache:为何它是所有优化的基础
理解了成本结构,就能明白为什么 Prompt Cache 如此重要。
很多人第一次听到缓存,会以为缓存的是“答案”。其实更接近的理解是:缓存的是稳定前缀的处理结果。也就是说——如果两次请求的前半段几乎相同,服务端就不必每次都从头处理那一大段相同的内容。[1]、[2]
原理可以先粗略理解成:
固定前缀 → 缓存命中 → 不必每次都从头处理
最容易命中缓存的内容,通常包括这些:
- System Prompt
- Tool / MCP 定义
- Skill 定义
- 长文档背景
- 稳定的 few-shot 前缀
为什么官方文档总在强调“静态内容放前面,动态内容放后面”?因为缓存命中的对象通常是前缀,而不是整段任意位置的拼图。
看这张图会更直观:
请求 1:系统提示词 / Tool 定义 / 项目背景 → 本轮问题 A
请求 2:系统提示词 / Tool 定义 / 项目背景 → 本轮问题 B
相同前缀,可复用
这里有几个关键的推论。
第一,Prompt Cache 省的不是首次成本,而是重复成本。 第一次发送长前缀时,通常还是要正常付费,真正的价值在第二次、第三次以及后续多次复用时才会体现出来。
第二,缓存不是“写短”,而是“写稳”。 如果你频繁改动系统提示词、经常调整 Skill Prompt,那缓存理论上存在,但在实践中很难命中。
第三,缓存优化和上下文治理本身是同一件事。 减少前缀抖动、将稳定内容前置、把变化内容后置,本质都是在提升“可复用比例”。
所以 Prompt Cache 本质上不是为了“让模型更聪明”,而是为了让人“不必为同一段前缀反复买单”。官方数据也印证了这一点:OpenAI 与 Anthropic 都提到,长前缀命中缓存后,输入成本和延迟都可能显著下降。[1]、[2]
1.5 一张全览图:五层优化模型
梳理完成本来源后,再看优化路径就会清晰很多。
这篇文章的核心框架分为五层。
层级 | 主题 | 作用 | 特点 | 覆盖 |
|---|---|---|---|---|
第一层 | 使用习惯 | 先减少无意义上下文 | 零成本,即刻可做 | 本篇覆盖 |
第二层 | 模型路由 | 让不同任务匹配不同模型 | ROI 最高 | 本篇覆盖 |
第三层 | Context 工程 | 稳定前缀,减少重复传输 | 系统级优化 | 下篇覆盖 |
第四层 | 代码图谱 | 减少盲目搜索,缩短检索链路 | 降低检索成本 | 下篇覆盖 |
第五层 | Agent 架构 | 将任务分配给合适的单元 | 提升长期可维护性 | 下篇覆盖 |
它们并非并列的小技巧,而是一条从便宜到贵、从易到难的升级路径。
- 使用习惯解决的是“无意义的历史和无效 Token”
- 模型路由解决的是“昂贵模型处理简单任务”
- Context 工程解决的是“相同前缀重复发送”
- 代码图谱解决的是“每次都从零开始查找代码”
- Agent 架构解决的是“所有任务都塞进同一个大上下文”
这五层背后,其实只有一个总目标:
- 让模型少看无关内容
- 让便宜模型多处理标准任务
- 让昂贵模型只进行高价值推理
还有一条贯穿全文的线索:观测与预算治理。
没有数据,所有的优化都会变成一种主观感受。你觉得自己“省钱了”,但不知道具体省在哪里,也不确定这种节省是否以牺牲质量为代价。这个话题,我们留到下篇详细展开。
到这里,第一章真正想建立的心智模型可以浓缩成一句话:你只问了 0.1K,系统替你承担了 200K。减少重复的上下文,就是一切优化的起点。
一旦脑子里有了这张图,第二章那些“看起来很琐碎”的使用习惯,就不再是零散的经验技巧,而会变成非常顺其自然的工程操作。
第二章 使用习惯:最便宜也最被低估的优化
如果你现在就想开始节省开支,首先要动的不是架构,也不是知识图谱,而是使用习惯。
这一层几乎不需要任何工程投入,却经常能带来第一波最大的收益。接下来聊的九个习惯,都是今天就能改变的。
2.1 一个 Session,只做一件事
很多人习惯将 AI Agent 当作一个永不关闭的长对话窗口:上午修复 Bug,下午编写文档,晚上讨论架构规划,第二天接着继续。
体验上确实很流畅,但成本上就是一场灾难。
原因很简单:Session 越长 → 继承的历史越多 → 每一轮对话就越昂贵。
修复 Bug 开一个会话,进行重构开一个,写文章开一个,查询线上问题再开一个。不要将它们混在一起讨论。主题层面的切割,就是最便宜也最有效的上下文管理方式。
2.2 长会话不压缩,就是负债
很多人舍不得清理历史,总觉得“越完整,模型越稳定”。
但模型真正需要的,并不是你从头到尾的完整试错过程。它需要的是:
- 现在要干什么
- 已经完成了什么
- 哪条路行不通
- 卡在了哪里
- 下一步打算怎么做
那些 /compact 命令本质上做的,就是这么一件事:
把完整的历史压缩成一个可以继续工作的状态
对话记录本身不是资产。未经压缩的长对话就是负债,它让后续每一轮都不得不背负越来越沉重的历史包袱。
2.3 聊天记录不是数据库
不少团队习惯性地将背景、决策、约束、待办事项全部挂在会话上下文中,指望 Agent 能一路记到底。
后果很直接:会话越来越长,状态越来越难提取,成本持续攀升。
那些真正需要长期保留的信息,应该被“外置”出去:
- 项目文档
- Summary 文件
- Memory 文件
- Repo Map / Knowledge Graph
- 任务清单
让会话只承载“当前的工作状态”,而不是把整个项目的历史都背在身上。
2.4 少说废话,就是节省 Token
很多人只盯着优化输入,却忽略了输出端的成本同样很高。
在编码场景里,最浪费的回答往往不是“错误的”,而是“冗余的”:先复述一遍你的问题,再讲一段众所周知的技术背景,然后是一堆礼貌性的铺垫,最后才给出结论。
如果你只需要 diff、步骤、结论、表格或者 JSON——可以直接要求它这样输出。
这类约束非常有价值,因为它同时节省了两类成本:
- 输出更短
- 结果更可用 → 重试次数更少
在许多日常任务中,一句简单的指令就足够了:
直接给结论,不要复述问题,必要时再展开
像 Ca veman 这类思路之所以受欢迎,不是因为“简陋”,而是因为它能精准地消除那些高频的无效 Token。
2.5 Skill 并非免费能力
Skill 当然有价值,但它也伴随着成本。
每一个 Skill 都携带自己的 Description、Instructions、Examples 和触发逻辑。这些信息如果常驻在上下文中,就会占用宝贵的 Token 空间。
问题的关键不在于“能不能加载”,而在于:
- 高频、稳定、通用的 Skill,可以常驻。
- 低频、篇幅长、复用率低的 Skill,应该按需触发。
这和后端服务治理是一个道理:常驻的能力,要尽量追求少而精。
2.6 MCP 越多,不一定越强
MCP 最大的诱惑,是能让你的 Agent “什么都能接入”。
但从成本角度来看,每多一个 MCP,就意味着多一份 Tool Definition,多一层模型的选择成本。
不少人安装了 GitHub、Notion、Jira、Slack、Browser、Filesystem、Kubernetes、Docker 以及各种内部系统。看起来功能很强,实际上高频使用的可能就两三个。
工具太多带来的问题,远不止“文档变长”这一点:
- 模型的选择空间变大 → 决策速度变慢
- 错误调用的概率变高
- 每一轮都需要携带更重的定义
所以工具治理和依赖治理一样:关键不是“能不能安装”,而是“有没有必要让它常驻”。
2.7 CLI 优先于 MCP
这是一个有点尖锐但非常实用的原则:
能 CLI 解决 → 尽量用 CLI
能脚本解决 → 尽量用脚本
最后才考虑 MCP
很多操作已经有非常成熟的 CLI 工具:gh pr create、kubectl get pods、docker ps、git diff。AI 直接执行一条命令,比额外加载一整份 MCP 工具说明要轻量得多。
对于国内常见的研发平台,也已经有一些专门为 AI Agent 优化的 CLI 工具可以直接使用:
- tapd-ai-cli:腾讯 TAPD 的 AI Agent 专用 CLI,支持需求、缺陷、任务的查询和更新。直接用
tapd story list、tapd bug create之类的命令操作 TAPD,比加载一套 MCP 轻很多,还能用tapd skill init一键生成 SKILL.md 配置。 - gongfeng-cli:腾讯工蜂代码托管的 AI Agent 专用 CLI,专门针对 Agent 的认知模式优化了输出格式(Markdown + JSON 混合),支持 PR 创建、代码评审、项目管理等完整工作流,Token 消耗显著低于同等 MCP 方案。
这两个工具的共同思路很值得借鉴:它们是为 Agent 设计的,而不是给人类看的 UI 套了一层 CLI 外壳。输出格式、信息密度、命令发现机制,都专门针对 AI 的调用模式做了优化。
当然,MCP 的价值在于跨系统编排、结构化返回、权限统一收敛和内部业务能力包装上。
所以不是“CLI 永远优于 MCP”,而是:能用 CLI 解决的,先别急着上 MCP。
2.8 引用文件时带上完整路径
这是一个极其容易被忽略的小习惯,但它节省的 Token 是实实在在的。
很多人引用文件时习惯只写文件名:
看一下 config.go 的问题
帮我修改 utils.py
AI 收到这类请求,往往需要先搜索整个项目来定位这个文件,有时候还可能搜到同名文件或路径不确定,需要再次发起搜索确认。这些搜索调用和返回结果,全都要计入 Token 消耗。
一个更直接的做法是:
看一下 src/config/config.go 的问题
帮我修改 @/Users/yourname/project/utils.py
用 @ 符号加上相对路径或绝对路径,Agent 可以直接定位并读取,完全不需要经历任何搜索过程。
这个习惯对于大型项目来说效果更为显著——项目越大,搜索的代价就越高,目录层级越深,搜索越容易绕弯路。
只写文件名 → 搜索 → 可能多次确认 → 读取
完整路径 → 直接读取
一个简单的 @路径,就能省下一整条搜索链路。
2.9 一次说完意图,避免聊天式拆碎
在 AI Agent 的使用场景中,有一种非常常见的低效模式:
用户:帮我看一下这个函数
AI:你想让我做什么?
用户:找一下有没有 bug
AI:找到一个问题,要修吗?
用户:修一下
AI:修好了,还要写测试吗?
用户:写一下
表面上看,这像是在“正常沟通”。但实际上,每一轮来回都在消耗额外的 Token:重新组装上下文、重新代入历史、重新确认状态。四轮对话的总成本,往往是一次完整表达的好几倍。
更省的做法,是一次性把意图说清楚:
查看 @src/order/service.go 的 CreateOrder 函数,找出潜在的 bug,修复,并为修复后的函数编写单元测试。
这并非要求你把指令写得更长,而是要求你把目标说完整。一次对话,Agent 一次性跑完整个任务,省去了所有中间确认的来回成本。
越具体、越完整的指令,浪费的来回次数就越少。这和程序员提 Issue 的逻辑是完全一样的:把背景、期望、验收条件都写清楚,沟通成本才不会比写代码本身还高。
第三章 模型路由:别让昂贵模型处理简单任务
在习惯层面的优化做好之后,下一步收益最高的,就是模型路由了。
很多人一上来就会犯一个错误:所有环节无脑使用最强模型。看起来很稳妥,实际上最烧钱。
3.1 匹配优先,不是便宜优先
模型路由不是“一律使用便宜的”,而是先把任务类型分对:
- 复杂任务 → 强模型
- 简单任务 → 便宜模型
- 重复任务 → 稳定模型
架构设计需要长链路推理,该用贵的就用。编写单元测试、补充注释、生成提交信息这类工作,用便宜的模型完全足够。大规模批量分类和摘要,则适合走低单价模型或离线批处理。
3.2 一张表说清楚
任务 | 推荐模型档位 | 理由 |
|---|---|---|
编写 UT | 便宜模型 | 模式稳定、模板化 |
编写 commit | 便宜模型 | 输出短、风险低 |
Code Review | 中高档模型 | 需要语义理解 |
架构设计 | 强模型 | 长链路推理 |
复杂 Bug 分析 | 强模型 | 多步假设和验证 |
批量分类/摘要 | 低价或 Batch | 规模大、成本敏感 |
选择模型不是凭个人喜好,而是按照任务所需的能力来匹配。
3.3 先过便宜模型,再升级
很多任务并不需要一上来就用最贵的模型。
一个更省钱的模式可以简化为一条升级链路:
便宜模型先跑 → 判断复杂度 → 需要时才升级
举个例子:先让便宜模型对任务进行分类(重构?Bug?文档?),或者先做初步筛选(这个 PR 有没有高风险?),又或者先做一个摘要(把 20 页压缩成 1 页),然后再交给强模型进行下一步的推理。
这种级联式的工作流,既节省了成本,又能确保贵模型的算力都用在关键地方。
3.4 不只换模型,也要调整预算旋钮
现在许多模型都提供了一些成本控制旋钮:
reasoning effortthinking budgetverbositymax output tokens
它们影响的,其实是同一组核心变量:
思考深度、回答长度、花费多少
Google Gemini 的 thinkingBudget ,就允许按任务粒度来控制思维链的 Token 量,对于简单任务甚至可以设置为 0(直接关闭思考步骤)。OpenAI 也建议许多工作负载从 low 的 reasoning effort 开始尝试。
3.5 Skill / Agent / Command 都应绑定模型
模型路由不应该只存在于“主对话框”的抽象概念里,而应该落实到每一个具体的执行单元上。
Skill 绑定模型:编写 UT、编写 commit、格式修复、样板代码等标准化任务,可以明确绑定便宜模型。
以 CodeBuddy 为例,SKILL.md 文件的头部可以直接声明模型和上下文策略:
---
context: fork
model: deepseek-v4-pro
---
这里的 model 字段指定了该 Skill 使用的模型,而 context: fork 则表示把这类固定流程放到独立的执行上下文中,非常适合任务边界清晰、可以单独完成的 Skill。这样一来,低复杂度的 Skill 会自动走便宜模型,也无需将主会话的完整历史都带进去。
斜杠命令(Slash Command) 和 Agent 同样支持 model 参数绑定,可以在定义时就明确固化好模型选择。这样团队里的每个人在使用 /commit、/gen-ut 这类命令时,都会默认走便宜模型,而不需要依赖个人记得去手动切换。
Agent 绑定模型:
Planner → 中高档
Coder → 中档 / 便宜
Reviewer → 强
Command 绑定模型:很多命令本身就是固定模板,非常适合预设便宜的模型。
这类设计一旦固化下来,成本治理就从“靠人来记住切换”变成了“系统默认就帮你节省”。
本篇小结
本篇主要讲了三件事。
第一,搞清楚钱到底花在了哪里。 不是你问的那句话,而是历史记录、工具定义、代码文件被频繁重复地带上上下文。减少重复的上下文传输,是所有优化动作的根本逻辑。
第二,习惯层的收益被严重低估了。 一个 Session 只做一件事、及时使用 /compact、明确控制输出格式、精简对 Skill 和 MCP 的装载量、CLI 优先、引用文件带上完整路径、意图一次说全——这些都不需要任何工具配置,今天就可以开始用起来。
第三,模型路由的 ROI 非常高。 并不是所有任务都值得用最贵的模型。按照任务匹配模型,再加上对 reasoning effort 等旋钮的控制,通常是改造成本最小、同时收益最快的工程化手段。
好的习惯加上合理的路由,是在不动任何架构的前提下,能拿到的最可观的一笔收益。这也是为什么这篇文章把这两个话题放在了最前面——工具可以慢慢配置,但习惯越早建立越好。
今天就能做的行动清单
- 用
/new切断无关历史,一个 Session 只做一件事 - 长会话及时执行
/compact,别让历史变成包袱 - 指定输出格式,减少废话和不必要的重试
- 清点一下 Skill 和 MCP,低频使用的卸掉或设为按需加载
- 简单任务手动切换到便宜模型
- 能走 CLI 解决的,先别急着上工具
- 引用文件时用
@路径,不要只写文件名让 AI 去搜索 - 意图一次说完整,避免聊天式地一条一条拆碎指令
下篇预告:
习惯和路由层面的优化做完之后,下一步就要进入工具层和架构层了。
下篇会深入聊:
- RTK / Ca veman / headroom / context-mode:终端输出、模型回复、工具返回值分别怎么压缩
- Graphify / CodeGraph:代码图谱怎么建,怎么让 Agent 不再盲目搜索
- 多 Agent 边界:
/new、/compact、subagent、worktree 分别解决什么问题
参考资料
[1] OpenAI,《提示词缓存 | OpenAI API》 https://developers.openai.ac.cn/api/docs/guides/prompt-caching
[2] Anthropic,《Token-sa ving updates on the Anthropic API》 https://claude.com/blog/token-sa ving-updates
[3] OpenAI,《使用 GPT-5.5 | OpenAI API》 https://developers.openai.ac.cn/api/docs/guides/latest-model
[4] Google AI for Developers,《Thinking》 https://ai.google.dev/gemini-api/docs/thinking
[5] Anthropic,《Prompt caching》 https://platform.claude.com/docs/en/build-with-claude/prompt-caching
