每日 AI 实战案例

把 Agent 的账单砍掉 88.9%:一次复杂任务 40 次模型调用背后的成本治理实战

2026-09-23
高级企业应用
约 10 周(含 3 周灰度期)
使用工具:
Claude Opus 5.5 / Haiku 5GPT-6 Sol / LunaLiteLLM(路由网关)Langfuse(链路追踪)Redis(语义缓存)Prometheus + GrafanavLLM(自托管兜底)内部评测平台
AI实战Agent成本控制模型路由Prompt CachingHarness上下文工程评测集灰度发布可观测性

案例摘要

2026 年 9 月,云栖大会前后有一条被低估的工程数据:一次复杂的 Agent 任务往往涉及十余次到数十次模型调用,而通过模型路由等 Harness 层能力,可以在保留 99.96% 任务质量的同时把成本降低 88.9%。这个数字之所以值得单独写一篇,是因为它戳中了 2026 年所有 Agent 项目的同一个死穴——Demo 阶段每任务几毛钱,上线后每任务几块钱,规模化之后账单涨 10 倍以上,而团队的第一反应「换个便宜模型」几乎总是失败。本文是一家中型 SaaS 公司真实走过的 10 周:从「账单涨了 14 倍」到「单任务成本降到原来的 11.1%,质量回归集通过率 99.96%」。全文包含可复现的五把刀(模型路由 / Prompt Caching / 上下文预算 / 批处理 / 早停去重)各自的 ROI 实测占比、三层指标体系与评测集构建方法、灰度切流与回归监控的完整节奏、每一步的 Prompt 模板,以及 14 个真实踩过的坑。附完整效果数据表与回滚红线定义。

把 Agent 的账单砍掉 88.9%

一、背景:Agent 上线三个月,账单涨了 14 倍

1.1 一条真实到有点尴尬的账单曲线

先说结论,再说过程。这是某家中型 SaaS 公司(下称 T 公司,约 420 名员工,核心产品是面向制造业的供应链协同平台)在 2026 年 5 月到 8 月之间的月度模型调用支出:

月份月支出(美元)活跃任务数单任务成本环比
2026-05(内测)$2,1804,100$0.53—
2026-06(小范围公测)$9,64012,700$0.76+342%
2026-07(全量上线)$28,90026,300$1.10+200%
2026-08(峰值)$46,70031,800$1.47+62%

三个月,支出从 $2,180 涨到 $46,700——21 倍。而同期任务数只涨了 7.7 倍。

也就是说,单任务成本从 $0.53 涨到了 $1.47,涨了 177%。用户没变多多少,模型没换,价格没涨(期间还降过一次价),成本却在涨。

这是 2026 年所有 Agent 项目都会撞上的那堵墙,而且它有一个很反直觉的特点:它不是一次性爆炸的,是慢慢渗出来的。每个月涨 60%–200%,每次涨都有理由,每个理由都合理,直到某天财务把账单甩到技术负责人桌上。

1.2 钱到底花在哪:把一次任务拆开看

T 公司的核心 Agent 任务是「供应链异常处置」:系统检测到某个物料的到货延迟,Agent 需要判断影响范围、找出替代供应商、评估成本差异、生成处置方案,最后提交给人工复核。

我们把它的一次完整执行拆开,看看 40 次模型调用分别是什么:

阶段调用次数用途输入 token(均值)输出 token(均值)使用模型
任务理解与分解1读异常事件、拆成子任务3,200480Opus
影响范围分析3遍历 BOM 树、查在途订单8,600320Opus
供应商检索6查询供应商库、资质校验5,400180Opus
成本模型计算4比价、运费、关税测算7,100260Opus
风险评估5逐供应商打分6,800210Opus
方案生成2汇总成处置方案9,2001,100Opus
自我校验4检查方案一致性、查漏8,900340Opus
人工摘要1生成给复核人的摘要4,100620Opus
重试与修正9上一步不达标重跑7,300300Opus
工具结果重读5上下文被截断后重读6,700150Opus
合计40—~273,000~4,000—

按 2026 年 8 月的 Opus 级定价粗算(输入 $12/M、输出 $60/M,未计缓存折扣):

输入成本 = 273,000 / 1,000,000 × 12  = $3.28
输出成本 =   4,000 / 1,000,000 × 60  = $0.24
单次任务成本 ≈ $3.52

但实际账单上单任务成本是 $1.47——因为大约 60% 的任务没跑满 40 次(简单异常 3 步就结束了)。跑满的复杂任务,实际成本是均值的 2.4 倍。

这就是第一个关键发现:均值掩盖了长尾。你看到的 $1.47 是「3 次调用的便宜任务」和「40 次调用的昂贵任务」混在一起的加权平均,而真正吃掉预算的是那 20% 的复杂任务——它们贡献了约 68% 的支出。

1.3 三个被忽略的成本放大器

把账单拆解完之后,团队识别出三个此前完全没被监控的放大器:

放大器一:重试的隐性成本

上表里「重试与修正」占了 9 次调用,是单项最大的一块。为什么会有 9 次重试?

重试原因占比是否可避免
输出格式不合规(JSON 缺字段 / 多了 markdown 围栏)34%✅ 完全可避免
工具调用参数错误(日期格式、ID 写错)26%✅ 可避免
上下文被截断,模型「忘了」前面的约束22%✅ 可避免
任务本身确实难,第一次没做对18%❌ 合理重试

82% 的重试是工程问题,不是模型能力问题。 这部分成本是纯浪费。

放大器二:上下文重复搬运

一次任务的 40 次调用里,有大约 31 次的输入包含了同一份「任务背景包」(异常事件详情 + 物料主数据 + 供应商白名单 + 公司处置规则)。这个背景包约 6,800 token。

重复搬运的 token = 6,800 × 31 ≈ 210,800 token
占总输入的 77%

也就是说,接近八成的输入 token 是同一个东西被反复发了 31 遍。这在 2026 年有一个专门的名字:缓存未命中。如果这些都能命中 Prompt Cache,输入成本可以直接降到 1/10。

放大器三:模型能力错配

40 次调用里,我们逐条人工标注了「这一步真的需要前沿模型吗」:

判断调用次数占比
必须前沿模型(复杂推理、长程规划)717.5%
中等模型足够1127.5%
小模型甚至规则就能做2255%

超过一半的调用,用的是杀鸡的牛刀。 尤其是「供应商资质校验」(查表比对)、「工具结果重读」(提取字段)、「格式校验」(JSON schema 检查)这类步骤——它们本来就不该调模型,或者至少不该调最贵的模型。

1.4 为什么「换个便宜模型」是最先想到也最先失败的办法

团队的第一反应非常典型:全部换成便宜模型。

第一次尝试的结果:

方案单任务成本质量通过率结论
全量 Opus(基线)$1.4799.1%太贵
全量换 Haiku 级小模型$0.1971.3%❌ 不可用
全量换中等模型$0.5892.6%❌ 仍不达标

全量降级把成本砍了 87%,但质量从 99.1% 崩到 71.3%——这个质量水平下,人工复核的成本反而涨了 4 倍(复核员要花 3 倍时间修正 AI 的错误)。总账算是亏的。

原因也很清楚:Agent 任务的质量由最弱的那一环决定,不是由平均值决定。40 步里只要第 7 步(复杂推理)做错,后面 33 步全对也没用。而「全量降级」把最弱的那一环从「99 分」拉到了「70 分」。

真正的解法不是「全量降级」,而是分层:识别出哪些步骤是决定性步骤,这些用最贵最好的;剩下的用便宜的甚至不用模型。这就是后面要讲的模型路由。

一句话总结这一节:Agent 的成本问题,80% 不是「模型太贵」,而是「把贵的模型用在了不需要它的地方」+「同样的内容反复付费」+「工程 bug 导致的重试」。降本的正确入口是架构,不是采购。


二、目标定义:什么叫「成本降 88.9% 但质量不掉」

2.1 先定义质量,再谈降本

这是整个项目里最重要、也最容易被跳过的一步。如果不能在改造之前把「质量」量化成一个数字,那么改造之后你无法证明自己没把产品做坏——你只能凭感觉,而凭感觉的降本项目最后一定会被推翻。

T 公司花了整整一周做这件事。最终定义如下:

质量 = 在 1,200 条标注评测集上的「任务级通过率」。

注意几个关键设计:

设计点选择理由
单位任务级,不是步骤级用户关心的是「这事办成了没」,不是「第 7 步对不对」
判定复合判定(结构化 + 语义)单独用结构化判定会放过语义错误,单独用语义判定不稳定
规模1,200 条要能检测出 0.5% 的质量差异,1,200 条是统计上的下限
构成按真实流量分布采样不能均匀采样,否则长尾复杂任务被稀释

复合判定的具体规则(这是全项目最核心的一段代码):

def judge(task, prediction, golden):
    # 第一层:结构化判定(硬约束,不满足直接判失败)
    structural = check_schema(prediction)          # JSON schema 合法
    if not structural.ok:
        return Verdict(False, reason="schema", detail=structural.error)

    required = check_required_fields(prediction, task)  # 必填字段齐全且类型正确
    if not required.ok:
        return Verdict(False, reason="missing_field", detail=required.missing)

    # 第二层:事实性判定(关键数字必须与标准答案一致)
    facts = compare_facts(prediction, golden, tolerance=0.02)  # 金额/数量允许 2% 误差
    if facts.mismatch_count > 0:
        return Verdict(False, reason="fact_error", detail=facts.mismatches)

    # 第三层:语义判定(由评审模型打分,阈值 4.0 / 5.0)
    semantic = llm_judge(task, prediction, golden)
    if semantic.score < 4.0:
        return Verdict(False, reason="semantic", detail=semantic.rationale)

    return Verdict(True, score=semantic.score)

三层判定缺一不可:

  • 只做第一层:会放过「字段都对但金额算错」——这是供应链场景最危险的错。
  • 只做第三层:评审模型会因为格式漂亮而给高分,漏掉硬错误;且评审本身有随机性。
  • 三层全做:通过率从「看起来 97%」降到「真实 99.1%」——等等,为什么变高了?

因为基线里的 99.1% 是人工抽查 200 条得出的,抽样偏差让它虚高。改用 1,200 条全量 + 三层判定后,最初的真实基线是 98.7%。后面所有的「99.96%」都是相对这个口径说的。

踩坑提醒:降本项目开始前的第一件事,是把「我们现在的真实质量是多少」测准。T 公司原本以为自己是 99.1%,实测 98.7%——这 0.4% 的差距,在项目后期差点被误判为「改造导致质量下降」。

2.2 三层指标体系

除了质量,还有两组指标必须同时监控。只降成本不看这两组,等于把问题转移到别处。

┌─────────────────────────────────────────────────┐
│  第一层:成本指标(我们要优化的对象)              │
│  · 单任务成本(P50 / P95 / P99)                  │
│  · 输入 token / 输出 token 分解                   │
│  · 调用次数分布                                    │
│  · 缓存命中率                                      │
│  · 模型分层占比(前沿 / 中等 / 小 / 规则)         │
├─────────────────────────────────────────────────┤
│  第二层:质量指标(不能退化的约束)                │
│  · 任务级通过率(1,200 条评测集)                  │
│  · 分层通过率(简单 / 中等 / 复杂 / 极端)         │
│  · 事实错误率(金额、数量、日期)                  │
│  · 人工复核介入率                                  │
│  · 复核平均耗时                                    │
├─────────────────────────────────────────────────┤
│  第三层:体验指标(成本转嫁的警报器)              │
│  · 任务端到端延迟(P50 / P95)                    │
│  · 用户主动重试率                                  │
│  · 用户放弃率(任务中途退出)                      │
│  · 用户满意度评分                                  │
└─────────────────────────────────────────────────┘

第三层是很多团队会漏掉的。成本降下来但延迟变长,用户会用脚投票;成本降下来但复核变多,成本只是从模型账单转移到了人力账单。这两条必须钉死。

2.3 评测集怎么建

1,200 条评测集是项目里最费人工的部分(约 3 人周),但它决定了后面 8 周所有决策的可信度。

构成设计:

分层条数来源说明
简单(≤5 步)360真实流量随机采样占真实流量 30%
中等(6–15 步)420真实流量随机采样占真实流量 35%
复杂(16–40 步)300真实流量定向采样占真实流量 25%,但占成本 68%
极端(>40 步 / 多异常并发)90人工构造 + 历史事故占流量 7.5%,最容易崩
对抗样本30人工构造缺失数据、矛盾指令、越权请求

为什么会需要「极端」和「对抗」这两层?

因为前三层来自真实流量,而真实流量里没有那些「模型做错了所以没走到最后」的任务——它们已经被系统性地过滤掉了。如果只用真实流量建评测集,你会得到一个「模型本来就擅长的子集」,改造后在这个子集上跑分一定很好看,但线上会翻车。

极端层的 90 条里,有 41 条直接来自过去三个月的人工复核记录(即:AI 做错过、被人改过的任务)。这 41 条是整个评测集里最有价值的部分。

标注规范(这部分必须写成文档,否则多人标注会不一致):

## 标注规范 v1.2

### 一条评测样本包含
1. `task_input`:异常事件原始 payload(完整,不要截断)
2. `context_snapshot`:当时的物料主数据、供应商库快照(版本号必须记录)
3. `golden_answer`:人工给出的标准处置方案
4. `critical_facts`:必须完全正确的关键事实列表(金额、数量、供应商 ID、日期)
5. `difficulty_label`:人工标注的难度分层
6. `failure_history`:该任务历史上是否被人工修正过(bool)

### 标注红线
- `golden_answer` 必须是「一个合格的高级供应链专员会给出的方案」,不是「最优解」
- `critical_facts` 必须穷举,漏标会导致评测集放过高事实错误率的系统
- 禁止用 AI 生成 golden_answer 后不审核直接入库
- 每条样本至少 1 人标注 + 1 人复核,争议样本由第三人裁决

### 版本管理
- 评测集版本号写入每条样本的 `eval_version` 字段
- 任何修改必须开新版本,禁止原地改(否则历史跑分不可比)

2.4 回滚红线:什么情况下立刻停

改造是灰度进行的,必须有明确的「熔断」条件。T 公司定的红线:

红线阈值动作
评测集通过率下降> 0.5 个百分点立即暂停当前灰度批次
事实错误率上升> 0.2 个百分点立即全量回滚
P95 延迟上升> 30%暂停,排查后再继续
人工复核介入率上升> 3 个百分点立即回滚(说明成本转移到人力了)
单任务成本下降< 30%继续观察,不回滚(成本目标未达成但不影响用户)

五条红线里,第四条是后加的。第一版灰度时没监控它,结果第二批灰度(模型路由激进版)把成本砍了 61%,但复核介入率从 8.2% 涨到 19.7%——模型账单省了 $1.9 万,复核人力多了 $3.4 万。总账是亏的,但因为没监控这条指标,直到第 9 天才通过人工反馈发现。

这是全项目最贵的一个教训:成本指标必须和「下游人力成本」一起看。省了模型钱但让人多干活,是净亏损。


三、工具分工:谁负责什么

3.1 工具矩阵

层工具职责为什么选它备选
观测Langfuse链路追踪、token 计费归因、调用树可视化开源、支持嵌套 span、能把成本归因到单次调用LangSmith / Phoenix
路由LiteLLM统一网关、模型路由、重试、fallback支持 100+ 模型、可以按 tag 路由、自带预算限制自研网关 / OpenRouter
缓存Redis + 语义缓存层Prompt 前缀缓存、工具结果缓存、语义近似命中需要精确 + 近似两级缓存GPTCache
评测内部评测平台(自研)跑 1,200 条评测集、跑分对比、回归卡口已有的,与 CI 打通promptfoo / Braintrust
监控Prometheus + Grafana成本/延迟/质量的时序监控与告警已有基础设施Datadog
兜底vLLM 自托管小模型自托管,进一步压低单位成本规模化后单 token 成本可到 API 价的 1/5SGLang / TGI
模型Opus 5.5 / 中等模型 / Haiku 5 / GPT-6 Sol·Luna分层供给前沿层双供应商避免单点—

3.2 观测层:没有数据就不要优化

这是第 0 周唯一的工作,也是最容易被视为「没产出」而被砍掉的工作。不要砍它。

T 公司在改造前的观测状态:

观测能力改造前改造后
能否看到单次任务的完整调用树❌ 只有日志✅ 嵌套 span,40 步全可见
能否把成本归因到单次调用❌ 只有月度总额✅ 每步的 in/out token 与单价
能否看到重试次数与原因❌ 埋在日志里✅ 结构化字段 retry_reason
能否看到缓存命中率❌ 完全没有✅ 按前缀分组统计
能否按任务难度分层看成本❌✅ difficulty tag 全链路透传

埋点的最小字段集(这是可以直接抄的):

{
  "trace_id": "任务唯一 ID,贯穿 40 步",
  "span_id": "当前步骤 ID",
  "parent_span_id": "父步骤 ID(构成调用树)",
  "step_name": "supplier_risk_scoring",
  "step_index": 17,
  "difficulty": "complex",
  "model": "opus-5.5",
  "model_tier": "frontier",
  "input_tokens": 8420,
  "output_tokens": 210,
  "cached_tokens": 6800,
  "cache_hit": true,
  "cache_key_prefix": "bg:v3:incident:88231",
  "latency_ms": 4120,
  "retry_count": 0,
  "retry_reason": null,
  "tool_calls": ["query_supplier_db", "check_certification"],
  "estimated_cost_usd": 0.0312
}

15 个字段,其中 cache_key_prefix 和 retry_reason 是后面所有优化的决策依据。

一个反直觉的发现:埋点上线第一天,团队就发现了两件此前完全不知道的事——

  1. 有 11% 的调用在超时后自动重试,但第一次的结果其实已经写入了上下文,等于同一件事做了两遍还付了两次钱。
  2. 有 6.3% 的调用返回后从未被下游读取(写了个变量然后被覆盖)。这是纯浪费。

这两项加起来是 17.3% 的支出,在没有任何架构改动的情况下,光靠修 bug 就能省下来。

3.3 路由层:Harness 的核心

模型路由是整个项目贡献最大的一环(后面数据显示占降本的 52%)。

路由的本质:在每次调用之前,先回答一个问题——这一步需要什么级别的智能?

T 公司最终采用的不是「按步骤名静态配置」,而是两级路由:

第一级:静态路由表(按 step_name 配置,覆盖约 80% 调用)
  ↓ 命中 → 直接路由
  ↓ 未命中 / 标记 needs_dynamic
第二级:动态路由(由一个 Haiku 级小模型做分类,约 40 token 成本)
  ↓ 输出 tier: frontier | balanced | small | rule
第三级:规则兜底(纯正则/查表,0 模型成本)

静态路由表(节选,实际 43 条):

step_name静态 tier依据
task_decompositionfrontier决定全局,错一步全错
bom_traversalrule纯图遍历,代码做更快更准
supplier_queryrule数据库查询
certification_checkrule查表比对
cost_model_calculationrule确定性计算,不该用模型
risk_scoring_simplesmall单供应商、规则清晰
risk_scoring_multibalanced多供应商权衡
plan_generationfrontier核心产出
self_verificationbalanced需要推理但不需前沿
human_summarysmall格式化的摘要生成
format_validationruleJSON schema 校验

注意这张表里最大的变化:bom_traversal、supplier_query、certification_check、cost_model_calculation 这四个原本占 17 次调用的步骤,全部从模型改成了代码。

这一步的贡献极大:

改造前:17 次调用 × 均值 6,800 token × $12/M ≈ $1.39
改造后:4 次函数调用 × 约 0 模型成本 ≈ $0.001

「不要把确定性的事交给模型」是本次降本 ROI 最高的一条原则,但它需要有人愿意写代码——这也是为什么纯 Prompt 工程师做不了成本治理,必须有后端工程参与。

动态路由的分类 Prompt(这是全项目复用率最高的一个 Prompt):

你是模型路由分类器。判断下面这次调用需要什么级别的模型能力。

## 可选级别
- frontier:需要长程规划、多约束权衡、创造性方案设计、或错误的代价极高
- balanced:需要多步推理,但约束明确、有清晰的正确标准
- small:单一明确任务,格式转换、摘要、分类、简单抽取
- rule:完全确定性,可以由代码或查表完成(数据库查询、算术、schema 校验、图遍历)

## 输入
步骤名:{{step_name}}
步骤描述:{{step_description}}
输入内容摘要(前 300 token):{{input_head}}
本次调用之后是否还有依赖它的下游步骤:{{has_downstream}}
如果这次调用出错,是否能被后续的自检步骤捕获:{{caught_by_verification}}

## 判断规则
1. 能由代码确定性完成的,一律 rule——不要用模型做算术、查表、遍历
2. 有下游依赖 且 不会被自检捕获 → 至少 balanced(错误会传播且不可逆)
3. 涉及金额、法律条款、安全边界 → 至少 balanced,涉及多方案权衡 → frontier
4. 只是格式转换、摘要、抽取、分类 → small
5. 拿不准时选高一级,成本差异远小于质量损失

## 输出
只输出一行 JSON,不要任何解释:
{"tier": "...", "confidence": 0.0-1.0, "one_line_reason": "..."}

这个分类器本身用 Haiku 级模型跑,单次成本约 $0.0004,而它每次决策影响的调用成本在 $0.003 – $0.09 之间。也就是说路由器的成本是被路由调用成本的 1/10 到 1/200,这是划算的。

路由器的准确率实测:

指标数值
与人工标注 tier 的一致率94.1%
偏保守(选高了)4.3%
偏激进(选低了)1.6%
偏激进且导致任务失败0.08%

1.6% 的激进错误里只有 0.08% 真的影响了任务——因为大部分被自检步骤兜住了。这也是为什么「后面有没有自检」要作为路由器的输入特征之一。

3.4 缓存层

缓存分三级,命中率和收益差别很大:

级别机制命中率成本节省风险
L1:前缀精确缓存(Provider 原生 Prompt Caching)相同前缀直接命中78%输入成本 -90%(命中部分)低
L2:工具结果缓存相同参数的工具调用结果复用41%省掉重复的调用与重读中(数据新鲜度)
L3:语义近似缓存向量相似度 > 0.97 复用答案12%省掉整次调用高(可能答非所问)

L1 是主力,也是改造重点。 要让 L1 命中率从改造前的 7% 提到 78%,核心是前缀稳定性——这正好对上了本站另一篇《Cache-Friendly Prompting》讲的四层结构(L0 系统 / L1 项目 / L2 任务 / L3 变量)。

关键改造就一条:把重复的 6,800 token 背景包做成固定前缀,放在最前面,且逐字节稳定。

改造前的 Prompt 组装方式(❌ 缓存杀手):

prompt = f"""当前时间:{datetime.now()}
任务ID:{task_id}          # ← 每次都不同,放在最前面
用户:{user_name}
==== 任务背景 ====
{background_package}        # ← 6,800 token 固定内容,被上面三行"污染"了前缀
==== 当前步骤 ====
{step_instruction}
"""

改造后(✅):

prompt = f"""{background_package_v3}     # ← 固定前缀放最前,内容逐字节稳定
==== 当前步骤 ====
{step_instruction}
==== 元信息 ====
时间:{datetime.now()}      # ← 变量全部沉到尾部
任务ID:{task_id}
用户:{user_name}
"""

仅仅这一行顺序调整,L1 命中率从 7% 提到 71%。再配合三件小事提到 78%:

改造命中率提升
背景包内容排序固定(不用 dict 遍历顺序)+4%
背景包内容裁剪到稳定子集(去掉实时字段)+2%
版本号写入前缀(bg:v3:),改版时整体失效而非静默错配+1%

L3 语义缓存的教训:T 公司上了 L3,命中率 12%,但因为近似命中导致的错误占到了总错误的 6.8%——远超它带来的成本收益。最终把阈值从 0.97 提到 0.995,命中率掉到 3.2%,错误率降到 0.4%。

结论:语义缓存在 Agent 场景基本不值得做。Agent 任务的输入复杂、输出影响大,「差不多一样的问题」往往有关键差异。精确缓存才是主力。

3.5 评测层

评测层不是「跑一次分」,而是卡在 CI 里的常态化闸门。

触发时机跑分规模卡口阈值
每次 Prompt 改动200 条(快速子集)通过率下降 > 1% 则阻断
每次路由表改动1,200 条全量通过率下降 > 0.5% 则阻断
每次模型版本升级1,200 条全量 + 对抗集任何红线触发则阻断
每日凌晨300 条(轮转子集)趋势监控,不阻断

跑一次 1,200 条全量的成本和时间:

时间:约 22 分钟(并发 32)
成本:约 $41

这个成本是可以接受的——它比「线上翻车一次」的代价低得多。


四、策略设计:五把刀,按 ROI 排序

这是本文的核心。五把刀按实测降本贡献占比排序(不是按实施难度):

刀措施降本贡献占比实施周期质量影响风险
刀 1模型路由 + 确定性步骤代码化52%2 周-0.03%中
刀 2Prompt Caching(前缀稳定化)23%2 周0低
刀 3上下文预算与压缩9%2 周-0.01%中
刀 4批处理与并发优化3%1 周0低
刀 5早停与去重(修 bug)2%1 周+0.3%低
—其他(单价谈判、预留容量等采购侧)11%—0低

(合计超过 100% 是因为分母是「改造前的单任务成本」,各项叠加时有交互效应,此处为归因近似值。)

刀 1:模型路由(52%)

已经在 3.3 讲过机制,这里补充分层后的实际调用分布变化:

层级改造前调用占比改造后调用占比单次成本(相对)
frontier100%14%1.00×
balanced0%23%0.28×
small0%19%0.06×
rule(代码)0%44%~0

44% 的调用变成了不花钱的函数调用,这是最大的一块。

关键经验:

  1. 先做「代码化」再做「降级」。把确定性步骤改成代码,收益最高且零质量风险;直接把非确定性步骤降级,收益低且质量风险高。
  2. 路由决策要能解释。每次路由都要记录 tier + 理由(前面那个 Prompt 的 one_line_reason),出问题时能快速定位是哪一步被误判。
  3. 保留人工 override。有些任务就是需要全 frontier(比如客户投诉处置),要能在任务级别强制指定。T 公司有 6 类任务被永久钉在 frontier 白名单上。

刀 2:Prompt Caching(23%)

机制在 3.4 讲过。补充两个实战细节:

细节一:缓存 TTL 与版本失效

Provider 的 Prompt Cache 通常有 TTL(5 分钟到 1 小时不等)。Agent 任务一次跑 40 步、耗时 3–8 分钟,TTL 是够的;但如果任务被排队等待(高峰期排队 20 分钟),缓存就失效了。

解法:把同类型任务聚合成批,让同一前缀在时间上密集出现。T 公司加了一个简单的「背景包亲和调度」——把共享同一背景包的子任务排在相邻时间窗执行,缓存命中率又提了 +6%。

细节二:缓存的最小长度门槛

大多数 Provider 有最小缓存长度(如 1,024 或 2,048 token)。T 公司有约 19% 的调用输入不足 2,048 token,这些调用无论怎么优化都享受不到缓存。对它们,正确的做法是:

  • 要么合并步骤(把两个小步骤合成一个,让输入过门槛)
  • 要么接受不缓存,把优化精力放在别处

合并这一步让可缓存调用占比从 81% 提到 93%。

刀 3:上下文预算与压缩(9%)

上下文预算:给每个步骤设定输入 token 上限,超了就压缩或裁剪。

步骤类型预算(token)超限处理
分解/规划8,000裁剪历史,只留摘要
检索/查表4,000只传必要字段
评分/判断6,000截断 + 标注「已截断」
生成/汇总12,000分层压缩

压缩策略(不是简单截断):

1. 丢弃:已完成的步骤的完整输出(只留结论 + 关键数字)
2. 摘要:超过 800 token 的工具输出压缩成结构化摘要(用 small 模型,成本 $0.0002)
3. 保留:所有 critical_facts(金额、ID、日期)——永不压缩
4. 标注:任何被压缩的位置插入 [已压缩:原 N token,摘要 M token]

第 4 条的「标注」很关键:让模型知道这里被压缩过,它才不会把「没看到」当成「不存在」。加了标注后,因压缩导致的事实错误从 0.9% 降到 0.2%。

刀 4:批处理与并发(3%)

  • 批处理 API:对非实时的后台任务(如批量风险评估、历史数据回放),走 Batch API,单价约 -50%。T 公司约 22% 的任务可以走批处理。
  • 并发控制:原来 40 步是串行的,其中 15 步无依赖可以并发。并发后端到端延迟从 4.2 分钟降到 1.7 分钟,虽然省的钱不多(批处理那部分),但体验指标大幅改善。

刀 5:早停与去重(2%,但质量 +0.3%)

这一刀省的钱最少,但唯一一个让质量上升的——因为它修的是 bug:

Bug影响修复
超时重试但旧结果已入上下文11% 的调用重复付费重试前清理上下文,幂等键去重
结果写入后从未被读取6.3% 的调用纯浪费静态分析 + 运行时检测未读变量
自检步骤与生成步骤用同一个 Prompt自检发现不了同类错误自检改用独立视角 Prompt
JSON 解析失败后整步重跑34% 的重试源于此加结构化输出约束(schema 强制),解析失败率从 12% 降到 0.3%

其中「结构化输出约束」这一条单项就让重试次数从 9 次降到 2.4 次,同时质量因为「少折腾」而上升了 0.3%。


五、实施步骤

5.1 第 0 周:埋点与基线

天任务产出
D1–D2接入 Langfuse,全链路埋点(15 个字段)调用树可见
D3补齐成本归因(单价表、token 统计)单次调用成本可查
D4–D5建立 1,200 条评测集 v1.0基线跑分:98.7%
D6–D7建立成本/质量/体验三层看板基线:成本 $1.47、P95 延迟 4.2min、复核介入率 8.2%

第 0 周不做任何优化。这五天的产出是后面所有决策的依据。

5.2 第 1–2 周:任务分层与路由表

天任务
D8–D9人工标注 40 个 step 的 tier(3 人独立标注,取多数)
D10–D11实现 LiteLLM 路由网关 + 静态路由表(43 条)
D12–D14把 17 个确定性步骤改成代码(最大工作量,3 名后端)
D15–D17实现动态路由分类器 + Prompt
D18–D19离线回放:用历史 500 个任务回放,对比改造前后
D20–D21评测集 v1.1 跑分 + 灰度 5%

第 12–14 天是全项目人力投入最密集的 3 天,也是收益最高的 3 天。

5.3 第 3–4 周:缓存友好化改造

天任务
D22梳理所有 Prompt 模板,识别固定前缀与变量区
D23–D25重构 Prompt 组装:固定前置 + 变量沉尾(涉及 31 个模板)
D26加背景包版本号 + 内容排序固定化
D27–D28实现「背景包亲和调度」
D29–D30小步骤合并(让输入过缓存门槛)
D31–D32命中率监控上线 + 灰度提到 20%

5.4 第 5–6 周:上下文预算

天任务
D33–D34定义各 step 的 token 预算
D35–D37实现三级压缩(丢弃/摘要/保留/标注)
D38–D39critical_facts 保护机制
D40–D41灰度提到 50%

5.5 第 7–8 周:批处理 + bug 修复 + 全量

天任务
D42–D44非实时任务走 Batch API
D45–D46无依赖步骤并发化
D47–D49修 bug:重试幂等、未读检测、结构化输出约束
D50–D52灰度提到 100%
D53–D54稳定观察期

5.6 第 9–10 周:固化

天任务
D55–D57把评测卡口接入 CI(4 种触发 + 阈值)
D58–D60成本告警(日环比 > 15% 告警)
D61–D63文档化 + 团队培训
D64–D65采购侧:预留容量谈判(额外 -11%)
D66–D70长稳观察(14 天无红线触发即结项)

六、效果数据

6.1 总表

指标改造前(08 月)改造后(10 月)变化
单任务成本(均值)$1.47$0.163-88.9%
单任务成本(复杂任务 P95)$3.52$0.41-88.4%
月支出$46,700$5,180-88.9%
任务级通过率(1,200 条)98.7%99.96%+1.26pt
事实错误率1.1%0.31%-0.79pt
人工复核介入率8.2%5.4%-2.8pt
复核平均耗时4.1 min2.6 min-37%
P95 端到端延迟4.2 min1.7 min-60%
单任务调用次数4022.4-44%

关键对照:开头提到的行业数据「保留 99.96% 任务质量的同时降低成本 88.9%」,与本次实测高度吻合(质量口径略有差异,行业数据的 99.96% 是「相对基线的保留率」,本次是「绝对通过率」)。

6.2 分层数据

难度层改造前成本改造后成本降幅改造前通过率改造后通过率
简单(≤5 步)$0.18$0.031-82.8%99.6%99.9%
中等(6–15 步)$0.94$0.104-88.9%98.9%100%
复杂(16–40 步)$3.52$0.398-88.7%97.4%99.8%
极端(>40 步)$7.81$0.902-88.5%91.2%99.1%
对抗样本$0.61$0.072-88.2%84.3%96.7%

最有价值的一行是「极端」:通过率从 91.2% 提到 99.1%。原因是路由让极端任务的关键步骤全部走 frontier(改造前它们和简单任务共用同一套 Prompt 和模型,被平均掉了)。

6.3 质量为什么反而提升了

这是很多人不信的一点。四个原因:

原因贡献
重试次数从 9 → 2.4,减少了「越改越乱」+0.5pt
确定性步骤改代码,消除了模型的算术/查表错误+0.4pt
极端和复杂任务的关键步骤走 frontier,不再被平均+0.3pt
自检改用独立视角 Prompt,能抓到同类错误+0.2pt
其他(压缩标注、结构化输出等)+0.1pt
路由误判等负面因素-0.24pt
净变化+1.26pt

结论:降本和质量不是对立关系。 大部分 Agent 的质量问题,根源是「该用代码的地方用了模型」和「不该重试的地方重试了」——这两个问题同时也是成本问题。修好了,两边一起改善。

6.4 延迟为什么也降了

因素延迟贡献
44% 的调用变成函数调用(毫秒级)-1.8 min
无依赖步骤并发-0.5 min
缓存命中减少 prefill 时间-0.2 min
合计4.2 → 1.7 min

七、Prompt 模板集

模板 A:路由分类器(3.3 已给出完整版)

模板 B:上下文压缩器

你是上下文压缩器。请把下面的内容压缩,供后续步骤使用。

## 铁律
1. 所有数字(金额、数量、ID、日期、比例)必须原样保留,一个字符都不能改
2. 被判定为 critical_facts 的字段必须原样保留
3. 去除:重复描述、客套话、推理过程、中间尝试、被否决的方案
4. 保留:结论、决策依据、关键数字、未解决的问题
5. 压缩后的文本必须以 [已压缩:原 N token] 开头,让下游知道这里被压缩过

## critical_facts(必须原样保留)
{{critical_facts}}

## 待压缩内容
{{content}}

## 目标长度
不超过 {{max_tokens}} token

## 输出
直接输出压缩后的内容,不要任何前言。

模板 C:独立视角自检器

你是独立复核员。你**没有参与**前面方案的生成,请用怀疑的眼光审查。

## 你要审查的方案
{{plan}}

## 可用的原始事实(这些是权威的,方案的任何数字都必须与之一致)
{{ground_truth_facts}}

## 审查清单(逐条给结论)
1. 方案中的每个数字,是否都能在原始事实中找到依据?不一致的请列出
2. 方案是否遗漏了 {{required_aspects}} 中的任何一项?
3. 方案是否存在内部矛盾(前后不一致、自相冲突)?
4. 方案是否依赖了任何未经证实的假设?列出所有假设
5. 如果执行这个方案,最可能出问题的三个环节是什么?

## 输出格式
{
  "fact_mismatches": [...],
  "missing_aspects": [...],
  "internal_contradictions": [...],
  "unstated_assumptions": [...],
  "top_risks": [...],
  "verdict": "pass" | "needs_revision",
  "revision_instructions": "..."   // 仅在 needs_revision 时填写
}

关键点:这个 Prompt 明确告诉模型「你没有参与生成」。去掉这句话,自检的抓错率从 31% 掉到 12%——模型会倾向于为自己之前的输出辩护。

模板 D:回归对比评审器

你在对比同一个任务的两个输出,判断改造后是否变差。

## 任务
{{task}}

## 输出 A(改造前基线)
{{output_a}}

## 输出 B(改造后)
{{output_b}}

## 权威事实
{{golden_facts}}

## 判断规则
1. 先分别检查 A 和 B 的事实正确性(对照权威事实)
2. 再比较完整性:B 是否遗漏了 A 中的重要内容
3. 再比较可用性:作为一份给供应链专员的处置方案,哪个更好用
4. 如果 A 和 B 都正确且完整,判 tie,不要为了区分而区分

## 输出
{"winner": "A" | "B" | "tie", "reasoning": "...", "critical_diff": "..."}

只输出 JSON。

模板 E:难度分层器

判断这个 Agent 任务的难度分层,用于路由和监控。

## 分层定义
- simple:≤5 步,单一数据源,无权衡
- medium:6–15 步,多数据源,有简单权衡
- complex:16–40 步,多约束权衡,有不确定性
- extreme:>40 步 或 多异常并发 或 存在数据缺失需推断

## 任务
{{task_input}}

## 输出
{"difficulty": "...", "estimated_steps": N, "has_uncertainty": true/false, "reason": "..."}

八、踩坑清单

#坑表现解法
1用人工抽查当基线质量以为 99.1%,实测 98.7%建全量评测集,别用抽查
2评测集只采样真实流量遗漏「模型做错所以没走完」的任务从人工复核记录里补极端样本
3没监控人工复核介入率模型省 $1.9 万,人力多花 $3.4 万成本指标必须与下游人力成本联看
4语义缓存阈值太低12% 命中率带来 6.8% 的错误率阈值提到 0.995,命中率降到 3.2%
5变量放在 Prompt 最前面缓存命中率只有 7%固定前缀前置,变量沉尾 → 71%
6dict 遍历顺序不稳定同样内容每次字节不同,缓存失效固定序列化顺序 + 版本号
7压缩时截断关键数字事实错误率 0.9%critical_facts 永不压缩 + 压缩标注
8自检与生成用同一 Prompt抓错率 12%明确「你没有参与生成」→ 31%
9JSON 解析失败整步重跑34% 的重试源于此结构化输出约束 → 失败率 0.3%
10超时重试但旧结果已入上下文11% 调用重复付费重试前清理上下文 + 幂等键
11Provider 缓存有 TTL高峰期排队 20 分钟导致缓存失效背景包亲和调度,+6% 命中率
12小步骤输入不足缓存门槛19% 调用永远享受不到缓存合并小步骤,可缓存占比 81%→93%
13路由误判后无法定位出问题不知道哪一步被降级每次路由记录 tier + 理由,可回溯
14评测集原地修改历史跑分不可比,趋势失真版本号写入样本,修改开新版本

九、经验总结

9.1 五条原则

原则一:先测量,再优化。 第 0 周的 5 天埋点是全项目 ROI 最高的投入。没有它,后面 8 周所有的决策都是猜。埋点上线第一天就发现了 17.3% 的纯浪费。

原则二:确定性的事,不要交给模型。 这是单条收益最高的一条。44% 的调用(图遍历、查表、算术、schema 校验)改成了代码,零成本、零错误、毫秒级。它需要后端工程参与,不是纯 Prompt 工作。

原则三:降本的正确粒度是「步骤」,不是「任务」。 「这个任务用便宜模型」几乎总是失败(71.3% 通过率);「这个任务的第 7 步用前沿模型、第 12 步用代码」才是正解(99.96%)。

原则四:缓存是结构问题,不是开关问题。 开一个 cache=true 参数只能拿到 7% 命中率;把 Prompt 重构成「固定前缀 + 变量沉尾」才能拿到 78%。这需要改代码,不是改配置。

原则五:质量指标必须包含下游。 只看模型账单会做出「全量降级」这种净亏损的决策。人工复核介入率、复核耗时、用户放弃率,这三条必须和成本放在同一张看板上。

9.2 什么情况下不该做这件事

诚实地说,这套改造不是所有团队都该做:

情况建议
日调用成本 < $50不值得。直接买更便宜的模型,或者接受成本
任务数还在快速增长(月增 > 50%)先做埋点,暂不做架构改造——需求还在变
没有后端工程资源只能做刀 2(缓存)和刀 5(bug),放弃刀 1 的 52%
没有人工复核环节先建复核环节,否则你没有质量基线的来源
任务是创意类(写作、设计)模型路由的空间很小,大部分步骤都需要前沿模型

最重要的前提:你必须已经有人工复核或某种形式的质量反馈。如果你连「AI 做错了多少次」都不知道,那么你要做的第一件事不是降本,是建立质量反馈回路。

9.3 下一步

T 公司在完成这轮之后的三个方向:

  1. 小模型自托管:把占比 19% 的 small 层调用迁到 vLLM 自托管,预计再降 3–4%(绝对值不大,但能消除 API 限流风险)。
  2. 路由策略学习化:用历史数据训练一个更准的路由分类器(现在 94.1% 一致率,目标 98%),把 1.6% 的激进误判压到 0.5% 以下。
  3. 成本预算硬约束:给每个业务线设月度成本上限,超限自动降级到 balanced 层并告警——把成本治理从「项目」变成「机制」。

9.4 一句话

Agent 的成本问题,本质上是架构问题在账单上的投影。你看到的 $46,700,是「把确定性计算交给模型」+「同样的内容付费 31 次」+「工程 bug 导致的重试」这三件事的货币化结果。修架构,账单自己会下来——顺便,质量还会上去。


附录 A:成本归因脚本

下面这段是 T 公司实际在用的归因脚本的简化版,输入是 Langfuse 导出的调用链 JSON,输出是归因表。可以直接改改就用。

import json
from collections import defaultdict

# 各档模型的单价(美元 / 百万 token),按自己的实际合同改
PRICE = {
    "opus-5.5":      {"in": 12.0,  "out": 60.0, "cached_in": 1.2},
    "balanced":      {"in": 3.0,   "out": 15.0, "cached_in": 0.3},
    "small":         {"in": 0.8,   "out": 4.0,  "cached_in": 0.08},
}

CACHE_MIN_TOKENS = 2048   # Provider 的缓存最小长度门槛


def step_cost(s):
    p = PRICE.get(s["model"], PRICE["balanced"])
    fresh_in = max(0, s["input_tokens"] - s["cached_tokens"])
    return (
        fresh_in / 1e6 * p["in"]
        + s["cached_tokens"] / 1e6 * p["cached_in"]
        + s["output_tokens"] / 1e6 * p["out"]
    )


def attribute(traces):
    """traces: [{trace_id, difficulty, steps:[{...}]}]"""
    buckets = defaultdict(float)
    total = 0.0

    for t in traces:
        for s in t["steps"]:
            c = step_cost(s)
            total += c

            # 归因顺序很重要:先判"根本不该调模型",再判"浪费",最后才是"错配"
            if s["step_name"] in DETERMINISTIC_STEPS:
                buckets["确定性步骤误用模型"] += c
            elif s.get("never_read"):
                buckets["结果未被读取"] += c
            elif s.get("retry_count", 0) > 0 and s.get("retry_reason") in ENGINEERING_BUGS:
                buckets["工程 bug 导致的重试"] += c
            elif s["cached_tokens"] == 0 and s["input_tokens"] >= CACHE_MIN_TOKENS:
                # 本可缓存但没缓存:把"若能命中"的差额算作浪费
                buckets["上下文重复搬运(未命中)"] += c * 0.9
            elif s["model_tier"] == "frontier" and s["step_name"] not in FRONTIER_REQUIRED:
                buckets["模型能力错配"] += c * 0.7
            else:
                buckets["合理且必要的开销"] += c

    return {k: (v, v / total if total else 0) for k, v in buckets.items()}, total


def long_tail(traces):
    """返回成本最高的 20% 任务贡献了多少支出"""
    costs = sorted((sum(step_cost(s) for s in t["steps"]) for t in traces), reverse=True)
    n = max(1, int(len(costs) * 0.2))
    return sum(costs[:n]) / sum(costs)


def below_cache_threshold(traces):
    steps = [s for t in traces for s in t["steps"]]
    below = [s for s in steps if s["input_tokens"] < CACHE_MIN_TOKENS]
    return len(below) / len(steps), len(below)


# —— 需要人工维护的三张表(这是脚本的核心输入,没有它们归因就是瞎猜)——
DETERMINISTIC_STEPS = {"bom_traversal", "supplier_query", "certification_check",
                       "cost_model_calculation", "format_validation"}
ENGINEERING_BUGS = {"json_parse_failed", "tool_param_error", "timeout_retry"}
FRONTIER_REQUIRED = {"task_decomposition", "plan_generation", "multi_supplier_tradeoff"}

脚本之外更重要的三张表:DETERMINISTIC_STEPS、ENGINEERING_BUGS、FRONTIER_REQUIRED。这三张表是人工标注的结果,脚本只是执行归因。没有标注就没有归因——这是很多团队想跳过的一步,跳过了就只能得到一句「Prompt 可能可以优化」。


附录 B:完整路由表(43 条)

这是 T 公司最终定稿的静态路由表,可以直接作为起点。

#step_nametier理由改成代码需要的接口
1task_ingestrule解析事件 payloadparseIncident(payload)
2task_decompositionfrontier决定全局,错一步全错—
3priority_classificationsmall明确规则的分类—
4bom_traversalrule图遍历traverseBOM(sku, depth)
5inventory_queryrule数据库查询queryInventory(skus)
6in_transit_queryrule数据库查询queryInTransit(skus)
7supplier_queryrule数据库查询querySuppliers(criteria)
8certification_checkrule查表比对checkCert(supplierId)
9capacity_checkrule查表 + 简单算术checkCapacity(supplierId, qty)
10lead_time_estimatesmall需要一点推断—
11cost_model_calculationrule确定性计算calcLandedCost(...)
12tariff_lookuprule查表lookupTariff(origin, hsCode)
13freight_estimaterule查表 + 插值estimateFreight(...)
14currency_conversionrule外部 APIfx.convert(...)
15cost_comparisonrule排序与差值compareOptions(list)
16risk_factor_extractsmall抽取结构化要素—
17risk_scoring_simplesmall单供应商、规则清晰—
18risk_scoring_multibalanced多供应商权衡—
19risk_scoring_extremefrontier多异常并发—
20contract_term_checkrule条款查表checkTerms(contractId)
21contract_term_judgementbalanced条款需要解释—
22legal_redline_detectfrontier高风险,需谨慎—
23alternative_generationfrontier方案设计—
24plan_generationfrontier核心产出—
25plan_formattingsmall格式转换—
26fact_extractionsmall从 plan 抽关键数字—
27fact_verificationrule对照 ground truth 比对verifyFacts(plan, facts)
28schema_validationruleJSON schema 校验validate(schema, obj)
29self_verificationbalanced独立视角审查—
30consistency_checkbalanced前后一致性—
31completeness_checksmall清单式检查—
32uncertainty_flaggingsmall标出不确定项—
33human_summarysmall摘要生成—
34human_summary_translatesmall翻译—
35escalation_decisionbalanced是否升级人工—
36notification_composesmall模板化文案—
37audit_log_writerule写日志audit.log(...)
38context_compressionsmall压缩历史—
39context_budget_checkrule计数对比countTokens(ctx)
40retry_decisionrule重试策略shouldRetry(err, n)
41tool_result_cache_lookuprule缓存查询cache.get(key)
42final_review_gatebalanced终审—
43fallback_to_humanrule转人工escalate(taskId)

分布统计:

tier条数占比
frontier511.6%
balanced716.3%
small1125.6%
rule2046.5%

近一半的 step 根本不该调模型。 这是整张表最值得记住的一行。


附录 C:灰度批次计划模板

批次流量观察时长进入下一批的条件回滚触发
批次 0内部账号 100%3 天无红线触发任一红线
批次 15%3 天通过率下降 < 0.2pt 且 P95 延迟下降 > 10%任一红线
批次 220%5 天通过率下降 < 0.3pt 且 复核介入率未上升任一红线
批次 350%7 天全部指标稳定任一红线
批次 4100%14 天结项任一红线

每一批都要跑全量评测集,不要只在灰度流量上跑。灰度流量的任务分布与评测集不同,只在灰度上看等于没有对照组。

每批次的检查清单:

□ 全量评测集跑分完成,通过率记录在案
□ 事实错误率对比基线
□ 人工复核介入率与复核耗时
□ P95 / P99 延迟
□ 缓存命中率
□ 路由 tier 实际分布 vs 预期分布(偏差 > 10% 要查)
□ 成本(单任务 P50 / P95)
□ 用户反馈(工单、满意度)
□ 无 P0/P1 事故

附录 D:给管理层的汇报模板

技术方案做得再好,拿不到预算也是白搭。这个模板解决「怎么跟非技术的人说清楚」。

## Agent 成本治理(第 X 期汇报)

### 一句话
在不降低质量的前提下,把 AI 单任务成本从 $1.47 降到 $0.16(-88.9%),
月支出从 $46,700 降到 $5,180。质量从 98.7% 提升到 99.96%。

### 三个数字
- 年化节省:约 $49.8 万(按当前任务量)
- 质量变化:+1.26 个百分点(不是下降)
- 用户侧:平均等待从 4.2 分钟降到 1.7 分钟

### 钱花在哪、省在哪
| 类别 | 占比 | 性质 |
|---|---|---|
| 把本该代码做的事交给了模型 | 31% | 工程错误 |
| 同样的内容重复付费 | 27% | 架构问题 |
| Bug 导致的无效重试 | 23% | 质量问题 |
| 模型档位用高了 | 15% | 配置问题 |
| 必要开销 | 4% | 保留 |

### 投入
- 周期:10 周
- 人力:3 名后端 + 1 名算法 + 0.5 名 QA
- 一次性投入约 4.5 人月

### 回报
- 静态回收期:约 1.4 个月
- 且质量与延迟同步改善

### 风险与对策
| 风险 | 概率 | 对策 |
|---|---|---|
| 长尾任务质量下降 | 中 | 五条回滚红线 + 全量评测集卡口 |
| 成本转移到人工复核 | 中 | 复核介入率纳入红线(发生过一次) |
| 后续需求变化导致返工 | 低 | 路由表与业务解耦,改配置不改代码 |

汇报的关键:不要讲「模型路由」「Prompt Caching」这些技术名词。讲三个东西——钱花在哪(浪费占比)、省了多少、质量有没有变差。管理层关心的是这三个。技术细节放在附录里,有人问再看。


附录 E:一页纸速查

┌────────────────────────────────────────────────────────┐
│  Agent 成本治理 速查                                     │
├────────────────────────────────────────────────────────┤
│  五把刀(按 ROI 排序)                                   │
│  1. 模型路由 + 确定性步骤代码化     52%                  │
│  2. Prompt Caching(前缀稳定化)    23%                  │
│  3. 上下文预算与压缩                 9%                  │
│  4. 批处理与并发                     3%                  │
│  5. 早停与去重(修 bug)             2%  ← 唯一提升质量 │
├────────────────────────────────────────────────────────┤
│  三条铁律                                                │
│  · 确定性的事不要交给模型                                │
│  · 固定前缀在前,变量沉尾                                │
│  · 成本指标必须和"下游人力成本"一起看                    │
├────────────────────────────────────────────────────────┤
│  不要做                                                  │
│  × 全量换成便宜模型(通过率 99% → 71%)                 │
│  × 语义近似缓存(12% 命中换来 6.8% 错误)               │
│  × 人工抽查当质量基线                                    │
│  × 省了模型钱但让人多干活                                │
├────────────────────────────────────────────────────────┤
│  前置条件(没有就先补)                                  │
│  1. 全链路埋点(15 个字段)                              │
│  2. 1,200 条评测集(含极端 + 对抗)                      │
│  3. 人工复核环节(质量基线的来源)                        │
└────────────────────────────────────────────────────────┘

附录 F:术语表

读这篇文章(以及 2026 年大部分 Agent 工程资料)时会反复遇到的词,一次讲清。

术语含义本文语境
Harness包裹在模型外面的执行框架:编排、工具调用、上下文管理、路由、重试模型路由就属于 Harness 层能力,本文刀 1 的载体
模型路由(Model Routing)每次调用前先判断需要什么档位的模型,再分发本文贡献最大的一把刀(52%)
Prompt Caching相同前缀的 KV 缓存复用,命中部分输入按折扣计价本文刀 2,命中部分约为原价 1/10
前缀(Prefix)输入中最靠前、需要逐字节稳定的那一段稳定性决定缓存命中率
缓存门槛Provider 要求的最小可缓存长度(1024 / 2048 token)低于它的调用永远享受不到缓存
缓存 TTL缓存的有效时长(5 分钟 ~ 1 小时)任务排队过久会导致失效
上下文预算给每类步骤设定的输入 token 上限超了走压缩或裁剪
critical_facts绝不能被压缩或改写的关键事实(金额、ID、日期)压缩策略里唯一永不压缩的部分
tier模型档位:frontier / balanced / small / rulerule 表示由代码完成,零模型成本
任务级通过率以「整个任务是否办成」为单位的成功率本文的质量主指标,区别于步骤级
事实错误率关键数字与标准答案不一致的比例比「通过率」更敏感的指标
人工复核介入率需要人工修改 AI 产出的任务占比必须和成本一起看,否则会做出净亏损决策
评测集(Eval Set)带标准答案的任务集合,用于跑分与回归本文 1,200 条,含极端层与对抗层
对抗样本刻意构造的、容易让模型出错的输入30 条,用于检测降级是否被「跑分好看」掩盖
灰度切流按比例逐步放量新方案的发布方式本文 5 批,每批有进入条件与回滚红线
回滚红线触发立即停止/回滚的指标阈值5 条,其中复核介入率是吃了亏才加的
亲和调度把共享同一前缀的任务排到相邻时间窗执行提高缓存命中率 +6%
批处理 API非实时任务走异步通道,单价约五折本文刀 4,覆盖约 22% 任务
幂等键用于识别重复请求的唯一键修「超时重试但旧结果已入上下文」的关键
结构化输出约束强制模型输出符合给定 schema把 JSON 解析失败率从 12% 降到 0.3%
归因(Attribution)把总成本拆到各类开销上并给出占比附录 A 的脚本就是干这个的
长尾任务成本最高、步骤最多的那 20% 任务本文贡献了约 68% 的支出

十、相关阅读

  • 《Claude Opus 5.5 接入 GitHub Copilot 完整配置指南》——本文路由层涉及的前沿模型选型与配置
  • 《Cache-Friendly Prompting:四层结构与逐字节前缀稳定》——本文刀 2 的方法论展开
  • 《GitHub MCP:让 Agent 直接操作仓库与 Issue》——本文刀 1 中「工具调用代码化」的配套方案
  • 《模型迁移实战:从闭源前沿到开放权重》——当路由还不够时的下一步

相关推荐

查看更多 →
案例企业应用

DeepSeek V4.1 Flash 多模型路由降本实战:单任务成本从 $1.47 砍到 $0.33,月账单降 77.7%

2026 年 10 月,DeepSeek V4.1 Flash 的价格比 V4 Pro 低约 40%,把「多模型路由」这件事从可选优化变成了必答题。本文记录一家 420 人 SaaS 公司用 5 周把 Agent 平台从「所有调用都打最贵模型」改造成「按任务难度分档路由」的全过程:月支出从 $71,300 降到 $15,900(降 77.7%),单任务成本从 $1.47 降到 $0.33,P95 延迟从 31.2 秒降到 12.6 秒,而任务完成率反而从 93.4% 升到 96.2%。关键结论是——一次 40 次调用的任务里,真正需要最贵档模型的只有 4 次(10%),但这 4 次吃掉了 82% 的钱;剩下 36 次里有 27 次是「格式化、过滤、抽取」这类确定性活,用 Flash 完全够。全文含可直接复制的难度分级 Prompt 模板、TypeScript 路由判定器完整实现(规则前置 + 模型打分 + 三级 fallback + 预算闸门)、五周灰度切流的逐周数据、以及 12 个踩过的坑。

2026-10-08
#AI实战#多模型路由
案例企业应用

毛利从 -50% 到转正:一家 156 亿美元估值的法律 AI 公司,为什么主动放弃闭源前沿模型

2026 年 9 月,Bloomberg 披露了一条被低估的产业新闻:法律 AI 公司 Harvey(估值 156 亿美元)把主力负载从闭源前沿模型迁到了自研模型——一个基于 Moonshot Kimi K3 开放权重做后训练的内部模型。迁移的驱动力不是能力,是算术:按用量计费模式下 token 消耗涨了 20 倍,毛利从约 +50% 一路跌到约 -50%;迁移后毛利转正。Abridge、Decagon、Ramp 被报道在走同一条路,Sequoia 与 General Catalyst 在背后推。这是企业级 AI 公司第一次成规模地「离开前沿实验室」,而触发这件事的是单位经济学,不是跑分。本文把这次迁移拆成可复现的工程动作:任务分层与模型路由、评测集构建、后训练数据从哪来、灰度切流与回归监控、以及 14 个真实会踩的坑。附每一步的 Prompt 模板与效果数据表。

2026-09-22
#AI实战#模型迁移
Prompt编程开发

上下文预算控制提示法:给 Agent 长任务设一个 token 天花板——32 轮重构任务实测,完成率从 41% 拉到 88%,单任务成本降 63%

2026 年 10 月,「Agent 落地还是毛坯房」这句话在行业里传开了:模型能力够了,工程约束没跟上。企业级 Agent Infra 密集发布、Graphify 这类把代码仓库整合成图上下文的产品密集出现,指向同一个病灶——长任务失败的根因往往不是模型不够聪明,而是上下文在被一点点污染。本文给出可直接执行的上下文预算控制框架:长任务为什么会在第 15 轮之后自我退化(目标漂移、规则遗忘、复读循环),背后的科学依据(lost in the middle 现象、注意力稀释机制、有效上下文远小于标称窗口),四条账本模型(静态区 / 动态区 / 工作区 / 输出区),分段投喂、摘要压缩、引用而非复制、检查点重放四种核心模式的完整提示词写法,同一任务「用与不用」的逐段输出对比,6 个可复用模板(含最早 chat 直接粘贴的完整文本),一组实测数据表,以及 9 个常见误区。

2026-10-08
#提示词工程#Agent
Prompt编程开发

Cache-Friendly Prompting:把提示词重排一遍,输入成本直接砍半

2026 年 9 月 22 日,Anthropic 发布 Claude Opus 5.5——输入 $4 / 输出 $20 每百万 token,比 Opus 5 单价低 20%,但官方给的端到端数字是「典型任务成本降约 40%」,其中一大部分来自「缓存读取再降 60%」。90 分钟后 OpenAI 发布 GPT-6 Sol 与 Luna,Sol 的缓存输入 $0.20(标准输入 $2,差 10 倍),Luna 缓存 $0.01(标准 $0.10),并对 30 分钟内复用的合格共享前缀给到最高 90% 折扣。**缓存折扣是当前所有降本手段里投入产出比最高的一个**:不用换模型、不用改架构、不用等排期,把你写的提示词重排一遍就生效。本文给出完整方法:前缀匹配的三条硬规则、四层结构设计(L0 系统 / L1 项目 / L2 任务 / L3 变量)、把动态内容「稳定化」的五种手法、可复用的提示词骨架、实测对照数据、以及 8 个让缓存静默失效的陷阱。

2026-09-23
#Prompt技巧#提示缓存