让助手从一段话里提取日期,和让它排查跨文件的 bug,不一定要给同样的计算预算。前者可能直接输出就够了;后者可能需要读代码、跑测试,再根据失败继续查。
选模型时,先把三个问题拆开:用哪个模型、在哪里运行、这次要花多少计算。 开放权重模型也能通过托管 API 使用;同一个模型可能支持不同推理预算;外部路由器(router)则可以把请求分给不同模型。它们不是一个开关。
想先做选择,看比较表和检查顺序。想弄清“自动思考”和 routing 的区别,看谁在决定;4 条请求的例子可以直接手算。
1. 先看任务做没做好
用检查笔记的助手举例。一个模型可能很会润色,却找不出公式里的符号错误;另一个计算不错,但总想把原文改成自己的写法。只比综合榜单分数,很容易漏掉这些差别。
先收集一小组有代表性的任务:有明确错误的、没有问题的、来源冲突的,以及工具会失败的。写清楚怎样才算完成,再让候选(candidate)方案在相同条件下运行。除了最终答案,也看它有没有读对文件、用对版本、尊重“只检查不修改”的要求。
长任务要测整个执行过程。前一步读错版本,后面推理得再认真,也可能沿着错误材料继续走。反过来,一次失败也未必意味着整项任务失败:系统可能重试、换工具,或者请用户补充信息。
为什么“每步 95%,20 步只剩 36%”只能作提醒?
若恰好需要 20 步、每步成功率都是 0.95、各步独立,而且任何一步失败都会让整项任务失败,那么:
$$P_{\mathrm{success}}=0.95^{20}\approx0.358.$$
实际步骤难度会变,错误会相关,也可能有恢复路径。这道乘法提醒我们别只测单步,却不能替代端到端评估。更实用的记录是:任务成功率、失败发生在哪一步、恢复了几次,以及最后用了多少时间和成本。
2. API 和自部署,各自多了什么工作?
| 要比较什么 | 托管 API | 自部署开放权重模型 |
|---|---|---|
| 任务质量 | 测具体模型和版本,不把“API”当能力等级 | 同样实测;微调(fine-tuning)和工具也可能改变结果 |
| 成本 | token、缓存、重试、服务方案等 | 算力、闲置容量、存储、运维和维护时间 |
| 延迟 | 网络与服务端负载;也能优化上下文、并发和输出长度 | 可调部署、batch 和并行,但排队与维护由自己负责 |
| 数据边界 | 核对地域、保留策略、合同和私有连接 | 核对日志、遥测、工具和外部依赖,不只看权重在哪里 |
| 定制 | 看服务支持哪些微调、工具和配置 | 控制较多,也要承担训练、评估与发布工作 |
| 版本 | 有的可固定快照,但仍要跟进退役安排 | 固定权重、tokenizer、模板和推理环境 |
小团队可以先用符合数据要求的 API 做基线(baseline),不用先解决一整套 serving。已有闲置算力、特殊部署要求或稳定大流量的团队,起点可能相反。没有“请求超过某个数量就一定自部署”的通用界线。
3. “自动决定要不要思考”,是谁在决定?
看到一个模型有 thinking 模式,不妨追问:这是调用方选的,还是模型生成过程中自己选的?两者都可以有用,但不是同一种能力。推理模型为什么想得越久越可能做对、什么时候多想也没用,见推理模型与测试时计算。
- 调用前:应用指定日期提取用较短预算,bug 排查用更长预算。决定来自配置或规则。
- 生成中:模型选择经过相应训练的模型,可以较早结束思考段,也可以继续生成。仍受最大预算限制。
- 系统外层:选择模型路由器先看请求,决定交给 A 还是 B;它不等于模型内部的停止行为。
手动模式控制。 原始 Qwen3 混合思考型号提供 thinking / non-thinking 控制;这说明调用方可以选模式,不代表每次都由模型自动判断。后来的 Qwen3-4B-Instruct-2507 是非思考型号,不能把早期接口套到所有 checkpoint 上。Qwen3 发布说明 · 具体模型卡
模型学出的选择。 AutoThink(2025)研究让 R1 风格模型学习何时保留显式思考。训练先平衡两种模式,再提高表现,最后引入长度相关奖励(reward)。只改 prompt 能产生模式变化,却不等于已经学会按难度分配计算。AutoThink §2–3
一个容易读错的细节:该论文第 2 阶段去掉的是 batch-level 平衡,保留了按模式与正确性区分的基础奖励,不是简单的“答对 1 分、答错 0 分”。主要实验是数学题;我们没有复现它,也不能据此推断任意 agent 都会受益。
前两层合到一起。 截至 2026-10,有的托管 API 已经把“调用前指定”和“生成中选择”合成一套接口。以 Anthropic 的 Claude API 为例:调用方用 effort(从 low 到 max)设一个倾向,模型对每个请求自己决定要不要想、想多少;文档明确说调用方不再设 thinking token 预算,硬上限只有 max_tokens,effort 是软引导,不保证 token 数。Claude 文档:Steering thinking 这样一来,“日期提取用较短预算”就变成“给这类请求设较低的 effort”,个别难题模型仍可能多想。要按请求类型核对响应里实际的 thinking token 数,不能只看配置。
外部路由。 应用估计哪种模型更适合当前请求;即使候选模型没有 thinking 开关,也能做 routing。自适应深度则讨论网络内部多算几层或几轮,别把隐藏状态(hidden state)迭代和多生成一些文字混在一起。
4. 混着用:路由和级联差在哪儿?
| 做法 | 什么时候决定 | 付出的代价 | 常见失败 |
|---|---|---|---|
| 请求前路由(routing) | 看到请求后、生成答案前 | 路由器 + 被选模型 | 没看见答案,可能选错 |
| 级联(cascade) | 先生成,再检查是否升级 | 首次回答 + 检查 + 可能的第二次回答 | 放过错误,或无谓升级 |
| 故障兜底(fallback) | 超时、限流或验证失败后 | 重试、切换和状态恢复 | 把恢复服务误当成答案正确 |
| 蒸馏(distillation) | 训练阶段,不是这次请求里 | 教师数据、训练与维护 | 学到教师偏差,或只适合窄任务 |
FrugalGPT(2023)研究级联选择;RouteLLM(2024,修订于 2025)用偏好数据学习请求前路由。可以借鉴机制,但不能把当时的价格和节省比例当成今天的部署结论。
路由选错后可以再加输出检查或兜底,并非“没有补救”。只是要把补救成本和延迟一起算。蒸馏可以与以上策略组合,不是“每条请求的第 4 种分法”。
5. 算一下:选错对象就白花钱
下面全是人为构造的结果,不是模型测评。A 每次成本记为 1,B 为 5;路由器每次额外花 0.1。为看清互补性(complementarity),故意让 B 在第 4 题上出错。
| 请求 | A 是否完成 | B 是否完成 |
|---|---|---|
| 提取文中日期 | 是 | 是 |
| 改写一小段文字 | 是 | 是 |
| 找到跨文件错误 | 否 | 是 |
| 遵守特殊的本地格式 | 是 | 否 |
| 方案 | 完成数 | 总成本 |
|---|---|---|
| 全用 A | 3 / 4 | 4 |
| 全用 B | 3 / 4 | 20 |
| 选对了:A → A → B → A | 4 / 4 | 8.4 |
| 选错了:A → B → A → A | 3 / 4 | 8.4 |
两种路由都调用 B 一次,成本一样,但后者没有比全用 A 多完成任何任务。难点不只是减少贵模型调用,而是把它用在确实有帮助的请求上。
“选对了”是看过两个结果后写出的理想对照,不是上线就知道的答案。真实路由器只能用调用前可得的信息;把结果标签或未来反馈塞进输入,就会得到看似漂亮、无法部署的结果。
用 Python 核对这 4 种分配
import math
outcomes = [(1, 1), (1, 1), (0, 1), (1, 0)]
costs = {"A": 1.0, "B": 5.0}
def score_plan(choices, overhead=0.0):
if len(choices) != len(outcomes) or any(name not in costs for name in choices):
raise ValueError("Choose A or B for each request")
if not math.isfinite(overhead) or overhead < 0:
raise ValueError("Overhead must be finite and nonnegative")
completed = sum(result[0 if name == "A" else 1]
for result, name in zip(outcomes, choices))
cost = sum(costs[name] + overhead for name in choices)
return completed, round(cost, 6)
assert score_plan("AAAA") == (3, 4.0)
assert score_plan("BBBB") == (3, 20.0)
assert score_plan("AABA", 0.1) == (4, 8.4)
assert score_plan("ABAA", 0.1) == (3, 8.4)
代码只回放(replay)给定结果,不会训练或调用路由器。真实实验要另留测试集,并报告不确定性、分任务表现、拒答、超时和成本,不是用这 4 条样本估计上线收益。
再用滑块看成本和质量怎样变化
图里是另一组假设,不是上述样本的实测扩展。它固定两类请求的成功率,还人为让级联检查比请求前分类更准;检查开销没有计入;路由只加了固定的示意开销(成本 0.05、延迟 0.1)。适合观察假设变化,不适合直接选供应商。
6. 成本怎么算,才不漏掉失败的请求?
把每轮输入、输出、工具调用、重试都记下来。还要统计失败任务花掉的钱:只在成功请求里算平均成本,会把反复尝试却没完成的部分藏掉。
先把每次模型调用的价格看作固定值:A 花 $C_A$,B 花 $C_B$;每次路由花 $r$,检查一次回答花 $v$。设交给 B 的比例为 $u$:
$$ \begin{aligned} C_{\text{route}}&=r+(1-u)C_A+uC_B,\\ C_{\text{cascade}}&=C_A+v+uC_B. \end{aligned} $$
级联中的 A 已经答过一次,不能省掉那笔账。两个方案的 $u$ 也未必相同。真实请求长度不同,应逐条累计输入、输出和缓存费用,而不是一律套固定价格。
API 与自部署的月成本估算器
默认数字只是可替换的假设。这里合并估计 prefill 和 decode 吞吐,按副本全天运行计费,没模拟排队、峰值容量、缓存命中或服务等级要求。它展示成本曲线,不是报价或容量规划器。
7. 等待、上下文和版本,也会影响选择
用户等的是整个任务。 同时发出的独立调用,不该简单相加;后一步依赖前一步,则在关键路径上。分别记录排队、首 token、生成、工具耗时,以及端到端的中位数和长尾(long tail)。使用 API 也能改上下文、并发、超时和输出长度,并非只能等服务商。
弄清哪些内容反复发送。 若每次完整重发历史,初始内容为 $b$ token,每步再加 $a$,连续调用 $k$ 次的输入总量为:
$$kb+\frac{ak(k-1)}{2}.$$
例如 $b=1000,a=200,k=4$,四次输入为 1000、1200、1400、1600,共 5200 token。使用摘要、窗口、检索(retrieval)或缓存后,存储、计算和计费口径会变化;不能说所有 agent 成本都平方增长。输出和工具返回也要另算。
固定的不应只有模型名。 权重、tokenizer、聊天模板、工具 schema、采样设置和服务端版本,都可能影响结果。升级后重新跑代表性任务,而不只是确认接口还能返回文字。
8. 自部署时,哪些账容易漏?
- 闲置与峰值容量。 按峰值配置的机器,低谷也可能继续计费;平均利用率很高也可能意味着请求在排队。
- Prefill、decode 和 KV cache。 长输入、长输出和大量并发的瓶颈不同,要用自己的长度分布测试。
- 维护时间。 升级、回滚、值班、监控和事故恢复,都需要有人负责。
PagedAttention 主要改善 KV 内存管理,RadixAttention 侧重可共享前缀的复用;它们不是同一个优化,也不会消除所有限制。推理服务一条请求和缓存与 attention kernel有具体过程与来源。
想继续深入系统实现,也可以读 Awesome-ML-SYS-Tutorial。这里先把选型问题讲清楚,不假装一张成本图就完成了部署设计。
9. 真要开始时,我会按这个顺序检查
- 任务和边界。 允许用什么数据、哪些动作需要确认、失败到什么程度可以接受?
- 单模型基线。 先测一个简单方案,留出独立评估任务,不急着加路由。
- 找到差异。 哪些请求值得更多计算?哪些无论换模型还是延长思考,都只是缺信息?
- 比较完整方案。 路由器、检查器、重试、长尾延迟一起算,再和基线比较。
- 小范围试,持续复测。 输入分布、版本和价格变化后,原来的分配可能不再合适。
还有个常见误判:低 token entropy 或较大的 top-1 / top-2 概率差,只说明下一 token 分布集中,不等于任务一定正确。若用它们触发升级,先在留出数据上检查它们与失败的关系。很自信地读错了用户意图,多想一会儿也不一定能解决。
本页术语 11
- 路由器 router
- 决定一条输入走哪条处理路径、或各分支占多少权重
- 候选 candidate
- 召回阶段捞出来、等待精排挑选的内容
- 微调 fine-tuning
- 在预训练权重上继续训练以适配具体任务
- 基线 baseline
- 用来比较新方法的参考方法或配置
- 奖励 reward
- RL 里指导策略更新的标量信号
- 隐藏状态 hidden state
- 递归模型在时间步之间传递的压缩表示
- 蒸馏 distillation
- 用一个模型的输出训练另一个通常更小的模型
- 互补性 complementarity
- 新模块贡献了多少别的通道拿不到的相关候选
- 回放 replay
- 用固定输入重新执行一段数据或模型链路,检查结果是否一致
- 长尾 long tail
- 出现频率很低但总量可观的那部分情况
- 检索 retrieval
- 从外部语料里找出相关内容