尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

RAG基础与实践:为AI Agent搭建私有知识获取管道

发布时间:2026/9/28 15:43:05

资讯中心
01
ARTICLE

RAG基础与实践:为AI Agent搭建私有知识获取管道

RAG基础与实践:为AI Agent搭建私有知识获取管道
做 AI Agent 的人迟早会撞上一堵墙模型上下文窗口再大也装不下你的业务知识模型再聪明也没法凭空知道你们公司的产品参数、部门流程、历史决策。前几篇聊 Agent 的规划和工具调用时我还比较从容但真到了让 Agent 回答业务问题的阶段才意识到它背后必须有一条看不见的知识获取管道——也就是 RAGRetrieval-Augmented Generation检索增强生成。RAG 这个词这两年快被聊烂了但说实话多数文章都停在什么是 RAG的科普层面。真把 RAG 作为 Agent 的一块基础设施去搭建时细节多到头皮发麻文档怎么切、向量怎么选、检索结果怎么过滤、模型怎么编排环环都是坑。这篇是走进 AI Agent系列的第四篇我打算把 RAG 基础讲透——它在大模型应用里的真实定位、整条链路每个环节的核心逻辑、一个能跑通的最小闭环以及我在实际项目里摸出来的调参和排坑经验。不管你是用 LangChain、LlamaIndex还是打算自己造轮子只要准备给 Agent 喂私有知识这篇都能帮你搭一个相对完整的坐标系。1. 为什么 AI Agent 需要一条知识获取管道1.1 大模型的记忆天花板与知识割裂先说一个很多人不太愿意面对的事实大模型的知识本质上停留在训练数据那个时间点。它见识广但认识你。你说我们公司的售后政策是什么它大概率会给你一个流畅但完全虚构的答案——因为它没见过你公司那篇 2024 年改了三版的《售后服务管理办法》。这就是知识割裂问题的根源。企业的知识散落各地产品手册在 Wiki业务规范在 PDF历史决策在聊天记录数据口径在数据库。Agent 要变成一个真正能干活的生产力工具就必须通过某种管道主动去获取这些知识而不是指望模型记得。有人会问现在上下文窗口不是动辄几十上百万 token 吗一股脑全塞进去不就行了我用过一个很土但有效的比喻上下文窗口就像办公桌你可以把所有资料堆满整张桌子但桌子越大你要从里面找到某一份文件的时间就越长注意力也会被大量无关信息稀释。业界有个著名的lost in the middle现象——模型对上下文中间部分的内容记忆最差。硬塞不但费钱、费延迟效果也未必好。所以问题从怎么把知识塞进去变成了怎么在需要的时候把最相关的知识精准捞出来这正是 RAG 干的事。1.2 RAG 能解决什么不能解决什么把 RAG 拆开看它就是先检索再生成两段式先从知识库里找出与问题相关的片段再把这些片段作为参考材料交给大模型作答。它解决的核心问题有三个第一知识时效性。知识库里的文档可以随时更新今天改完明天就能生效不需要重新训练模型。第二私有化知识接入。企业内部的非公开资料通过 RAG 能安全地附加到模型能力之上模型本身不接触训练数据核心资料只出现在检索结果和生成上下文中。第三可溯源性。每次回答都能关联到具体的知识来源出了问题可以追责到某一份文档这在金融、医疗等强合规场景几乎是硬性要求。同时也能显著降低幻觉——给模型提供了真实依据瞎编的概率会小很多但注意是小很多不是归零。RAG 不解决什么也很重要。它不负责逻辑推理文档里没有的推理链条别指望它推出来它治不了烂文档——源文档本身就是错的、互相矛盾的检索得再好也是垃圾进、垃圾出它也不是低延迟的万能药多一跳网络检索就多一份延迟开销。很多人对 RAG 期待过高上线后才发现问题出在知识库本身质量太差这时候换什么检索策略都救不回来。1.3 什么时候应该上 RAG我在实际项目里会这样判断如果场景是模型需要回答超出其训练知识范围、且内容会持续更新的业务问题RAG 基本是首选方案。典型场景包括企业知识库问答、客服助手、代码库问答助手、合规审查辅助、销售售前资料查询。如果场景是高度确定性的结构化业务操作比如查订单状态、算工资、走审批流那直接查数据库、调 API 更合适硬套 RAG 属于杀鸡用牛刀。还有一种常见选择题是RAG 还是微调。我的经验是要补的是知识就选 RAG要改的是行为风格就选微调。比如希望模型用特定语气、严格按照公司格式输出微调更合适希望模型知道某个产品的具体参数RAG 成本低、更新快优势明显。两者并不互斥复杂系统里经常混用。2. RAG 核心链路拆解五个环节的为什么2.1 知识接入文档加载与清洗是地基RAG 的第一个环节是知识接入也是最容易被低估的环节。很多人以为就是把 PDF 扔进去其实 PDF 解析能折腾到怀疑人生。扫描版 PDF 要先 OCR复杂表格经常被解析成乱序文本多栏排版会打乱阅读顺序页眉页脚混进正文。我见过一个真实案例一份产品规格书的页脚是第 3 页共 12 页结果检索出来的答案里频繁出现共 12 页这种莫名其妙的内容因为每次切分都把页脚带进去了。我的建议是在进入切分和向量化之前先做一轮清洗和格式统一。规则包括去重、去除无意义符号和重复页眉页脚、统一日期格式、把表格转成 Markdown 或键值对结构。同时一定要保留并丰富元数据来源、章节、页码、更新时间、权限范围。这些元数据在后面对检索结果做过滤时价值巨大——比如只查 2024 年以后的文档只查某个产品线的资料没有元数据就只能对所有结果做全文扫描效率低而且容易混入过期内容。接入的文档类型决定了清洗策略。Markdown/HTML 类结构良好清洗成本最低PDF 要看是文字版还是扫描版Word 要注意样式层级是否规范。这一步没有太多技术含量但它的质量决定了后续所有环节的上限值得多花时间。2.2 切分策略chunk 大小为什么这么敏感清洗完的文档要切成块因为向量检索不能一整个文档去比对——文档太长语义会被稀释切得太碎单个片段又缺上下文。chunk 的大小选择是个经典的过犹不及问题。这里先明确一个概念chunk 是检索的最小单元也是大模型看到的最小上下文单位。切分后的每个 chunk会被 embedding 成一个向量检索时用户的query 变成向量去匹配最相似的一批 chunk最后这批 chunk 被塞进 Prompt 供模型作答。所以 chunk 直接决定了模型能看到什么。大小怎么定经验值一般在 300 到 800 token 之间同时保留 10% 到 20% 的 overlap重叠部分。overlap 的作用是避免句子被拦腰切断导致语义断裂。但要注意overlap 只是缓解问题不是根治。比如一句话被切到两个 chunk 里各自都只剩半句重叠再多也恢复不了原意。更好的办法是按结构切Markdown 按标题层级切代码按函数和类切普通文本按段落边界切。现在很多框架默认的 RecursiveCharacterTextSplitter 就是按分隔符优先级递归切分先按段落切段落太长再按句子切尽量避免拦腰斩。我做过一个对照实验同一批技术文档用 200 token 切分时回答涉及多步骤流程的问题经常漏掉后半段用 1000 token 切分时单步细节问题的检索准确率明显下降。最终选了 500 token 50 token overlap兼顾了两种情况。后面在调优部分我会再展开怎么系统性地验证这个参数。2.3 Embedding文本到向量的那一步chunk 切好了下一步是把文本映射成向量。Embedding 模型的本质是把语义相似度翻译成向量空间距离语义相近的句子向量距离就近语义无关的句子向量距离就远。选 embedding 模型时我最看重三个指标语言支持、向量维度、最大输入长度。做中文场景首选对中文支持好的模型比如 BGE 系列、M3E 系列或者 OpenAI 的 text-embedding-3-small对中文也够用。向量维度影响存储成本和检索速度维度越高理论上表达力越强但存储和计算开销也越大。text-embedding-3-small 是 1536 维可以降到 512 维BGE-M3 是 1024 维。很多场景下降维度并不会带来明显效果下降但成本显著降低。容易被忽略的一个点是query 和文档在 embedding 时可能要用不同的指令前缀。部分模型提供了 query instruction 和 passage instruction比如 BGE 系列在检索阶段给 query 加上为这个句子生成表示以用于检索相关文章这样的指令能明显提升检索精度。如果你直接用同一个 embedding 接口同时处理 query 和文档等于放弃了免费的优化。另外相似度度量方式也要和模型的训练方式匹配。常用的是余弦相似度很多向量库默认也是它。有些场景会改用内积或欧氏距离这个要看模型文档说明别想当然。2.4 向量存储与检索索引embedding 完成后chunk 向量要存起来供后续检索。向量数据库和索引的选择取决于数据规模和部署形态。小规模项目几万条以内直接用 FAISS 这类向量索引库就够了它甚至不需要独立服务本地持久化一个文件就行我已经在很多项目里用它跑通了验证。中等规模且已有 PostgreSQL/Mysql 的团队可以优先考虑 pgvector 这类扩展少引入一个组件。企业级大规模、高并发、需要在线扩容的场景才值得上 Milvus、Qdrant 这类独立向量数据库。索引类型这块最常用的是 HNSWHierarchical Navigable Small World。它是基于图的近似最近邻索引检索速度很快但建库时有两个参数值得关注M每个节点的最大连接数越大召回越准但内存占用越高和 efConstruction建图时的搜索宽度。实际经验数据量在百万级以内默认参数基本够用数据量上去了优先考虑先粗召回再精排的策略而不是一味调大 M。还有一个非常实用但经常被忽略的能力元数据过滤。向量检索负责语义匹配结构化过滤负责精确条件两者结合效果远好于纯靠向量。比如只检索 2024 年发布的、属于产品 A 的文档这类需求就应该用元数据过滤直接筛掉不符合条件的向量而不是把所有向量都拉出来算相似度。2.5 生成端增强发生在提示词里检索到的相关 chunk最终要通过 Prompt 传递给大模型。这个环节看起来简单但 Prompt 的结构直接影响回答质量。我的标准模板一般包含三块系统角色指令、参考材料、用户问题。角色指令里一定要写明两件事只依据提供的材料回答材料中找不到答案时明确说不知道不要编造。第二句尤其重要它是对抗幻觉的最后一道防线。很多人以为 RAG 加上了幻觉就消失了其实如果模型觉得自己知识库里应该有答案它还是倾向于编一个出来。明确指令能有效压制这种倾向。另外有条件的话把每个 chunk 的来源标注传给模型让它在回答后附上引用来源这样既方便用户核对也方便你事后排查是哪一段文档导致了错误回答。我曾经在一个项目里给每个 chunk 的文本前面加上[资料1][2.3节]xxx这样的前缀模型回答时就会带上[资料1]引用排查效率提升一大截。3. 实操从零跑通一个最小 RAG 闭环3.1 技术选型框架、服务还是自研动手前先选型。市面上三条路用 LangChain/LlamaIndex 这类生态编排框架用现成的 RAG 服务现在很多平台已经把 RAG 封装成 Service比如 AgentScope 2.0 里提出的 RAG as Service 思路直接调接口就能用或者自己用 FAISS 加一个 embedding 接口几十行代码搭最小链路。我的建议是学习阶段和快速验证用框架或现成服务先跑通再谈优化一旦进入生产一定要搞明白框架每一步在干什么。LangChain 这类框架封装层级多版本升级又频繁搜索一下就知道网上大量报错都来自版本不匹配。如果你只是为了做一个 demo 展示效果框架确实快但要做生产系统强烈建议至少把核心链路切分、向量化、检索、重排自己实现一遍哪怕最后生产还是用框架这一遍会给排查问题带来巨大帮助。有些团队会纠结必须把向量数据库搭起来。我个人的看法是最小验证阶段不需要独立数据库。FAISS 本地索引 一个 embedding 接口 一个 LLM 接口已经是完整闭环。把这条链路跑透了再按需接入真正的向量库迁移成本不高。3.2 最小实现代码走读我以一个产品手册的知识库问答为例带大家走一遍最小实现。先准备一份 Markdown 文档作为知识源然后用 LangChain 简化演示但每一步我都会说明底层在做什么。第一步文档加载与切分from langchain_community.document_loaders import TextLoader from langchain_text_splitters import RecursiveCharacterTextSplitter # 1. 加载文档 loader TextLoader(product_manual.md, encodingutf-8) docs loader.load() # 2. 切分文档 splitter RecursiveCharacterTextSplitter( chunk_size500, # 每个块约 500 token chunk_overlap50, # 重叠 50 token尽量保持语义完整 separators[\n\n, \n, 。, , , , ], ) chunks splitter.split_documents(docs) print(f切分完成共 {len(chunks)} 个块)注意separators的写法它让切分器优先按段落边界切段落太长再退到按句号、逗号切最后才按字符硬切。这个优先级最大程度保证了 chunk 的语义完整性。第二步向量化与存储from langchain_openai import OpenAIEmbeddings from langchain_community.vectorstores import FAISS # 3. 向量化 embeddings OpenAIEmbeddings(modeltext-embedding-3-small) # 4. 构建 FAISS 索引并持久化 vectorstore FAISS.from_documents(chunks, embeddings) vectorstore.save_local(kb_index) print(知识库索引已保存到 kb_index 目录)这一步做了三件事把每个 chunk 调 embedding 接口转成向量把向量和 chunk 文本、元数据一起存入 FAISS 索引持久化到本地。以后启动应用时直接FAISS.load_local(kb_index, embeddings)加载就行不需要每次重新构建。第三步检索与生成from langchain_openai import ChatOpenAI from langchain_core.prompts import ChatPromptTemplate from langchain_core.runnables import RunnablePassthrough # 5. 构造检索器取 top-4 相关片段 retriever vectorstore.as_retriever(search_kwargs{k: 4}) # 6. 构造 LLM llm ChatOpenAI(modelgpt-4o-mini, temperature0) # 7. Prompt明确只依据资料回答禁止编造 prompt ChatPromptTemplate.from_template( 你是一名知识库助手。请仅依据以下资料回答用户的问题。 如果资料中没有相关信息直接回答资料中未找到相关信息不要编造。 【资料】 {context} 【问题】 {question} ) # 8. 组装检索增强生成链 rag_chain ( {context: retriever, question: RunnablePassthrough()} | prompt | llm ) question 这款产品支持的最大并发连接数是多少 answer rag_chain.invoke(question) print(answer.content)这条链的执行逻辑是用户问题先传给 retrieverretriever 把问题向量化在 FAISS 里找最相似的 4 个 chunk把它们的文本拼进{context}连同原问题一起交给模型。模型只参考这 4 段资料回答。如果你不用 LangChain核心也就四段逻辑切分、调 embedding 接口、FAISS 检索、拼接 Prompt 调 LLM。理解这四段框架只是帮你省了几行代码。3.3 参数怎么定效果怎么验代码跑通只是开始参数怎么定才是真正的工作量。一组我常用的起点参数参数建议起点调整方向chunk_size500 token回答偏笼统就调小上下文不足就调大chunk_overlap5010%句子频繁被切断时适当加大top_k4单点事实问题可减到 3复杂问题加到 6-8temperature0知识问答场景严格用 0不要让它发挥embedding 模型text-embedding-3-small / bge-m3中文场景优先选中文能力强的模型最关键的还是怎么验。我的做法是上线前无论如何先准备一套评测集找 20 到 30 个真实业务问题每个问题配好标准答案和来源文档。然后跑一遍 RAG统计两个指标召回命中率——检索出的 chunk 里是否包含能回答问题的那段文档答案正确率——大模型最终回答是否符合标准答案。前者验证检索环节后者验证生成环节。这一步看着朴素却是整个调优过程里最有价值的事。没有评测集你永远不知道参数调整到底是在变好还是变坏。实测下来还有个小经验召回命中率低先查切分和 embedding召回命中率高但答案不对先查 Prompt 和生成参数两者都正常但效果不稳定再查知识库本身的文档质量问题。4. 检索质量调优从能用到好用4.1 混合检索与重排召回只是第一步基础闭环能跑通但离好用还很远。最常见的问题是纯向量检索对精确关键词不敏感。比如文档里写的是SKU-10086你问产品编号 10086 对应的型号语义虽然匹配但 embedding 模型对这类精确符号匹配往往力不从心。解决办法是混合检索把语义检索向量和关键词检索BM25结合起来。BM25 是传统的关键词匹配算法对精确词、产品编号、型号这类信息非常友好。两者结果可以做简单加权也可以用 RRFReciprocal Rank Fusion融合排序——给每个结果按排名赋分再把两路分数加总。公式不复杂核心思想是两路检索都排在前面的结果优先给高分。混合检索解决了召回但召回回来的结果里依然鱼龙混杂。这时候就需要重排Rerank。embedding 模型算的是粗粒度相似度重排模型也叫 cross-encoder比如 bge-reranker会把 query 和候选文档成对地过一遍模型输出更精细的相关性打分。重排模型质量更高但速度慢所以正确用法是先向量/关键词混合检索召回 top 50 个候选再用重排模型精排取前 3-5 个作为最终上下文。这一步在我的项目里效果提升非常明显属于性价比最高的调优手段。有个容易犯的错误是把重排结果直接当最终答案排序喂给模型却忘了重排模型只看相关性、不看业务优先级。如果知识库有明确的优先级规则比如标准优先于草案、新版本优先于旧版本在精排后还要做一层规则融合否则最权威的文档反而可能被排到后面。4.2 让 Agent 学会什么时候查、怎么查我见过不少团队把 RAG 做成每问必查不管什么问题都先检索再生成。这其实是过度设计也是最容易埋雷的做法。有些问题模型自己就能答得很好——比如闲聊、通用常识、对已有知识的推理强行检索只会把噪声引入上下文增加幻觉风险。更合理的做法是让 Agent 先做意图判断这个问题需不需要知识库需要的话查哪一类知识这就是 Agent 中有条件的检索。我在实际项目中常用的实现方式是把知识库检索设计成 Agent 的一个工具Tool而不是无脑前置。Agent 根据用户问题自行决定是否调用这个工具、调用哪个知识库。搜索语言模型回答一个问题可以拆成三步判断要不要查、决定怎么查、决定信多少。这几步拆开可控性和可观测性都显著提升排查问题时也能清楚地看到这个回答用了哪一段资料。怎么查也值得设计。用户的原问题往往不适合直接作为检索 query。举个例子用户问这个产品的续费政策有没有变化直接拿这句话去向量检索匹配到的是续费相关文档但用户真正关心的是新旧政策对比。这时候可以先用 LLM 把问题重写Query Rewrite成更利于检索的形式比如提炼出2024 年 续费政策 调整 对比再去做检索。我实测下来Query Rewrite 是收益率极高的改进手段甚至比换 embeddin 模型带来的提升还大。4.3 从 RAG 到 Agentic RAGRAG 的进阶形态就是把它从单次检索变成 Agent 决策流程中的一环这就是近一年很热的 Agentic RAG 方向。它的核心是让大模型不再是一次检索、一次生成的被动管道而是拥有检索工具的 Agent可以自主决定检索什么、检索几次、多轮检索、根据初步结果决定是否补充检索。举个例子用户问对比一下 A 和 B 两款产品的容灾方案。传统 RAG 只能拿整句话去检索结果要么偏 A要么偏 B。Agentic RAG 会先拆解问题分别检索 A 的容灾方案、B 的容灾方案甚至再检索一次性能对比数据最后综合多轮检索结果作答。这种检索计划能力是传统 RAG 很难做到的。Agenti 化还有一个价值把 RAG 和 Agent 的其他技能组合起来。比如检索到某份文档后Agent 可以调用解析工具提取表格可以调用代码工具验证文档里的配置命令可以调用数据库接口核对文档中的数字。知识不再是唯一的输入源而是和工具协作的一部分。当然引入 Agent 决策也带来新的问题多轮检索的延迟、失败路径的处理、成本控制。要用 Agent 的智能又要防 Agent 的自由发挥——我的办法是把 Agent 的检索行为约束在预定义模式下最多检索两轮、每轮最多返回 5 个 chunk、检出结果必须经过相关性验证才能进入上下文。这是工程上的分寸问题比堆技术参数重要得多。在更前沿的方向上还有人用 Ontology 和知识图谱来辅助 RAGOntology RAG以及用图结构组织文档关系的 GraphRAG。这些方案本质上都是试图解决纯向量检索难以捕捉知识间复杂关联的问题适合文档之间引用、层级、依赖关系非常强的场景。对于大多数从 0 到 1 的项目先把基础 RAG 和 Agentic RAG 做扎实比一上来就上图谱方案要稳妥。5. 常见问题与排查实录5.1 问题速查表整理一份我反复遇到、也是社区问得最多的排查表现象可能原因排查与解决明明知识库有答案模型却说不知道top_k 太小或切分后关键内容被切断加大 top_k改结构化切分检查召回结果里是否真有答案检索结果明显不相关embedding 模型不合适或 query 太口语化换中文能力更强的 embedding 模型加 Query Rewrite 做检索改写回答内容张冠李戴chunk 切分破坏了上下文或重排后优先级规则没生效检查 chunk 边界加入重排后的业务规则融合幻觉仍然出现Prompt 没有强约束不知道就直说在 Prompt 中明确禁止编造并让模型优先引用资料原文所有检索分数都偏低query 与文档语言/风格差异大尝试双语 embedding或归一化后再算相似度检索速度越来越慢索引参数不合理或数据量增长检查 HNSW 参数考虑增加元数据过滤缩小候选集同一问题答案不稳定temperature 偏高或候选 chunk 顺序不稳定知识问答场景 temperature 设为 0排序后固定输出顺序PDF 表格内容完全检索不到PDF 解析失败表格被打散换表格专用解析器或转成 Markdown 表格后再入库5.2 我踩过的坑和几条经验最后分享几条纯靠踩坑攒出来的心得。第一条PDF 里的表格是检索效果的头号杀手。普通 PDF 解析器对表格的处理能力非常差经常把表格拆成残缺的文本碎片检索时永远匹配不到完整内容。我现在处理含表格的文档会专门做一步表格识别把表格提取出来转成结构化文本或 Markdown再进切分流程效果立竿见影。第二条别迷信相似度分数的绝对值。不同 embedding 模型输出的分数范围差异很大跨度从 -1 到 1甚至更高。拿 0.5 作为全局阈值这件事完全不靠谱。我的建议是用分数的相对排序来做取舍如果要设阈值必须针对你的数据集实测校准。调好的项目里如果检出的 top 4 分数都极低大概率是知识库里根本没有相关内容这时候宁可让模型说不知道。第三条元数据过滤是最容易被忽略的免费午餐。有一次用户公司上线新政策后Agent 老是被旧版文档误导一度以为是检索排序的问题。排查到最后发现就是没有按政策版本做元数据过滤新旧文档混在一起召回了。加一个只检索有效状态为启用的文档的过滤条件问题直接消失。第四条从第一天就把检索日志留好。生产环境里每次问答的检索结果、相似度分数、最终使用的 chunk、模型输出我全都会记日志。后面每出一个线上问题翻日志大概率几分钟就能定位是检索环节还是生成环节的问题。没有日志遇到问题只能凭空猜那是最痛苦的状态。第五条也是最重要的——知识库的质量决定了 RAG 的上限。很多团队把时间花在调检索参数上却对入库文档的质量放任不管。文档过时、互相矛盾、表述含糊这些问题在检索层再怎么优化也解决不了。做 RAG 项目建议把至少一半的精力放在知识治理上更新过期文档、合并重复内容、给关键文档加规范的结构化元数据。这才是投入产出比最高的地方。这套 RAG 基础链路做完之后再回头看会发现它并不神秘——本质就是用工程手段把知道什么和需要知道什么这两件事精确地对接起来。下一篇我会继续沿着走进 AI Agent的路线聊聊 Agent 的长期记忆与知识经验的沉淀到时候你会看到RAG 只是知识获取管道的第一站距离完整的 Agent 知识体系还有很长的路要走。
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。