想象你是一位新入职的管家,被派往一座巨大的宅邸。主人(用户)常常问你一些细碎的问题:“去年花园派对用的那套蓝色瓷器放在哪?”“三年前请的园丁叫什么名字?”你不可能把所有事情都记在脑子里——那是记忆宫殿的活儿,但宫殿再大,也有装不下或记忆模糊的时候。于是你学聪明了:在宅邸旁边专门盖了一座图书馆。每当主人提问,你先进图书馆查档案、翻索引、找书页,把相关资料带到书桌上,再组织成一份工整的回信,最后请一位质检员核对信息是否准确,这才呈给主人。这套“查书—写信—质检”的流程,就是我们要讲的 RAG(检索增强生成)架构。 RAG 的全称是 Retrieval-Augmented Generation,意思是“检索增强的生成”。它把一个普通的大语言模型(LLM),从“凭记忆答题”升级为“查资料再答题”。整个过程分成三件事:检索(Retrieval)——从外部知识库中找到相关片段;生成(Generation)——把片段组织成自然语言答案;评估(Evaluation)——检查答案是否忠实、相关、完整。这三件事循环往复,让 AI 既能引用最新知识,又能减少胡编乱造。
RAG 是当前 AI 落地中最实用的架构之一。掌握它,你就掌握了让大模型“连接企业私有数据、实时更新知识、可控生成答案”的核心技能——这是从“会聊天”走向“能干活”的关键一跃。
可视化演示
展示RAG(检索增强生成)架构的三阶段流程:检索相关文档、LLM生成回答、评估质量指标,揭示检索增强如何提升大模型回答的事实准确性。
本节配有交互动效(进入视口后自动加载,约 3KB)。
RAG检索增强生成流水线 检索模块从知识库获取Top-K相关文档 LLM结合检索上下文生成事实性回答 answer=LLM(query,context) 检索增强减少幻觉
概念总览
管家站在新建成的图书馆前,深吸一口气。主人第一次问他:“上个月项目复盘的重点是什么?”他没有立刻回答,而是快步走进图书馆,在索引卡片柜前停下,抽出几张卡片,再跑到对应的书架前翻找,最后回到书桌前奋笔疾书。这个“查—找—写”的过程,就是 RAG 的缩影。检索增强生成把大模型的“记忆”外挂到一个可随时更新的知识库上,让模型不再只靠训练时固化的参数记忆。
为什么要这样做?因为纯粹的 LLM 有三个天生的短板:知识陈旧(训练数据截止于某个时间点)、幻觉频发(不懂装懂地编造事实)、无法定制(不懂企业内部的私有资料)。RAG 的思路非常朴素:既然记忆不可靠,那就去查资料。用户提问后,系统先从外部知识库检索相关文本片段,再把片段拼进提示词让 LLM 参考着写答案。这就像考试从“闭卷”变成“开卷”。
整个流程构成一个 检索—生成—评估 的闭环。检索负责“找对书”,生成负责“写好信”,评估负责“把好关”。若评估发现答案不理想,则反馈给检索环节重新调整查询,再生成一轮。如此循环,答案越改越准。
图书馆的第一天工作结束,管家在日志上写下:“查书不是万能的,但不查书是万万不能的。” RAG 的哲学正是如此——把“记忆力”交给知识库,把“理解力”留给模型。
- 检索输入系统把用户问题转换为检索查询,到知识库中匹配最相关的文本片段。
- 生成依赖LLM 以检索到的片段作为参考资料,生成回答。
- 质量评估用评估指标判断答案是否忠实于依据、是否回应问题。
架构分层
图书馆不是一间空旷的大厅,而是划分了不同功能的区域:门口是接待处(应用层)、中间是索引卡片区(索引层)、深处是档案库房(数据层)、角落还有写作间和质检岗(生成与评估层)。RAG 架构同样按职责自上而下分成四层,每层各司其职,层与层之间通过标准接口对接。
数据层是图书馆的馆藏仓库,存放各类原始文档:PDF、网页、数据库记录、工单日志。它不关心“怎么被找到”,只负责“存得好”。索引层是目录卡片柜,把数据层的内容加工成可快速检索的形式——切块、向量化、建倒排索引。如果说数据层是书,索引层就是书的目录和检索标签。
生成层是写作间。LLM 在这里阅读检索层送来的资料,组织语言、生成答案。它不直接访问数据库,只依赖提示词里塞进来的上下文。评估层是质检岗,负责检查生成层的产出是否忠实于资料、是否切题、引用是否正确。评估不过关,就退回检索层重新找材料。
管家把四层比喻画成一张图贴在图书馆墙上:资源在底层,智慧在顶层,中间用索引搭桥,用评估守门。团队新来的实习生看一眼就明白了整个系统的骨架。
- 数据层职责负责文档的接入、清洗、格式统一,是知识的最原始来源。
- 索引层加工将清洗后的语料切块、嵌入成向量,构建快速检索结构。
- 生成层调用LLM 把检索片段作为上下文,生成用户可读的答案。
- 评估层把关评估答案质量,输出分数或修正信号,驱动下一轮迭代。
索引构建
档案室里的书不能整本塞给检索员——书太厚,翻起来慢,而且主人只关心某一页的某一段话。RAG 的做法是把文档“拆书分章”,切成合适大小的块(chunk),然后为每块生成一个语义“指纹”(向量),最后把指纹卡片按序排进索引柜。这个过程叫索引构建(Indexing)。
第一步是分块(Chunking)。分块大小要恰到好处:块太大,包含太多噪音,检索不精准;块太小,语义不完整,答案缺上下文。常用策略是固定 token 数(如 256 或 512)加重叠窗口,让相邻块共享一些内容,避免关键信息被拦腰截断。第二步是向量化(Embedding),用嵌入模型把每块文本映射成一个高维向量,语义相近的文本向量距离更近。第三步是元数据标记,给每块贴上来源文档、章节、时间戳等标签,方便后续过滤和溯源。
最后全部向量存入向量数据库(如 Milvus、FAISS、pgvector)。数据库内部用近似最近邻(ANN)算法加速查找,避免在百万级向量中逐一比对。至此,图书馆的“目录卡片”准备完毕,静待检索员使用。
管家在整理档案时感叹:“书拆成页,页编上码,码挂上锁——索引构建就是给知识上'定位系统'。” 有了这套系统,无论馆藏多少书,检索员都能在毫秒级找到主人要的那一页。
- 文本映射每个文本块通过嵌入模型得到一个固定维度的向量。
- 维度含义\(d\) 是向量维度,常见如 768 或 1536,由嵌入模型决定。
- 距离度量检索时计算查询向量与文档向量的相似度,选 Top-K。
检索融合
第二天,主人问:“去年下半年我们有哪些供应商合同到期?”单靠语义检索,可能找到一堆关于“合同管理”的泛泛之谈;单靠关键词检索,又会漏掉那些用词不同但意思相近的句子。聪明的检索员不会只用一把钥匙开门——他会同时让语义检索和关键词检索两条通道工作,再融合结果。
语义检索(向量检索)用嵌入模型把查询和文档都变成向量,计算余弦相似度,擅长“意思相近但字面不同”的匹配。关键词检索用 BM25 等算法做精确词项匹配,擅长代码、型号、人名等必须精确命中的查询。两条通道各有侧重,于是有了混合检索(Hybrid Search):用加权求和或 RRF(Reciprocal Rank Fusion)把两路结果合并,让双方的优势互补。
合并之后还有一个关键步骤——重排序(Rerank)。召回阶段为了速度用了轻量模型,选出大约 50 个候选片段;重排序阶段用更重的交叉编码器逐一精算相关性,重新打乱顺序,只保留 Top 5 送入生成层。这就像检索员先快速扫一遍书架,抱回一堆候选书,再坐在桌前逐本翻看目录,挑出最相关的三页。
管家发现,双通道检索就像同时问两位老员工:一位靠关键词记忆(“发票号码我记得”),一位靠语义理解(“你说的是不是那个流程?”)。两人意见综合,再请部门主管定夺——这就是重排序的角色。
- 归一化得分两种检索的分数范围不同,需要先归一化到同一尺度。
- 加权融合用权重 \(\alpha\) 控制两种信号的侧重。
- 重排精筛交叉编码器对查询-文档对打分,输出精排后的 Top-K。
生成优化
材料齐了,但直接全部堆到 LLM 面前却未必是好事。上下文窗口再大,塞进 50 个片段也会稀释注意力,甚至超出限制。作家拿到检索员抱来的一摞书,不会整本抄写,而是先筛选精要、组织提纲,再动笔写回信。这一节讲的就是生成环节的优化艺术。
提示词组装(Prompt Assembly) 是第一步。系统把用户问题、检索片段、指令模板拼成一个结构化的提示词,明确告诉模型:“请仅依据以下资料回答,不要编造。若资料不足以回答,请说明不知道。” 模板固定而内容灵活,相当于回信的固定格式和可变素材。上下文压缩 是第二步:对检索片段做剪裁,去掉与问题无关的冗余内容,按相关性排序装配进提示词。有时还会用摘要模型先压缩长文档,只保留最相关的句子。
引用溯源 是第三步:生成答案时标注信息来源编号,用户点击编号即可查看原始文档。这不仅提升可信度,也让评估模块更方便核验。参数调控 是第四步:把温度(temperature)调低让输出更确定,开启 top_p 采样控制多样性,设置 max_tokens 限制长度——这些旋钮决定了回信的“语气和篇幅”。生成优化不是修改模型权重,而是调整模型“怎么看资料、怎么写答案”。
管家在写作间贴了一张纸条:“好回信 = 模板定骨架 + 材料填血肉 + 引用标出处。” LLM 的生成能力不变,变的是喂给它的资料和约束方式。
- 角色约束段system 部分设定模型扮演“严谨的助手”,要求仅依据资料作答。
- 材料注入段把检索到的片段按序排列,并标注编号 [1]、[2] 等。
- 回答指令段告诉模型引用编号来源,并规定输出格式。
评估体系
信写好了,能直接寄给主人吗?不行。管家会让质检员先读一遍:这封信的依据是真的吗?有没有夸大或臆造?有没有答非所问?引用编号和原文对得上吗?这套“质检”对应 RAG 的评估体系。没有评估,RAG 就像一个没人检查作业的学生,错都不知道错在哪。
最核心的三个评估维度:忠实度(Faithfulness) 检查答案是否忠于检索到的上下文——如果答案声称“合同 2025 年到期”,但原文写的是“2024 年”,就是扣分项;相关性(Relevancy) 检查答案是否回应了用户的问题——问“怎么请假”,答“公司福利很好”,就是不相关;上下文命中率(Context Relevancy) 评估检索回来的片段与问题的匹配度——如果检索环节就拿错了材料,生成环节再努力也白搭。
工程上常用 RAGAS 等框架自动化计算这些指标:先用 LLM 生成“判断题”或“选择题”来测试答案,再统计通过率。评估结果不只用于打分,更重要的是构成反馈闭环:低分答案触发问题分析,可能是分块策略不合理、嵌入模型不匹配、重排序没生效,逐一修正后重新评估,如此迭代。评估不是终点,而是优化的起点。
质检员在周报上写道:“上周 12 封回信中,3 封引用错误,2 封答非所问——不是作家不努力,是材料没找对。” 评估把问题定位到了检索环节,这正是反馈闭环的价值。
- 陈述抽取把答案拆成若干独立陈述句。
- 依据判定逐一判断每个陈述能否由上下文推导出来。
- 比例计算所有被支持的陈述除以总陈述数,得到忠实度分数。
AI 应用场景
智能客服知识库问答
阶段:检索 + 生成 + 评估
解决的问题:传统客服依赖人工翻阅规章制度和 FAQ,响应慢、标准不一;大模型直接问答又会幻觉频出,把 A 产品的退换货政策安到 B 产品上。RAG 让模型每次回答前先查企业知识库,再基于检索到的条款作答,并附上原文链接供客户核对。
具体案例:某电商公司把《售后政策手册》《产品说明书》《物流规则》导入 RAG 系统。用户提问“电饭煲内胆裂了能换吗?”,系统检索到“内胆属于易损件,7 天内可换新”的条款,生成的答案自动标注条款编号。评估模块每天统计忠实度分数,发现连续三天低于 0.9 就触发告警,提醒运营更新文档或调优检索参数。
企业内部文档智能问答
阶段:索引构建 + 检索融合
解决的问题:大型企业文档分散在 Confluence、钉钉、SharePoint 多个平台,员工搜不到、看不完。RAG 先把多源文档统一接入、分块、向量化,构建企业统一的“知识图书馆”,再通过混合检索融合关键词和语义匹配,让员工用自然语言就能跨平台找资料。
具体案例:某制造企业把 2 万份工艺文档、安全规范和设备手册建立 RAG 索引。工程师问“3 号产线气动阀型号及维护周期”,系统先语义检索到相关段落、再用关键词确认型号"FESTO VZBA-20",重排序后返回 Top 3 文档。评估反馈显示,问题解决时间从人均 40 分钟降到了 5 分钟。
Python 演示
# 最小 RAG 演示:分块 + 嵌入 + 检索 + 生成模板import math # 模拟文档库DOCUMENTS = [ "公司年假政策:入职满一年可享5天年假,满三年可享10天。", "年假申请需提前三天在OA系统提交,经部门经理审批。", "未休年假可顺延至次年三月,逾期作废。", "离职时未休年假按日工资三倍折算补偿。",] def chunk_docs(docs, chunk_size=12): """按字符数简单分块""" chunks = [] for doc in docs: for i in range(0, len(doc), chunk_size): chunks.append(doc[i:i+chunk_size]) return chunks def embed(text): """简化嵌入:按关键词表统计词频作为向量""" vocab = ["年假", "申请", "审批", "离职", "补偿", "顺延", "OA", "经理"] vec = [0.0] * len(vocab) for i, word in enumerate(vocab): if word in text: vec[i] = 1.0 return vec def cosine_sim(vec1, vec2): """余弦相似度""" dot = sum(a * b for a, b in zip(vec1, vec2)) norm1 = math.sqrt(sum(a * a for a in vec1)) norm2 = math.sqrt(sum(b * b for b in vec2)) if norm1 == 0 or norm2 == 0: return 0.0 return dot / (norm1 * norm2) def retrieve(query, chunks, top_k=2): """检索最相关的 top_k 个块""" q_vec = embed(query) scored = [(cosine_sim(q_vec, embed(c)), c) for c in chunks] scored.sort(key=lambda x: x[0], reverse=True) return [c for _, c in scored[:top_k]] def generate(query, contexts): """模拟 LLM 生成:模板拼接 + 来源标注""" template = ( "请仅依据以下资料回答问题。\n" "【资料】\n{}\n" "【问题】{}\n" "【回答】" ) ctx_text = "\n".join(f"[{i+1}] {c}" for i, c in enumerate(contexts)) return template.format(ctx_text, query) def evaluate(answer, contexts): """简单评估:检查回答中是否包含资料来源编号""" supports = all(f"[{i+1}]" in answer for i in range(len(contexts))) return supports def main(): chunks = chunk_docs(DOCUMENTS) query = "年假没休完离职怎么算" contexts = retrieve(query, chunks) prompt = generate(query, contexts) print("=== 检索到的资料 ===") for i, c in enumerate(contexts, 1): print(f"[{i}] {c}") print("\n=== 发给 LLM 的提示词 ===") print(prompt) print("\n=== 评估检查 ===") print("引用编号齐全:", evaluate(prompt, contexts)) if __name__ == "__main__": main()
chunk_docs(docs, chunk_size=12)把长文档切成小块,模拟索引构建中的分块策略;块太大检索不精准,块太小语义不完整。embed(text)用简单的词频表模拟嵌入向量,真实系统中会用 BERT 或 OpenAI embedding 模型生成高维语义向量。cosine_sim(vec1, vec2)计算查询与文档的余弦相似度,得分越高代表语义越接近,是语义检索的核心数学操作。retrieve(query, chunks, top_k=2)对所有分块打分排序,取 Top-K 返回,对应 RAG 的召回阶段。generate(query, contexts)把检索结果和用户问题组装成提示词模板,要求模型“仅依据资料回答”,对应生成阶段的提示词组装。evaluate(answer, contexts)检查提示词中是否包含引用编号,模拟评估环节对答案可溯源性的基本校验。
常见误区
误区我以为 RAG 就是装个 Milvus,把 PDF 全丢进去,然后让 GPT 直接回答就行。结果检索出来的内容乱七八糟,答案也错得离谱。
正解向量数据库只是 RAG 的“仓库”,真正决定效果的是仓库里的“编目质量”——分块策略是否合理、嵌入模型是否匹配语料、元数据是否完整、检索融合和重排序是否到位。就像图书馆不是有了书架就能找到书,还得有好的索引卡片和检索员。
为何常见:RAG 的入门 Demo 确实只需要三步(导入、检索、生成),让人觉得很简单;但工程上每个环节都有大量调优空间,效果差距往往藏在这些“看不见的细节”里。
误区检索嘛,多召回一点总没错,把 top 20 个片段全放进提示词,让模型自己挑重点。结果答案变得冗长且前后矛盾。
正解上下文窗口有限,片段越多噪音越大,LLM 的注意力会被无关信息稀释。正确做法是先召回较多候选,再用重排序精选 Top 3-5 个片段,必要时做上下文压缩和去重。这和写作一样:书桌上堆满资料反而写不出好文章,只留最相关的几页才是正道。
为何常见:直观上觉得“信息越多越安全”,忽略了 LLM 的注意力机制对噪声敏感,也忽略了 token 成本随长度上升。
误区RAG 做完了,我人工读了几条答案,觉得还行就算验收通过。结果用户反馈频出,说答案和原文对不上。
正解人工抽读只能发现显眼问题,系统性评估需要量化指标:忠实度检查答案是否有依据,相关性检查是否答所问,上下文命中率检查检索质量。用 RAGAS 等框架批量跑分,并建立“低分→归因→修正”的反馈闭环,才能持续优化。
为何常见:评估意识薄弱,觉得“生成结果能读就行”;但 RAG 的价值恰恰在于可控和可信,没有量化评估就无法证明它比纯 LLM 更可靠。
误区听说 RAG 能解决幻觉和知识更新问题,那微调是不是就没用了?
正解RAG 解决的是“外部知识获取”,微调解决的是“模型行为风格”,二者是互补关系。如果模型本身理解能力弱、指令遵循差,再好的检索资料也生成不出高质量答案。通常做法是:用微调让模型学会“依据资料作答”的规范,用 RAG 提供最新资料。
为何常见:把 RAG 神话为“万能药”,忽略了它只是架构层面的优化,而微调是模型层面的优化,两者作用层级不同。
面试题
Q1. RAG 中 "R" 的核心作用是?
- A.让模型生成更流畅的文本
- B.从外部知识库检索相关信息← 正确答案
- C.压缩模型的上下文窗口
- D.对答案进行语法纠错
答案:B。RAG 的 R 即 Retrieval,核心是从外部知识库中检索与问题相关的文本片段。选项 A 是生成环节的目标,C 是优化手段,D 是后处理,都不属于检索的职责。
Q2. 混合检索为什么同时使用语义检索和关键词检索?
- A.为了增加系统复杂度
- B.两种检索速度不同可以互补提速
- C.语义检索擅长意图匹配、关键词检索擅长精确命中,互为补充← 正确答案
- D.关键词检索效果总是更好,需要语义来兜底
答案:C。语义检索能抓住“意思相近但字面不同”的查询,关键词检索能精确匹配型号、人名等专有名词。两者融合才能兼顾“理解”与“精确”,选项 A、D 描述不准确,B 与速度无关。
Q3. 文档分块时加入重叠窗口的主要目的是?
- A.增加向量数量以提升召回率
- B.避免关键信息恰好被切断在相邻块的边界← 正确答案
- C.减小单块 token 数以节省成本
- D.让嵌入模型训练更充分
答案:B。分块时如果恰好把一句完整的话拦腰截断,该块语义就会残缺。重叠窗口让相邻块共享边界内容,降低信息被切断的概率。A 是副产品而非目的,C 与重叠方向相反,D 与嵌入训练无关。
Q4. 重排序(Rerank)在 RAG 中的作用是?
- A.重新生成用户问题
- B.对召回候选做精细相关性打分并精选 Top-K← 正确答案
- C.压缩向量维度加快检索
- D.把文本格式化为 Markdown
答案:B。召回阶段追求速度,用轻量模型选出较多候选;重排序用更重的交叉编码器逐一精算相关性,精选少量片段送入生成层。A 属查询改写,C 属向量优化,D 属格式化,均非重排序职责。
Q5. 以下哪些属于 RAG 评估体系的维度?
- A.忠实度(Faithfulness)← 正确答案
- B.相关性(Relevancy)← 正确答案
- C.上下文命中率(Context Relevancy)← 正确答案
- D.模型参数量大小
答案:ABC。RAG 评估围绕“答案是否忠实于依据、是否回应问题、检索材料是否命中”三个维度展开。模型参数量是模型本身的属性,与一次对话的答案质量无关,故 D 不选。
Q6. 忠实度(Faithfulness)的计算方式是?
- A.检索片段数与生成答案字数之比
- B.答案中能被上下文支持的陈述数占总陈述数的比例← 正确答案
- C.提示词模板的固定部分占比
- D.用户对回答的点赞率
答案:B。忠实度把答案拆成陈述句,逐一判断是否能由上下文支持,再用支持数除以总陈述数。A 与数量和长度有关而非语义,C 是工程实现细节,D 是主观反馈,均不能度量“忠于依据”。
Q7. 关于 RAG 生成优化,以下说法正确的是?
- A.低温度(temperature)让输出更确定← 正确答案
- B.上下文压缩是为了减少无关信息干扰← 正确答案
- C.引用溯源标识来源文档编号提升可信度← 正确答案
- D.提示词模板应包含尽量多无关示例
答案:ABC。低温度让概率分布更尖锐,输出更确定;压缩上下文可降低噪声、节省 token;引用溯源让答案可核验。提示词模板应精炼相关示例,无关示例只会干扰模型,D 错误。
Q8. 为什么 RAG 能缓解大模型幻觉问题?
- A.因为检索到的资料比模型参数更权威
- B.因为模型生成时不再依赖训练数据
- C.因为生成时有了外部资料作为依据,减少凭空编造← 正确答案
- D.因为参数被冻结不会更新
答案:C。幻觉源于模型凭记忆编造。RAG 让模型先看检索到的相关资料再作答,相当于“开卷考试”,每句话都有来源可循,凭空编造的概率大幅下降。A 不绝对,B、D 表述错误。
Q9. 评估反馈闭环中,发现忠实度低最可能先排查哪个环节?
- A.用户网速是否过慢
- B.检索到的上下文是否与问题匹配← 正确答案
- C.前端按钮样式是否美观
- D.显卡温度是否过高
答案:B。忠实度考察答案是否忠于上下文。若上下文本身与问题不匹配,模型无米下锅、只能硬编,忠实度自然低。因此先检查检索质量(分块、嵌入、重排序),而非网络、样式或硬件。
Q10. RAG 架构包含以下哪些层次?
- A.数据层← 正确答案
- B.索引层← 正确答案
- C.生成层← 正确答案
- D.评估层← 正确答案
答案:ABCD。RAG 自上而下分为应用层、生成层、检索层、数据层,也可细化为数据层、索引层、生成层、评估层四层。四个选项正是图中“图书馆”的四个功能区,缺一不可。