Agent意图识别分层架构:从规则到大模型的完整设计与落地
引言
在构建智能Agent的过程中,意图识别是一个核心模块。面对用户的自然语言输入,系统需要快速、准确地判断用户的意图,并将其路由到相应的处理逻辑。然而,在实际生产环境中,意图识别面临着多重挑战:既要保证高频请求的低延迟和低成本,又要处理模糊表达和长尾需求,还要确保高风险操作的零容错。
许多开发者容易陷入"非此即彼"的思维定式:要么依赖规则引擎,要么押注机器学习模型。事实上,成熟的工业级方案往往是分层架构——让规则、小模型、大模型各司其职,协同工作。
本文将详细介绍这套分层架构的设计思路、实现要点以及关键指标的度量方法。
一、分层架构概览
一个完整的意图识别系统应包含三层,请求依次流过,越靠前越快、越便宜、越确定。
+------------------+ | 规则引擎 | <- 确定性、高风险、边界清晰 +------------------+ | (未命中) +------------------+ | 小模型分类器 | <- 固定意图、高并发、有标注数据 +------------------+ | (低置信度) +------------------+ | 大模型兜底 | <- 模糊表达、复杂语义、长尾请求 +------------------+| 层级 | 核心职责 | 适用场景 | 优势 |
|---|---|---|---|
| 规则引擎 | 处理确定性、高风险、边界清晰的请求,命中后直接返回 | 敏感词拦截、黑名单校验、查余额等固定指令 | 极低时延、可审计、安全边界 |
| 小模型分类器 | 处理固定意图集合中有标注数据且高并发的请求 | 高频同义表达(如"余额多少?"“还剩几个钱?”) | 性价比高、速度快 |
| 大模型兜底 | 处理模糊表达、复杂语义及低置信度的长尾请求 | 用户表达含糊、全新意图、多条件复合查询 | 灵活性最高 |
二、各层详细设计
2.1 规则引擎 —— 系统的安全底线
很多人认为规则是"笨办法",但在生产系统中,规则恰恰是确定性的保障。
核心作用:
- 极低时延(通常 < 10ms),无需等待模型推理
- 命中原因清晰,可审计、可追溯
- 高风险操作前置拦截,避免模型误判造成事故
典型场景:
- 敏感词过滤:"把钱全部转走"直接拒绝
- 身份校验:未认证用户不允许执行转账
- 固定指令:"查余额"直接路由到余额查询接口
工程化要点:
- 规则必须版本化管理,支持热加载和回滚
- 每条规则应有唯一ID,便于监控和日志审计
- 设置规则命中率告警,防止规则过宽或过窄
# 伪代码:规则引擎classRuleEngine:def__init__(self):self.rules=load_rules_from_config()# 版本化配置defmatch(self,user_input:str)->Optional[Intent]:forruleinself.rules:ifrule.pattern.search(user_input):log_rule_hit(rule.id,user_input)# 可审计returnrule.intentreturnNone2.2 小模型分类器 —— 主流请求的性价比核心
小模型(如BERT-small、DistilBERT、FastText)擅长处理同一意图的不同表达。例如:
- “卡里还剩多少钱?”
- “余额多少?”
- “查一下账户余额”
这些表达各不相同,但意图都是"查余额"。如果用规则穷举,写一百条也写不完;而小模型可以泛化学习。
适用前提:
- 意图集合稳定:不能频繁新增或删除意图
- 高质量标注数据:每类意图至少几百条样本
- 高并发、低延迟:P99延迟需控制在100ms以内
- 持续监控漂移:线上数据分布变化会导致效果下降,需定期重训或增量学习
部署方式:
- 模型转换为ONNX格式,利用CPU/GPU推理
- 使用缓存减少重复计算(相同输入可直接命中缓存)
# 伪代码:小模型分类器classSmallModelClassifier:def__init__(self,model_path:str):self.session=ort.InferenceSession(model_path)defpredict(self,user_input:str)->Dict[str,float]:input_ids=tokenize(user_input)outputs=self.session.run(None,{"input_ids":input_ids})probs=softmax(outputs[0])return{intent:probforintent,probinzip(INTENT_LIST,probs)}2.3 大模型兜底 —— 最后的防线
当规则和小模型都无法确定意图时(如低置信度、模糊表达、全新场景),交由大模型处理。
大模型的优势:
- 强大的语义理解能力,能处理复杂的上下文
- 可主动向用户发起意图澄清
- 能够处理未见过的长尾意图
常见做法:
- 调用LLM API(如GPT-4、Claude、混元等)进行意图理解和生成回复
- 设计Prompt模板,引导模型输出结构化意图
- 结合few-shot示例提高准确率
注意事项:
- 大模型延迟较高(通常 > 1s),不适合做主路径
- 成本远高于规则和小模型,因此流量占比应控制在10%以内
- 需要设置超时熔断机制,防止模型挂起导致系统阻塞
三、低置信度处理策略
低置信度场景是整个系统的关键风险点。核心原则是:
意图识别的终点不是猜中标签,而是避免错误的工具调用。
3.1 置信度校准
模型输出的概率值(如90%)并不等于真实准确率。需要通过校准方法(如Platt Scaling、Isotonic Regression)将模型输出映射到真实概率空间。
3.2 意图澄清
当Top1和Top2置信度接近时(差值 < 0.2),不应硬选,而应向用户发起澄清:
用户:帮我把那个转过去 Agent:请问您是想【转账】还是【转交文件】?3.3 超时降级
每层都需要设置超时时间和熔断阈值。例如小模型推理超过200ms则直接跳过本层,交给大模型处理;大模型超过5秒则返回"暂时无法理解,请稍后再试"。
3.4 安全默认行为
对于任何低置信度的工具调用请求,系统应默认拒绝执行,并向用户解释原因。宁可让Agent说"我不确定",也绝不能静默执行可能错误的操作。
# 伪代码:路由决策defroute_intent(user_input:str,timeout=500ms):# 1. 规则层rule_result=rule_engine.match(user_input)ifrule_result:returnexecute_with_safety_check(rule_result)# 2. 小模型层(带超时)try:sm_probs=small_model.predict_with_timeout(user_input,timeout)top1,top2=get_top_two(sm_probs)iftop1.confidence>0.9and(top1.confidence-top2.confidence)>0.2:returnexecute(top1.intent)eliftop1.confidence>0.6:# 低置信度,走大模型passelse:returnclarify_with_user(top1,top2)exceptTimeoutError:# 超时降级returnfallback_to_llm(user_input)# 3. 大模型兜底llm_result=llm_complex_understanding(user_input)returnllm_result四、效果评估指标
衡量分层架构的价值,需要关注以下三个核心指标:
4.1 分意图准确率
不要只看总体准确率。总体95%可能隐藏着某个关键意图只有70%的事实。应统计每个意图的精确率、召回率和F1值。
4.2 误执行率
最关键的指标。指错误调用工具的比例。分层架构的目标是将误执行率降到最低:
- 规则层:理论上为0(严格匹配)
- 小模型层:< 1%
- 大模型层:< 5%(但可通过澄清降低实际影响)
4.3 延迟与成本
分层架构的经济价值体现在:
| 层级 | P99延迟 | 单次成本 | 预期流量占比 |
|---|---|---|---|
| 规则层 | < 10ms | 几乎为0 | 30% |
| 小模型层 | < 100ms | 低 | 60% |
| 大模型层 | < 2s | 高 | 10% |
相比全量使用大模型,分层架构可将整体成本降低80%以上,同时显著提升响应速度。
五、总结
- 规则守住底线:确保安全性和可审计性
- 小模型覆盖主流:高效处理高频请求,控制成本
- 大模型兜住长尾:处理模糊和复杂场景
三者通过路由逻辑串联,形成一套兼顾准确率、延迟、成本和风险的系统。在设计时,务必重视低置信度处理策略,避免因错误执行导致严重事故。