<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>成本优化 on Chico's Tech Blog</title><link>https://realtime-ai.chat/tags/%E6%88%90%E6%9C%AC%E4%BC%98%E5%8C%96/</link><description>Recent content in 成本优化 on Chico's Tech Blog</description><image><title>Chico's Tech Blog</title><url>https://github.com/chicogong.png</url><link>https://github.com/chicogong.png</link></image><generator>Hugo</generator><language>zh-cn</language><lastBuildDate>Tue, 05 May 2026 11:00:00 +0800</lastBuildDate><atom:link href="https://realtime-ai.chat/tags/%E6%88%90%E6%9C%AC%E4%BC%98%E5%8C%96/index.xml" rel="self" type="application/rss+xml"/><item><title>Prompt Caching 实战:把推理成本和延迟砍下来</title><link>https://realtime-ai.chat/posts/prompt-caching/</link><pubDate>Tue, 05 May 2026 11:00:00 +0800</pubDate><guid>https://realtime-ai.chat/posts/prompt-caching/</guid><description>同一段 system prompt 反复 prefill 是在烧钱。这篇讲清 prompt caching 怎么命中、缓存断点放哪、Anthropic/OpenAI/Gemini/DeepSeek 各家计费与 TTL 差异,以及对延迟的影响。</description><content:encoded><![CDATA[<p>先说一个很多团队没算过的账。</p>
<p>假设你的 Agent 有一段 4000 token 的 system prompt:角色设定、工具说明、几个 few-shot 例子,雷打不动。用户每轮真正输入的,可能就 30 个字。一天 10 万次请求,这 4000 token × 10 万,就是 4 亿个 token 反复进入模型做同一件事——把固定前缀重新算一遍。</p>
<p>这部分计算,90% 是白烧的。因为前缀一模一样,模型每次算出来的中间结果(KV cache)也一模一样。<strong>Prompt caching 就是把这份中间结果存下来,下次直接复用。</strong> 它不改你的代码逻辑,不动模型质量,却能把输入侧成本砍掉一大半,顺带把首 token 延迟压下去。</p>
<p>2026 年,它依然是被严重低估的省钱手段。不是因为难,恰恰是因为太简单——简单到大家以为&quot;开了就行&quot;,结果断点放错位置,缓存全程没命中,白付一笔写入费还不自知。</p>
<h2 id="它到底缓存了什么">它到底缓存了什么</h2>
<p>要用对,先得知道模型推理分两个阶段。</p>
<p><strong>Prefill(预填充)</strong>:把你的整段 prompt 一次性喂进模型,逐 token 算出每一层的 KV(key/value)向量。这一步是并行的、算力密集的,prompt 越长越慢。</p>
<p><strong>Decode(解码)</strong>:基于 prefill 的结果,一个一个吐出回答 token。</p>
<p>Prompt caching 缓存的,就是 prefill 阶段算出来的那份 KV。注意:它缓存的是<strong>前缀</strong>,不是&quot;整个 prompt&quot;。模型从第一个 token 开始,一段一段比对——只要某个位置往前的内容和缓存里的完全一致,这段就能复用;一旦遇到第一个不一样的 token,从那里往后全部得重算。</p>
<pre class="mermaid">flowchart LR
  A["请求 prompt"] --> B{"逐 token 比对前缀"}
  B -->|"前缀命中"| C["复用 KV<br/>(便宜 + 快)"]
  B -->|"遇到第一个差异"| D["从这里往后重新 prefill"]
  C --> D
  D --> E["Decode 出 token"]
</pre><p>这张图就是 prompt caching 的全部精髓。所有的&quot;怎么用对&quot;,归结成一句话:<strong>让不变的东西待在前面,让变化的东西待在后面。</strong></p>
<h2 id="为什么前缀的顺序决定一切">为什么前缀的顺序决定一切</h2>
<p>各家请求体的拼接顺序是固定的:<strong>tools(工具定义)→ system(系统提示)→ messages(对话历史)</strong>。模型按这个顺序拼成一条长 prefix,再从头比对。</p>
<p>这意味着排在越前面的内容,越&quot;值钱&quot;——它一旦变化,后面所有东西的缓存全部作废。所以一个合格的可缓存 prompt,结构应该长这样,从稳定到易变排列:</p>
<table>
  <thead>
      <tr>
          <th>位置</th>
          <th>放什么</th>
          <th>变化频率</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>最前</td>
          <td>工具定义、函数 schema</td>
          <td>几乎不变</td>
      </tr>
      <tr>
          <td>靠前</td>
          <td>system prompt、角色设定、few-shot 例子</td>
          <td>发版才变</td>
      </tr>
      <tr>
          <td>中间</td>
          <td>知识库片段、长文档、检索结果</td>
          <td>按会话变</td>
      </tr>
      <tr>
          <td>最后</td>
          <td>当前用户输入、本轮变量</td>
          <td>每次都变</td>
      </tr>
  </tbody>
</table>
<p>最常见的翻车,是把&quot;变化的东西塞进了前面&quot;。比如有人喜欢在 system prompt 顶部写一句 <code>当前时间:2026-05-05 11:23:07</code>。看着无害,实际是灾难——这个时间戳每秒都不一样,等于把整条 prefix 的第一个字就改了,<strong>后面 4000 token 的缓存全程一次都命中不了</strong>。同类的坑还有:user ID、请求 UUID、A/B 实验分组标记、随机打乱的 few-shot 顺序。</p>
<p>如果你确实需要给模型当前时间,把它放到对话消息的<strong>最后</strong>,跟用户输入待在一起。前面那一大坨稳定前缀,该缓存照样缓存。</p>
<h2 id="缓存断点放哪自动-vs-手动">缓存断点放哪:自动 vs 手动</h2>
<p>这里是各家最大的分歧,也是最容易用错的地方。</p>
<p><strong>自动派(OpenAI、Google 隐式缓存、DeepSeek)</strong>:你什么都不用做。系统自动识别请求之间的公共前缀,命中了就给你折扣。OpenAI 对超过 1024 token 的 prompt 自动启用;DeepSeek 是后端自动复用磁盘上的前缀缓存;Gemini 2.5 及以后的模型默认开启隐式缓存。</p>
<p>自动派的好处是零成本接入,坏处是<strong>没有保证</strong>。命中是&quot;尽力而为&quot;的——Google 自己也写明,隐式缓存只在系统判定命中时才给折扣,你无法强制。</p>
<p><strong>手动派(Anthropic,以及 Gemini 的显式缓存)</strong>:你得自己在 prompt 里打一个 <code>cache_control</code> 标记,告诉模型&quot;缓存到这里为止&quot;。这个标记叫<strong>缓存断点(cache breakpoint)</strong>。Anthropic 一个请求最多打 4 个断点。</p>
<p>手动派麻烦一点,但换来确定性:你明确知道哪一段被缓存了。</p>
<p>手动派最经典的错误,是<strong>把断点打在了会变的块上</strong>。比如这样的结构——一大段静态知识库,后面跟一个&quot;包含时间戳 + 用户输入&quot;的块,然后断点打在最后这个块上。结果时间戳每次都变,这个块的 hash 每次都不同,缓存永远写入、永远读不到。</p>
<p>正确做法:<strong>断点打在「最后一个跨请求不变」的块的末尾</strong>,而不是打在变化的块上。把静态前缀和动态后缀切开,断点卡在它们的交界处。</p>
<pre class="mermaid">flowchart TB
  subgraph 错误["错误:断点在变化块上"]
    A1["静态知识库 8000 token"] --> A2["时间戳 + 用户输入 ⟵ 断点"]
  end
  subgraph 正确["正确:断点在静态前缀末尾"]
    B1["静态知识库 8000 token ⟵ 断点"] --> B2["时间戳 + 用户输入"]
  end
</pre><p>还有一个多轮对话特有的坑:对话越滚越长,你的断点可能被挤到&quot;上一次写入位置&quot;20 多个块之外,超出回溯窗口,于是又一次踩空。多轮场景里,务必随着对话增长<strong>滚动更新断点位置</strong>,让它始终贴着最新的稳定边界。</p>
<h2 id="四家的计费和-ttl差得不小">四家的计费和 TTL,差得不小</h2>
<p>省多少、贵多少、能存多久——各家规则不一样,接之前一定要看清。</p>
<table>
  <thead>
      <tr>
          <th>厂商</th>
          <th>缓存写入</th>
          <th>缓存读取</th>
          <th>TTL</th>
          <th>模式</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Anthropic</td>
          <td>1.25×(5 分钟)/ 2.0×(1 小时)输入价</td>
          <td>0.1× 输入价</td>
          <td>5 分钟默认,可选 1 小时</td>
          <td>手动断点</td>
      </tr>
      <tr>
          <td>OpenAI</td>
          <td>不额外收费</td>
          <td>视模型 0.1×~0.5× 输入价</td>
          <td>几分钟,空闲淘汰</td>
          <td>自动</td>
      </tr>
      <tr>
          <td>Google Gemini</td>
          <td>隐式无写入费;显式按标准输入价计</td>
          <td>约 0.1× 输入价(2.5+ 省 90%)</td>
          <td>隐式自动;显式按 TTL 计存储费</td>
          <td>隐式自动 / 显式手动</td>
      </tr>
      <tr>
          <td>DeepSeek</td>
          <td>不额外收费</td>
          <td>约 0.1× 输入价(cache hit 价)</td>
          <td>后端管理,存储免费</td>
          <td>自动(磁盘)</td>
      </tr>
  </tbody>
</table>
<p>几个要点单独拎出来说。</p>
<p><strong>Anthropic 是唯一对&quot;写入&quot;收钱的。</strong> 写一次缓存比正常输入贵 25%(5 分钟档)。这意味着如果你的 prompt 写进去之后根本没被复用就过期了,你是<strong>净亏</strong>的——多付了 25%,一分钱折扣没拿到。所以 Anthropic 的缓存只对&quot;高频复用同一前缀&quot;的场景划算。读取确实便宜,只要 1/10 输入价。</p>
<p><strong>TTL 是个隐形雷区。</strong> Anthropic 默认 TTL 在 2026 年初从 1 小时悄悄变回了 5 分钟,不少团队因此缓存创建成本涨了 20%~30% 还没察觉。5 分钟意味着:如果你的请求间隔超过 5 分钟,缓存早凉了,每次都是冷启动重新写入。好消息是 TTL 的时钟会在每次命中时<strong>重置</strong>——只要请求够密,缓存能一直续命。需要长间隔复用的,Anthropic 可以花 2 倍写入价买 1 小时 TTL。</p>
<p><strong>OpenAI 和 DeepSeek 对开发者最省心</strong>:不收写入费,自动命中,几乎是&quot;白送的折扣&quot;。DeepSeek 2026 年 4 月把 cache hit 价格再砍到发布价的 1/10,V4-Flash 上缓存命中把输入成本从 $0.14 压到 $0.0028 每百万 token——98% 的降幅。</p>
<p><strong>省钱幅度的体感</strong>:输入侧能省 50%~90%。具体看你的 prompt 里&quot;固定前缀占比&quot;有多高——前缀越长、变量越短,省得越狠。一个 8000 token 知识库 + 50 token 提问的 RAG 应用,几乎是为 prompt caching 量身定做的。</p>
<h2 id="别忘了它还能压延迟">别忘了它还能压延迟</h2>
<p>省钱是它最出名的好处,但对实时类应用,<strong>降延迟才是关键收益</strong>。</p>
<p>命中缓存时,prefill 这一步被整段跳过。前面说过,prefill 是算力密集的,prompt 越长越慢。跳过它,首 token 延迟(TTFT)的下降立竿见影——DeepSeek 给过一个数据:128K 的长 prompt 高度命中缓存时,首 token 延迟从 13 秒压到 500 毫秒。</p>
<p>这对语音 Agent、实时对话这种&quot;首 token 延迟就是及格线&quot;的场景,意义比省钱大得多。一个挂着长 system prompt 和工具定义的语音助手,把这部分缓存住,等于每一轮对话都省掉了几千 token 的 prefill 时间。如果你正在为 TTFT 抠毫秒,prompt caching 应该排在优化清单的前列。</p>
<p>不过有个前提:<strong>省下来的延迟,得真的有缓存可命中</strong>。冷启动那一次(第一次写入)不但不快,Anthropic 那边还更慢更贵。所以 prompt caching 优化的是&quot;稳态延迟&quot;,不是&quot;首次延迟&quot;。</p>
<h2 id="一份排查清单为什么我没命中">一份排查清单:为什么我没命中</h2>
<p>如果你接了 prompt caching,但账单没怎么降,大概率是踩了下面某一条。按顺序自查:</p>
<ol>
<li>
<p><strong>前缀里有变量。</strong> 时间戳、UUID、user ID、随机数——但凡有一个混进了 system prompt 或工具定义,整条缓存作废。把它们全部赶到 messages 末尾。</p>
</li>
<li>
<p><strong>断点打错位置(手动派)。</strong> 断点要打在&quot;最后一个不变块&quot;的末尾,不是打在变化块上。切开静态与动态的交界。</p>
</li>
<li>
<p><strong>请求间隔超了 TTL。</strong> Anthropic 默认才 5 分钟。低频请求(比如定时任务、长间隔轮询)很可能每次都冷启动。要么提高请求密度,要么买长 TTL。</p>
</li>
<li>
<p><strong>prompt 太短没够门槛。</strong> OpenAI 要超过 1024 token 才会自动缓存。短 prompt 本来也省不了多少,不用纠结。</p>
</li>
<li>
<p><strong>工具定义或 system prompt 偷偷变了。</strong> 多人协作时,有人调了一下工具描述、改了个标点,排在最前面的 tools 段一变,后面全塌。把可缓存前缀<strong>当成发布制品来管理</strong>,别让它随手改。</p>
</li>
<li>
<p><strong>few-shot 例子顺序不固定。</strong> 有些代码每次随机打乱 few-shot 顺序&quot;增加多样性&quot;——这会让前缀每次都不同。要缓存,就固定顺序。</p>
</li>
</ol>
<h2 id="落地建议">落地建议</h2>
<p>不用一上来就上复杂方案。三步走:</p>
<p><strong>第一步,把 prompt 重新排版。</strong> 不管你用哪家,先按&quot;工具 → system → 知识库 → 用户输入&quot;从稳到变重排一遍,把所有变量揪到最后。光这一步,自动派(OpenAI / DeepSeek / Gemini)就能开始命中了,一行代码没动。</p>
<p><strong>第二步,手动派打好断点。</strong> 用 Anthropic,就在静态前缀末尾打 <code>cache_control</code>;多轮对话记得滚动更新断点。</p>
<p><strong>第三步,盯住命中率。</strong> 各家 API 响应里都会返回 cache 相关字段(命中 token 数、写入 token 数)。把&quot;缓存读取 token / 总输入 token&quot;做成一个监控指标。它要是长期偏低,回到上面那份清单逐条查。</p>
<p>最后提醒一句取舍:prompt caching 不是&quot;开了就一定赚&quot;。对 Anthropic 这种收写入费的厂商,低频、前缀短、变量多的场景,反而可能亏。先搞清楚自己的流量形态——<strong>高频复用同一份长前缀,才是它的主场</strong>。判断对了,这是你能拿到的、性价比最高的一次优化:不掉质量,不改逻辑,省一半成本,还顺手降了延迟。</p>
<hr>
<p>参考资料:</p>
<ul>
<li><a href="https://platform.claude.com/docs/en/build-with-claude/prompt-caching">Prompt caching - Claude API Docs</a></li>
<li><a href="https://github.com/anthropics/claude-code/issues/46829">Cache TTL silently regressed from 1h to 5m · Issue #46829</a></li>
<li><a href="https://openai.com/index/api-prompt-caching/">Prompt Caching in the API | OpenAI</a></li>
<li><a href="https://developers.openai.com/api/docs/guides/prompt-caching">Prompt caching | OpenAI API</a></li>
<li><a href="https://docs.cloud.google.com/gemini-enterprise-agent-platform/models/context-cache/context-cache-overview">Context caching overview | Google Cloud</a></li>
<li><a href="https://developers.googleblog.com/gemini-2-5-models-now-support-implicit-caching/">Gemini 2.5 Models now support implicit caching - Google Developers Blog</a></li>
<li><a href="https://api-docs.deepseek.com/news/news0802">DeepSeek API introduces Context Caching on Disk</a></li>
</ul>
]]></content:encoded></item><item><title>Agent 的 token 账单怎么管</title><link>https://realtime-ai.chat/posts/agent-token-cost/</link><pubDate>Thu, 30 Apr 2026 11:00:00 +0800</pubDate><guid>https://realtime-ai.chat/posts/agent-token-cost/</guid><description>Agent 上线后 token 成本最容易失控:多轮、长上下文、工具结果会成倍放大开销。这篇讲清钱花在哪、怎么定位大头,以及 prompt caching、上下文压缩、模型路由、步数熔断等可落地手段。</description><content:encoded><![CDATA[<p>先说一个数字:同样问&quot;帮我查一下这个 bug&quot;,发给聊天机器人和发给 Agent,token 消耗能差 <strong>50 倍</strong>。</p>
<p>聊天机器人就一来一回:你发一段、它回一段,结束。Agent 不一样——它跑的是一个循环:看任务、调工具、读文件、改代码、再检查。<strong>循环里的每一步,都要把到目前为止积累的全部上下文,重新发给模型一次。</strong></p>
<p>这就是 Agent 账单的根源。2026 年有人审计了 30 个在生产环境跑 Agent 的工程团队,一个 20 人的团队,单月 API 账单能冲到 11 万美元;用 Claude Code 或 Cursor 这类编码 Agent 的开发者,人均每月 400 到 1500 美元,失控的案例几天就烧掉 4000 美元以上。</p>
<p>更要命的是,这笔钱不是匀速烧的。Demo 跑得好好的,一上量就爆——大部分企业的 Agent 项目,在大规模铺开后的头 90 天里,实际花销会超出试点预算 4 到 11 倍。所以做 Agent,成本不是上线之后再优化的事,是设计时就得算进去的一笔账。</p>
<p>这篇把这笔账拆开:钱花在哪、怎么找到大头、有哪些真能省的手段、怎么设预算和熔断、怎么监控。</p>
<h2 id="钱到底花在哪">钱到底花在哪</h2>
<p>先建立一个最反直觉的认知:<strong>Agent 跑一个任务的成本,主要不是输出,是输入。</strong></p>
<p>模型 API 按 token 收费,输入和输出分开计价。聊天场景里,大家盯着输出看。但 Agent 不一样,它的成本大头在<strong>输入侧的重复计费</strong>。</p>
<p>为什么?因为对话历史会&quot;滚雪球&quot;。Agent 每调一次工具,就要把整段对话历史连同工具返回的结果,一起再发一次。一段已经积累到 10 万 token 的上下文,在后续<strong>每一次</strong>调用里,都按 10 万输入 token 收费——不是只收新增的那部分。一个跑到第 20 步的编码 Agent,光是文件读取塞进来的内容,单步输入就能超过 5 万 token,按 Sonnet 4.6 的价(每百万输入 token 3 美元)算,<strong>每一步 0.15 美元</strong>,二十步就是 3 美元,而这还只是一个任务。</p>
<p>把烧钱的来源列清楚,主要是这四个:</p>
<table>
  <thead>
      <tr>
          <th>成本来源</th>
          <th>为什么烧钱</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>多轮累积</td>
          <td>历史每轮都重发,N 步任务的输入约为单步的 N 倍量级</td>
      </tr>
      <tr>
          <td>长上下文</td>
          <td>大 system prompt、塞满的 RAG 检索结果,每次调用都全额计费</td>
      </tr>
      <tr>
          <td>工具结果</td>
          <td>一次文件读取、一次数据库查询返回几千 token,且永久留在上下文里</td>
      </tr>
      <tr>
          <td>多 Agent</td>
          <td>主 Agent 派生子 Agent,每个子 Agent 自己又是一个完整的 token 循环</td>
      </tr>
  </tbody>
</table>
<p>这四项里,<strong>多轮累积和工具结果是最隐蔽的</strong>——它们不在你写的 prompt 里,是 Agent 自己在运行时长出来的。你 review 代码时看不到,只有看账单才发现。</p>
<h2 id="先定位大头再动手">先定位大头,再动手</h2>
<p>不要凭感觉优化。第一步永远是<strong>按维度把成本拆开看</strong>,否则你很可能花两天去抠一个只占 5% 的环节。</p>
<p>至少要能按这几个维度归因(attribution):</p>
<ul>
<li><strong>按 Agent / 任务类型</strong>:哪类任务最贵?是&quot;代码重构&quot;还是&quot;简单问答&quot;?</li>
<li><strong>按步骤</strong>:成本是均匀分布,还是集中在某几步(比如某个返回巨量结果的工具)?</li>
<li><strong>按输入/输出</strong>:再确认一次,是输入贵还是输出贵——多数 Agent 是输入。</li>
<li><strong>按用户 / 会话</strong>:是不是 5% 的重度用户烧掉了 80% 的钱?</li>
</ul>
<p>这里有个观测层的坑要提前知道:Agent 的一次&quot;请求&quot;,在 trace 里会炸开成 8 到 15 个 span——API 调用、token 流式输出、embedding 查询、向量库检索、prompt 拼装、guardrail 检查、结果解析……普通 API 接口才 2 到 3 个。如果你的监控是按&quot;请求数&quot;做采样的,Agent 会瞬间把你的可观测性预算也撑爆。所以 Agent 的成本监控,<strong>得按 token 和按美元来记,不能只按请求数</strong>。</p>
<p>拆完之后你大概率会看到一个二八分布:某一两类任务、某一两个工具,吃掉了大半账单。先打这些点。</p>
<h2 id="真能省钱的几个手段">真能省钱的几个手段</h2>
<p>定位完大头,下面是 2026 年实测有效的手段,按&quot;性价比&quot;从高到低排。</p>
<h3 id="prompt-caching第一个要上几乎免费">prompt caching:第一个要上,几乎免费</h3>
<p>这是投入产出比最高的一项,优先级最高。</p>
<p>原理很简单:Agent 的上下文里有一大块是<strong>固定不变的前缀</strong>——system prompt、工具定义、few-shot 示例。每一步调用都把这块重新做一遍前向计算(prefill),纯属浪费。prompt caching 就是把这段固定前缀缓存住,后续调用直接命中缓存。</p>
<p>2026 年的价格,缓存命中的输入 token 只按基础价的 <strong>0.1 倍</strong>收费,也就是 9 折优惠——Anthropic 是这个价,GPT-5.4 现在也对齐到了 90% 的缓存折扣。对一个多轮 Agent,固定前缀往往占输入的一大半,命中率拉高之后,输入成本砍掉 50% 到 90% 是常态。</p>
<p>要拿到这个收益,有个纪律:<strong>别让缓存失效</strong>。缓存命中的前提是前缀逐字节一致。所以要把&quot;不变的东西&quot;放前面、&ldquo;会变的东西&quot;放后面——system prompt 和工具定义放最前,动态的对话历史和检索结果放后面。一旦你在 system prompt 里塞了个当前时间戳,整个缓存就废了。</p>
<h3 id="上下文压缩对付滚雪球的正面手段">上下文压缩:对付&quot;滚雪球&quot;的正面手段</h3>
<p>prompt caching 省的是固定前缀;滚雪球的对话历史得靠压缩。</p>
<p>最直接的做法是<strong>定期把历史压成摘要</strong>。Agent 跑了 30 步,前 20 步的细节其实没必要逐字带着——把它们总结成一段&quot;已完成:确认了 bug 在 X 模块,排除了 Y 假设&rdquo;,用摘要替换原始对话。Anthropic 在 2026 年 2 月放出的 Compaction API(beta)就是把这件事自动化:让模型自动总结、压缩对话历史,实现近乎&quot;无限&quot;的对话长度,不用手动裁剪或重开会话。</p>
<p>工具结果也要管。一次文件读取返回 5000 token,但 Agent 真正需要的可能只是其中一个函数。可以做的:工具返回时就<strong>截断或摘要</strong>,只保留相关片段;旧的工具结果在后续轮次里<strong>替换成一句占位符</strong>(&quot;[此处曾读取 config.py,已处理]&quot;)。</p>
<h3 id="按难度选模型别用大炮打蚊子">按难度选模型:别用大炮打蚊子</h3>
<p>不是每一步都需要最强的模型。</p>
<p>2026 年 Claude 三档价差很大:Haiku 4.5 是每百万 token 1/5 美元(输入/输出),Sonnet 4.6 是 3/15,Opus 4.7 是 5/25。<strong>Haiku 比 Sonnet 便宜 5 倍,比 Opus 便宜 25 倍。</strong></p>
<p>一个 Agent 流程里,真正需要顶配模型做复杂推理的步骤可能只占两三成。剩下的——意图分类、格式整理、判断&quot;任务完成了没&quot;、简单的工具参数填充——交给 Haiku 完全够用。做法就是按步骤的难度做路由(routing):简单步骤走小模型,复杂推理才升到 Sonnet 或 Opus。一个 500 输入 / 100 输出 的 Haiku 分类调用,成本大约 0.001 美元,几乎可以忽略。</p>
<h3 id="限制步数和递归给失控的循环装个闸">限制步数和递归:给失控的循环装个闸</h3>
<p>前面说企业 Agent 超预算 4 到 11 倍,原因之一就是<strong>没有上限的工具调用递归</strong>。</p>
<p>Agent 卡在一个错误里出不来,会一遍遍重试同一个工具;主 Agent 派生子 Agent,子 Agent 再派生……如果没有硬上限,一个本该 10 步的任务能跑成 200 步。必须设硬限制:</p>
<ul>
<li><strong>单任务最大步数</strong>(比如 25 步,到了就强制收尾或交还给人)</li>
<li><strong>多 Agent 的递归深度上限</strong>(比如最多 2 层)</li>
<li><strong>同一项的重试次数上限</strong>——一个实战配置是:同一项每天最多重试 3 次,两次重试之间至少隔 2 小时,不可重试的错误直接跳过,别困在死循环里</li>
</ul>
<h3 id="缓存工具结果--batch能省就省">缓存工具结果 + batch:能省就省</h3>
<p>两个补充手段。</p>
<p><strong>缓存工具结果</strong>:很多工具调用是确定性的、可重复的——查同一个文档、跑同一个查询。给工具调用层加一个缓存,相同输入直接返回上次结果,连模型调用都省了。语义缓存(semantic cache)更进一步,语义相近的请求也能命中。</p>
<p><strong>batch(批处理)</strong>:如果你的任务不需要实时返回——离线评测、批量数据标注、夜间跑的报告——走 Batch API,输入输出都打五折。把 prompt caching 的 9 折和 batch 的 5 折叠加,极端情况能把成本压到原来的 5%。代价是异步,最长可能等 24 小时,所以只适合离线场景。</p>
<p>下面这张图是这些手段的处理顺序:</p>
<pre class="mermaid">flowchart TD
  A[Agent 收到一步请求] --> B{固定前缀?}
  B -->|是| C[命中 prompt cache<br/>输入按 0.1x 计费]
  B -->|否| D[正常计费]
  C --> E{这步难度?}
  D --> E
  E -->|简单| F[路由到 Haiku]
  E -->|复杂| G[路由到 Sonnet/Opus]
  F --> H{工具结果是否过大?}
  G --> H
  H -->|是| I[截断/摘要后入上下文]
  H -->|否| J[直接入上下文]
  I --> K{历史是否过长?}
  J --> K
  K -->|是| L[压缩成摘要]
  K -->|否| M[继续]
</pre><h2 id="给-agent-设预算和熔断">给 Agent 设预算和熔断</h2>
<p>省钱手段是&quot;开源节流&quot;里的节流。但 Agent 还需要一道<strong>硬性的财务闸门</strong>——再怎么优化,也得有个东西在它失控时直接把它停掉。</p>
<p>这就是成本熔断(cost circuit breaker):预设一个开销上限,Agent 触到上限就强制中断,而不是任由它把账单跑飞。</p>
<p>预算定多少?别拍脑袋。<strong>先量,再定。</strong> 取一个有代表性的两周样本,统计每个完整任务消耗 token 的 p50 和 p95,然后把上限设在 <strong>p95 的 1.5 倍</strong>。这个值能覆盖正常的波动,又能在真正异常时及时触发。</p>
<p>熔断要分层设,至少三层:</p>
<table>
  <thead>
      <tr>
          <th>层级</th>
          <th>触发条件</th>
          <th>动作</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>单任务</td>
          <td>单个任务 token 超 1.5× p95</td>
          <td>中断该任务,记录,交还给人</td>
      </tr>
      <tr>
          <td>单用户/会话</td>
          <td>用户当日累计超额度</td>
          <td>拒绝新请求或降级到小模型</td>
      </tr>
      <tr>
          <td>全局</td>
          <td>全组织当日总花销超阈值</td>
          <td>告警 + 限流,保住核心业务</td>
      </tr>
  </tbody>
</table>
<p>关键点:熔断的动作必须是<strong>确定性的、自动执行的</strong>。运行时的预算治理需要两样东西——明确的限额,加上确定的补救动作。光设个数字、靠人看告警手动去关,等你看到消息,钱已经烧完了。</p>
<h2 id="监控该怎么做">监控该怎么做</h2>
<p>最后是监控。没有监控,前面所有的优化都是一次性的——这个月省下来,下个月一个新功能上线又涨回去,你还不知道。</p>
<p>Agent 的成本监控,要盯这几个指标:</p>
<ul>
<li><strong>每任务成本(cost per task)</strong>:最核心的北极星指标。优化做对了,这个数应该往下走。</li>
<li><strong>缓存命中率</strong>:prompt caching 的命中率。如果某次发布后它突然掉下来,八成是有人改了 system prompt 把缓存搞失效了。</li>
<li><strong>每任务平均步数</strong>:悄悄往上爬,通常意味着 Agent 开始绕路或卡循环。</li>
<li><strong>token 成本归因</strong>:持续按 Agent、按用户、按任务类型拆,二八分布的那个&quot;二&quot;要一直盯着。</li>
<li><strong>熔断触发次数</strong>:偶尔触发是正常的安全网;频繁触发说明预算设低了,或者真有 Agent 在失控。</li>
</ul>
<p>把这些接进你现有的可观测性系统,设好告警。一个务实的目标:认真做完一轮成本优化的团队,通常能在 30 天内把 Agent 成本降低 55% 到 75%。</p>
<h2 id="一份上线前的清单">一份上线前的清单</h2>
<p>把上面的东西收成一张可勾选的表,Agent 上线前过一遍:</p>
<ul>
<li><input disabled="" type="checkbox"> 成本能按 Agent、用户、任务类型、步骤拆开归因</li>
<li><input disabled="" type="checkbox"> 固定前缀(system prompt、工具定义)放在最前,且已开 prompt caching</li>
<li><input disabled="" type="checkbox"> system prompt 里没有时间戳之类会破坏缓存的动态内容</li>
<li><input disabled="" type="checkbox"> 对话历史有压缩/摘要机制,不会无限滚雪球</li>
<li><input disabled="" type="checkbox"> 工具返回结果会截断或摘要,旧结果会被占位符替换</li>
<li><input disabled="" type="checkbox"> 简单步骤路由到小模型,只有复杂推理才上顶配</li>
<li><input disabled="" type="checkbox"> 设了单任务最大步数、多 Agent 递归深度、重试次数上限</li>
<li><input disabled="" type="checkbox"> 确定性的工具调用结果有缓存</li>
<li><input disabled="" type="checkbox"> 离线、非实时的任务走了 Batch API</li>
<li><input disabled="" type="checkbox"> 三层熔断(单任务/单用户/全局)都已配置,且动作是自动执行的</li>
<li><input disabled="" type="checkbox"> 预算阈值是基于 p95 实测数据定的,不是拍脑袋</li>
<li><input disabled="" type="checkbox"> 每任务成本、缓存命中率、平均步数都在监控里,有告警</li>
</ul>
<p>最后说一句优先级。如果时间有限,先做三件事:<strong>开 prompt caching、设步数上限、配单任务熔断</strong>。这三样投入小、见效快,而且能挡住最致命的那种&quot;一夜之间烧掉几千美元&quot;的事故。上下文压缩、模型路由这些是细水长流的优化,可以上线之后慢慢调。</p>
<p>Agent 的账单不会自己变小。但只要你知道钱花在哪、装好了闸门,它至少不会变成一个你不敢看的数字。</p>
<hr>
<p>参考资料:</p>
<ul>
<li><a href="https://leanopstech.com/blog/agentic-ai-cost-runaway-token-budget-2026/">AI Agents Burn 50x More Tokens Than Chats — LeanOps</a></li>
<li><a href="https://fast.io/resources/ai-agent-token-cost-optimization/">AI Agent Token Cost Optimization: Complete Guide for 2026 — Fastio</a></li>
<li><a href="https://dev.to/waxell/ai-agent-context-window-cost-the-compounding-math-your-architecture-is-hiding-2227">AI Agent Context Window Cost: The Compounding Math — DEV Community</a></li>
<li><a href="https://www.obviousworks.ch/en/token-optimization-saves-up-to-80-percent-llm-costs/">Token optimization 2026: Saving up to 80% LLM costs — Obvious Works</a></li>
<li><a href="https://fountaincity.tech/resources/blog/ai-agent-cost-circuit-breaker/">The Cost Circuit Breaker: Financial Controls for Production AI Agents — Fountain City</a></li>
<li><a href="https://blogs.oracle.com/ai-and-datascience/runtime-budget-guardrails-agentic-ai">Runtime Budget Guardrails for Agentic AI — Oracle</a></li>
<li><a href="https://www.truefoundry.com/blog/llm-cost-attribution-agentic-cicd">Agentic Token Explosion: Attribute, Budget, and Control LLM Costs — TrueFoundry</a></li>
<li><a href="https://oneuptime.com/blog/post/2026-03-07-ai-agents-breaking-observability-budget/view">AI Agents Are Breaking Your Observability Budget — OneUptime</a></li>
<li><a href="https://platform.claude.com/docs/en/about-claude/pricing">Claude API Pricing — Anthropic Docs</a></li>
<li><a href="https://tokenmix.ai/blog/openai-batch-api-pricing">OpenAI Batch API 2026: 50% Off Every Model — TokenMix</a></li>
</ul>
]]></content:encoded></item></channel></rss>