1. 从一张失控的账单说起:为什么“判断”层成了 Agent 的成本黑洞
过去一年,我帮三个团队做过智能体(Agent)系统的成本审计,场景各不相同——一个做电商客服自动回复,一个做代码仓库的自动巡检,还有一个做多轮数据分析问答。三个项目在技术栈上几乎没有交集,但翻完它们的调用日志之后,我发现了一个高度一致的规律:真正吃掉预算的,往往不是那些“干活”的模型,而是那个负责“决定下一步干什么”的模型。
这个发现一开始让我有点意外。按照直觉,一个 Agent 系统里最贵的应该是执行层——比如生成一段长代码、写一篇长文、跑一次复杂的多步推理。但账单不会骗人。我统计过一个中等规模客服 Agent 的月度调用分布:执行类调用(生成回复、改写文案、抽取字段)平均每次消耗 800 到 1500 个 token,而判断类调用(意图识别、路由决策、是否需要调用工具、调用哪个工具、结果是否合格)平均每次只有 200 到 400 个 token。单次看,判断调用便宜得多。但问题在于频率——一个用户请求进来,执行层可能只被触发一两次,而判断层会被触发五到十五次,甚至更多。
这就是标题里说的“账单”问题的核心。判断层单次便宜、总量惊人,而且它对延迟极度敏感,对错误极度不容忍。你用一个通用大模型去做判断,就像请一位博士去按电梯按钮——他能按对,但每次都要思考三秒,而且收费按博士标准。这篇文章我想把这件事彻底拆开讲清楚:判断层到底在做什么、为什么它值得一个专用模型、专用模型该怎么选怎么训怎么落地,以及我在实操中踩过的那些坑。
适合读这篇的人有三类:正在做 Agent 系统、被成本或延迟卡住的工程师;在评估“要不要自研小模型”的技术负责人;以及单纯好奇“为什么大厂都在往小模型判断层砸资源”的从业者。不管你是哪一类,我尽量把每个决策背后的账算给你看,而不是只给结论。
2. 判断层到底在判断什么:把黑盒拆成可枚举的决策点
2.1 一个请求进来,判断层要回答的五个问题
很多人对“判断层”的理解是模糊的,觉得它就是“让模型想想下一步”。这种模糊认知直接导致无法优化。我在实际项目里会把判断层的职责拆成五个可枚举的决策点,每一个都可以单独统计、单独优化:
- 意图归类:这个请求属于哪一类任务?是查询、是操作、是闲聊、还是需要转人工?这是一个典型的多分类问题,类别数通常在 5 到 30 之间。
- 路由决策:这个任务应该交给哪个执行器?是走检索、走代码执行、走数据库查询,还是直接由生成模型回答?
- 工具选择与参数填充:如果需要调用工具,调哪个、传什么参数?这一步往往被拆成“选工具”和“填参数”两个子判断。
- 结果校验:执行层返回的结果是否满足要求?需不需要重试、改写或降级?
- 终止判断:当前轮次是否已经可以给用户答复,还是需要继续循环?
这五类判断有一个共同特征:输入短、输出短、类别有限、逻辑确定性强。它们不需要模型写诗,不需要模型做开放式推理,只需要模型在一个相对封闭的空间里做出稳定、快速、可预测的选择。这恰恰是专用模型最擅长的战场,也是通用大模型最浪费的战场。
2.2 为什么通用大模型做判断是“杀鸡用牛刀”
我做过一个对比实验,用同一个通用大模型分别做“意图归类”和“开放式问答”。意图归类任务里,输入是一句用户话,输出是一个类别标签,平均消耗 180 个 token,延迟 900 毫秒。开放式问答平均消耗 1200 个 token,延迟 4 秒。单看意图归类,它确实“便宜又快”。但当你把意图归类、路由、工具选择、结果校验串起来,一个请求走完判断链路要调用四到六次,累计 token 就上去了,累计延迟也上去了。
更关键的是能力错配。通用大模型的参数里,绝大部分容量用来存储世界知识和语言生成能力,而判断任务根本用不到这些。你让它做意图归类,它脑子里同时装着“怎么写十四行诗”和“怎么解释量子力学”,这些知识在判断时全是噪声。专用模型可以把全部容量聚焦在判断模式上,用十分之一的参数量达到同等甚至更高的准确率。这不是玄学,是容量分配的基本逻辑。
2.3 判断错误的代价:为什么这一层不能“差不多就行”
执行层出错,用户可能只是看到一句不太通顺的话,重试一次就好。判断层出错,整个链路会跑偏。我见过最典型的一个案例:一个客服 Agent 把“我要退订会员”误判成“我要咨询会员权益”,结果执行层热情洋溢地介绍了一堆权益,用户直接炸了。这个错误的根源不在执行层,而在判断层的一次分类失误。
判断层的错误有三个放大效应:第一,它会污染后续所有步骤,因为路由错了,执行层再努力也是南辕北辙;第二,它往往不可逆,用户已经收到了错误响应,你没法悄悄撤回;第三,它高频发生,一个请求判断十次,每次 95% 准确率,整体链路准确率就掉到 60% 以下。这就是为什么判断层值得单独投入——它不是“差不多就行”的环节,而是整个 Agent 可靠性的地基。
3. 专用判断模型的选型逻辑:不是越小越好,而是越“专”越好
3.1 参数量、延迟与准确率的三方博弈
选专用判断模型,第一个要面对的就是参数量选择。我的经验是把判断模型分成三档来考虑:
| 档位 | 参数量级 | 典型延迟 | 适用判断类型 | 部署成本 |
|---|---|---|---|---|
| 极轻量 | 0.1B 以下 | 10-30ms | 二分类、简单意图 | 极低,可 CPU 推理 |
| 轻量 | 0.5B-3B | 30-120ms | 多分类、路由、工具选择 | 低,单卡可承载 |
| 中量 | 7B-14B | 150-500ms | 复杂校验、多步判断 | 中,需专用推理卡 |
这张表不是拍脑袋来的,是我在多个项目里实测后收敛出来的区间。核心逻辑是:判断任务的复杂度决定了它需要多少“思考容量”。二分类任务,比如“这句话是不是投诉”,0.1B 的模型微调后就能做到 97% 以上准确率,再大就是浪费。但如果是“从二十个工具里选出正确的那个并填对参数”,0.5B 以下往往力不从心,因为工具描述本身就要占掉不少上下文容量。
我个人的默认起点是1B 到 3B这个区间。它足够覆盖绝大多数判断场景,延迟能压到 100 毫秒以内,单张消费级显卡就能跑起来。除非你的判断任务涉及长上下文(比如要读完整个对话历史再判断),否则没必要上 7B。
3.2 基座选择:为什么我优先看“指令跟随”而非“知识储备”
选基座模型时,很多人习惯看榜单排名,但判断层专用模型的选型逻辑和通用模型完全不同。判断任务不需要模型知道“法国的首都是哪里”,它需要模型严格按格式输出、稳定遵循指令、对边界情况不胡乱发挥。
所以我看基座时优先关注三个指标:指令跟随的稳定性(给它一个输出格式,它会不会偶尔跑偏)、对短输入的敏感度(判断任务输入往往只有一两句话,模型能不能抓住关键信息)、微调后的收敛速度(同样的数据量,哪个基座更快达到目标准确率)。知识储备、多语言能力、长文生成能力,这些在判断场景里权重很低。
具体到基座家族,我一般会准备两到三个候选,用同一批判断数据做小规模微调对比,看谁在验证集上的 F1 更高、输出格式违规率更低。这个过程通常只需要一两天,但能避免后面几周的返工。
3.3 自研微调 vs 提示工程:什么时候该动手训模型
这是被问得最多的问题:我能不能不训模型,靠精心设计的提示词让通用模型做判断?答案是能,但有条件。
如果你的判断任务类别少于 5 个、每天调用量低于一万次、准确率要求低于 90%,那提示工程完全够用,没必要折腾微调。但只要越过其中任何一条线,微调的性价比就会迅速反超。我算过一笔账:一个每天调用十万次的判断任务,用通用模型加提示词,每次 300 token,按常见定价一个月成本在四位数;用 1B 专用模型自部署,一次性微调成本加推理硬件摊销,两到三个月就能回本,之后全是净省。
更重要的是延迟和稳定性。提示工程依赖通用模型的“理解力”,而通用模型对提示词的微小改动很敏感,今天调好的提示词,明天换个版本可能就飘了。专用模型一旦训好,行为是锁定的,这对生产环境至关重要。
4. 训练一个判断模型:数据、方法与那些没人告诉你的细节
4.1 数据从哪来:三条我验证过的采集路径
训练判断模型,数据是最大的门槛。好消息是,判断任务的数据比生成任务好造得多,因为它的标签是离散的、可验证的。我常用的三条路径:
第一条,日志回捞加人工标注。从现有 Agent 的运行日志里捞出判断层的输入输出,人工修正错误标签。这条路径最真实,但成本高,适合做验证集和难例补充。
第二条,规则合成加模型改写。用规则生成大量“模板化”的判断样本,再用一个通用模型把它们改写成多样化的自然表达。比如意图归类,你可以先写“我要退款”这个模板,让模型改写出五十种不同说法。这条路径能快速上量,但要注意改写后的样本可能带有模型自身的偏见,需要抽样人工检查。
第三条,执行层反哺。这是我最推荐的一条。让执行层在完成任务后,回传“这次判断是否正确”的信号,用这个信号自动构造正负样本。比如工具调用后如果执行成功,就说明工具选择判断是对的;如果执行报错,就说明判断可能有问题。这条路径能持续产生高质量数据,而且完全自动化。
我的经验配比是:合成数据占 60% 打底,日志回捞占 30% 补真实分布,执行反哺占 10% 做持续迭代。这个比例不是固定的,但合成数据打底、真实数据校准的思路是通用的。
4.2 标注的坑:判断任务的标签比你想的更容易错
判断任务的标注有一个隐蔽陷阱:标注者的一致性往往比想象中低。我做过一次测试,让三个标注者独立标注同一批“是否需要转人工”的判断样本,结果两两一致率只有 82%。也就是说,光靠人标,天花板就在 82% 左右,你训出来的模型再好也超不过这个上限。
解决办法是把判断标准写成可执行的规则文档,而不是靠标注者的直觉。比如“是否需要转人工”,不能只说“感觉用户很生气就转”,而要写成“出现明确投诉词、出现退款要求、连续两轮未解决问题,满足任一即转”。规则越具体,标注一致性越高。我一般会要求标注规则文档至少覆盖 90% 的常见情况,剩下 10% 的边界情况单独讨论定标。
4.3 微调方法:全参、LoRA 还是更轻的方案
判断模型的微调,我基本不用全参微调,原因很简单:判断任务的数据量通常不大(几千到几万条),全参微调容易过拟合,而且每次迭代都要重训,成本高。LoRA 及其变体是我的默认选择,它在判断任务上的表现和全参微调差距很小,但训练快、显存省、可以多版本并存。
具体参数上,我常用的配置是 rank 16 到 32、alpha 32、dropout 0.05,学习率在 1e-4 到 2e-4 之间。判断任务的训练轮数不宜多,通常 3 到 5 轮就收敛,再多就过拟合。我会在验证集上盯着 F1 和格式违规率两个指标,F1 不再涨、格式违规率开始升,就停。
还有一个细节:判断模型的输出格式要强制约束。我一般让模型输出结构化的标签或 JSON,并在训练数据里保证 100% 格式正确。推理时再加一层格式校验,格式不对直接判为失败并走兜底逻辑。这比指望模型“自觉”可靠得多。
5. 落地部署:把判断模型塞进现有 Agent 链路
5.1 推理加速:判断层对延迟的容忍度有多低
判断层是链路上的“收费站”,每个请求都要过。它的延迟会直接叠加到用户感知的总延迟上。我给自己定的红线是:单次判断延迟不超过 150 毫秒,整条判断链路(四到六次调用)不超过 600 毫秒。超过这个数,用户就会觉得“卡”。
达到这个目标,光靠模型小还不够,推理侧的优化同样关键。我常用的组合是:量化 + 批处理 + 缓存。量化到 INT8 通常能带来 1.5 到 2 倍加速,精度损失在判断任务上几乎可以忽略。批处理能把并发请求的吞吐拉起来,但要注意判断请求往往是串行依赖的,批处理窗口不能设太大,否则反而增加延迟。缓存则是针对高频重复判断——比如同一类意图的相似表达,命中缓存直接返回,能省掉大量推理。
5.2 兜底策略:判断模型也会错,错了怎么办
再好的判断模型也有出错的时候,关键是出错之后系统不能崩。我的兜底策略分三层:
第一层,置信度阈值。让模型输出判断结果的同时输出一个置信度,低于阈值的判断不走自动路径,转人工或转通用模型复核。
第二层,格式与合法性校验。输出不符合预期格式、或选了一个不存在的工具,直接判为失败,走默认路径。
第三层,执行结果反馈。如果执行层报错,回滚到上一个判断点,换一个候选判断重试。这三层叠起来,能把判断错误对用户的影响降到很低。
5.3 监控与迭代:判断模型不是训完就完事
判断模型上线后,我会重点监控四个指标:准确率(抽样人工评估)、延迟分布、格式违规率、兜底触发率。其中兜底触发率是最灵敏的预警信号——它一升,说明模型开始遇到训练分布之外的情况了。
迭代节奏上,我一般两周做一次小迭代,用执行反哺的新数据增量训练一版 LoRA,A/B 测试后灰度上线。这个节奏既能跟上业务变化,又不会因为频繁更新引入不稳定。判断模型的迭代和通用模型不同,它追求的是稳定中的缓慢进化,而不是每次大跃进。
6. 常见问题与排查技巧实录
6.1 判断模型准确率上不去,先查这五个地方
| 现象 | 可能原因 | 排查动作 |
|---|---|---|
| 训练集准确率高,验证集低 | 过拟合 | 减少训练轮数,增加 dropout,检查数据泄漏 |
| 某几个类别准确率特别低 | 类别不平衡 | 检查样本分布,对少数类过采样或加权 |
| 输出格式频繁违规 | 训练数据格式不统一 | 清洗训练数据,确保 100% 格式一致 |
| 线上准确率低于离线 | 数据分布漂移 | 对比线上线下输入分布,补充线上真实样本 |
| 延迟忽高忽低 | 批处理窗口或缓存策略问题 | 检查批处理配置,优化缓存命中率 |
这张表是我踩坑踩出来的,基本覆盖了八成以上的判断模型问题。遇到准确率问题,按这个顺序查,能省很多时间。
6.2 几个我踩过的坑,你可以直接避开
坑一:用生成任务的思路做判断数据。我早期犯过一个错,把判断样本写得很长很详细,结果模型学会了“看长度猜答案”。判断样本要短、要贴近真实输入,别加戏。
坑二:忽略负样本的质量。判断任务里,负样本(不该触发某路径的样本)往往比正样本更重要。我见过一个模型把所有请求都判成“需要转人工”,因为负样本太少。正负样本比例我一般控制在 1:1 到 1:2 之间。
坑三:微调后不做格式约束。有一次我偷懒,没在推理层加格式校验,结果模型偶尔输出一段解释文字而不是标签,下游解析直接崩了。从那以后,格式校验成了我的标配。
坑四:用同一个模型做所有判断。意图归类和结果校验的输入输出差异很大,硬塞进一个模型会互相干扰。我现在的做法是按判断类型分模型,或者至少分 LoRA 适配器,效果明显更好。
6.3 一个实用的判断模型自检清单
上线前我会过一遍这个清单,你可以直接抄:
- 验证集 F1 是否达到业务要求(通常 92% 以上)
- 输出格式违规率是否低于 0.5%
- 单次推理延迟 P99 是否低于 150 毫秒
- 兜底逻辑是否覆盖所有失败路径
- 是否有置信度输出和阈值机制
- 监控指标是否接入告警
- 是否有两周一次的迭代计划
这个清单不复杂,但能挡住绝大多数上线事故。
7. 我对判断层专用化的一点个人判断
做了这几个项目之后,我越来越确信一件事:Agent 系统的竞争力,正在从“执行层有多强”转移到“判断层有多准多快多省”。执行层的能力大家都能买到,无非是选哪个通用模型的问题;但判断层是每个系统独有的,它承载着你的业务逻辑、你的工具集、你的用户习惯,这些东西通用模型给不了,只能靠专用模型来沉淀。
专用判断模型的价值不在于它多聪明,而在于它足够专注、足够稳定、足够便宜。它就像工厂流水线上的质检工,不需要懂设计,只需要在零点几秒内判断“这个合格不合格”。你让设计师去干质检,不是不行,是浪费,而且设计师还会走神。
最后分享一个我最近在试的小技巧:把判断模型的输出和置信度一起记录下来,定期做一次“判断审计”,专门看那些高置信度但实际错误的案例。这些案例往往揭示了训练数据里的系统性盲区,比随机抽样高效得多。我靠这个方法在一个项目里找到了三类之前完全没意识到的判断错误模式,补进去之后整体准确率提了四个点。判断层的优化没有终点,但每一点提升都会直接反映在账单和用户体验上,这笔账怎么算都值。