【大模型实战】手把手教你基于LLM与RAG的AI智能体意图识别深度实践,全程干货,简单易懂!!
在构建AI智能体的征途中,精准的意图识别(Intent Detection)是决定成败的第一道关卡。它负责将用户自由形式的输入(Query)映射到系统预定义的具体任务上,例如“查询天气”、“预订机票”或“播放音乐”。随后的槽位抽取(Slot Filling)则从输入中提取执行任务所需的关键参数,如“北京”、“明天”或“周杰伦”。 最常见的初级方案(提示词工程),即将所有意图定义、少量示例(Few-Shot)和思维链(CoT)逻辑都塞进一个庞大的提示词(Prompt)中,是一种简单快捷的“冷启动”方法。 此方案的弊端显而易见:
- 提示词膨胀与性能瓶颈:随着意图数量的增加,提示词会变得异常冗长,超出模型的上下文窗口限制,并导致推理成本和延迟飙升。
- 泛化能力受限:模型的能力完全受限于提示词中有限的示例,对于用户千变万化的口语化、模糊化甚至错误的表达方式,识别准确率会急剧下降。
- 维护噩梦:每次增加新意图或修复一个错误的识别案例(Bad Case),都需要重写和调试复杂的提示词,牵一发而动全身。
为了构建真正智能、鲁棒且可维护的AI智能体,我们引入更先进的范式——检索增强生成(Retrieval-Augmented Generation, RAG)。RAG通过从外部知识库中动态检索与当前用户问题最相关的信息,来“增强”LLM的能力,从而实现更精准、更具扩展性的意图识别。
【PS:为了帮助更多热爱技术、渴望成长的朋友,我特别整理了一份涵盖大模型领域的宝贵资料集,内容包含:DeepSeek部署安装教程,AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频,有需要的朋友可以点击下方卡片免费获取!】
编辑【2025最新总结】AI大模型全套学习资料,免费领取!含最新学习路线、大厂面试真题、可落地的项目实战、经典的PDF书籍.......3 赞同 · 4 评论 文章
核心架构:RAG如何赋能意图识别
RAG的核心思想是“先检索,再生成”。它将意图识别任务从一个封闭的“记忆力测试”(依赖LLM内部知识和有限的提示词示例)转变为一个开放的“开卷考试”(允许LLM参考外部知识库)。 其核心工作流程如下: 接下来,我们将分步详解如何从零开始构建这样一个系统,并提供相应的实战代码。
深度实践:从零构建RAG意图识别系统
第一步:构建高质量的意图知识库
知识库的质量直接决定了RAG系统的上限。这个知识库不仅是意图的简单罗列,更是一个包含丰富、多样化表达方式的“意图语料库”。
1. 定义意图与泛化语料
首先,明确智能体需要支持的所有意图。然后,针对每个意图,我们需要收集和生成大量的同义句(Query),覆盖各种可能的表达方式。
- 人工构造:根据业务经验,手动编写种子语料。
- 线上数据挖掘:从真实用户日志中清洗和标注数据。
- LLM数据增强:利用LLM的生成能力,对种子语料进行扩充和泛化,这是最高效的方式。
代码实战:使用LLM进行意图数据泛化 下面的Python代码展示了如何调用LLM API,为一个给定的意图(如“查询公交线路”)和一些种子Query,生成更多样化的同义句。
import os
from openai import OpenAI
import json
# 建议使用环境变量来管理API密钥,避免硬编码
# client = OpenAI(api_key=os.environ.get("OPENAI_API_KEY"))
# 为方便演示,此处直接提供一个虚拟key
client = OpenAI(api_key="YOUR_API_KEY_HERE", base_url="YOUR_API_BASE_URL_HERE") # 替换为你的API Key和Base URL
def generate_similar_queries(intent_name, intent_description, seed_queries, count=10):
""" 使用LLM为一个意图生成多样化的同义查询。
Args:
intent_name (str): 意图名称。
intent_description (str): 意图的详细描述。
seed_queries (list): 种子查询列表作为示例。
count (int): 希望生成的查询数量。
Returns:
list: 生成的同义查询列表。
"""
# 构建一个强大的提示词,引导LLM进行高质量的生成
prompt = f"""
你是一个AI智能体的数据增强专家。你的任务是为一个特定的意图生成多样化的用户查询。
**意图名称:** {intent_name}
**意图描述:** {intent_description}
**请参考以下示例查询:**
{', '.join(seed_queries)}
**要求:**
1. 生成 {count} 条与上述意图相关、但表达方式不同的用户查询。
2. 风格需要口语化、简洁,并模拟真实用户的提问习惯。
3. 覆盖不同的句式,例如:陈述句、疑问句、甚至省略部分信息的短语。
4. 不要包含礼貌用语,如“请”、“谢谢”。
5. 仅输出一个JSON格式的列表,不要包含任何其他解释性文字。例如:["查询1", "查询2", ...]
"""
print("--- Sending Prompt to LLM ---")
print(prompt)
print("-----------------------------")
try:
response = client.chat.completions.create(
model="gpt-4-turbo", # 可以替换为你选择的模型
messages=[{"role": "user", "content": prompt}],
temperature=0.8, # 提高一点温度以增加多样性
response_format={"type": "json_object"},
)
# 假设模型会返回一个包含 "queries" 键的JSON对象
generated_text = response.choices[0].message.content
# 由于 response_format="json_object",可以直接解析
# 但为了稳健,我们还是做一下检查
result_data = json.loads(generated_text)
# 假设返回的JSON结构是 {"queries": ["...", "..."]}
# 如果不是,你可能需要根据实际返回调整这里的解析逻辑
if"queries"in result_data and isinstance(result_data["queries"], list):
return result_data["queries"]
else:
# 尝试直接解析列表
return json.loads(generated_text)
except Exception as e:
print(f"An error occurred: {e}")
return []
# --- 示例 ---
intent_name = "查询公交线路"
intent_description = "用户想要查询某条公交线路的详细信息,比如途经的站点。"
seed_queries = [
"911路公交车都经过哪些站?",
"查一下15路",
"告诉我虹桥枢纽4路的路线"
]
augmented_queries = generate_similar_queries(intent_name, intent_description, seed_queries, 20)
print("\n--- Generated Queries ---")
print(json.dumps(augmented_queries, indent=2, ensure_ascii=False))
通过这种方式,我们可以为每个意图轻松生成数百甚至数千条高质量的语料,为构建一个强大的RAG知识库打下坚实的基础。
2. 知识库的构建与向量化
生成语料后,我们需要将其存储并转化为向量,以便进行高效的相似度检索。
- 数据整理:将所有意图的语料整理成结构化数据,每条数据至少包含query(用户问题)和intent(对应意图)两个字段。
- 文本嵌入:选择一个合适的文本嵌入模型(Text Embedding Model),将每一条query文本转换成一个高维向量。
- 存入向量数据库:将文本及其对应的向量存储到向量数据库中(如FAISS, Milvus, Pinecone等)。
第二步:实现端到端的RAG意图识别流程
现在,我们将把所有部分串联起来,构建一个完整的意图识别流程。 代码实战:使用LangChain实现完整的RAG意图识别流程 这个例子将使用 LangChain框架来简化向量化和检索的过程。我们使用 FAISS 作为内存向量数据库,OpenAIEmbeddings 作为嵌入模型。在生产环境中,可以轻松替换为其他向量数据库(如 Milvus, Pinecone)和嵌入模型。
import json
import os
from openai import OpenAI
# LangChain 相关库
# 需要安装: pip install langchain langchain-openai faiss-cpu tiktoken
from langchain_community.vectorstores import FAISS
from langchain_openai import OpenAIEmbeddings
from langchain.schema import Document
# --- 0. 准备工作 ---
# 假设这是我们通过第一步构建的知识库
knowledge_base = [
{"query": "明天天气怎么样?", "intent": "查询天气", "slots": {"city": "默认", "time": "明天"}},
{"query": "查一下北京的天气", "intent": "查询天气", "slots": {"city": "北京", "time": "今天"}},
{"query": "后天上海会下雨吗", "intent": "查询天气", "slots": {"city": "上海", "time": "后天"}},
{"query": "给我放一首周杰伦的歌", "intent": "播放音乐", "slots": {"artist": "周杰伦", "song": "任意"}},
{"query": "我想听七里香", "intent": "播放音乐", "slots": {"artist": "周杰伦", "song": "七里香"}},
{"query": "来点音乐", "intent": "播放音乐", "slots": {"artist": "任意", "song": "任意"}},
{"query": "订一张明天去上海的机票", "intent": "预订机票", "slots": {"departure_city": "当前城市", "destination_city": "上海", "date": "明天"}},
{"query": "从北京到广州的航班", "intent": "预订机票", "slots": {"departure_city": "北京", "destination_city": "广州", "date": "今天"}},
]
# --- 配置 API ---
# LangChain 会自动从环境变量 `OPENAI_API_KEY` 和 `OPENAI_BASE_URL` 读取配置
# 建议使用环境变量,而不是在代码中硬编码
# os.environ["OPENAI_API_KEY"] = "YOUR_API_KEY_HERE"
# os.environ["OPENAI_BASE_URL"] = "YOUR_API_BASE_URL_HERE"
# 为方便演示,我们在这里实例化 client 和 embeddings
# 替换为你的API Key和Base URL
api_key = "YOUR_API_KEY_HERE"
base_url = "YOUR_API_BASE_URL_HERE"
client = OpenAI(api_key=api_key, base_url=base_url)
embeddings = OpenAIEmbeddings(openai_api_key=api_key, openai_api_base_url=base_url)
# --- 1. 使用 LangChain 构建向量知识库 ---
print("Step 1: Building vector store with LangChain...")
# 将原始知识库转换为 LangChain 的 Document 格式
# 我们将 query 作为 page_content,将 intent 和 slots 作为 metadata
documents = [
Document(
page_content=item['query'],
metadata={'intent': item['intent'], 'slots': json.dumps(item['slots'])} # Metadata值必须是字符串、整数、浮点数或布尔值
) for item in knowledge_base
]
# 从 documents 创建 FAISS 向量存储
# 这一个步骤会自动处理文本的 embedding 和索引的创建
try:
vector_store = FAISS.from_documents(documents, embeddings)
print("Vector store built successfully with FAISS.")
except Exception as e:
print(f"Error building vector store: {e}")
vector_store = None
def retrieve_examples_langchain(user_query, k=3):
"""
使用 LangChain 的向量存储检索最相似的K个示例。
"""
print(f"nStep 2: Retrieving examples for query: '{user_query}' with LangChain")
ifnot vector_store:
print("Vector store is not available.")
return []
# FAISS.similarity_search会返回 Document 对象列表
retrieved_docs = vector_store.similarity_search(user_query, k=k)
# 将 Document 对象转换回我们原来的字典格式,以便下游函数使用
examples = [
{
"query": doc.page_content,
"intent": doc.metadata['intent'],
"slots": json.loads(doc.metadata['slots'])
} for doc in retrieved_docs
]
print(f"Retrieved {len(examples)} examples.")
return examples
def build_prompt_with_rag(user_query, examples):
"""
构建带有检索到的示例的动态提示词。
"""
print("\nStep 3: Building dynamic prompt with retrieved examples...")
examples_str = "\n".join([f"// 示例\n用户输入: {ex['query']}\n输出: {json.dumps({'intent': ex['intent'], 'slots': ex['slots']}, ensure_ascii=False)}"for ex in examples])
prompt = f"""
你是一个任务型对话机器人的NLU(自然语言理解)引擎。
你的任务是根据用户最新的提问,识别出用户的意图(intent)并抽取出相应的槽位(slots)。
请严格参考下面提供的示例,理解如何进行意图识别和槽位抽取。
{examples_str}
---
现在,请处理以下用户的最新提问。
请严格按照JSON格式输出,不要包含任何其他解释。
用户输入: {user_query}
输出:
"""
print("Prompt built.")
return prompt
def recognize_intent_with_rag(user_query):
"""
执行完整的RAG意图识别流程。
"""
# 1. 检索 (使用 LangChain 版本)
examples = retrieve_examples_langchain(user_query)
# 2. 构建提示词
prompt = build_prompt_with_rag(user_query, examples)
print("\n--- Final Prompt to LLM ---")
print(prompt)
print("---------------------------")
# 3. 调用LLM
print("\nStep 4: Calling LLM for final recognition...")
try:
response = client.chat.completions.create(
model="gpt-3.5-turbo",
messages=[{"role": "user", "content": prompt}],
temperature=0, # 对于分类和提取任务,使用低温
response_format={"type": "json_object"},
)
result = response.choices[0].message.content
print("LLM call successful.")
return json.loads(result)
except Exception as e:
print(f"An error occurred during LLM call: {e}")
return {"error": str(e)}
# --- 最终测试 ---
if vector_store:
test_query_1 = "帮我找一首林俊杰的歌"
result_1 = recognize_intent_with_rag(test_query_1)
print(f"\n--- Result for '{test_query_1}' ---")
print(json.dumps(result_1, indent=2, ensure_ascii=False))
test_query_2 = "后天广州天气如何"
result_2 = recognize_intent_with_rag(test_query_2)
print(f"\n--- Result for '{test_query_2}' ---")
print(json.dumps(result_2, indent=2, ensure_ascii=False))
第三步:处理多轮对话的挑战
书籍PDF及配套代码可点赞文章后添加小助手获取

在真实的对话场景中,用户很少在一句话内提供所有信息。上下文理解能力至关重要。 挑战: 用户:“帮我订一张去北京的票” 智能体:“好的,什么时候出发?” 用户:“明天” 在处理“明天”这个输入时,如果只看当前Query,系统无法知道这是在回答出发时间。 解决方案:将历史对话融入RAG检索 如您提供的文章中“高阶方案D”所述,最有效的方法是在RAG检索前,将近期的对话历史和当前Query拼接成一个更完整的上下文。 代码实战:拼接对话历史
def assemble_context(history, current_query):
"""
将历史对话和当前查询拼接成一个用于检索的上下文字符串。
Args:
history (list of dicts): [{"role": "user/assistant", "content": "..."}]
current_query (str): 最新的用户输入。
Returns:
str: 拼接后的上下文。
"""
# 只保留最近几轮对话,避免上下文过长
recent_history = history[-4:] # 例如,保留最近2轮对话(user+assistant)
history_str = ""
for turn in recent_history:
role = "用户"if turn["role"] == "user"else"助手"
content = turn["content"]
history_str += f"{role}: {content}\n"
context_for_retrieval = f"对话历史:\n{history_str}最新提问: {current_query}"
return context_for_retrieval
# --- 示例 ---
history = [
{"role": "user", "content": "帮我订一张去北京的票"},
{"role": "assistant", "content": "好的,什么时候出发?"}
]
current_query = "明天"
context = assemble_context(history, current_query)
print("--- Context for RAG Retrieval ---")
print(context)
# 接下来,将这个 'context' 字符串作为 recognize_intent_with_rag 函数的输入
# result = recognize_intent_with_rag(context)
# ...
为了让这种方式更有效,我们的知识库也需要升级,包含一些多轮对话的Case,让RAG可以检索到包含上下文的示例。
总结与展望
相较于传统的提示词工程,基于RAG的意图识别方案提供了无与伦比的优势:
- 高准确性:通过动态检索最相关的示例,极大增强了LLM在特定领域的意图理解和槽位抽取能力,尤其擅长处理“长尾”和模糊的用户表达。
- 超强扩展性:增加或修改意图,只需在知识库中增删数据并重新向量化即可,无需改动核心代码和复杂的提示词,系统维护变得简单高效。
- 可控性与可解释性:当出现Bad Case时,我们可以通过分析RAG的检索结果,快速定位问题是出在检索阶段还是LLM的理解阶段,并能通过向知识库添加针对性Case来快速修复。
- 成本效益:由于大部分“知识”外置于知识库,我们可以选用更小、更轻量级的LLM模型来完成最终的推理,从而显著降低API调用成本和系统延迟。
从简单的提示词工程,到引入RAG进行单轮识别,再到融合对话历史实现多轮上下文理解,这是一条构建高级AI智能体的必经之路。通过本文提供的深度解析和实战代码,希望能为您在AI智能体的探索之路上点亮一盏明灯。
最后的最后
为了帮助开发者打破壁垒,快速了解大模型核心技术原理,学习相关大模型技术。从原理出发真正入局大模型。这里给大家准备了一份涵盖了AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频 全系列的学习资料。这些学习资料不仅深入浅出,而且非常实用,让大家系统而高效地掌握AI大模型的各个知识点。
这份完整版的AI大模型学习资料,朋友们如果有需要的话可以点击下方卡片免费领取【保证100%免费】
编辑【2025最新总结】AI大模型全套学习资料,免费领取!含最新学习路线、大厂面试真题、可落地的项目实战、经典的PDF书籍.......3 赞同 · 4 评论 文章
大模型知识脑图
为了成为更好的 AI大模型 开发者,这里为大家提供了总的路线图。它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。
第一阶段(10天):初阶应用
该阶段让大家对大模型 AI有一个最前沿的认识,对大模型 AI 的理解超过 95% 的人,可以在相关讨论时发表高级、不跟风、又接地气的见解,别人只会和 AI 聊天,而你能调教 AI,并能用代码将大模型和业务衔接。
- 大模型 AI 能干什么?
- 大模型是怎样获得「智能」的?
- 用好 AI 的核心心法
- 大模型应用业务架构
- 大模型应用技术架构
- 代码示例:向 GPT-3.5 灌入新知识
- 提示工程的意义和核心思想
- Prompt 典型构成
- 指令调优方法论
- 思维链和思维树
- Prompt 攻击和防范
- ....
第二阶段(30天):高阶应用
该阶段我们正式进入大模型 AI 进阶实战学习,学会构造私有知识库,扩展 AI 的能力。快速开发一个完整的基于 agent 对话机器人。掌握功能最强的大模型开发框架,抓住最新的技术进展,适合 Python 和 JavaScript 程序员。
- 为什么要做 RAG
- 搭建一个简单的 ChatPDF
- 检索的基础概念
- 什么是向量表示(Embeddings)
- 向量数据库与向量检索
- 基于向量检索的 RAG
- 搭建 RAG 系统的扩展知识
- 混合检索与 RAG-Fusion 简介
- 向量模型本地部署
- ....
第三阶段(30天):模型训练
恭喜你,如果学到这里,你基本可以找到一份大模型 AI相关的工作,自己也能训练 GPT 了!通过微调,训练自己的垂直大模型,能独立训练开源多模态大模型,掌握更多技术方案。
到此为止,大概2个月的时间。你已经成为了一名“AI小子”。那么你还想往下探索吗?
- 为什么要做 RAG
- 什么是模型
- 什么是模型训练
- 求解器 & 损失函数简介
- 小实验2:手写一个简单的神经网络并训练它
- 什么是训练/预训练/微调/轻量化微调
- Transformer结构简介
- 轻量化微调
- 实验数据集的构建
- ....
第四阶段(20天):商业闭环
对全球大模型从性能、吞吐量、成本等方面有一定的认知,可以在云端和本地等多种环境下部署大模型,找到适合自己的项目/创业方向,做一名被 AI 武装的产品经理。
- 硬件选型
- 带你了解全球大模型
- 使用国产大模型服务
- 搭建 OpenAI 代理
- 热身:基于阿里云 PAI 部署 Stable Diffusion
- 在本地计算机运行大模型
- 大模型的私有化部署
- 基于 vLLM 部署大模型
- 案例:如何优雅地在阿里云私有部署开源大模型
- 部署一套开源 LLM 项目
- 内容安全
- 互联网信息服务算法备案
- ...
学习是一个过程,只要学习就会有挑战。天道酬勤,你越努力,就会成为越优秀的自己。
书籍PDF及配套代码可点赞文章后添加小助手获取

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐

所有评论(0)