「AI Agent 全栈开发 50 讲」——从本地模型部署到多智能体系统,一年省 87 万 第 12 课 | RAG 检索增强生成:让 LLM 基于真实知识回答

发布时间:2026/9/11 0:34:47

「AI Agent 全栈开发 50 讲」——从本地模型部署到多智能体系统,一年省 87 万 第 12 课 | RAG 检索增强生成:让 LLM 基于真实知识回答 第 12 课 | RAG 检索增强生成让 LLM 基于真实知识回答前 3 课我们分别搭建了嵌入、向量数据库、Rerank 三个组件。这节课我们把它们串起来构建第一个完整的 RAG 系统——让 LLM 基于真实知识回答问题告别幻觉。一、什么是 RAG1.1 LLM 的两个致命问题LLM 很强大但有两个致命问题知识截止日期训练数据有截止时间训练后的新知识它不知道幻觉Hallucination遇到不知道的它会编造一个看起来很合理的答案比如你问“你们的智能手表 Ultra 有什么功能” 纯 LLM 会回答“智能手表通常具有心率监测、运动追踪、消息通知等功能…”看起来对但这是泛泛而谈不是基于你的实际产品。如果你问它一个具体产品“扫地机器人 S8 的吸力是多少” 纯 LLM 回答不了——它不知道。1.2 RAG 的解决方案RAGRetrieval Augmented Generation检索增强生成的核心思想很简单先检索再回答。用户问题 → 从知识库检索相关文档 → 把文档和问题一起给 LLM → LLM 基于文档回答类比LLM 是学生RAG 是开卷考试。不给资料纯 LLM学生只能凭记忆回答给资料RAG学生可以查阅资料后给出准确答案。1.3 业务价值在竞品监控 Agent 中RAG 的价值非常直接场景纯 LLMRAG 增强“竞品 X 最近有什么动作”泛泛回答可能编造基于最新爬取的新闻回答“我们的价格和竞品比怎么样”不知道没有数据基于数据库中的价格对比“最近一周有什么行业动态”训练数据截止了基于实时数据回答二、RAG 架构全景在线阶段问答离线阶段知识入库原始文档文本分块BGE 嵌入ChromaDB 存储用户问题BGE 嵌入ChromaDB 检索粗排 Top-20BGE-Reranker精排 Top-5构建 Prompt问题 文档LLM 生成基于文档回答最终答案图 1RAG 完整架构本节课串联的组件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 向量检索coarseself.collection.query(query_texts[query],n_resultsself.recall_k,# 默认 20)# 阶段 2精排BGE-Rerankerpairs[[query,doc]fordocincoarse[documents][0]]scoresself.reranker.compute_score(pairs,normalizeTrue)# 过滤低分 排序results[rforrinresultsifr[score]self.similarity_threshold]returnresults[:self.top_k]3.2 Prompt 构建这是 RAG 最关键的部分——如何把检索结果有效地嵌入 Promptdefbuild_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]})\nf{doc[document]}\nf 相关性:{doc[score]:.2f})context\n\n.join(context_parts)promptf你是一个专业的商品顾问。请根据以下商品信息回答用户的问题。 ## 已知商品信息{context}## 回答要求 1. 只基于上述商品信息回答不要编造信息 2. 如果上述信息不足以回答问题请明确说明 3. 回答时引用具体的商品名称 4. 如果合适可以对比多个商品的特点 ## 用户问题{query}## 你的回答returnpromptPrompt 的设计要点明确信息来源用## 已知商品信息分隔让 LLM 知道哪些是事实约束行为要求只基于上述信息回答防止幻觉引用要求要求引用具体商品名让 LLM 的回答可追溯降级处理如果信息不足要求 LLM 明确说明3.3 问答接口defask(self,query:str,verbose:boolTrue)-dict:docsself.retrieve(query)ifnotdocs:return{answer:抱歉在知识库中没有找到相关信息...,sources:[]}promptself.build_prompt(query,docs)answerself.llm.chat(prompt,temperature0.3)return{query:query,answer:answer,sources:[{name:d[metadata][name],score:d[score]}fordindocs],}四、RAG vs 纯 LLM 对比我们用同一个问题在两种模式下测试问题“你们的智能手表有什么功能”维度纯 LLMRAG 增强回答内容“智能手表通常具有心率监测、运动追踪…”“智能手表 Ultra 支持血氧、心率、睡眠监测100 运动模式续航 14 天5ATM 防水支持独立通话”准确性泛泛而谈不一定准确基于实际产品数据100% 准确具体性没有具体型号引用了具体产品名和参数可追溯无法追溯可追溯到来源文档幻觉风险高低有约束结论RAG 把 LLM 从凭记忆回答变成了查阅资料回答准确性和可靠性大幅提升。五、RAG 效果优化5.1 检索参数调优参数推荐值说明recall_k20粗排召回数太少漏召回太多 Rerank 慢top_k5精排返回数太多 Prompt 过长太少信息不足similarity_threshold0.3低于此分数的文档不纳入 Prompt5.2 Prompt 优化技巧在实际测试中我们发现了几个有效的 Prompt 优化技巧编号文档[1] [2] [3]让 LLM 更容易引用标注相关性显示相关性: 0.96让 LLM 知道哪些文档更可靠明确禁止编造最好加上如果信息不足说’不知道’控制 temperatureRAG 场景建议temperature0.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 → LLMClientPrompt 是关键好的 Prompt 约束 LLM 行为防止幻觉RAG 比纯 LLM 更准确基于真实数据回答具体、可追溯从下一节课开始我们将进入LangChain的世界——用框架来简化 Agent 开发不再从头造轮子。我们下一课见。系列教程导航上一篇第 11 课 | Rerank 模型部署粗排 精排双重保险下一篇第 13 课 | LangChain 入门Chain 与 Prompt 模板本系列共 50 课持续更新中。关注我不迷路。
延伸阅读

更多相关文章

2026/9/11 0:34:47

工业防护系统化设计与模块化架构实践

1. 工业防护为何需要系统化思考 第一次接触大型化工厂的防护改造项目时,我犯了个典型错误——把防护措施拆解成孤立的单元来处理。腐蚀区域用防腐涂料,机械磨损部位加装护板,电气设备配齐防爆外壳。三个月后回访时,防腐涂层因结构…

2026/9/11 0:34:47

电力系统Simulink建模:从基础模块到实战技巧

1. 为什么电力工程师需要掌握Simulink? 作为一名在电力行业摸爬滚打多年的工程师,我至今记得第一次用Simulink搭建三相短路模型时的震撼——原本需要几天手工计算的暂态过程,现在点几下鼠标就能可视化呈现。这种体验就像给电力系统分析装上了…

2026/9/11 0:34:47

微电网改进下垂控制Simulink仿真:虚拟阻抗与二次调节策略

孤岛型微电网里,下垂控制几乎是绕不开的基础方案,但真正搭起Simulink模型跑起来之后,你会发现传统下垂一堆问题:频率电压稳态偏差、无功功率均分精度差、线路阻抗一不匹配就环流。这篇文章我就围绕“改进下垂控制”这个主题&#…

2026/9/11 3:30:14

Vue.js工业园区污水实时监控系统开发实践

1. 项目背景与核心需求工业园区污水监控系统正面临数字化转型的关键时期。传统的人工采样实验室分析模式存在数据滞后、人力成本高、应急响应慢三大痛点。我们团队基于Vue.js开发的这套在线监控管理系统,实现了从"事后处理"到"实时预警"的跨越式…

2026/9/11 3:30:14

高斯过程回归:原理、Python实现与不确定性预测

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/11 3:30:14

嵌入式ADC省IO采集与Modbus浮点数传输实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/11 3:30:14

用VS Code搭建STM32开发环境:从Keil迁移到开源工具链

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/11 3:30:13

MySQL数据库操作与优化实战指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/11 3:25:13

Azure APIM自建网关自签名证书信任问题解决方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/10 16:39:38

超人会飞不算本事:系统稳定依赖清晰规则与边界设计

开头先不绕弯子。“#斯坦李吐槽dc 所以超人是无缘无故会飞的嘛哈哈哈哈哈哈哈锤哥真是技术人才啊!#雷神 #复联”这类调侃式短标题,第一波冲击力在于它把两个宇宙的角色塞进同一个吐槽箱里,但细想一下就能发现,它真正碰到的根本不是…

2026/9/10 11:16:38

超人VS蜘蛛侠:拆解超级IP的影响力与传播方法论

把“蜘蛛侠 vs 超人”放在 CSDN 上聊,可能很多人第一反应是走错片场了。但如果把这两个角色看成“两个持续运营了 80 多年的文化产品”,你会发现,这场比较本质上是两个不同 IP 策略的长期结果对比:超人赢在定义了整个超级英雄题材…

2026/9/9 16:31:09

基于CNN的调制信号识别:MATLAB实现时频图分类实战

简介:本资源是一套面向通信工程与信号处理方向学习者、研究者的深度学习实践方案,聚焦调制信号自动检测与识别这一典型无线通信任务,解决传统方法依赖人工特征、低信噪比下性能下降等痛点。压缩包共12个文件(10.73MB)&…

2026/9/10 12:32:02

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/10 15:19:50

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/10 15:49:53

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码