
1. 引言“Agent意图识别怎么做”面试官抛出这个问题时很多候选人脱口而出“用大模型啊把用户问题扔给GPT让它分类就行了。”这句话基本就把自己送走了。意图识别是Agent系统的入口也是决定整个对话流程走向的“第一道关卡”。如果面试官只想知道“用哪个模型”他根本不会问这个问题。他真正想考察的是在真实的生产环境中你如何设计一个高可靠、低延迟、可维护的意图识别方案本文将从一个真实的面试场景出发拆解意图识别的核心挑战并给出从简单到复杂的完整技术方案。2. 面试官的潜台词当面试官问“Agent意图识别怎么做”时他其实在考察以下几个维度场景理解你是否清楚意图识别在Agent架构中的位置和作用方案选型你是否了解不同方案的优缺点并能根据业务场景做出合理选择工程落地你是否考虑过延迟、成本、准确率、冷启动、多轮对话等实际问题异常处理当用户输入模糊、多意图、或不在预设范围内时你的系统如何应对一句话回答“用大模型”等于告诉面试官你只看到了冰山一角。3. 意图识别的核心挑战在生产环境中意图识别远不止“分类”这么简单。以下是几个最常见的挑战3.1 意图模糊与歧义用户说“我想查一下”可能是查订单、查余额、查物流也可能是查天气。同一个表达在不同上下文中含义完全不同。3.2 多意图交织“帮我取消订单再重新下单顺便看看有没有优惠券。”——一句话包含三个意图如何拆解3.3 未知意图Out-of-Domain用户问了一个你系统从未设计过的意图比如在客服系统里问“你们公司股票代码是多少”系统不能崩溃也不能胡乱匹配。3.4 冷启动与意图迭代新业务上线时没有历史数据训练模型业务迭代时新增意图如何快速上线4. 方案一基于规则与关键词最基础但最可靠对于意图明确、表达固定的场景规则匹配是最简单、最可控的方案。4.1 关键词匹配INTENT_KEYWORDS{查订单:[订单,物流,快递,到哪了],退换货:[退货,换货,退款,不想要了],咨询客服:[人工,客服,转人工],}defrule_based_intent(text:str)-str:forintent,keywordsinINTENT_KEYWORDS.items():forkwinkeywords:ifkwintext:returnintentreturnunknown优点零成本、零延迟、完全可控。缺点无法处理同义表达、无法泛化、维护成本随意图数量线性增长。4.2 正则表达式对于更复杂的模式如订单号、日期、金额正则表达式是更好的选择。importredefextract_order_intent(text:str)-dict:# 匹配“查询订单20240726”patternr查询订单(\w)matchre.search(pattern,text)ifmatch:return{intent:查订单,order_id:match.group(1)}returnNone适用场景FAQ机器人、简单指令系统、作为其他方案的兜底。5. 方案二基于传统机器学习小样本、可解释当意图数量增多10-50个且有一定标注数据时传统ML方案是性价比最高的选择。5.1 流程文本向量化使用TF-IDF、Word2Vec或Sentence-BERT将用户输入转为向量。分类器使用逻辑回归、SVM或随机森林进行分类。阈值控制设置置信度阈值低于阈值则归为“未知意图”。5.2 代码示例fromsklearn.feature_extraction.textimportTfidfVectorizerfromsklearn.linear_modelimportLogisticRegression# 假设已有标注数据train_texts[查一下我的订单,我要退货,转人工]train_labels[查订单,退换货,咨询客服]vectorizerTfidfVectorizer()X_trainvectorizer.fit_transform(train_texts)classifierLogisticRegression()classifier.fit(X_train,train_labels)defml_intent(text:str,threshold:float0.7)-str:Xvectorizer.transform([text])probaclassifier.predict_proba(X)max_probmax(proba[0])ifmax_probthreshold:returnunknownreturnclassifier.classes_[proba[0].argmax()]优点可解释性强、训练快、适合小样本场景。缺点需要标注数据、对语义泛化能力有限、难以处理复杂句式。6. 方案三基于大语言模型灵活、泛化强这是目前最主流、也是面试官最想听你深入聊的方案。6.1 Prompt Engineering最直接的方式通过Prompt让LLM输出意图分类。importopenaidefllm_intent(text:str,intents:list)-str:promptf 你是一个意图识别系统。请从以下意图列表中选择最匹配的一个{, .join(intents)}用户输入{text}请只输出意图名称不要输出其他内容。 responseopenai.chat.completions.create(modelgpt-4o-mini,messages[{role:user,content:prompt}],temperature0,)returnresponse.choices[0].message.content.strip()优点零样本、泛化能力强、能处理复杂表达。缺点延迟高、成本高、输出不稳定幻觉、依赖API。6.2 Function Calling推荐更优雅的方式利用LLM的Function Calling能力让模型“调用”意图函数。intent_functions[{name:query_order,description:用户查询订单状态,parameters:{type:object,properties:{order_id:{type:string,description:订单号}}}},{name:return_product,description:用户申请退换货,parameters:{type:object,properties:{reason:{type:string,description:退换货原因}}}}]deffunction_calling_intent(text:str)-dict:responseopenai.chat.completions.create(modelgpt-4o,messages[{role:user,content:text}],toolsintent_functions,tool_choiceauto,)tool_callresponse.choices[0].message.tool_calls[0]return{intent:tool_call.function.name,params:json.loads(tool_call.function.arguments)}优点结构化输出、天然支持参数提取、可控性高。缺点仍依赖LLM、需要设计好function schema。6.3 小模型微调平衡方案对于延迟和成本敏感的场景可以微调一个轻量级模型如BERT、TinyBERT、Qwen2.5-0.5B。fromtransformersimportAutoTokenizer,AutoModelForSequenceClassificationimporttorch# 加载微调后的模型model_nameyour-fine-tuned-intent-modeltokenizerAutoTokenizer.from_pretrained(model_name)modelAutoModelForSequenceClassification.from_pretrained(model_name)deffinetuned_intent(text:str)-str:inputstokenizer(text,return_tensorspt,truncationTrue,max_length128)withtorch.no_grad():outputsmodel(**inputs)pred_idoutputs.logits.argmax().item()returnid_to_intent[pred_id]优点延迟低毫秒级、成本低、可离线部署。缺点需要标注数据、需要训练和部署流程、泛化能力弱于大模型。7. 生产级方案混合架构在实际系统中没有人只用一种方案。一个成熟的意图识别系统通常是多层漏斗架构用户输入 │ ▼ ┌─────────────┐ │ 规则匹配 │ ← 最快、最便宜处理高频固定表达 │ (关键词/正则)│ └──────┬──────┘ │ 未命中 ▼ ┌─────────────┐ │ 小模型分类 │ ← 处理常见意图毫秒级响应 │ (BERT微调) │ └──────┬──────┘ │ 置信度低 ▼ ┌─────────────┐ │ 大模型兜底 │ ← 处理复杂、模糊、未知意图 │ (LLMFC) │ └──────┬──────┘ │ ▼ ┌─────────────┐ │ 未知意图处理 │ ← 引导用户、转人工、记录日志 └─────────────┘7.1 关键设计原则快慢分离90%的请求在规则和小模型层解决只有10%的复杂请求才走LLM。置信度阈值每一层都设置阈值低于阈值则降级到下一层。兜底策略所有层都未命中时必须有优雅的兜底如“抱歉我没有理解您的意思请换种说法”或转人工。日志与迭代所有未命中或误判的案例都要记录用于后续优化模型或补充规则。8. 面试加分项多轮对话中的意图识别面试官可能会追问“如果用户在多轮对话中逐步补充信息意图怎么变”8.1 意图继承与修正# 第一轮用户:我要退货意图:退换货# 第二轮用户:订单号是12345意图:退换货(继承上一轮意图提取参数order_id)# 第三轮用户:算了我不退了帮我查一下物流意图:查订单(意图修正)实现方式维护对话状态dialog_state记录当前意图和已提取参数。每轮输入先判断是否意图切换还是补充参数。可以使用LLM判断“用户是否改变了主意”。8.2 槽位填充Slot Filling意图识别通常与槽位填充配合使用。例如“查订单”意图需要提取order_id槽位。classIntentSlotFilling:def__init__(self):self.current_intentNoneself.slots{}defprocess(self,user_input:str):# 1. 意图识别new_intentdetect_intent(user_input)ifnew_intent!self.current_intent:# 意图切换重置槽位self.current_intentnew_intent self.slots{}# 2. 槽位填充extractedextract_slots(user_input,self.current_intent)self.slots.update(extracted)# 3. 检查是否所有必填槽位已填满ifall_slots_filled(self.current_intent,self.slots):returnexecute_intent(self.current_intent,self.slots)else:returnask_for_missing_slots(self.current_intent,self.slots)9. 总结回到面试官的问题“Agent意图识别怎么做”现在你可以这样回答“意图识别是Agent系统的入口我通常会根据业务场景设计一个多层混合架构。对于高频固定表达用规则匹配对于常见意图用微调的小模型对于复杂模糊的输入用LLM的Function Calling兜底。同时我会设计置信度阈值、未知意图处理和对话状态管理确保系统在真实生产环境中的可靠性。另外所有未命中的案例都会记录用于持续迭代优化。”这样的回答才是一个有深度、有工程思维的候选人该有的样子。下次面试官再问这个问题别再一句话把自己送走了。