☰
Agent成本黑洞:用轻量文本分类器替代大模型调用,调用量砍80%
2026/10/12 3:26:25 网站建设 项目流程

没动手做之前,我也没想到 Agent 里最大的成本黑洞不是模型单价,而是调用次数。上个月我接手了一个内部用的“智能工单助手”Agent,跑了两周数据一拉,账单让我直接清醒了:一次用户提问,后台平均要烧掉 4 到 5 次大模型调用,意图识别一次、信息抽取一次、路由决策一次、回复润色再来一次,这还是没算上失败重试的情况。大模型是能说会道,但大多数时候我们根本不需要它开口说话,只需要它做一道选择题。

后来我花了一个周末,把大部分调用替换成一个“不会说话”的轻量模型,准确说是一个 100MB 不到的文本分类器,加一套规则引擎和应急兜底。结果非常直接:Agent 里的大模型调用量砍掉了大约八成,账单同步缩水,响应时延也从原来的 4 到 6 秒降到了 1.5 秒以内。这篇就是把完整的改造思路、踩坑过程和能直接抄走的做法分享出来,给正在被 Agent 账单折磨的人一个参考。

1. 账单爆炸的根源:不是模型贵,而是调用太“碎”

1.1 我拆了一遍调用链,发现一半工作都是重复劳动

先说这个“智能工单助手”的原始架构。当时接手的时候,整个流程是标准的“大模型全家桶”式设计:用户提交一个问题,系统先让大模型判断这是什么类型的工单,再让大模型从文本里抽出关键字段,比如设备型号、故障描述、用户紧急程度,接着让大模型决定这条工单路由给哪个处理组,最后还要让大模型把答复重写一遍让它更像人话。

单看设计逻辑没有大问题,毕竟每个环节确实都需要“智能”。但问题在于,这 4 次调用中至少有 3 次属于典型的“能力过剩”——分类、字段抽取、路由决策,本质上都是结构化输出任务,大模型能做,但它是用极高的成本在做。我在测试集上跑了一遍统计,用户常见问题类型大约只有 12 类,工单里需要抽的字段只有 6 个,路由目标是 5 个处理组。这些东西的复杂度,根本不需要一个几千亿参数的大模型来推理。

更直观的一组数据是:当时一次完整的工单回复流程,如果命中的是高频标准问题,Token 消耗中约 70% 都花在了“阅读理解用户的话并归个类”上。换句话说,每次用户提问,真正需要大模型发挥语义生成能力的部分,只有最后那一小步。

1.2 “能说会道”的模型干“分类”的活,本身就是资源错配

我后来反思了一下,这类问题的根源是很多 Agent 框架的设计惯性。框架为了追求通用性,把所有环节都抽象成“大模型调用”,开发者用起来顺手,但这种顺手让你不怎么思考:这个环节是不是真的需要生成能力?

来打个比方。如果每天有 1 万个人到前台问“财务部怎么走”,正常的做法是立一块指示牌,或者安排一个前台按照部门清单指路,而不是让一位资深专家对每个访客做 5 分钟深谈。我们 Agent 里的情况就是:所有访客都被拽进了专家会谈室。分类、抽参、路由这些环节,本质上是在做“匹配”,而匹配这件事,机器学习里的老办法已经做得又快又准。

而且大模型调用还隐藏着一个成本问题:即使是同一个模型,输出内容的长度直接决定账单金额。让大模型做分类,它会给你解释“根据您的描述,这个问题可能属于……原因是……”——几十个字的分类结论,硬生生写成了三百字小作文。相比之下,分类器返回的是整数编号,干净得像一块指示牌。

2. 核心设计:用“分类器 + 规则 + 小模型”做粗筛,只把少数难题交给大模型

2.1 我给这套分流机制取了个朴素的层级结构

改造的方向其实只有一句话:明确每一层该干什么,大模型只出现在最不能被替代的位置。

我最终落地的是三级分流结构:

第一级是规则层。用户的问题进来后,先走一个基于关键词和正则的快速匹配。工单系统里有大量标准化问答,比如“账号锁定怎么办”“如何重置密码”“报销流程是什么”。这些问题的表述方式非常固定,规则命中率能做得很高。规则层只负责返回一个“问题类型编号”,不产生任何模型调用,耗时基本可以忽略。

第二级是分类器层。规则没命中的问题,交给一个轻量文本分类器。这个分类器是我用之前积累的带标签语料微调出来的,模型底座是一个开源的中文文本表示模型,量化之后体积只有 90MB 左右。分类器的作用是从 12 个工单类型里选一个最合适的,同时输出一个置信度分数。这一步在 CPU 上跑平均耗时 20 毫秒,费用可以按“几乎为零”计算。

第三级才轮到大模型。分类器置信度低于阈值,或者分类结果属于需要复杂推理的少数类型,比如“跨系统数据不一致”“需要与多个部门协调”这类,才把完整文本交给大模型处理。另外,最终面向用户的回复生成这一步,我保留了大模型调用。这一步是大模型真正的价值所在,因为要产生自然、得体的表达,不是做选择题。

2.2 训练“不会说话”的模型,比想象中省事

听到“要训练一个分类器”很多人可能打退堂鼓,但实际操作下来,难度比想象中低很多。我当时用的训练数据来自两个部分:一是历史工单里已经标好类别的 8000 条样本,二是从规则层能命中的高频问题里反向抽取的 2000 条样本。总共 1 万条,按 8:1:1 切分成训练集、验证集和测试集。

训练脚本用的是常见文本分类流程,文本表示模型接一个全连接分类头,用交叉熵损失微调。超参数上,学习率取了 2e-5,batch size 是 32,在单张消费级显卡上大概让模型跑了 8 个 epoch,验证集准确率稳定在 97.5% 左右,满足上线要求。我把整个训练到导出量化的流程写成了一个脚本,后面每隔两周拉一批新工单增量微调一次。

值得提的是,分类器输出的置信度我到今天依然觉得是它最大的价值。大模型回答你不会给你概率,但分类器会。这意味着我可以设一个“疑罪从有”的阈值,凡是置信度低于 0.7 的,全部转给大模型做二次判断。宁可漏杀,不可错杀,是这类系统上线时必须守住的底线。

2.3 为什么非要留一道“产线人工检验”?

光有自动分类还不够,分类器偶尔会把“账号锁定”误判成“密码重置”,这俩在外观上确实接近。为了让系统不至于带病运行,我加了一层产线人工检验:对每条工单,系统在返回结果的同时附带分类器置信度、命中的规则编号、最终进入的处理流程,以及大模型是否参与的标记。人工质检时只需要看“置信度低但被分类器直接处理”的那批样本,抽样标准是每 500 条抽 20 条。

这个设计在成本和准确率之间找了一个平衡点。分类器并不是越长越聪明,它也有认知边界,我们需要给它配一个“它有把握”的信号,让系统知道什么时候该相信它,什么时候不该信。

3. 改造落地的完整流程:从拉开调用清单到切换流量,每一步都能复现

3.1 第一步:把 Agent 的每一次大模型调用都登记在册

改造前第一件事不是写代码,而是给现有 Agent 的调用做一次全面盘点。我建了一张表格,把每一次大模型调用的触发条件、输入内容、输出结构、单次平均 Token 消耗、调用结果是否影响主流程这几项全部记录下来。

做完盘点之后,我把这些调用分成了三类:

  • 可无损替代:输出是一个固定枚举值,比如问题类型、处理组编号、紧急程度。这类调用对应的是分类和路由任务,可以替换为规则或分类器,替换后行为不变。
  • 可条件替代:输出虽然包含结构化信息,但只在部分场景下需要大模型的泛化能力。比如字段抽取,我观察到大约 60% 的工单只有“设备型号”和“故障类型”两个字段需要抽,并且格式高度统一,用正则就能提取。只有剩下 40% 格式混乱的工单,才需要大模型兜底。
  • 不可替代:输出是自然语言表述,比如最终回复生成,以及少量需要复杂推理才能得出结论的场景。这类调用保留原样。

我最终的替换比例是:四次调用中,规则加分类器替换了两次,条件替代了一次,剩一次大模型调用。网上有些人做汇报喜欢用“砍掉 80% 调用”这种响亮说法,更准确地说,我们把原来五次的调用压缩成了一次,换算过来就是减少约 80%。

3.2 第二步:流量灰度切换,别在周五直接全切

我把流量切换分成了三个阶段,节奏上宁可慢,不出事故。

第一阶段是影子模式。所有请求照常走原来的“大模型全家桶”,同时并行跑新的分流链路,只记录结果,不下发生产。这一步我用的是旁路日志对比,持续跑了两天,大概积累了 6000 条对比数据。核心指标是两个:新路子选出的类型与大模型选出的类型是否一致、不一致时大模型的结论是否明显更合理。

第二阶段是双写模式。新链路的结果开始影响下游处理,但每一条请求仍然同步保留一份大模型调用的结果,两条链路的结果都写进表里。这样做的好处是,即使新链路出了错,日志里依然有大模型结果可以随时纠正。如果某个分类器的误判率超过 1.5%,我会立刻把该类型的热度阈值调高,让更多请求临时交回大模型处理。

第三阶段才是完全切换。双写模式稳定运行一周后,我关闭了大模型在分类、路由、字段抽取三个环节的调用。此时整个系统只剩下回复生成环节会调大模型。关闭之后我连续盯了三天线上指标,确认没有明显异常,才彻底删掉旧的调用代码。

3.3 第三步:兜底熔断机制,这是我第一批就加上的保险

这个改造最怕的不是误判,而是下游系统“接不住”。比如分类器把工单类型判错了,工单就会被送到错误的处理组,用户可能被来回踢皮球,这种体验比慢三秒还糟糕。

我的做法是在分流链路上加了三个保险:

第一,置信度阈值动态调整。分类器的默认阈值是 0.7,但每个类型的热门程度不一样,高频类型的阈值可以放宽到 0.6,低频类型的阈值则收紧到 0.8。因为高频类型样本量大、分类器对它见过足够多样本,出错的概率相对低;低频类型样本少,宁可多交给大模型。

第二,多类型 Top-2 兜底。分类器不仅返回最大概率的类别,还返回第二大概率类别。如果最大类别对应处理组的负载过高,或者规则层提示冲突,系统会自动改用第二类别。这个设计大大减少了边界误判造成的连锁反应。

第三,链路熔断开关。我在配置中心放了一个全局开关,名为“大模型兜底模式”。一旦监控发现分类器整体准确率跌破 85%,或者错误路由的工单数量明显上升,就一键把全链路切回“大模型处理所有环节”。这个开关我在灰度期间实际触发过两次,每次只花十秒就能恢复,给了运营团队充足的安全感。

4. 实测结果与踩坑复盘:数字好看,但坑也不少

4.1 上线两周的数据变化:成本、时延与准确率

先放结论,这是两周线上数据的对比。

表格里区分了改造前和改造后:

指标改造前改造后
单次提问平均大模型调用次数4.31.1
单次提问平均 Token 消耗约 2800约 700
端到端平均响应时延4.6 秒1.2 秒
工单类型判别准确率96.8%96.1%
路由正确率97.2%95.9%
账单成本(月度估值)基准价降至约 28%

准确率确实出现了一点下降,幅度在 1 到 1.3 个百分点之间。但这里有个重要背景:原来大模型做分类也不是百分百准确,它的错误率本身就是 3% 到 4%。我替换之后,新增的误差只有 1 个百分点左右,而且大部分落在“账号锁定”和“密码重置”这种相邻类型之间,对最终处理结果的影响没有想象中大。

用户实际能感受到的最大变化是速度。原来 4.6 秒的响应时间其实是有点尴尬的:说快不快,说慢又让人着急。降到 1.2 秒之后,整个体验从“等一下”变成了“即时反馈”,再加上我们前端做了流式展示,用户反馈是“问题刚发出去,回复就开始一个字一个字往外蹦了”。

4.2 第一次改造时我踩过的连环坑

这个方案不是一次到位,期间我踩过三个比较典型的坑,在这里展开说下,帮你绕开。

第一个坑是语料判断过拟合。第一版分类器训练时,我把全部历史工单都拿去训练了,结果模型把“时间”“姓名”这些无关字段当成了判断依据。测试的时候准确率有 98%,但一遇到新同事写的表述,立刻打回原形。后来改成只取固定几个关键特征字段,并且在数据清洗时优先保留问题描述部分的文本,准确率才稳定下来。这个教训是:分类器训练数据宁缺毋滥,要让它学到的是“语义”而不是“格式”。

第二个坑是阈值拍脑袋。我第一次设置的置信度阈值是 0.8,结果大约 30% 的请求都因为低置信度被甩给大模型,成本没省下来。后来我把阈值降到 0.7,误判率上升了 0.4 个百分点,但大模型调用量却下降了 40%。这里面有一条很典型的成本曲线:阈值每降低 0.05,大模型兜底率就会明显下降,但准确率也随之下滑。最终我通过统计验证集上的准确率变化曲线,选了 0.7 这个平衡点,留出了约 9% 的请求兜底空间。

第三个坑是规则层的正则冲突。关键词命中经常出现叠加问题,比如“重置密码”和“账号锁定”两条规则同时命中同一条工单。我最初的优先级是写死顺序,效果很差。后来改成命中后比较规则权值,权值一样时再走分类器决定。这样处理之后,规则层的冲突率从 5.2% 降到了 0.8%。

4.3 不可替代的那几次大模型调用,值得单独优化

改造完成后剩下的那次大模型调用也不是没有优化空间。我发现回复生成这个环节的开销,很大一部分是 Prompt 里塞了太多上下文。很多工单其实不需要完整的历史记录,只需要相关字段和分类结果。

我把给大模型的上下文精简了三分之一,指令也从“请根据以下对话历史生成回复”改成了“请根据工单类型和抽取的关键字段生成回复”,同时要求回复不超过 80 字。这个改动让单次回复生成的 Token 消耗直接降了一半。很多时候,大模型高消耗不是模型的问题,是输入输出设计的问题。

还有一个优化点是把回复模板和自定义内容分开。标准话术部分直接用模板渲染,大模型只负责生成个性化的补充说明。模板占比约为 60%,这意味着大模型每次只需要生成几十字的个性化内容,成本再次下降。

5. 这套方案的适用边界:什么场景能抄,什么场景不能硬套

5.1 能直接复用的场景特征

这套方案并非万能,它高度依赖一个前提:你的 Agent 环节里存在大量“固定枚举输出”的调用。归纳一下,直接适合改造的场景有三个特征:

第一个特征是输出空间有限且可枚举。比如问题类型固定 30 类,路由目标固定 8 个科室,字段列表固定 10 个。只要满足“输出结果能预先列全”,分类器就能胜任。反之,如果你的 Agent 需要开放式创意回复,那就不在这套方案的讨论范围内。

第二个特征是历史数据充足且带标签。训练分类器需要历史样本,样本越多、标注越规范,效果越好。如果你是从零开始做新项目,没有历史工单数据,那可能需要先跑一段时间大模型方案,积累数据后再改造,不要一开始就上分类器。

第三个特征是错误代价可容忍或有兜底。工单类型分错可以转人工重新分发,但如果是医疗诊断、法律建议这类场景,错误代价极高,分布式分类器需要非常谨慎,我个人的建议是这类场景不要轻易把大模型从主链路上去掉。

5.2 建议保留大模型调用的几种情况

有几类调用我是强烈建议继续使用大模型的。首先是情感分析类的任务,尤其是用户情绪已经激化,需要重点安抚的场景。分类器对“愤怒”和“失望”的区分经常不到位,但大模型结合上下文可以给出更合理的应对策略。

然后是多级推理任务,比如“如果 A 数据不一致且用户近期修改过配置,那可能是同步延迟或配置回滚”,这种多条件组合判断,轻量模型处理起来相当吃力。

最后是目标用户对回复质量要求极高的场景。如果你们的用户群对 AI 回复的“温度”有要求,那回复生成这个环节只能依赖大模型。省掉的应该是前置路由那些“决策型调用”,而不是输出型调用。

我的原则很简单:把大模型当作“知识工作者”而不是“前台接待”。知识工作者我们请来解决复杂问题,前台指路这种流程化工作没必要占用他。

6. 顺带分享一点关于模型选择的心得

6.1 学习如何挑一个“不会说话但可靠”的模型

我经常被问到一个问题:你是怎么选这个模型的?这里有一个可复用的选择思路。你不需要直接上最贵最大的模型,而是列出几个候选的轻量模型,分别做同一批分类测试,比较它们在验证集上的表现。

我当时的候选集合有三个,分别是不同规模的文本表示模型。最终选的是一个体积适中、量化之后 90MB 的版本,因为在验证集上它的准确率和 F1 分数与更大的模型相差不到 0.5%,但 CPU 推理速度快了将近三倍。其实这类文本分类任务,模型的瓶颈普遍不在参数规模,而在训练数据的质量和数量上。有时换一个更干净的训练集,比换一个更大的模型收益更高。

6.2 定期做模型复检,不然准确率会悄悄退化

分类器上线后不是一劳永逸。线上用户的表达方式一直在变,今天新来了一个业务线,明天出了一个新产品,新词和新型问题会不断出现,模型的准确率会缓慢下滑。我建议固定一个两周一次的复检节奏:每两周从线上抽一批新样本,人工标注后做一轮增量微调。

另外监控指标不要只盯着整体准确率,分类的是每个类的准确率。我最初只看了整体指标,结果有段时间“退款流程”类准确率跌到 82% 却没有被发现,因为其他高频类把它拉平了。后来我在监控面板上加了按类型拆分的准确率趋势,这类问题很快就暴露了。

整体的优化逻辑很简单:各类问题分开观察,才不会让低频类的问题悄悄拖垮整体质量。

这套改造做下来,我自己最大的收获是:Agent 优化很多时候并不是越高级越好,关键是想清楚每一层该承担什么职责。大模型是集团军,但不是每件小事都要派集团军出场。如果你也在做 Agent,建议先拉一拉自己的调用日志,看看多少次调用是在做分类和匹配,那部分可能就是你最省钱的地方。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询