作者:老陈
地址:
https://zhuanlan.zhihu.com/p/1994124775983970078
https://zhuanlan.zhihu.com/p/1994409280238012063
经授权发布,如需转载请联系原作者
01 结论先行
在做垂直领域 Agent 落地时,踩到的最大坑不是“模型不够聪明”,而是不够稳定。 同样的输入,在多轮对话和复杂上下文(RAG、多工具返回、多步骤流程)下,模型会出现:
该调用工具不调用
调用了但参数不对
甚至在多轮对话中直接编造工具返回结果
对于“要端到端自动跑通”的业务流程来说,这类不确定性会导致整体一次通过率很难过 50%。
最初尝试过用更大的模型(如 Qwen3 235B、DeepSeek V3.1 671B)配合 Prompt/Context Engineering 去“优化流程”,但实践中发现:
当上下文越做越长、链路越做越复杂时,优化很难系统化复用
在某条路径上变好,不保证在更多轮次、更多工具返回格式、更多输入变体上依然稳定。
因此尝试了新的思路:用参数更小、推理成本更可控的 Qwen3-8B,把关键能力(领域理解 + 工具调用契约)通过后训练固化进模型。
具体做法分两阶段:
SFT:先把垂直领域背景知识、业务流程、字段含义注入,让模型“懂业务”;
DPO:再专门对齐工具调用偏好(何时调用、调用哪个函数、参数怎么填、如何解读返回),让模型“守规矩”。
结果:
SFT 后工具调用指标短期并没有变好(甚至略降),但回答开始贴近业务领域;
在扩大 DPO 数据覆盖(从 v1 到 v2,数据集扩大到原来的 5X)后,工具调用相关指标从约 30% 级别提升到约 97%~99% 级别;
在多轮对话与“think/推理能力”上做抽查回归,未发现明显损坏。
训练资源: SFT 用 1 张 A800 80G,DPO 用 2 张 A800 80G,整体投入“中小团队可承受”。
推理资源: 1 张 A800 80G,训练和导出模型为Qwen3 8B + lora合并,fp16版本,未作量化。
核心经验:在垂直 Agent 场景,与其无限加码 Prompt/Context 工程去对抗漂移,不如用小模型做可控后训练,把工具调用契约写进模型参数里,它更可回归、更可版本化,也更适合工程落地。
02 开源模型更强了,为什么垂直 Agent 仍然难上线?
过去一年开源 LLM 的通用能力提升非常快,选择落地方案时,直觉是:选更大的基座模型,再加一点 Prompt Engineering、RAG 和流程编排,就能实现端到端自动化。但在垂直专业领域 + 多工具调用 + 多轮对话的 Agent 形态下,这条路经常会卡在“稳定性”上。
原因在于:垂直落地不是要做到“能聊会聊”,而是要做到“能稳定且准确执行”。系统对 LLM 的要求不是偶尔答对,而是持续满足三件事:
(1)该调用工具就调用:对陌生场景不能依靠幻觉凭空猜测;
(2)调用要严格正确:函数名、参数、类型、枚举值都要对,还能结构化输出方便解析;
(3)返回要稳定解读:工具返回一复杂,模型很容易被格式噪声带偏,导致同一条数据多次处理结论不一致。
而单纯依赖 Prompt/Context 工程会引入一个现实困境:
1. 为了“修补模型能力”,上下文会越来越长(多轮历史、RAG 片段、工具返回、流程状态……),这会带来指令衰减与注意力漂移,最终表现为“前几轮守规矩,后几轮开始乱来”。
2. 当你用流程去强行兜底(重试、校验、补充提示)时,系统复杂度上升,失败模式也会变得更随机,导致流程优化很难稳定复用。
在这样的背景下,我把目标从“把流程编排得更强”转成“把行为对齐得更稳”:用 8B 小模型做后训练,把领域语义与工具调用契约显式固化下来,让模型在复杂上下文里也能更像一个可控组件,从而真正支撑端到端流程自动化。
03 现有指标表
指标含义定义:
tool_call_accuracy:是否调用工具(与期望一致);若调用,则函数名与参数必须完全正确才算对(严格口径)。
tool_name_accuracy:在“模型发生工具调用”的情况下,函数名正确率。
tool_args_accuracy:在“模型发生工具调用”的情况下,参数与预期一致的比例。
response_quality:回答是否存在超短、结尾重复、或不匹配的 <think>标签等格式问题(值越高越好)。
表1:各训练阶段指标对比
阶段 | tool_call_accuracy | tool_name_accuracy | tool_args_accuracy | response_quality |
|---|---|---|---|---|
Baseline:Qwen3-8B(未训练) | 34.8% | 44.2% | 25.7% | 100.0% |
SFT 后 | 32.7% | 42.2% | 24.1% | 100.0% |
DPO v1 后(失败) | 32.3% | 40.1% | 23.2% | 100.0% |
DPO v2 后(数据集扩大 5X) | 97.3% | 99.3% | 96.4% | 100.0% |
表2:相对 Baseline 的变化
阶段 | tool_call_accuracy 变化 | tool_name_accuracy 变化 | tool_args_accuracy 变化 |
|---|---|---|---|
SFT 后 vs Baseline | -2.1 % | -2.0 % | -1.6 % |
DPO v1 后 vs Baseline | -2.5 % | -4.1 % | -2.5 % |
DPO v2 后 vs Baseline | +62.5 % | +55.1 % | +70.7 % |
下面用两组来自真实 MCP 服务环境的对话片段,展示在业务场景、输入内容、MCP 服务一致的情况下,出现的非常典型、且对端到端自动化极其致命的工具调用失败行为。
MCP 服务:URI 安全/ reputation 查询服务(支持 IP、域名、URL 等对象的信誉与安全信息查询)
业务背景:网络安全自动化运维。对不同 URI 资源进行分析,并根据查询结果进入后续不同处理流程(例如:是否升级为威胁处置、是否入库、是否需要人工复核等)
对比原则:同一套工具接口、同一类输入、同一条业务链路;差异仅来自模型(235B vs 671B)
评估重点不在于“模型答得像不像人”,而在于:Agent 是否遵守工具调用契约、是否能稳定地产生可追溯的执行链。一旦工具调用失真,后续推理再“顺滑”,也只是建立在错误事实上的幻觉链条。
04 Case 1(Qwen3-235B):多轮对话后“自我模仿”并编造工具结果,
逐步形成跳过调用的习惯
模型:Qwen3-235B
现象概述:在多轮对话的初期,模型表现正常,能够准确发起工具调用并解析结果。但随着对话轮数增加,Context 中积累了多个“发起调用 -> 获得工具调用结果并解读”的历史数据后,意外的现象发生了:在后续的对话中,模型不再发起真实的工具调用请求。相反,它基于之前的历史数据格式,凭空编造了一个工具查询结果,并基于该“伪造结果”继续做分析与决策。也就是说,它跳过了本应发生的真实工具调用。一旦出现一次幻觉式的伪造返回,模型往往会在后续轮次里延续这种模式,表现出一种“既定行为惯性”:不再调用工具,而是持续编造。这时候模型掉入了一种自回归陷阱。

分析:这是大模型在长上下文中典型的“路径捷径” (Shortcut Learning) 现象。模型“认为”自己已经掌握了工具返回数据的规律(格式正确),为了省事或基于概率预测,它直接跳过了Action步骤,输出了Observation。
典型失败特征
1. 格式像真的:返回结构、字段名、排版都高度模仿早期真实工具结果,让人第眼不易察觉。
2. 链路断点隐蔽:表面上 reasoning 是连续的,但在执行链路上,关键的“tool call 事件”消失了。
3. 错误会被放大:后续每一步分析、分类、升级处置决策,都会建立在这份“虚构询结果”上,导致不可控风险。
对业务的直接影响
不可审计:你无法证明“依据哪个真实查询结果做出决策”。
不可回放:重跑同一请求可能产生完全不同的链路。
不可上线:一旦进入自动化写库/处置动作,编造 tool result 的风险是硬性不可接受的。
05 Case 2(DeepSeek V3.1-671B):同输入多次运行行为链不同,结论与执行决策相反(解读逻辑不一致)
模型:DeepSeek V3.1-671B
现象概述:在本质相同的输入下进行两次调用,模型产生了不同的行为链(behavior trace):包括是否调用工具、如何引用工具返回、如何解释字段含义等环节都出现差异,最终导致结论相反、执行决策相反。对照两张截图可以看到:模型对工具返回的解读存在明显不一致,表现为逻辑跳步、证据使用混乱、推理链条自相矛盾。


典型失败特征:
1. 同一证据不同解读:对相同/类似字段的含义给出不同解释,或引用了不一致的键字段作为结论依据。
2. 推理链条漂移:前半段推理似乎遵循规则,但到关键决策点出现跳跃,导致最终动作选择相反。
3. 一致性缺失:对于需要批量处理 URI 的场景,这种“不稳定”会直接拉低端到端一次成功率,并显著增加人工复核成本。
对业务的直接影响
结果不可复现:类似输入重复处理,输出不一致,无法形成可依赖的自动化策略。
策略不可固化:你很难通过 Prompt/流程把“解读方式”稳定下来,因为漂移来自模型内部对结构化返回的理解不稳。