这道题问的是大模型意图识别输出格式不理想怎么优化,其实本质是同一个问题:怎么在模型自由生成的文本和我们要的结构化数据之间,搭一座桥。不是让模型学会写JSON,而是让它只在我们划定的输出空间里选择。
具体我会从三个层面来拆解,先说提示工程,这是最轻量、见效最快的。核心做法是给模型一个明确的格式模板,比如用###输出格式###把字段名、类型、可选值都写清楚。再给两三个[[Few-shot]]示例,而且示例里要包含推理过程,就是让模型先分析用户输入里的关键词,再输出结构。举个例子,用户说“我要退款,订单号是12345”,你让模型先写一句分析“用户提到退款和订单号,属于售后意图”,再输出JSON。这样能大幅减少跳步导致的格式错乱。
但提示工程有个明显的边界:它管不了模型生成的随机性。同一个提示,temperature高一点就可能多出个逗号或者字段名写错。所以第二层是解码控制,说白了就是用参数和API特性把输出空间锁死。最简单的做法是把temperature调到0.1以下,top_p用0.9,减少格式变异。如果模型支持JSON Mode,直接强制输出合法JSON。更推荐的是[[Function Calling]],你把意图定义成工具函数,slot作为参数,模型只负责填充参数,根本不生成自由文本。这在小红书这类场景里非常实用,因为用户query短且意图明确,Function Calling几乎零格式错误。
第三层是微调,适合前面两层兜不住、或者需要处理大量边界情况的时候。微调的目标不是让模型变聪明,而是让它见过各种格式错误。构造数据时,正样本要覆盖口语化输入、省略主语、多意图等复杂情况;负样本要加入字段缺失、类型错误、多余字段的输出,让模型学会对比。用[[LoRA]]微调就行,r设到128,target modules选q_proj和v_proj,学习率2e-4,早停监控格式合法性指标。这里有个坑:微调数据里格式正确的样本和格式错误的样本比例,我一般控制在4:1左右,负样本太多会让模型过于保守,反而不敢输出。
所以真正落地的时候,我不会只押一个方案。我会用分层防御的思路:提示工程先兜底,保证90%的场景格式正确;解码控制作为第二道防线,用Function Calling或者低temperature锁死输出;微调提升处理极端输入的上限;最后再加一道后校验,JSON解析失败时用规则兜底,比如正则提取字段。这里有个前提:如果业务对格式的硬性要求极高,比如金融风控的意图识别,那Function Calling加后校验是必须的,提示工程只能当辅助。
另外,我最近在思考一个问题:当意图类别特别多、比如超过50个时,Function Calling的schema会变得很臃肿,模型反而容易混淆。这种情况下,是不是应该把意图识别拆成两步,先用模型粗分类,再针对子类用Function Calling提取槽位?这个取舍我还没完全想清楚,但感觉是个值得深挖的方向。
总的来说,我更倾向把格式优化看成一套组合拳,而不是依赖单一技巧。先分层防御,再根据业务场景调优,最后用后校验兜底。