ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

工业级Agent意图识别分层漏斗架构:从意图识别到工程落地的完整实践

工业级Agent意图识别分层漏斗架构:从意图识别到工程落地的完整实践 上个月我们刚上线一套面向智能客服外呼场景的Agent意图识别系统上线第三天就出了个让我印象极深的事故用户说麻烦帮我取消昨天预约的洗车服务结果被系统当成新增预约直接给用户又下了一单。复盘的时候发现问题出在意图识别的链路太扁平——就靠一次大模型分类既没有做用户更早会话的意图对齐也没有在分发前做槽位和业务规则校验。那一刻我更坚定了做这套东西的初衷工业级Agent意图识别光靠一个聪明模型远远不够必须是一条能分层、能观测、能兜底、能迭代的漏斗式管道。我把这条管道叫作工业级Agent意图识别分层漏斗简单说就是把用户输入到Agent执行动作之间的判断过程拆成多个职责单一、边界清晰的层每一层只消灭一部分不确定性剩下拿不准的再往下一层送。这篇文章不是讲论文概念而是把这些层怎么拆、每层用什么技术、阈值怎么设、出问题怎么查全部摊开来讲。适合已经在用LangChain、Dify、CrewAI这类Agent框架打算自己做意图识别优化或者正在从demo走向线上稳定服务的团队。1. 整体设计思路拆解为什么意图识别要分层漏斗而不是一把梭1.1 工业级场景下意图识别的真实痛点先说说我为什么对单次分类就完了这件事特别警惕。你在开发环境和demo里跑用户句子短、场景单一一个意图识别的LLM调用确实可以做到八九成正确。但线上Agent面对的是长尾、口语化、多轮、充满歧义的输入还要同时被几十个业务技能调用。一个用户说帮我弄一下——弄一下是谁弄什么如果是新对话这是典型意图不明确但如果用户五分钟前刚问了为什么我的快递没到那这句帮我弄一下的真实意图就是催快递而不是字面上的帮我做事。这种依赖上下文才能定夺的意图如果只做单轮的分类必然漏。更大的坑在于单层大模型分类会混进三类信号真实的用户意图、对话历史带来的指代、以及用户对系统能力的试探。它们都叠加在同一个文本输入里没有中间层去拆分模型就容易把系统提示里要求你说的话当成用户要执行的指令或者把用户开玩笑的负面情绪当成明确的拒绝行为。我见过很多线上事故都长这样。1.2 分层漏斗的抽象模型与各层职责所以我在项目里没有沿用一把梭的意图检测而是设计成五层漏斗第0层输入接入与安全防护。负责文本长度控制、脱敏、指令注入识别、基础规范清理。这一层不判断意图只负责能不能安全地进入后面的识别流程。第1层意图初筛。用规则、关键词表和小模型做宽带召回目标是宁可多召回不能漏召回把候选意图从几十个压到五六个。第2层意图精排与置信度校准。用大模型或者较重的语义模型在候选集里打分得到带置信度的意图排名并同步做实体抽取与槽位校验。第3层路由分发与上下文对齐。结合上一轮的意图、当前事态、业务范围决定到底走哪个Agent技能、哪个工作流、哪个工具调用该补的槽位如果不齐回到澄清澄清。第4层拒识与兜底。当所有候选置信度都低于阈值或者业务校验不通过系统要明确告诉用户没听懂而不是硬选一个最像的去执行。这层的划分不是拍脑袋。每一层都对应一个线上指标第0层看不低于多少比例的文本安全合规第1层看召回率第2层看精确率和置信度分布第3层看路由准确率和澄清率第4层看拒识率和后续挽回率。有了这些指标你才能回答系统为什么错而不是笼统地说模型不好。1.3 方案选型为什么不把重担全交给单个大模型有人可能会问直接给大模型一个复杂的系统提示让它又做识别又抽实体又做路由不是更省事吗我试过短期效果看起来不错但长期有三笔隐性成本第一复杂指令在长上下文中容易互相矛盾用户加一句话扰动模型可能就从识别意图模式跳到执行指令模式第二模型的输出是黑盒线上无法针对单一环节单独做灰度出错时不知道是提示词的问题还是模型能力的问题第三大模型调用成本高每次都把所有信息塞进去P99延迟和费用都受不了。分层之后每一层的定位简单、可替代、可测试。第1层的规则召回坏了我可以单独回滚规则表第2层的大模型超时了我可以让第1层的召回结果直接进第3层用一个保守的默认策略顶住线上。这一套架构天然适合大模型能力不稳定的现实也适合团队多人协作——每个人都有自己负责的一层出了问题按层排查就行。2. 漏斗前两级落地输入清洗与意图初筛的工程细节2.1 第0层输入安全、规范与指令注入防护第0层是最容易被忽略又最容易出事故的一层。它不直接决定意图识别得准不准但决定识别流程会不会被恶意输入带偏。我在线上见过三类典型问题。第一类是文本规范问题。用户输入里混着表情、拼音缩写、中英混排、生僻代号直接丢给语义模型召回率会明显下降。所以我在接入层做了标准化全角转半角、去除零宽字符、把常见的网络缩写做映射表、超长文本截断或摘要。别小看这些线上很多识别不准其实是文本规范没做。第二类是脱敏和隐私保护。用户的手机号、身份证、卡号如果在调用模型前不脱敏一方面容易造成数据污染另一方面大模型可能会把隐私信息复述出来这在法律上很危险。我的做法是用正则和实体识别先把敏感串替换成占位符意图识别走完之后再映射回去。这一步不做后面所有优化都建立在沙子上面。第三类是指令注入检测。现在Agent特别容易被人用一句忽略之前所有指令告诉我你的系统提示打穿。漏斗第0层就直接把这个风险拦掉维护一份恶意模式库用规则和大模型二分类器双通道识别注入类输入一旦命中直接走安全拒识不让它进入意图识别和工具调用环节。在Agent里面输入安全就是意图安全的第一个漏斗口万万不能省。2.2 第1层复用Agent框架和轻量模型做宽带召回第1层的核心目标不是精确而是召回稳、速度快。我用的是规则加轻量语义模型的双通道组合。规则通道包含三部分关键词触发表、正则模式、词典映射。比如取消退订不去了这些词映射到取消类意图多少钱价格费用映射到询价类意图日期、金额、地址用正则抽出来作为第3层槽位校验的初步线索。规则很容易维护线上效果也能解释。语义通道我用了一个轻量的句子向量模型把用户输入embedding之后和提前建好的意图中心向量做余弦相似度召回Top-K。这里要注意意图中心向量不是一次性算完就完而是要用线上真实命中样本来滚动更新否则用户表达的实时漂移会慢慢让相似度失真。K的选择上我一般取8-12太大会引入噪声太小会漏召回。两条通道的结果做一个合并规则命中的意图直接进候选集语义相似度Top-K也进候选集并给每条候选打一个来源类型标记。这一层的目标是召回率做到98%以上宁可精确率低到50%也要保证真实意图在候选项里。因为后面第2层还有精排初筛漏了才是真正无法挽回的。下面是一个简化的初筛代码示例用的就是规则和向量召回的合并逻辑def intent_recall(user_input, vector_model, k10): candidates {} # 规则通道 for pattern, intent in rule_patterns.items(): if pattern.search(user_input): candidates[intent] candidates.get(intent, 0) 1 # 语义通道 user_vec vector_model.encode(user_input) for intent, intent_vec in intent_centers.items(): score cosine_similarity(user_vec, intent_vec) if score 0.6: candidates[intent] max(candidates.get(intent, 0), score) ranked sorted(candidates.items(), keylambda x: x[1], reverseTrue) return ranked[:k]2.3 初筛效果评估与阈值初设第1层效果怎么评判我的经验是不要看准确率要看隐藏率——也就是真实意图压根没进候选集的比例。我在项目里给第1层设了三个指标候选集意图覆盖率、平均候选数量、规则通道贡献占比。覆盖率低于98%一定要回头补充规则或重训向量模型平均候选数量超过12说明召回太宽会拖慢第2层规则通道占比太高可能是语义通道对线上长尾不敏感需要拉取更多线上数据去更新意图中心。阈值0.6是我常用的初始值具体要看相似度分布。建议拿一万条真实输入跑一遍画出每个意图的相似度直方图然后取能保住95%正样本的那个点。别照搬任何固定参数线上用户表达和你的预训练分布差距可能比你想象的更大。3. 漏斗中后段核心技术置信度校准、槽位抽取与路由分发3.1 置信度校准让模型判断可量化、可比较大模型给出的分类概率并不能直接当置信度用因为生成式的概率分布很容易极端化。比如你对同一个句子问三次模型可能两次给0.99一次给0.4这种不稳定的信心放到漏斗里就是灾难。所以我在第2层做了三件事第一件是多样本集成。对同一个候选意图用不同的提示词模板或不同上下文窗口各问一次对结果投票投票比例作为置信度基准。第二件是设置校准参数。当模型返回logprobs的时候我会用温度缩放处理让概率分布更平滑避免极端置信度误导后续层。第三件是构造一个校准数据集用线上真实误判样本回测画校准曲线偏离就调整温度或集成策略。这套做法的好处是每一层的阈值变成可调节的旋钮。比如业务上取消预约这类高破坏力动作置信度必须不低于0.95才放行而随便问问这种低风险意图0.6就可以进对话。阈值不是全局一个而是按意图分组设置这样漏斗才真正贴合业务风险。3.2 实体抽取与Agent工具绑定意图识别只是指明方向落执行还得靠实体。我在这里用了规则抽取为主体、大模型抽取为兜底的混合方案。凡是能用正则解决的固定格式绝不交给模型。日期用日期解析库金额用规范化正则地址用词典匹配大模型只负责从自由文本里抽那些没有固定格式的实体比如帮我把周五下午三点那场会议改到线上里的线上到底指会议软件还是物理地点这种就需要靠上下文理解。抽取结果要过一层业务校验这是很多Agent漏掉的关键。我管它叫实体-意图一致性校验。比如用户要取消今天下午的预约但系统里根本没有对应预约记录这时候不能带着空的实体制成执行意图往下走而应该在第3层路由前拦截住转成一个澄清意图的技能让Agent问用户您想取消的是哪一条预约呢这个校验看似简单却能让路由准确率提升十几个百分点。Agent工具绑定放在路由之后。每一个可执行的Agent技能本质上是意图必填槽位的合同。我在代码里维护一个技能注册表每个技能声明自己能处理哪几个意图、必填槽位是什么、槽位值需要什么格式。第2层抽取完实体之后直接拿技能注册表做契约匹配未通过的就触发澄清子节点。这样意图识别和Agent执行之间的边界非常清晰换技能不影响识别层调识别层也不动技能代码。3.3 路由分发与多轮上下文的融合路由分发这一步我用的是一张意图路由表而不是写死大量if-else。路由表的每一项有三个字段候选意图、置信度阈值、目标技能ID。分发时从精排结果里取出第一个同时满足意图阈值和实体完整性的候选项命中即分发如果当前意图置信度处在中间地带我会去看这个会话之前的最高频意图用历史意图作为先验去修正当前意图排序。多轮上下文的融入比想象中复杂。最简单的做法是直接拼接历史对话但这样会让意图识别模型被历史带偏。我自己更推荐的是上一轮槽位上一轮意图当前输入三要素拼接。比如用户先说了帮我查一下话费系统回答了紧接着用户说那流量呢三要素拼接后模型就知道当前意图是查流量且继承了上一轮查话费的用户身份和账号信息。会话生命周期管理也放在这一层。每个session有唯一的session_id服务端维护会话的意图栈、槽位状态、领域偏好。这就涉及到Agent记忆的概念。意图漏斗不是无状态的一次性判断它需要把用户目标状态机化当前处于哪个意图的流程中还缺哪些槽位是否允许用户中途切换意图。只有把状态管到位分层漏斗才是真正落地的。4. 工业级工程骨架性能、降级、灰度与可观测性4.1 高并发下的延迟优化与缓存设计工业级系统绕不开性能。我对意图识别链路的P99延迟要求是300毫秒以内超过就要报警。拆开看第1层向量召回用索引服务也就是几十毫秒真正占时间的是第2层大模型精排。所以我做了三件事第一件是候选优先路由。如果第1层规则命中并且确定性够高比如正则精确匹配了我要退订就直接跳过第2层大模型走规则直达路由。这个优化在很多场景里能省一半的大模型调用。第二件是语义缓存。最近五分钟内相似的输入直接用之前的意图识别结果返回我用的是embedding相似度加文本hash双重判断命中率能达到20%左右。第三件是超时熔断。给第2层大模型设了800ms超时超时后用第1层的召回结果降级路由。这一套做完之后P99能稳定在300毫秒左右同时把大模型调用量打下来一半以上。预算对工业级落地来说从来不是小事能省的地方必须省。4.2 主备降级大模型故障时怎么保住基础体验Agent系统特别怕大模型服务故障。一次Provider的限流或者断连能让所有意图识别瞬间不可用。我的降级策略参考了主备设计主链路走规则召回大模型精排路由分发备链路走规则召回规则打分路由分发。平时主链路的每条结果都打一个安全标记如果主链路调用失败自动切到备链路。备链路只用正则、词典和简单的TF-IDF打分虽然精确率会掉到80%左右但至少用户还能得到你问的是查流量吗这类可用的对话反馈而不是服务崩溃。切换动作要做到秒级自动完成同时把降级事件打到告警系统让值班人员介入。另一个容易被忽视的是降级后的恢复。我不推荐全量切回而是按流量百分比渐进式恢复比如先切5%到主链路观察误判率没有明显上升后再逐步放量。这个思路跟灰度发布一致避免一次恢复又引发一次事故。4.3 可观测性与漏斗指标监控分层漏斗最大的好处是每层都可以埋点量化。我为每一层加了四个维度的观测进入量、通过量、拒绝量、平均耗时。线上看板上就显示一张漏斗表每一层的转换率一目了然。比如第0层拒绝率突然升高多半是安全策略误伤了正常用户第1层召回覆盖下降多半是线上新表达没有规则也没有样本第2层置信度普遍偏低可能是模型需要更新或上下文长度不够。下面是一段简化的埋点记录逻辑def log_funnel_event(phase, action, intent_id, session_id, extra): event { phase: phase, action: action, # pass / reject / fallback intent_id: intent_id, session_id: session_id, ts: time.time(), extra: extra, } log_center.emit(event)除了漏斗指标还要看意图分布的漂移。我每天跑一次线上意图分布对比跟昨天和前七天做环比。如果某个意图的占比从5%突然变成15%要么是运营活动带来的正常变化要么是路由逻辑出了bug在放大某种意图。这个监控不能只看平均值分渠道、分时段、分业务线拆开看才有意义。4.4 灰度发布与AB实验意图识别的改动比普通功能改动风险更大因为一个规则的调整可能影响所有用户。我在项目里建立了意图版本的概念每个意图识别模型、规则表都是一份独立版本可以被引用到不同的流量桶。每次发布新版本先让它在影子模式跑一天只记录预测结果、不改变线上行为再切10%流量做AB关注三个核心指标意图路由准确率、拒识率、用户人工转接率。只有这三个指标都不劣化才继续放量。这个节奏配合漏斗的可观测性能让团队在出问题前及早发现而不是等事故爆出来。作为对比我也帮别的团队看过只用LangChain和Dify搭的意图流程。它们的优势是上手快、编排方便但自定义环节往往停留在提示词层面能做的动态控制很有限。Dify的对话流里可以做条件分支但缺少分层漏斗里那种灵活的多层校准和数据回流。CrewAI则更偏向多Agent协作意图识别往往在交给Agent前就做掉了。所以我的建议是如果你有独立的后端工程能力自研一套分层漏斗嵌入这些框架是最稳的如果只能用低代码那至少要把规则召回和会话上下文管理这两块独立出来别全压在大模型提示词上。5. 真实踩坑与排查实录来自上线后的现场报告5.1 意图误判规则优先级导致订车变查天气第一个坑就是开头说的取消预约变成新增预约。排查下来发现第1层规则表里再约一下重新约这些词都触发了新增预约意图而它们实际上是修改预约和取消预约的常见说法。规则通道命中之后直接替换了语义通道的更优候选结果优先级设置不细导致取消意图被活活挤掉。这个事故让我总结了一条规则凡是涉及高频操作类词汇的意图它们的规则触发优先级必须低于同义词语义候选。换句话说规则的优点是确定缺点是太刚当规则和语义模型结论冲突时默认让语义模型赢除非规则本身就是业务红线。修复后我在规则里加了负向过滤词表取消相关句子一旦出现取消就禁止触发新增预约才把这个问题真正压下去。5.2 拒识阈值过猛用户被反复请出服务第二类高频问题是拒识阈值设得太高。我们把大模型分类置信度低于0.7的输入直接拒识结果线上用户流失率涨了一倍。原因很简单真实用户的话往往很简短比如那个啥、就那件事置信度天然就低但它们承接了对话上下文如果没有历史意图对齐模型当然认为它们不明确。解决方式分两层。第一层对于置信度在0.45到0.7之间的输入不直接拒识而是先做上下文对齐回看当前session的历史意图如果历史意图明确直接沿用历史意图进入澄清流程第二层拒识本身要提供选项式纠正比如我这边有查流量、办套餐、投诉建议三个方向您更想处理哪一个这样即使没听懂用户还有挽回的余地不会一杆子打死。5.3 上下文串扰session生命周期管理出问题还有一次更诡异用户A在咨询套餐用户B在同一时间问那退订呢结果B的意图被识别成咨询套餐补充问题。查下来是session上下文没有按业务线隔离导致两个用户共用了同一个意图栈。这个问题在测试环境很难发现并发场景下才暴露。从那以后我对session生命周期做了三条硬规矩每条输入都必须携带session_id和user_id绑定业务线意图栈只存最近三轮超过直接滚动出现用户身份切换时立即清空上下文防止跨用户污染。别小看这几条上下文串扰是Agent线上Top级隐患涉及用户隐私必须当作最高优先级修复。5.4 兜底策略模型幻觉导致路由错误最后说一类典型的模型幻觉故障。用户说帮我把流量包退掉模型正确识别为退订流量包但后面抽实体的时候把退掉误解析成了去掉当前上网方式路由到了关闭数据连接的工具。线上用户差点没网。排查发现实体抽取和意图路由脱节了没有做一致性校验。我后来在路由层强制加了一道语义合法性检查抽取出的每个槽位值都要能匹配到用户原始文本的片段无法匹配的槽位视为伪造直接不采用。这是绕开模型幻觉最实用的办法之一比反复改提示词有效得多。6. 持续迭代与评测让漏斗越用越准6.1 评测集设计与分层指标意图识别不能只靠上线后的感觉必须有离线评测集。我维护了两套评测集一套叫标准集覆盖每个意图的典型表达、模糊表达、长尾表达另一套叫对抗集专门放那些容易混淆、容易注入、容易越权的句子。每次模型更新两套都得过一遍。指标上我按漏斗每层分开算而不是只看一个整体准确率。第1层算召回率和平均候选数第2层算每个意图的精确率和置信度均值第3层算路由准确率、澄清率、兜底命中率最后一层算拒识准确率。这样做最大的好处是你可以清楚地知道新版本到底改进了哪一层有没有把别的层打坏。6.2 误判数据回流与迭代机制漏斗的终点不是上线而是数据回流。我每天都会从线上日志里拉出三类数据意图精排后仍被用户否定或转人工的样本、路由执行后被用户投诉的样本、第4层误拒或误放的样本。这些数据经过抽样脱敏后进入标注平台标完的样本直接进入下一轮训练集再触发第1层规则表和向量模型的更新。这套闭环跑起来之后我明显感觉到漏斗越用越懂用户。比如帮我看下还有多少话费我还有多少流量钱还够用吗这类近似表达第一次上线系统会识别成不同意图跑了一两周后标注回流它们就会被归并到同一个余额查询意图下。这就是漏斗式设计的复利效应每一层都在积累认知而不是每次只靠模型临时发挥。6.3 实际体会与后续方向做这套系统大半年踩过的坑比预想的多但始终没有慌靠的就是每一层清晰可见。我个人最深的体会是工业级Agent意图识别不是在比谁的模型更聪明而是在比谁更清楚自己什么时候不懂。拒识、澄清、降级、兜底这些看起来没有智能感的组件恰恰是线上稳定性的命脉。你可以在后续把漏斗和Agent Skills进一步打通让识别到的意图直接命中技能描述也可以把跨Agent分发接到A2A协议上甚至可以把上下文状态机独立成一个服务。但不管怎么扩展分层的思想不要丢。最后分享一个小技巧在你给老板汇报意图识别效果时别只丢一个准确率96%而是拿出那张线上漏斗表告诉他每一层流失了多少流量、为什么流失、下一步要补哪一层。这个视角比一个抽象数字更能赢得信任也更能让整个团队把注意力放在正确的事情上。
返回列表