拓冰建站拓冰建站
首页 / 资讯中心 / 正文

LLM路由省钱?别只看单次调用成本,用cost-per-success评估

你有没有遇到过这种情况同一个 LLM 任务团队把模型从“贵的大模型”切成“便宜的小模型”单次调用成本下降了 80%月底一算账总成本反而没降多少甚至业务指标还变差了。原因不复杂。你省下的只是单次调用的钱但小模型“失败后让你重试”的钱、“答错后让下游解析逻辑兜底”的钱、“没有完成用户请求导致人工介入”的钱全都没有被算进去。也就是说绝大多数团队在评估 LLM 路由策略时盯的是 cost-per-call而真正影响业务成本的是另一个数字cost-per-success。这篇文章想讲清楚一个判断LLM 路由省不省钱不能看每次调用花了多少而要看每成功完成一个任务平均花了多少。前者是账单视角后者是业务视角。后面所有内容都围绕这个判断展开——包括两个指标的本质区别、只盯着单次调用价格会踩哪些坑、怎么在现有系统里把 cost-per-success 算出来以及如何基于它设计路由策略。1. 这篇文章真正要解决的问题先给三个真实到不能再真实的场景你在做客服意图识别。简单问题用便宜小模型每条 0.002 美元看起来很美。但小模型把“退款流程”识别成“投诉”一单走错流程后面人工客服介入的成本是 2 美元。你在做代码生成。小模型生成的代码跑不过编译重试三次终于跑通了但三次调用的总成本已经超过直接用大模型。更麻烦的是每次重试都让用户体验变差。你在做 RAG 知识库问答。检索回来的上下文一长小模型就开始“胡言乱语”不能直接返回给用户只能再叠一层校验模型。这一套流程跑下来时间和钱都翻倍了。这些场景里单次调用成本都不是真正的成本。真正的成本是“把一个任务做成功”这件事花了多少钱。但为什么绝大多数团队不看这个数字因为 cost-per-call 太容易统计了。模型供应商账单上有调用次数、token 数、单次价格拉出来就是一个清清楚楚的数字。而 cost-per-success 要求你把跨链路的数据串起来任务 ID、模型名、尝试次数、是否成功、每次调用成本、业务侧结果。这需要打标需要日志规范需要跨团队对齐“什么叫成功”。所以它难也正因为难才没有人测量。这篇文章适合三类读者正在做 LLM 应用成本治理的工程师想搞清楚“路由省钱”到底该怎么省。做 Agent、编排框架、网关层开发的开发者需要给上层业务提供成本评估能力。给团队定技术指标的负责人想找到一个比 cost-per-call 更合理的北极星指标。读完这篇文章你会得到一套从指标定义、日志打标到路由策略落地的完整方案。更关键的是你会知道为什么“便宜模型每次调用便宜”这件事很多时候是个统计学错觉。2. cost-per-call 与 cost-per-success 的本质区别2.1 一次“调用成功”不等于一次“任务成功”先做概念区分。Cost-per-call单次调用成本用总调用花费除以调用次数。它回答的问题是“我每让模型干一次活平均花多少钱”。Cost-per-success单次成功成本用总花费除以成功完成的任务数。它回答的问题是“我每真正解决一个业务问题平均花多少钱”。两者的差别落在“一次调用成功”和“一个任务成功”的区别上。一个典型的坏例子用 LLM 做 JSON 输出解析。模型确实返回了一段合法 JSON但 JSON 里的字段值是编造的、不符合业务约束的。这时候调用“成功”了任务“失败”了。如果只看 cost-per-call你会觉得系统运行得挺好但 task success rate 可能只有 85%剩下的 15% 全部要靠下游逻辑去补。再举个更直观的例子。在 LLM Agent 场景里Agent 调用一次工具、拿到一个中间结果这个中间结果本身没有对错。但当它用这个错误中间结果继续推理最终给用户一个错误答案时这次“调用”在链路里看起来仍然是成功的。业务侧的人看到的是“这次对话没解决问题”成本侧的人看到的是“调用正常无异常计费”。Cost-per-success 把这两层东西拉通到了一个数字里。2.2 两个指标的核心差异对比维度Cost-per-callCost-per-success统计粒度单次 API 调用一个业务任务/一次用户请求回答的问题每次调用花多少钱每成功一个任务花多少钱受什么影响模型单价、token 数模型单价、token 数、成功率、重试次数、下游修复成本适合评估供应商账单、用量趋势路由策略、模型选型、产品业务成本对“成功”的定义拿到 HTTP 200 响应即可需要业务侧确认“结果可用”统计难度低账单自带高需要跨链路打标从表格能看出来cost-per-call 是一个运营指标它适合监控账单不适合评估决策。而 cost-per-success 是一个经营指标它直接反映“模型选型 路由策略 失败处理”三个环节的共同结果。2.3 为什么“没人测量”是常态三个原因决定了 cost-per-success 在业界几乎没有被系统性测量第一成功定义需要跨团队对齐。后端说“调用没报错就是成功”算法说“准确率达标就是成功”业务方说“用户问题真正解决了才是成功”。三方对不齐这个指标就没法统一统计。第二跨链路打标有技术成本。一次用户请求可能经历“意图识别 → 信息抽取 → RAG 检索 → 生成 → 校验”五层每一层都可能调用不同模型。需要从入口请求开始传递一个 task_id所有下游日志都带上它才能最终聚合出“这个任务到底花了多少钱、最终成没成”。很多系统的日志根本没做这件事。第三样本量不足时波动巨大。如果一天只有几百个任务一个失败任务的成本占比就会让 CPS 剧烈跳动。需要积累足够样本才能得到稳定数字这要求团队有耐心做长周期观测。3. 只盯着 cost-per-call 会踩哪些坑3.1 把“模型返回了内容”当成“任务成功了”这是最隐蔽、最普遍的坑。我们默认调用只要没有抛出异常、返回了内容就算“成功”。但 LLM 的失败不是网络那样非黑即白——它可能会一本正经地给出错误答案而且格式很好看。如果你用这个“伪成功”的响应去算 cost-per-call数字会很漂亮但一旦用户投诉、下游解析失败、人工介入这些成本全在系统的另一端悄悄产生。3.2 忽略重试的乘法效应很多团队给路由策略加了“失败重试”机制小模型失败后自动升级到大模型。这个设计本身没问题但如果重试的触发条件太宽松成本就会爆炸。举个例子。小模型单次 0.002 美元大模型单次 0.02 美元十倍差距。如果小模型成功率只有 80%那么 100 个任务里大约 20 个需要重试。假设重试里有 15 个直接升级到大模型这部分成本就是 0.3 美元——等于 150 次小模型调用。换算下来平均每个任务的实际成本已经悄悄涨了 50%。更麻烦的是重试带来的延迟成本。用户等一次重试可能要多等 2 到 3 秒在实时交互场景里这比多花几分钱更伤体验。3.3 忽略下游级联成本模型能力不足不等于“调用失败”它只是让下游更辛苦。举两个例子信息抽取模型输出错误后面做数据库写入时发生冲突需要回滚和补偿。客服机器人理解错了用户意图分配了错误的处理流程人工客服接手时还需要额外解释一遍。这两类成本都很难在调用日志里体现但它们确实是因为“模型没有成功完成任务”才发生的。不把它们算进去你永远不知道自己选的路由策略到底给业务造成了多大负担。3.4 离线评测和线上表现严重脱节另一个常见误判离线评测集上小模型准确率只比大模型低 3 个百分点就觉得小模型“够用”。但离线评测集往往是高频、标准化的题目线上场景里大量请求是长尾的、模糊的、超出训练分布的。这些请求上小模型的失败率可能不是 3%而是 30%。所以离线评测只能作为初筛真正决定路由策略优劣的是线上真实的 cost-per-success。3.5 一个算账示例下面是一个示意数据帮你直观感受两个指标选错会带来什么样的误判。指标方案 A大量用便宜小模型方案 B优先用高质量大模型单次调用平均成本0.002 美元0.01 美元任务成功率80%98%1000 个任务的总调用次数约 1250 次含重试约 1020 次含重试总调用成本约 2.5 美元约 10.2 美元成功任务数约 800 个约 980 个业务侧失败处理成本示意约 20 美元用户投诉、人工介入等约 2 美元实际总成本约 22.5 美元约 12.2 美元cost-per-success约 0.028 美元约 0.012 美元看单次调用成本方案 A 只有方案 B 的五分之一看 cost-per-success方案 B 反而更便宜。这就是“只看 cost-per-call 会把路由策略带偏”的最直接证据。注意这里的具体数字只是示意不同场景下成功率差异和业务失败成本都不同。但结论是稳定的一旦把“成功”纳入分母很多看似便宜的模型组合会原形毕露。4. cost-per-success 的底层拆解4.1 核心计算公式要落地这个指标先要把它拆到可以统计的颗粒度。建议用下面的公式CPS (有效调用直接成本 失败验证成本 下游恢复成本 人工介入成本) / 成功任务数有效调用直接成本最终成功任务在完成过程中所有模型调用的累计花费。注意不是所有调用的总花费而是“归因到成功任务上的花费”。失败验证成本为了判断一次调用是否失败而付出的成本。比如你加了一个小模型去验证主模型输出这个验证模型的调用成本也要算进来。下游恢复成本任务失败后触发重试、回滚、补偿逻辑产生的额外系统消耗。人工介入成本业务侧因为任务失败而投入的人力。这部分最难量化但最不能忽略。一个粗暴的估算方式是人工处理一次失败的耗时 × 团队时薪。4.2 计算举例假设一个客服工单分类任务每天 1000 个任务采用“小模型优先失败后升级大模型”的路由策略。小模型单次调用 0.003 美元成功率 85%其中 85% 的成功任务平均调用 1 次15% 的任务失败后升级到大模型。大模型单次调用 0.03 美元介入后成功率 95%成功任务平均调用 1.2 次。每天约 150 个任务升级到大模型其中约 142 个最终成功约 8 个仍然失败需要人工介入。人工介入一次约 5 分钟团队综合成本按每小时 20 美元估算即每次约 1.67 美元。根据这个示意数据算下来每天的总成本里人工介入成本约 13 美元反而超过了模型调用成本。而如果只用单次调用成本评估你会得出“模型层很便宜”的错误结论。真正有价值的动作是把这四类成本全部记录到日志里定期聚合得到每个模型的真实 CPS。4.3 什么时候 cost-per-success 才有意义只在“任务”粒度上计算才有意义。如果统计粒度还是单次调用那 CPS 退化为 cost-per-call毫无新意。所以要落地这个指标第一步永远是建立任务维度的可观测性而不是先去找更便宜的模型。5. 路由评测的三个层级很多团队对路由策略的评估只有一个指标要么纯看成本要么纯看精度。这里给出一个更完整的框架三层指标联动。5.1 质量层质量层关注“模型输出本身行不行”task success rate最终任务成功率passk生成式任务多次采样后的通过率重试率需要升级模型或重新生成的比例校验通过率下游规则校验的通过比例这一层的问题在于只看质量会过度倾向于“贵的大模型”导致成本失控。所以它必须和成本层配合。5.2 成本层成本层关注“完成一个成功任务花了多少钱”cost-per-success核心指标单任务平均调用次数token 消耗效率输入 token 中有效信息占比缓存命中率prompt 缓存是否生效这一层就是本文讨论的重点。通过它你可以发现“便宜模型组合”的本质成本。5.3 业务层业务层关注“这个任务成功后给产品带来什么价值”转化率对话是否促成了购买/留资/解决问题工单率用户是否对结果不满而发起工单用户满意度/反馈人工介入率三层指标的关系可以这样理解质量层告诉你“模型水平如何”成本层告诉你“这样的水平花多少钱”业务层告诉你“这个钱花得值不值”。任何单一层次的指标都不足以支撑路由决策。6. 如何把 cost-per-success 落进现有系统6.1 第一步给日志加上任务级信息最核心的动作是所有下游链路都带上一个 task_id并且在每一次模型调用日志里记录如下字段task_id任务唯一标识task_type任务类型意图识别/信息抽取/摘要生成等model_name本次调用使用的模型attempt第几次尝试success本次任务最终是否成功不是本次调用是否成功cost本次调用的费用latency_ms耗时route_policy当前路由策略版本下面是一个 JSON 日志的示意结构{ task_id: 031f8f1a-3d7e-4b2a-9e80-2b6d5c7a11f2, task_type: intent_classification, model_name: small-fast-model, attempt: 1, success: false, cost: 0.0021, latency_ms: 280, route_policy: cost-first-v1, ts: 2025-06-11T10:23:41.882Z }注意success字段标注的是“任务最终是否成功”而不是“本次调用是否成功”。如果你只记录本次调用状态就无法把重试链路聚合到同一个任务上。6.2 第二步按任务聚合计算 CPS日志里有了task_id之后可以用 SQL 做聚合。下面是一个示意 SQL按模型名统计每个模型的 cost-per-success-- 思路示例按模型名统计 total_tasks / success_tasks / total_cost / cps SELECT model_name, COUNT(DISTINCT task_id) AS total_tasks, COUNT(DISTINCT CASE WHEN task_success THEN task_id END) AS success_tasks, SUM(call_cost) AS total_cost, SUM(call_cost) / NULLIF(COUNT(DISTINCT CASE WHEN task_success THEN task_id END), 0) AS cps FROM llm_route_logs WHERE ts NOW() - INTERVAL 7 DAY GROUP BY model_name ORDER BY cps ASC;如果你的日志平台不是 MySQL把日期区间语法替换成对应数仓的写法即可。关键点在于success是任务级标志cost是调用级花费最终要按任务去重后再算分母。6.3 第三步用脚本算全链路归因如果日志分散在多个系统可以用脚本先把日志拉到一个临时表再跑归因逻辑。下面是一个 Python 示例模拟从日志聚合出 CPS 的过程# calculate_cps.py # 依赖pandas # 用途把一条条调用日志聚合为任务级成本统计 import json import pandas as pd # 模拟日志实际项目中可以从日志平台或数仓导出 logs [ {task_id: task_001, model_name: small-model, attempt: 1, success: False, cost: 0.002}, {task_id: task_001, model_name: large-model, attempt: 2, success: True, cost: 0.03}, {task_id: task_002, model_name: small-model, attempt: 1, success: True, cost: 0.002}, {task_id: task_003, model_name: large-model, attempt: 1, success: False, cost: 0.03}, ] df pd.DataFrame(logs) # 每个任务的总花费 cost_by_task df.groupby(task_id)[cost].sum() # 每个任务是否成功取该任务最后一次 attempt 的 success 状态 last_attempt df.sort_values(attempt).groupby(task_id).tail(1) success_by_task last_attempt.set_index(task_id)[success] # 组装任务表 task_df pd.DataFrame({total_cost: cost_by_task, success: success_by_task}) total_tasks len(task_df) success_tasks task_df[success].sum() failure_tasks total_tasks - success_tasks total_cost task_df[total_cost].sum() cps total_cost / success_tasks if success_tasks 0 else float(inf) print(ftotal_tasks: {total_tasks}) print(fsuccess_tasks: {success_tasks}) print(ffailure_tasks: {failure_tasks}) print(ftotal_cost: {total_cost:.4f} USD) print(fcost_per_success: {cps:.4f} USD)运行后你会得到类似这样的输出total_tasks: 3 success_tasks: 2 failure_tasks: 1 total_cost: 0.0640 USD cost_per_success: 0.0320 USD这个示例虽然简单但它把“重试链路”和“任务成功”揉在了一个统计逻辑里。你在实际项目中只需要把logs换成从日志平台查出来的真实数据即可。6.4 第四步接入现有路由层如果团队用的是 Spring AI 这类 Java 生态的 LLM 框架或者自研的 Agent 编排框架建议在路由层加一个统一拦截器专门负责打日志和统计。不必修改所有业务代码只要在网关或路由入口处生成 task_id然后用 MDC 或在上下文对象里传递就能把整条链路串起来。无论你用的是 RAG、Agent 还是 MCP 协议调用工具成本评估的底层逻辑都一样给任务打标让每一次模型调用都能归因到任务然后按任务聚合算 CPS。7. 用 cost-per-success 指导路由决策的实践方法7.1 完整的七步流程只看指标不够还要把 CPS 变成路由策略的输入。这里给出一个可以照做的流程定义成功标准。和业务方确认什么叫“任务成功”。如果是对话用户是否得到了可采纳的回答如果是信息抽取输出是否通过了下游规则校验。这一步不要自己拍板要拉上业务方一起定。给任务打标。在入口生成 task_id所有下游调用带上它。没有这一步后面全部免谈。小流量双跑。不要直接切换路由策略先让新策略跑 5% 的流量和旧策略并行采集日志。统计 CPS。按第 6 节的方法分别统计新旧策略的 cost-per-success。对比模型组合。不仅看平均 CPS还要看不同任务类型上的 CPS。意图分类场景和摘要生成场景最优路由策略很可能完全不同。灰度切换。CPS 明显更优的那个组合扩大流量到 20%、50%、100%。每次放量前都再看一次指标。持续监控。模型供应商价格、模型能力、线上数据分布都会变建议每周或每月重算一次 CPS。7.2 一个路由策略配置示例路由策略的配置最好独立于代码方便随时调整。下面是一个示意 YAML 配置# route-policy.yaml routing: default_policy: quality_first cost_guardrail: max_single_call_usd: 0.05 # 单次调用预算上限 max_attempts_per_task: 3 # 单任务最大重试次数 daily_budget_usd: 100 # 每日总预算 quality_threshold: min_success_rate: 0.90 # 路由后任务成功率下限 model_tiers: - tier: cheap models: [small-model-a, small-model-b] max_cost_usd: 0.003 max_attempts: 1 - tier: standard models: [standard-model] max_cost_usd: 0.01 max_attempts: 2 - tier: premium models: [premium-model] max_cost_usd: 0.05 max_attempts: 3这个配置表达了三个设计原则成功优先默认策略是 quality_first而不是 cost_first。只有当质量门槛达标时成本优化才有意义。成本护栏单次调用不能无限制地往上加钱单任务不能无限重试每天不能超预算。平滑降级如果 premium 模型不可用或价格飙升可以从配置层快速切回 standard不需要改代码。7.3 路由策略的常见误区很多团队做路由时会把“路由”理解成“选模型”。但从 cost-per-success 的角度看路由其实是在做“资源如何分配给任务”。它不仅包括模型选择还包括是不是所有任务都需要大模型简单任务可以用规则引擎或者小模型。是不是所有任务都需要走 RAG能从缓存命中的直接返回缓存。是不是所有任务都需要 LLM很多结构化任务用正则或代码更便宜。所以真正好的路由策略不是在某一个模型选出最便宜的而是让不同复杂度的任务走到了它该走的处理路径上。而评价这些路径孰优孰劣cost-per-success 是最好的度量衡。8. 常见问题与排查方法问题现象可能原因排查方式解决方案某个便宜模型 CPS 反而比大模型高便宜模型成功率太低重试次数过多按 task_id 查该模型的重试链路降低该模型的使用比例或设置重试次数上限离线评测准确率不错线上 CPS 很高线上分布和评测集差异大长尾请求失败率高按 task_type 拆分 CPS找到失败率最高的任务类型针对长尾任务类型路由到更高质量模型换了路由策略后业务指标波动只看了 CPS没有看业务层转化/工单率补充业务层指标对比新旧策略增加业务层指标监控设置回滚开关任务重试次数过多CPS 迅速恶化路由配置里没有 max_attempts_per_task 护栏查看路由配置和重试日志给路由策略加最大重试次数限制不同团队对“成功”定义不一致任务成功标志没有统一检查各团队日志中 success 字段的业务含义由质量/产品负责人统一成功定义写进接口文档统计周期太短CPS 波动大样本量不足少数失败任务拉高成本拉长统计周期或按天粒度看趋势至少统计 7 天以上避免单日噪音上游 prompt 改动后路由判断失效prompt 变化导致意图识别置信度分布变化对比 prompt 修改前后的路由日志路由决策中不要过度依赖 prompt 输出增加规则兜底模型供应商调价后 CPS 失真成本数据来自旧价目表更新成本映射表建立价目表配置自动化同步供应商价格9. 最佳实践与工程建议9.1 用任务粒度做成本归因永远不要用调用粒度去衡量路由策略。给每个用户请求或业务操作分配一个 task_id让所有下游模型的调用都挂在这个 task_id 下面。这是距离成本治理最近的一步却也是最容易被省略的一步。9.2 把 CPS 拆到任务类型和模型组合两个维度平均 CPS 会掩盖太多问题。正确做法是至少拆两个维度按 task_type 拆找到哪类任务在拖累整体成本。按 model_name 拆找到哪个模型组合在特定任务上表现最佳。只有拆到这两个维度你才能给出“意图分类用这个组合、摘要生成用那个组合”这种可执行的结论。9.3 给路由策略设置成本护栏在路由代码或配置层强制加三个限制单次调用预算上限防止某个异常请求把大模型当小模型用。单任务重试次数上限防止“重试到天荒地老”。每日总预算防止路由策略配置错误导致成本失控。没有护栏的成本优化本质上是一场冒险。9.4 把模型选择做成配置而不是硬编码很多团队把模型名直接写在代码里改一次路由策略就要发一次版本。更好的做法是把模型分级、路由策略、成本阈值全部放到配置中心让算法和业务同学也能参与调整而不是每次改模型都要等后端发版。9.5 定期重算 CPSLLM 模型的定价和性能不是一成不变的。供应商可能调价模型能力可能升级线上数据分布可能漂移。建议至少每月重算一次 CPS重新审视“便宜模型优先”的假设是否还成立。9.6 让成功定义成为团队共识在项目启动时就拉上算法、后端、业务方一起定义清楚什么算任务成功什么算任务失败失败后的人工介入成本怎么估算这个共识越早对齐后面的成本统计就越准确跨团队扯皮的次数就越少。10. 总结与后续学习方向这篇文章的核心结论其实只有一句话路由省钱的正确姿势是用 cost-per-success 而不是 cost-per-call 来评估。前者是账单视角后者是业务视角。当你把“成功”放进分母你会发现很多“便宜模型”其实并不便宜很多“贵模型”反而更划算。接下来的行动建议很具体在这一周的日志里加上 task_id。给每个模型调用记录 attempt、success、cost。按第 6 节的脚本跑一次 CPS。你大概率会看到一个让你意外的事实原来真正拖累成本的不是单次调用价格而是失败后的一系列连锁反应。如果你想继续深入建议往这几个方向拓展一是研究路由策略的自动化决策比如基于上下文置信度做动态路由二是探索多模型投票和校验机制对成功率的提升三是把 CPS 从离线统计变成在线实时指标让路由策略能根据实时成本动态调整。最后提醒一句不要为了追求成本而牺牲成功率。一个失败的请求给用户体验带来的损失往往比多花几分钱更贵。先把任务级成功事件记录下来再谈路由优化——这会是你做过的最有价值的成本治理动作。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门