Agent 意图识别怎么做?面试必会的 4 种方案深度解析
发布时间:2026/10/7 11:52:22 作者:尧图编辑部 阅读量:1,286

目录一、为什么意图识别是 Agent 的核心 意图识别为什么难二、四种方案总览三、方案一结构化 Function Calling3.1 原理3.2 代码实现3.3 优点3.4 局限四、方案二提示词分类4.1 原理4.2 代码实现4.3 进阶思维链分类4.4 优点4.5 局限五、方案三RAG 分类5.1 原理5.2 代码实现5.3 关键设计要点工具描述怎么写Top-K 怎么选用什么向量模型5.4 优点5.5 局限六、方案四模型微调6.1 原理6.2 数据准备6.3 训练代码LoRA 微调6.4 推理部署6.5 优点6.6 局限七、四种方案横向对比八、选型决策框架 实战经验混合方案九、面试高频问题与回答问题 1说说 Agent 的意图识别有哪些方案问题 2工具数量很大几百上千时怎么办问题 3Function Calling 和提示词分类有什么区别问题 4意图识别准确率怎么提升问题 5微调方案的冷启动问题怎么解决十、总结与实践建议核心要点回顾实践建议趋势展望一、为什么意图识别是 Agent 的核心Agent 的本质是感知→决策→执行而意图识别就是决策环节的灵魂——它决定了 Agent 该调用哪个工具、走哪条流程、返回什么结果。如果你正在准备大模型相关面试或者正在搭建一个 AI Agent 系统意图识别Intent Recognition是你绕不开的核心能力。它解决的是一个看似简单实则复杂的问题用户说了一句话Agent 怎么知道用户到底想干什么举个例子用户输入帮我查一下北京明天的天气Agent 需要识别出意图查询天气不是闲聊、不是翻译、不是代码生成实体地点北京时间明天对应工具调用天气 API参数提取city北京, date2026-10-07看起来很简单但当你有几十上百个工具、用户表达方式千差万别时这就成了一个相当有挑战的技术问题。小哲讲大模型面试这个视频就系统梳理了 4 种主流方案——这也是面试中高频被问到的知识点。意图识别为什么难表达多样性同一意图有无数种说法查天气/明天会下雨吗/北京冷不冷意图重叠一句话可能包含多个意图查天气并订机票歧义性同一句话在不同上下文意图不同苹果→水果 or 公司冷启动新工具加入时没有标注数据可用规模化从 10 个工具到 1000 个工具准确率怎么不掉二、四种方案总览视频系统梳理了 4 种从简单到复杂的意图识别方案每种方案适用的场景和成本差异巨大┌────────────────────────────────────────────────────────────────────────┐ │ Agent 意图识别 4 种方案按复杂度递增 │ ├────────────────────────────────────────────────────────────────────────┤ │ │ │ 方案一 方案二 方案三 方案四 │ │ 结构化FC 提示词分类 RAG分类 模型微调 │ │ ────── ────── ────── ────── │ │ 难度★ 难度★★ 难度★★★ 难度★★★★ │ │ 成本低 成本低 成本中 成本高 │ │ 工具数≤30 工具数≤50 工具数≤500 工具数∞ │ │ │ │ 原理让大模型 原理用提示词 原理用RAG检索 原理用标注 │ │ 直接选择工具 模板做分类 相关工具再决策 数据训练模型 │ │ │ │ ────────────────────────────────────────────────────────────────── │ │ 建议路径先从方案一起步按需升级到方案四 │ └────────────────────────────────────────────────────────────────────────┘维度方案一 结构化FC方案二 提示词分类方案三 RAG分类方案四 模型微调核心思路大模型原生 Function CallingPrompt 模板引导分类先检索再分类训练专用分类模型准确率中高中高最高延迟低1次调用低1次调用中2步检索分类最低小模型推理快成本低低中高训练部署维护加工具改配置改 Prompt改知识库重新训练三、方案一结构化 Function Calling难度★ 成本低 适用工具≤303.1 原理这是最直接的方案——利用大模型原生的Function Calling函数调用能力。你把所有可用工具的定义名称、描述、参数 schema作为上下文传给大模型让大模型自己判断该调用哪个工具。流程如下用户输入 ──→ 大模型带所有工具定义 ──→ 输出 tool_call ──→ 执行对应函数 │ ├─ 查天气(city, date) ├─ 订机票(from, to, date) └─ 闲聊()3.2 代码实现from openai import OpenAI client OpenAI() # 定义所有可用工具 tools [ { type: function, function: { name: get_weather, description: 查询指定城市的天气, parameters: { type: object, properties: { city: {type: string, description: 城市名}, date: {type: string, description: 日期如 2026-10-07} }, required: [city] } } }, { type: function, function: { name: book_flight, description: 预订机票, parameters: { type: object, properties: { from: {type: string, description: 出发城市}, to: {type: string, description: 到达城市}, date: {type: string, description: 出发日期} }, required: [from, to, date] } } } ] # 意图识别 让大模型选择调用哪个函数 response client.chat.completions.create( modelgpt-4o, messages[{role: user, content: 帮我查一下北京明天的天气}], toolstools ) # 大模型自动识别意图get_weather(city北京, date明天) tool_call response.choices[0].message.tool_calls[0] print(f识别到的意图{tool_call.function.name}) # get_weather print(f提取的参数{tool_call.function.arguments}) # {city:北京,date:2026-10-07}3.3 优点零开发成本不用训练模型、不用建知识库配置工具定义即可参数提取一体化意图识别和参数提取一步完成支持多工具并行模型可以同时调用多个工具parallel function calling生态成熟OpenAI、Claude、通义等主流模型都原生支持3.4 局限工具数量受限工具定义会占用 context 窗口30 个以上准确率明显下降依赖模型能力弱模型如小参数模型识别准确率低成本高每次调用都要传全部工具定义token 消耗大无确定性同样输入可能得到不同结果temperature0 时面试加分点提到 Function Calling 时主动说它会受到 context 窗口限制工具数超过 30 个建议换 RAG 方案——这就把你和只会背概念的人区分开了。四、方案二提示词分类难度★★ 成本低 适用工具≤504.1 原理不依赖模型的 Function Calling 能力而是用提示词工程让大模型扮演分类器。把所有意图类别列在 Prompt 里让模型输出一个分类标签再根据标签路由到对应处理逻辑。与方案一的区别Function Calling 输出的是工具调用结构提示词分类输出的是类别标签。前者直接执行后者还需要一层路由。用户输入 ──→ 大模型带分类Prompt ──→ 输出类别标签 ──→ 路由到对应处理 │ ├─ weather → 调用天气模块 ├─ flight → 调用机票模块 ├─ chitchat → 调用闲聊模块 └─ unknown → 兜底策略4.2 代码实现CLASSIFICATION_PROMPT 你是一个意图分类器。 请根据用户输入判断属于以下哪个意图类别只输出类别名不要输出其他内容。 意图类别 1. weather - 查询天气 2. flight - 订机票/查航班 3. translation - 翻译 4. code - 写代码/技术问题 5. chitchat - 闲聊/问候 6. unknown - 不属于以上任何类别 用户输入{user_input} 意图类别 def classify_intent(user_input: str) - str: 用提示词分类识别意图 prompt CLASSIFICATION_PROMPT.format(user_inputuser_input) response client.chat.completions.create( modelgpt-4o-mini, # 可以用小模型省钱 messages[{role: user, content: prompt}], temperature0, # 确定性输出 max_tokens20 # 只需要类别名 ) intent response.choices[0].message.content.strip().lower() return intent # 路由到对应处理 INTENT_HANDLERS { weather: handle_weather, flight: handle_flight, translation: handle_translation, code: handle_code, chitchat: handle_chitchat, unknown: handle_fallback, } intent classify_intent(帮我看看北京明天冷不冷) handler INTENT_HANDLERS.get(intent, handle_fallback) result handler(user_input)4.3 进阶思维链分类对于复杂场景可以在 Prompt 里加入思维链Chain-of-Thought引导模型先推理再分类准确率会明显提升COT_PROMPT 你是一个意图分类器。请按以下步骤分析 第一步分析用户输入中的关键词和意图线索 第二步与已知意图类别逐一比对 第三步排除明显不符合的类别 第四步从剩余类别中选出最匹配的 意图类别 1. weather - 查询天气 2. flight - 订机票/查航班 ... 用户输入{user_input} 请按上述步骤分析最后输出 分析过程... 最终类别只输出类别名4.4 优点灵活改 Prompt 即可调整分类逻辑不用改代码可解释思维链能输出推理过程便于调试模型无关任何大模型都能用不依赖 Function Calling 能力省钱可以用小模型gpt-4o-mini 级别即可4.5 局限类别数受限Prompt 里列 50 个以上类别模型容易遗漏需要额外路由层不像 Function Calling 直接输出可执行结构Prompt 调优玄学同样信息换种表述方式准确率可能差很多多意图场景弱一句话包含多个意图时处理麻烦面试加分点提到提示词分类时主动对比Function Calling——说FC 是端到端的提示词分类是分类路由两步这显示你理解了本质区别而不是只会用。五、方案三RAG 分类难度★★★ 成本中 适用工具≤5005.1 原理当工具数量从几十增长到几百甚至上千时前两种方案都会失效——Prompt 装不下那么多工具定义。RAG 分类方案的核心思路是先用检索找到最相关的几个候选工具再让大模型在小范围内做精准分类。这其实是一个检索重排的两阶段流程借鉴了 RAG检索增强生成的思路但用在意图识别上。用户输入 │ ▼ ┌──────────────────┐ │ 第一阶段检索 │ 从工具库中检索 Top-K 候选工具 │ 向量相似度 │ 如 Top-5 或 Top-10 └──────────────────┘ │ ▼ ┌──────────────────┐ │ 第二阶段重排 │ 让大模型在 Top-K 候选中精准分类 │ 大模型分类 │ 类似方案一的 Function Calling └──────────────────┘ │ ▼ 最终选中的工具5.2 代码实现import faiss import numpy as np from openai import OpenAI client OpenAI() # 第一步构建工具的向量索引 TOOLS [ {id: weather_query, name: 查询天气, desc: 查询指定城市的天气情况}, {id: flight_book, name: 预订机票, desc: 预订国内或国际航班机票}, {id: translation, name: 翻译文本, desc: 将文本翻译为指定语言}, # ... 可以有几百上千个工具 ] def build_index(tools): 为所有工具描述生成向量索引 descriptions [f{t[name]}: {t[desc]} for t in tools] embeddings [] for desc in descriptions: resp client.embeddings.create( modeltext-embedding-3-small, inputdesc ) embeddings.append(resp.data[0].embedding) dim len(embeddings[0]) index faiss.IndexFlatIP(dim) # 内积 余弦相似度向量已归一化 index.add(np.array(embeddings, dtypenp.float32)) return index index build_index(TOOLS) # 第二步检索阶段 - 找 Top-K 候选 def retrieve_candidates(user_input: str, k: int 5): 用向量相似度检索最相关的 K 个工具 query_emb client.embeddings.create( modeltext-embedding-3-small, inputuser_input ).data[0].embedding _, indices index.search( np.array([query_emb], dtypenp.float32), k ) return [TOOLS[i] for i in indices[0]] # 第三步重排阶段 - 大模型在候选中精准分类 def rerank_and_select(user_input: str, candidates: list): 让大模型在 Top-K 候选中选出最匹配的工具 tool_defs [ {type: function, function: { name: t[id], description: t[desc], parameters: {type: object, properties: {}} }} for t in candidates ] response client.chat.completions.create( modelgpt-4o, messages[{role: user, content: user_input}], toolstool_defs, tool_choiceauto ) if response.choices[0].message.tool_calls: return response.choices[0].message.tool_calls[0].function.name return None # 完整流程 candidates retrieve_candidates(帮我查北京明天天气, k5) selected rerank_and_select(帮我查北京明天天气, candidates) print(f选中的工具{selected}) # weather_query5.3 关键设计要点工具描述怎么写检索质量直接取决于工具描述的质量。好的描述应该包含同义词和口语表达查天气也要写明天冷不冷下雨吗包含典型用例用户可能会问北京明天天气怎么样包含边界澄清注意不包含历史天气查询Top-K 怎么选K5精准但可能漏召回适合工具间差异大K10召回率高但重排成本高适合工具间有重叠经验值K min(10, 总工具数的 5%)用什么向量模型text-embedding-3-smallOpenAI通用场景首选1536 维bge-large-zh智源中文场景更优免费可自部署句向量微调用标注数据微调 embedding 模型效果最好但成本高5.4 优点可扩展性强工具数到 500 也能保持高准确率成本可控重排阶段只传 Top-K 个工具定义token 消耗少新增工具快只需要更新向量索引不用重新训练5.5 局限两阶段延迟检索 重排 2 次网络调用检索质量依赖描述工具描述写得不好召回就崩仍受大模型 context 限制候选数 K 太大时重排准确率下降面试加分点提到 RAG 分类时主动说本质是检索重排的两阶段方案借鉴了 RAG 的思路——并能说出 K 值选择的经验值证明你不只是会用 faiss 而是真理解。六、方案四模型微调难度★★★★ 成本高 适用工具∞6.1 原理当前三种方案都不够用时工具上千、准确率要求 99%、延迟要求极低终极方案是用标注数据微调一个专用分类模型。这个模型不调用大模型 API而是一个小的、专门的分类器。思路类似于 BERT 时代的文本分类任务但用现代大模型架构如 LLaMA、Qwen做 LoRA 微调。┌──────────────────────────────────────────┐ │ 离线阶段训练 │ │ │ │ 标注数据 ──→ LoRA 微调 ──→ 分类模型 │ │ 用户输入正确意图 专用小模型 │ └──────────────────────────────────────────┘ │ ▼ ┌──────────────────────────────────────────┐ │ 在线阶段推理 │ │ │ │ 用户输入 ──→ 微调模型 ──→ 意图标签 │ │ 本地部署毫秒级 │ └──────────────────────────────────────────┘6.2 数据准备# 微调数据集格式JSONL # 每行一个样本用户输入 正确意图标签 {text: 帮我查一下北京明天的天气, label: weather} {text: 明天会下雨吗, label: weather} {text: 北京冷不冷, label: weather} {text: 订一张去上海的机票, label: flight} {text: 明天飞广州的航班有哪些, label: flight} {text: 你好, label: chitchat} {text: 谢谢, label: chitchat} # ... 至少每个意图 100-500 条样本6.3 训练代码LoRA 微调from peft import LoraConfig, get_peft_model from transformers import AutoModelForCausalLM, AutoTokenizer, TrainingArguments from trl import SFTTrainer import json # 加载基座模型如 Qwen2.5-7B model_name Qwen/Qwen2.5-7B tokenizer AutoTokenizer.from_pretrained(model_name) model AutoModelForCausalLM.from_pretrained(model_name, load_in_4bitTrue) # LoRA 配置只训练少量参数省显存 lora_config LoraConfig( r16, # LoRA 秩 lora_alpha32, # 缩放系数 target_modules[q_proj, v_proj], # 微调哪些层 lora_dropout0.05, task_typeCAUSAL_LM ) model get_peft_model(model, lora_config) # 准备训练数据把分类任务转为生成任务 def format_example(text: str, label: str) - str: return f用户输入{text}\n意图类别{label} train_data [] with open(intent_dataset.jsonl) as f: for line in f: item json.loads(line) train_data.append({text: format_example(item[text], item[label])}) # 训练 training_args TrainingArguments( output_dir./intent-classifier, num_train_epochs3, per_device_train_batch_size4, learning_rate2e-4, save_strategyepoch, ) trainer SFTTrainer( modelmodel, argstraining_args, train_datasettrain_data, ) trainer.train() model.save_pretrained(./intent-classifier-lora)6.4 推理部署from vllm import LLM # 加载微调后的模型vLLM 高性能推理 llm LLM(modelQwen/Qwen2.5-7B, lora_path./intent-classifier-lora) def classify(user_input: str) - str: prompt f用户输入{user_input}\n意图类别 output llm.generate([prompt], max_tokens10) return output[0].outputs[0].text.strip()6.5 优点准确率最高专用模型永远比通用模型强延迟最低7B 模型本地推理只要几十毫秒成本最低长期不用调用大模型 API可控性强可以针对 bad case 定向优化6.6 局限数据成本高每个意图至少 100-500 条标注样本训练成本高需要 GPU 算力维护难新增意图需要重新标注训练冷启动慢初期没有数据时无法使用泛化弱遇到训练集没见过的表达可能失效面试加分点提到微调时主动说微调方案不是银弹它有冷启动问题和泛化问题所以实际系统中常用微调RAG 的混合方案——这显示你有工程经验而不是只会做实验。七、四种方案横向对比对比维度方案一 FC方案二 提示词方案三 RAG方案四 微调工具数上限~30~50~500∞准确率85-92%80-90%90-97%95-99%延迟200-500ms100-300ms300-800ms10-50ms每次调用成本高传全部工具低小模型即可中检索重排极低本地推理初始开发成本1天1天3-5天2-4周新增工具成本改配置改Prompt改索引重新训练可解释性中高CoT中低冷启动能力强强中弱八、选型决策框架 实战经验混合方案实际生产系统中单一方案往往不够用。常见的混合方案FC RAG先用 RAG 检索 Top-10 工具再用 FC 在其中选择——兼顾规模和准确率微调 RAG微调模型做初筛RAG 做精排——兼顾速度和准确率提示词 兜底提示词分类做主路径命中 unknown 时回退到大模型 FC——省钱兜底规则前置 任意方案先用关键词规则处理高频简单意图如你好→闲聊剩下的走模型——大幅降低成本九、面试高频问题与回答问题 1说说 Agent 的意图识别有哪些方案回答框架按复杂度递增说四种——结构化 Function Calling、提示词分类、RAG 分类、模型微调。每种说一句原理、一句适用场景。最后补一句实际系统常混合使用。问题 2工具数量很大几百上千时怎么办回答框架不能直接用 Function Callingcontext 装不下。用 RAG 分类方案——先用向量检索召回 Top-K 候选再让大模型在小范围内重排。如果准确率还不够再用标注数据微调专用模型。问题 3Function Calling 和提示词分类有什么区别回答框架FC 是端到端的——直接输出可执行的工具调用结构函数名参数无需中间层。提示词分类输出的是类别标签还需要一层路由。FC 适合工具少且参数明确的场景提示词分类更灵活但多一步路由。问题 4意图识别准确率怎么提升回答框架分四步① 优化工具描述加同义词和用例② 加思维链引导模型推理 ③ 用 RAG 缩小候选范围 ④ 用 bad case 做微调数据训练专用模型。还要做 bad case 分析持续迭代。问题 5微调方案的冷启动问题怎么解决回答框架初期没有标注数据时先用 FC 或提示词方案上线同时收集用户反馈点击/修正行为作为标注数据。积累到每个意图 100 样本时再启动微调。这是典型的弱监督主动学习思路。十、总结与实践建议核心要点回顾意图识别是 Agent 的核心能力决定了 Agent 该调用什么工具、走什么流程四种方案按复杂度递增Function Calling → 提示词分类 → RAG 分类 → 模型微调工具数是选型的关键≤30 用 FC≤50 用提示词≤500 用 RAG更多用微调实际系统常混合使用如 RAGFC、微调RAG、规则前置任意方案微调不是银弹有冷启动和泛化问题需要配合其他方案实践建议从简单方案起步先用 Function Calling 上线验证 Agent 核心流程再根据瓶颈升级重视工具描述无论哪种方案工具描述质量直接决定准确率上限建立 bad case 反馈闭环用户修正行为是宝贵的标注数据要收集起来关注延迟和成本意图识别是每次请求都走的路径延迟和成本会被放大准备兜底策略任何方案都有识别不准的情况要有 unknown 类别和兜底处理趋势展望Agent 意图识别正在向几个方向演进多模态意图不只是文本还有图片、语音、视频输入的意图识别多意图并发一句话识别多个意图并并行处理早期的 parallel function calling 是雏形个性化识别根据用户历史行为调整意图识别权重端侧部署意图识别模型小型化部署到手机/IoT 端保护隐私降低延迟无论技术怎么演进用户说了什么 → Agent 该干什么这个核心问题不会变。掌握这四种方案你就在面试和实战中都有了扎实的基础。