
文章目录前言1. 一句话理解 RAG2. 先看大局RAG 就俩阶段3. 离线阶段知识库是怎么建成的3.1 解析原始资料3.2 把长文档切成 Chunk3.3 给每个 Chunk 加 Metadata3.4 用 Embedding 模型生成向量3.5 写入向量数据库4. 在线阶段用户提问后发生了什么4.1 客户端只负责提交问题4.2 服务端先处理一遍问题4.3 把问题转换成查询向量4.4 召回候选资料5. 相似度不会直接生成答案6. 为什么还需要过滤和 Rerank6.1 权限过滤6.2 Metadata 过滤6.3 Rerank 重排7. 最终发送给大模型的到底是什么8. 各个组件分别负责什么9. 用伪代码看一次完整调用10. RAG 最容易翻车的七个地方10.1 文档切分不合理10.2 只用向量相似度10.3 没有权限过滤10.4 检索多少内容都塞给模型10.5 没有拒答机制10.6 知识库没有及时更新10.7 不记录检索过程11. 怎么评价一个 RAG 系统11.1 检索质量11.2 生成质量11.3 工程指标12. 总结P.S. 无意间发现了一个巨牛的人工智能教程非常通俗易懂对AI感兴趣的朋友强烈推荐去看看 传送门https://blog.csdn.net/HHX_01前言大模型很聪明这点我不否认。但它聪明得很局部你问它公司退款几天到账它敢根据训练数据给你编一个答案语气比你们老板还笃定。所以有了 RAGRetrieval-Augmented Generation检索增强生成。说白了就一句话让模型在回答之前先翻书再答题。你把它理解成开卷考试就行普通大模型闭卷全靠记忆硬扛RAG 是给模型递小抄先查资料再照着资料写答案。1. 一句话理解 RAG核心流程长这样用户提问 → 从知识库检索相关资料 → 筛选出少量可靠原文 → 问题和原文一起交给大模型 → 大模型生成答案注意它既不是重新训练模型也不是把整个知识库打包发给模型。真要把整库都塞给模型破产的不是模型是你的 Token 余额——按字收费的知识库是给家里有矿的人准备的。2. 先看大局RAG 就俩阶段离线阶段把知识库建好在线阶段检索资料并生成答案。一个负责囤货一个负责卖货。中间要是断了档前面囤再多也是库存积压。3. 离线阶段知识库是怎么建成的3.1 解析原始资料企业里的数据来源五花八门PDF、Word、Excel产品说明和操作手册内部 Wiki数据库记录客服 FAQ网页和接口。系统要做的是把正文、标题、表格和层级关系提取出来同时把页眉、页脚、导航栏和重复内容这些噪声清掉。这一步很重要输入是错的后面模型再强也白搭。这就跟你炒菜一样食材都馊了就别怪大厨手艺不行。3.2 把长文档切成 Chunk一份几十页的文档一般不会整体存成一个检索单元而是拆成多个文本片段也就是 Chunk。比如退款规则.md Chunk 1退款申请条件 Chunk 2退款审核流程 Chunk 3退款到账时间 Chunk 4特殊情况处理为什么要切两个原因一个问题通常只跟文档里的一小部分有关整篇塞进模型上下文既浪费 Token又稀释重点。但 Chunk 不是越小越好。切太小语义不完整切太大无关内容跟着混进来。这跟切西瓜一个道理切太小全是皮切太大一口塞不下。切分策略直接决定 RAG 的最终效果属于那种看着不起眼、翻车全怪它的环节。3.3 给每个 Chunk 加 Metadata除了原文每个 Chunk 通常还带点元数据{documentId:refund-policy-2026,title:退款到账时间,department:finance,tenantId:1001,securityLevel:2,updatedAt:2026-09-01}这些东西用来干嘛用户权限过滤、租户隔离、按部门检索、排除过期文档、展示答案的引用来源。说句实在话生产环境里权限过滤的重要性往往不低于检索准确率。你答得再准把 A 部门的工资单答给 B 部门第二天你面对的可能就不是代码评审而是检讨书评审。3.4 用 Embedding 模型生成向量Embedding 模型会把文本转换成一组数字退款一般在 35 个工作日到账 ↓ [0.018, -0.231, 0.764, ...]这些数字表达的是文本的语义特征。语义相近的内容在向量空间里的距离通常也比较近。所以下面三句话文字不一样但可能被检索到一起退款多久到账 退款到账时间 退款几天能收到说白了Embedding 就是把文字翻译成坐标。模型可能看不懂中文但它知道这两句话住隔壁。但注意Embedding 向量不是答案也不代表模型学会了这段内容。它只是帮你把语义相近的文本捞出来。3.5 写入向量数据库最终存进去的通常不只是向量而是向量 原始文本或文本 ID 文档来源 权限信息 其他 Metadata到此离线知识库准备完毕。接下来轮到在线阶段表演。4. 在线阶段用户提问后发生了什么假设用户问了一句退款需要多久才能到账4.1 客户端只负责提交问题客户端一般只提交这些东西{question:退款需要多久才能到账,conversationId:c-123}同时携带用户登录凭证。客户端不应该下载整个知识库、自己过滤知识库内容、保存模型或知识库密钥、决定用户有没有权看某份文档。这些活儿都应该在服务端干。客户端就是个传话筒你可以让它传话但别让它当家。真让它自己过滤知识库它连自己是哪个版本的程序都说不清楚。4.2 服务端先处理一遍问题RAG 后端收到问题后可能先做错别字修正、指代消解、多轮对话补全、查询改写、关键词提取、租户和用户权限解析。举个例子用户追问那节假日呢系统会结合上一轮对话把它改写成退款在节假日期间需要多久才能到账这个环节相当于给问题补全主语。不然模型收到一句那节假日呢很可能以为你在问它今天放不放假。4.3 把问题转换成查询向量退款需要多久才能到账 ↓ Query Embedding然后用查询向量去知识库里找距离较近的文档向量。4.4 召回候选资料向量数据库可能返回类似这样的结果0.92 退款一般在 35 个工作日到账 0.86 节假日期间退款可能顺延 0.78 退款申请提交后进入审核 0.61 发票通常在订单完成后开具这个阶段通常会适当多取一些比如 Top-K 取 20 条。原因很简单初次检索讲究宁滥勿缺后面还有层层筛选等着呢。有些系统还会同时跑关键词检索。向量检索擅长语义相近关键词检索擅长编号、名称和专业术语。两者结果合并就是混合检索。5. 相似度不会直接生成答案这是 RAG 里最容易误解的地方我必须单独拉出来讲。相似度的作用是决定哪些资料更值得交给大模型阅读。它并不直接决定最终答案怎么写。相似度检索 → 选择参考资料 大模型 → 阅读参考资料并生成答案相似度是 0.92不意味着模型会按 92% 的权重抄这句话。这个分数只是给候选资料排序用的相当于老师批卷前先按名字排个序——排前面的不一定分高分高的也不一定排前面。最终答案仍然是模型根据 Prompt一个字一个字猜出来的。6. 为什么还需要过滤和 Rerank向量检索快是快但初次返回的内容不一定准。所以候选资料还要过几道关。6.1 权限过滤用户所属租户必须匹配 用户部门必须具备访问权限 文档安全等级不能超过用户等级权限过滤必须在资料发给模型之前完成。否则就算页面没展示敏感引用敏感内容也已经进过模型了。这就像你把工资单递给同事看了一眼再收回来——收回来也没用了人家已经看到了。6.2 Metadata 过滤系统还能限定只检索当前产品、只检索已生效的规则、排除过期文档、只查指定业务类型。相当于给检索加了一堆硬性条件不符合的直接出局。6.3 Rerank 重排Rerank 模型会把用户问题和每个候选片段放在一起重新判断相关性。典型流程向量数据库快速召回 20 条 ↓ Rerank 精确重新排序 ↓ 选择最终 35 条你可以把向量检索理解成海选把 Rerank 理解成决赛。海选的时候谁都能上决赛的时候评委把明显凑数的全刷掉。7. 最终发送给大模型的到底是什么系统不会把整个向量数据库发给模型。一般只发系统回答规则、用户问题、筛选出的少量原文、必要的对话历史。比如这样系统规则 你只能根据参考资料回答。 如果参考资料不足请明确回答无法确定。 回答时标注资料编号不要自行补充业务规则。 用户问题 退款需要多久才能到账 参考资料 [1] 退款审核通过后一般在 35 个工作日到账。 [2] 如遇法定节假日到账时间可能顺延。模型最后生成退款审核通过后一般会在 35 个工作日到账如遇法定节假日到账时间可能顺延。[1][2]所以更准确的说法是服务端先筛好指定阅读模型再照着组织答案。不是把图书馆搬过去而是递上几页重点还贴好了标签。8. 各个组件分别负责什么组件主要职责客户端提交问题、携带用户凭证、展示答案和引用业务后端鉴权、检索编排、Prompt 组装和异常处理Embedding 模型将问题或文档转换为语义向量向量数据库快速召回相似的候选资料Rerank 模型对候选资料进行更精确的重新排序大模型阅读最终原文并生成答案简单概括后端负责调度向量数据库负责初筛Rerank 负责精选大模型负责写作文。你负责验收以及验收时血压升高。9. 用伪代码看一次完整调用不考虑具体框架一次问答大致长这样Stringquestionrequest.question();// 解析用户、租户和文档权限。AccessScopescopepermissionService.resolve(request.userId());// 从知识库中召回较多候选资料。ListcandidatesknowledgeBase.search(question,scope,20);// 删除无权限、已过期或者分数过低的资料。ListfiltereddocumentFilter.filter(candidates,scope);// 对候选资料重新排序并取最终五条。Listcontextreranker.rerank(question,filtered).stream().limit(5).toList();// 没有可靠资料时停止回答避免模型猜测。if(context.isEmpty()){return现有资料不足暂时无法确定。;}// 将规则、问题和原文组装成 Prompt。PromptpromptpromptBuilder.build(question,context);// 调用大模型生成最终答案。StringanswerchatModel.generate(prompt);// 返回答案以及对应的文档来源。returnresponseBuilder.build(answer,context);这段代码体现了 RAG 的本质Retrieve检索资料 Augment把资料加入上下文 Generate模型生成答案三个词一套流程外面包装得再花哨内核就是这么回事。10. RAG 最容易翻车的七个地方10.1 文档切分不合理标题和正文被拆开或者一条业务规则被切成几个不完整片段检索结果就算看着相似也可能答非所问。就像把请勿践踏草坪切成请勿和践踏草坪路人看了可能更兴奋。10.2 只用向量相似度专有名词、错误码、订单号、精确编号这些更适合关键词检索。所以生产系统基本都是混合检索。纯向量检索碰到订单号就像让老外念你的身份证号念得挺流畅但一个都不对。10.3 没有权限过滤只追召回率、不带权限就可能越权访问和数据泄露。检索系统漏一条资料顶多被骂权限漏一条资料可能就得走流程了。10.4 检索多少内容都塞给模型内容太少可能漏答案内容太多增加成本、延迟和干扰。Top-K 和最终 Top-N 应该拿测试集评估而不是拍脑袋定。毕竟你拍脑袋定出来的数最后大概率会拍到自己脸上。10.5 没有拒答机制资料不足还硬让模型回答结果就是一本正经地编。一个靠谱的 RAG 系统应该允许回答根据当前知识库资料无法确定。会拒答的模型才是好模型。硬编出来的答案发出去是痛快删帖的时候就不痛快了。10.6 知识库没有及时更新RAG 能读新知识不代表它会自动知道知识变了。文档新增、修改、删除都得同步更新索引。不然你以为它答的是新政策其实它背的还是去年的旧课文。10.7 不记录检索过程出错的时候你得知道用户原始问题是什么、改写后的查询是什么、召回了哪些片段、每条资料的分数是多少、最终给模型发了什么、模型引用了哪些资料。不然问题一出来你只能对着日志干瞪眼像极了考试查分时发现分数不对但卷子早被收走了。11. 怎么评价一个 RAG 系统RAG 不能只看回答听起来是否自然。至少得分开评估三块。11.1 检索质量正确资料有没有被召回、无关资料多不多、正确资料的排名够不够靠前、权限过滤对不对。11.2 生成质量答案有没有参考资料支持、有没有添加资料里不存在的内容、引用准不准、资料不足时有没有正确拒答。11.3 工程指标接口耗时、Token 消耗、知识库和模型调用成功率、超时降级和重试情况。重点是检索错误和生成错误必须分开定位。模型答错了不一定是模型菜也可能是系统根本没给它正确资料。这就跟外卖难吃一样别急着骂骑手也可能是后厨压根做错了菜。12. 总结RAG 不是什么神秘的新模型它是一套检索、上下文组装、模型生成的工程流程。完整链路可以归纳成文档解析 → 文本切分 → Embedding → 向量入库 → 用户提问 → 相似度召回 → 权限过滤 → Rerank → 选择少量原文 → 组装 Prompt → 大模型生成 → 返回答案和引用记住几个关键边界客户端只提交问题不负责过滤知识库相似度负责选资料不直接生成答案模型只接收筛选后的少量原文不会读整个向量库RAG 后端负责鉴权、检索编排、上下文组装和异常处理资料不足时靠谱的系统应该拒绝猜测。一句话收尾RAG 干的事就是让模型学会先翻书再答题。书翻好了答案自然稳书没翻好模型再聪明也是巧妇难为无米之炊。P.S. 无意间发现了一个巨牛的人工智能教程非常通俗易懂对AI感兴趣的朋友强烈推荐去看看传送门https://blog.csdn.net/HHX_01