第 12 课 | RAG 检索增强生成:让 LLM 基于真实知识回答
前 3 课我们分别搭建了嵌入、向量数据库、Rerank 三个组件。这节课,我们把它们串起来,构建第一个完整的 RAG 系统——让 LLM 基于真实知识回答问题,告别幻觉。
一、什么是 RAG
1.1 LLM 的两个致命问题
LLM 很强大,但有两个致命问题:
- 知识截止日期:训练数据有截止时间,训练后的新知识它不知道
- 幻觉(Hallucination):遇到不知道的,它会"编造"一个看起来很合理的答案
比如你问:“你们的智能手表 Ultra 有什么功能?” 纯 LLM 会回答:
“智能手表通常具有心率监测、运动追踪、消息通知等功能…”
看起来对,但这是泛泛而谈,不是基于你的实际产品。如果你问它一个具体产品:“扫地机器人 S8 的吸力是多少?” 纯 LLM 回答不了——它不知道。
1.2 RAG 的解决方案
RAG(Retrieval Augmented Generation,检索增强生成)的核心思想很简单:
先检索,再回答。
用户问题 → 从知识库检索相关文档 → 把文档和问题一起给 LLM → LLM 基于文档回答类比:LLM 是学生,RAG 是开卷考试。不给资料(纯 LLM),学生只能凭记忆回答;给资料(RAG),学生可以查阅资料后给出准确答案。
1.3 业务价值
在竞品监控 Agent 中,RAG 的价值非常直接:
| 场景 | 纯 LLM | RAG 增强 |
|---|---|---|
| “竞品 X 最近有什么动作?” | 泛泛回答,可能编造 | 基于最新爬取的新闻回答 |
| “我们的价格和竞品比怎么样?” | 不知道,没有数据 | 基于数据库中的价格对比 |
| “最近一周有什么行业动态?” | 训练数据截止了 | 基于实时数据回答 |
二、RAG 架构全景
图 1:RAG 完整架构
本节课串联的组件:
- BGE-large-zh(第 9 课):嵌入模型
- ChromaDB(第 10 课):向量数据库
- BGE-Reranker(第 11 课):精排模型
- LLMClient(第 7 课):统一 LLM 客户端
三、RAG 核心流程实现
code/rag_qa.py实现了完整的 RAG 系统,核心类RAGSystem封装了三个关键方法:
3.1 检索模块
defretrieve(self,query:str)->list[dict]:# 阶段 1:粗排(ChromaDB 向量检索)coarse=self.collection.query(query_texts=[query],n_results=self.recall_k,# 默认 20)# 阶段 2:精排(BGE-Reranker)pairs=[[query,doc]fordocincoarse["documents"][0]]scores=self.reranker.compute_score(pairs,normalize=True)# 过滤低分 + 排序results=[rforrinresultsifr["score"]>=self.similarity_threshold]returnresults[:self.top_k]3.2 Prompt 构建
这是 RAG 最关键的部分——如何把检索结果有效地嵌入 Prompt:
defbuild_prompt(self,query:str,docs:list[dict])->str:context_parts=[]fori,docinenumerate(docs,1):context_parts.append(f"[{i}]{doc['metadata']['name']}({doc['metadata']['category']})\n"f"{doc['document']}\n"f" 相关性:{doc['score']:.2f}")context="\n\n".join(context_parts)prompt=f"""你是一个专业的商品顾问。请根据以下商品信息回答用户的问题。 ## 已知商品信息{context}## 回答要求 1. 只基于上述商品信息回答,不要编造信息 2. 如果上述信息不足以回答问题,请明确说明 3. 回答时引用具体的商品名称 4. 如果合适,可以对比多个商品的特点 ## 用户问题{query}## 你的回答"""returnpromptPrompt 的设计要点:
- 明确信息来源:用
## 已知商品信息分隔,让 LLM 知道哪些是"事实" - 约束行为:要求"只基于上述信息回答",防止幻觉
- 引用要求:要求引用具体商品名,让 LLM 的回答可追溯
- 降级处理:如果信息不足,要求 LLM 明确说明
3.3 问答接口
defask(self,query:str,verbose:bool=True)->dict:docs=self.retrieve(query)ifnotdocs:return{"answer":"抱歉,在知识库中没有找到相关信息...","sources":[]}prompt=self.build_prompt(query,docs)answer=self.llm.chat(prompt,temperature=0.3)return{"query":query,"answer":answer,"sources":[{"name":d["metadata"]["name"],"score":d["score"]}fordindocs],}四、RAG vs 纯 LLM 对比
我们用同一个问题在两种模式下测试:
问题:“你们的智能手表有什么功能?”
| 维度 | 纯 LLM | RAG 增强 |
|---|---|---|
| 回答内容 | “智能手表通常具有心率监测、运动追踪…” | “智能手表 Ultra 支持血氧、心率、睡眠监测,100+ 运动模式,续航 14 天,5ATM 防水,支持独立通话” |
| 准确性 | 泛泛而谈,不一定准确 | 基于实际产品数据,100% 准确 |
| 具体性 | 没有具体型号 | 引用了具体产品名和参数 |
| 可追溯 | 无法追溯 | 可追溯到来源文档 |
| 幻觉风险 | 高 | 低(有约束) |
结论:RAG 把 LLM 从"凭记忆回答"变成了"查阅资料回答",准确性和可靠性大幅提升。
五、RAG 效果优化
5.1 检索参数调优
| 参数 | 推荐值 | 说明 |
|---|---|---|
| recall_k | 20 | 粗排召回数,太少漏召回,太多 Rerank 慢 |
| top_k | 5 | 精排返回数,太多 Prompt 过长,太少信息不足 |
| similarity_threshold | 0.3 | 低于此分数的文档不纳入 Prompt |
5.2 Prompt 优化技巧
在实际测试中,我们发现了几个有效的 Prompt 优化技巧:
- 编号文档:
[1] [2] [3]让 LLM 更容易引用 - 标注相关性:显示
相关性: 0.96,让 LLM 知道哪些文档更可靠 - 明确禁止编造:最好加上"如果信息不足,说’不知道’"
- 控制 temperature:RAG 场景建议
temperature=0.3,降低随机性
5.3 降级策略
当检索不到相关内容时(相似度都低于阈值),有三种处理方式:
# 策略 1:直接拒绝回答(推荐)ifnotdocs:return"抱歉,在知识库中没有找到相关信息。"# 策略 2:降级为纯 LLM(不推荐,可能幻觉)ifnotdocs:returnllm.chat(query)# 策略 3:提示用户换个问法ifnotdocs:return"未找到相关信息,请尝试换个方式提问。"六、实战:商品知识库问答
运行code/rag_qa.py,你就能体验完整的 RAG 问答:
用户: 我想买一个适合在办公室长时间使用的设备,有什么推荐? 检索到 3 篇相关文档: [1] 人体工学办公椅 (家居办公) - 0.96 [2] 升降桌 E5 (家居办公) - 0.91 [3] 护眼台灯 L1 (家居办公) - 0.73 助手: 根据您的需求,我推荐以下办公设备: 1. **人体工学办公椅** — 这款椅子专为长期办公设计,4D 可调扶手、 135° 后仰、自适应腰靠、透气网布座垫,能有效缓解腰背疲劳。 2. **升降桌 E5** — 电动升降办公桌,双电机驱动,支持坐站交替健康办公。 4 档记忆高度,LED 触控面板,避免久坐带来的健康问题。 3. **护眼台灯 L1** — 国 AA 级照度,Ra98 高显色,无频闪无蓝光危害, 适合长时间阅读和办公,保护视力。 建议您优先考虑人体工学椅和升降桌的组合,这是长时间办公最有效的配置。 来源: 人体工学办公椅, 升降桌 E5, 护眼台灯 L1七、小结与预告
这节课我们完成了 RAG 系统的端到端搭建——从嵌入到检索,从 Rerank 到 LLM 生成,形成了一个完整的知识问答闭环。
核心收获:
- RAG = 检索 + 生成:先检索相关文档,再让 LLM 基于文档回答
- 四个组件协同:BGE → ChromaDB → BGE-Reranker → LLMClient
- Prompt 是关键:好的 Prompt 约束 LLM 行为,防止幻觉
- RAG 比纯 LLM 更准确:基于真实数据,回答具体、可追溯
从下一节课开始,我们将进入LangChain的世界——用框架来简化 Agent 开发,不再从头造轮子。
我们下一课见。
系列教程导航
上一篇:第 11 课 | Rerank 模型部署:粗排 + 精排,双重保险
下一篇:第 13 课 | LangChain 入门:Chain 与 Prompt 模板
本系列共 50 课,持续更新中。关注我不迷路。