ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

RAG从建库到生成:Agent知识库接入的实战经验与避坑指南

2026/9/26 4:34:46 拓冰建站 浏览量
RAG从建库到生成:Agent知识库接入的实战经验与避坑指南 在做Agent开发之前我对RAG是有偏见的。总感觉这玩意儿不就是“文档切一切、向量存一存、检索拼一拼”吗直到自己负责的Agent项目在回答私有知识库问题时连续翻车——它能准确说出文档里的某个结论却会在另一处煞有介事地编造一个根本不存在的条款我才静下心来把建库、检索、生成这条链路完整重学了一遍。这篇是Agent开发学习笔记的第七篇专门聊聊RAG从建库到检索到生成我会把这一路实测出来的经验、参数和坑都倒出来适合正在做Agent但对知识库接入还停留在“调用一个API”阶段的开发者。看完之后你会发现RAG真正的门槛不在Embedding和向量库而在那些没人写进教程的细节里。1. 为什么做了半年Agent我最后还是老老实实把RAG补上了RAGRetrieval-Augmented Generation检索增强生成这几年几乎成了Agent外接知识的默认方案。它的核心思路并不复杂既然大模型本身的参数化记忆不可靠那我们就把知识库放到模型外部按需检索相关片段塞进上下文让模型“照着读”。这本质上是在改变模型回答问题时的参考材料而不是改变模型自身的记忆。但越是看起来简单的方案落地时越容易暴露问题。我见过不少团队把RAG当成一个“灌数据”的动作文档往向量库里一丢就开始跑结果回答质量一塌糊涂。所以这篇文章我打算沿着建库、检索、生成三个环节逐步拆开讲中间穿插Agent场景下的特殊考虑。下面先聊聊我为什么必须补上RAG这一课。1.1 参数化记忆的边界幻觉不是bug而是特性要理解RAG为什么有效得先接受一个事实大模型的“知识”是压缩进去的。预训练阶段模型把所有训练语料压缩成几十亿甚至几千亿个参数回答问题时靠的是这些参数所编码的概率分布。这种记忆方式有两个天然缺陷一是时效性差模型知识截止于训练数据收集那一刻二是忠实度无保障训练语料里对同一件事存在多种说法时模型可能把不同说法揉在一起甚至把高频共现但毫无关联的信息编成“事实”。这两点叠加就是大家天天挂在嘴边的幻觉问题。幻觉在通用闲聊里不致命但在Agent场景里是致命的。Agent的核心价值是代替人执行任务它给出的答案、提取的字段、做的判断背后都需要可靠依据。我见过一个实际案例某客服Agent在回答退货退款政策时信心满满地把7天无理由退货说成了30天因为它训练数据里见过太多“30天退货”的高频表达概率上“30天”比“7天”更容易被采样出来。这种错误在纯参数化记忆的框架下几乎无解。RAG的思路相当于把“记忆”和“推理”拆开。记忆交给检索系统由它从知识库里精确抓取相关内容推理交给大模型由它基于给定的上下文组织答案。这样一来幻觉被限制在“检索不准确”这一个入口上而检索是可以用工程手段去评估、去改进的。对做Agent的人来说这是质的差别出了问题你知道该去查哪一环而不是对着模型参数干瞪眼。1.2 RAG、微调与长上下文三者选型的一次深度对比很多人会问那直接微调不行吗或者现在大模型上下文窗口动辄128K、200K干脆把资料全塞进去省掉检索这一步这三个方案我都试过说下切身感受。微调适合的是“格式、风格、能力”的迁移比如让模型学会用特定JSON结构输出或者模仿某种语气。但微调极不适合注入新事实尤其是会频繁更新的知识。原因很简单微调成本高、周期长每改一次数据就要重新训练一轮而业务知识库通常每周都在变。另外微调还有灾难性遗忘风险——强行注入新知识可能把模型原有能力覆盖掉。我见过一个团队把产品知识微调进模型之后模型的通用代码生成能力明显退化最后只能分开部署两个模型维护成本翻倍。长上下文方案看起来完美把几十份文档全塞进去模型确实能“看到”所有内容。但实测有三个问题第一是成本Token费用随上下文长度线性增长一次问答吃掉十几万Token并不稀奇第二是注意力稀释上下文越长模型对关键信息的关注度越低这就是论文里反复讨论的“迷失在中间”现象第三是响应延迟明显变长。我在一次测试中把30份合同文本塞入上下文结果模型在回答“哪一份合同包含竞业条款”时反而比只给它5份相关合同时表现更差——无关信息太多把关键信息淹没了。RAG恰好站在中间它不改变模型参数适合知识频繁更新的场景它也不把全部内容塞给模型只挑最相关的片段进入上下文在成本、延迟、准确率三者之间取得平衡。如果你做的是通用型Agent产品需要给不同客户接入各自的知识库RAG几乎是唯一现实的选择——你不可能为每个客户微调一个模型但你可以为每个客户维护一个索引。1.3 顺便聊聊RAG和MCP的关系最近MCPModel Context Protocol被炒得火热经常有人问我RAG和MCP是不是竞争关系。我的理解是它们根本不在同一个层次上。RAG是一种“增强生成”的架构模式解决的是知识从哪来、怎么用的问题。MCP是一种“工具接入”的协议标准解决的是Agent如何统一调用外部能力的问题。通过MCPAgent可以调用一个检索服务、一个数据库、一个代码执行器RAG里面的检索这一步完全可以封装成一个MCP Server暴露给Agent。甚至现在主流的Agent框架里RAG知识库经常就是以MCP工具的形式挂载的。所以正确的关系是MCP是管道RAG是管道里流动的一种能力。Agent通过MCP暴露工具接口RAG作为其中一个工具负责知识检索。你在设计Agent架构时不需要纠结二选一而应该把它们组合起来——RAG负责“还记得什么”MCP负责“还能调用什么”。2. 建库环节一份文档从PDF到向量的完整旅程RAG这名字听起来简单但“建库”这两个字背后是一整条离线数据处理管道。很多入门教程直接跳到Embedding加向量数据库让人误以为建库就是把文档切成一段段然后算向量。真实项目里建库至少包含文档解析、清洗、切分、向量化、入库五个环节每一步都可能让最终效果天差地别。2.1 文档解析层PDF和Word里那些反人类的内容建库的第一个拦路虎是文档解析。你以为PDF里提取文本很简单太天真了。我做过一个多行业知识库项目里面的PDF来源五花八门有扫描件、有表格导出件、有设计软件生成的矢量件。扫描件必须走OCR否则用pypdf直接提取出来要么是乱码要么干脆空白。而OCR本身的准确率又取决于扫描质量倾斜、阴影、手写批注都会引入噪声。更麻烦的是表格提取。PDF里的表格用pypdf或pdfplumber直接提取得到的文本顺序往往和视觉顺序完全不一致——说明文字、表头、单元格内容混在一起切分之后语义全乱。我的建议是能拿到原始Word、Markdown等源文件的优先用源文件只有PDF的情况下先尝试pdfplumber按区域提取再用unstructured这类工具做表格结构识别。不要迷信某一个解析库能搞定一切实际项目中我经常是pdfplumber、pymupdf、unstructured三件套轮换着用哪个效果好上哪个。Word文档也有坑。docx本质上是XML包里面除了正文还有批注、修订记录、页眉页脚、文本框。用python-docx读取时默认只会拿到body里的段落表格内容需要单独遍历目录和页眉页脚混进来向量库里就会塞进大量噪音。我在清洗环节的经验是先抽正文再过滤长度过短的文本片段比如少于20字的内容基本是导航或页码最后把文档标题、章节号作为元数据记录下来供后面检索过滤使用。2.2 切分策略chunk_size500还是按语义切切分是整个建库过程中对效果影响最大、也最容易被低估的一环。切得太粗一个chunk里包含多个主题检索时召回一堆噪声切得太细单个chunk表达的意思不完整模型生成时缺乏上下文。而且chunk的粒度要和你后面生成环节的上下文长度匹配不能拍脑袋定一个数字就完事。常用的切分策略有三种。第一种是固定长度切分比如每500个字符切一块重叠50到100个字符。实现简单、处理速度快但容易把一句话从中间断开语义完整性较差。第二种是递归结构切分LangChain里的RecursiveCharacterTextSplitter是典型代表它按照段落、句子、单词的优先级逐级切分尽量保证每个chunk是完整的段落或句子。对中文文档我一般把分隔符设置为[\n\n, \n, 。, , , ]效果比固定长度好不少。第三种是语义切分先用Embedding把句子向量化再用相似度聚类的方式寻找语义边界。这种方式切出来的块质量最高但计算量大、速度慢适合对答案质量极其敏感的场景。我的实测建议是内容结构清晰的正式文档规章制度、产品手册用递归切分知识密度高、句子跳跃大的内容会议纪要、技术博客用语义切分。chunk_size不要一刀切我常用的基线是500字、overlap控制在80到100字然后根据问答测试结果微调。如果你发现回答经常“答非所问”先别怀疑模型回去看看是不是chunk把两个主题切进了同一块。2.3 Embedding模型选型与向量库对比Embedding模型决定了文本在向量空间里的“距离”是否真的反映语义差异。中文场景下我测试过OpenAI的text-embedding-3-small、智源的bge-m3、阿里的text-embedding-v3等。结论是如果部署在海外、主要处理中英文混合内容OpenAI的接口省心且价格便宜如果数据不出境、纯中文内容多bge-m3是很能打的本地方案——它对中文语义的理解更细腻支持8192长度输入对长文档建库非常友好。至于最新的text-embedding-4系列我还在测评中目前看中文场景的提升幅度没有想象中大。向量数据库的选择也值得展开。单纯从功能上看Milvus、Qdrant、Weaviate这些专用向量库功能都很齐全但国内团队用得最多的其实是三者加一个Elasticsearch的kNN。我的取舍逻辑是这样如果团队已经重度用Elasticsearch做业务搜索那直接在其上启用向量检索少维护一套系统如果项目是独立知识库产品、对高并发和复杂过滤有要求选Milvus或Qdrant更合适它们对多维过滤的支持比ES原生更灵活如果只是个人学习、数据量在百万级以下性价比最高的其实是Chroma或者直接用SQLite加向量扩展。这里多说一句向量数据库的选型不太值得花太多时间纠结。数据量不大的时候迁移成本很低数据量真的大了你反而会更关注另一个问题——索引参数。比如HNSW的M参数和efConstruction参数会直接影响召回速度和召回质量。我在项目里默认用HNSWM16efConstruction200查询时ef64这几个值对绝大多数场景都够用。3. 检索环节别急着上重排序先把召回逻辑理清楚建库只是把食材备好真正决定RAG效果的是检索环节。检索的核心目标是在保证召回率的前提下最大化检索结果与用户问题的相关度。这里有两个关键词——召回率是“相关文档有没有被找出来”精确率是“找出来的东西是不是真的相关”。很多入门项目效果差不是生成模型不行而是检索环节直接拉垮了。3.1 混合检索为什么是默认答案纯向量检索有一个经典弱点它对字面匹配不敏感。用户问“合同中关于违约责任有哪些条款”文档里写的是“违约方应当承担的责任”Embedding语义上可能相关但向量距离不够近被Top-K截断掉了。反过来用户明明找的是“赔偿金计算方式”检索结果却因为语义飘忽召回一堆泛泛的“合同义务”内容。这种问题在专业领域里尤其常见因为专业文档的表述和日常提问方式差异很大。混合检索Hybrid Search能解决这个问题向量检索负责语义扩展BM25关键词检索负责精确匹配最后用RRFReciprocal Rank Fusion或加权合并的方式融合两路结果。我在项目里默认采用“向量召回Top-50 BM25召回到Top-20融合后取Top-5到Top-10”的策略效果比单一向量检索稳定得多。BM25在关键词精准命中场景上是纯向量很难超越的尤其对合同编号、型号规格、法律术语这类内容。需要特别提醒的是BM25对中文的支持依赖分词质量。用ES内置的standard分词器做中文检索基本是白搭必须挂IK分词或jieba分词否则关键词检索在中文里就是个摆设。我在一个法律文档项目里踩过这个坑——“劳动仲裁”被切成了“劳动”和“仲裁”两个词检索“劳动纠纷”时召回了大量只含“劳动”的无关文本。换上IK分词并配置自定义词典之后这个问题立刻缓解。3.2 Top-K、阈值与重排序的平衡Top-K这个参数新手最容易拍脑袋定。K设太大塞给模型的上下文塞满不相关内容K设太小正确答案连召回都没进来生成阶段再厉害也巧妇难为无米之炊。我的经验是如果用了Reranker召回阶段可以阔一点取15到30条交给Reranker精排后再取Top-5如果不用Reranker检索结果直接进生成阶段K值建议不超过8。关于相似度阈值我要泼一盆冷水别迷信某个固定的0.75之类的阈值。Embedding模型的向量分布因模型而异有的模型输出分数整体偏高有的整体偏低同一个阈值在不同模型上表现天差地别。更靠谱的做法是在开发环境里抽样一批真实问题跑一遍检索画出相关分数分布然后选一个能把“明显不相关”和“可能相关”分开的切割点。这个过程不需要多复杂跑几百条问题用直方图看一眼就清楚了。Reranker值不值得上我的答案是要看场景。对话型Agent追求响应速度每多一次Reranker调用就会带来几十到几百毫秒的额外延迟需要权衡。问答型知识库检索以准确率为优先Reranker带来的收益非常明显。我实测用bge-reranker-v2-m3做二次精排后Top-5命中率提升了8到12个百分点。这个提升幅度在检索场景已经相当可观代价只是多一次模型推理。3.3 元数据过滤检索准确率的第一道阀门一个经常被忽略但性价比最高的优化手段是元数据过滤。给每个chunk打上文档来源、章节编号、文档类型、更新时间、适用范围等标签检索时先按元数据粗过滤再做向量召回能大幅减少无关内容的干扰。举一个真实例子。我做过一个售后服务知识库里面既包含某产品的通用操作手册也包含针对不同固件版本的补充说明。如果用户问的是“V2.3固件下如何校准传感器”纯向量检索很可能把V2.1、V2.2的说明也召回来因为内容太相似了。但给chunk打上“固件版本”标签后检索时先用版本号过滤掉其他版本只在该版本的chunk里做向量搜索效果立竿见影。用户问题里没有提到版本号怎么办那就用默认版本过滤同时保留其他版本作为兜底。在设计元数据时我的建议是“检索与显示分离”一方面元数据参与过滤和排序另一方面元数据随检索结果返回生成阶段把来源信息一并展示给用户。这既提升了准确率又解决了Agent答案的“可解释性”问题。企业客户对这一点尤其买账——他们不关心你用了什么模型但非常关心“这个答案是基于哪份文档得出来的”。4. 生成环节提示词只占一半上下文管理才是大头检索到的chunk最终要交给大模型生成答案。这个环节看起来简单——拼个Prompt让它回答不就完了但实际跑下来生成环节的坑一点不比检索少。最典型的两个问题一是检索内容互相矛盾模型不知道信谁二是检索结果超出上下文窗口或者包含大量无关信息把模型带偏。4.1 问题改写与上下文压缩很多初学者直接把用户的原始问题丢去检索这在单轮问答里没问题但在对话场景里会迅速翻车。比如用户第一句问“退货政策是什么”Agent给出回答后用户追问“那运费谁出”——这里的“那运费谁出”显然指的是退货场景下的运费。如果直接用这句话去检索可能召回一堆和物流配送无关的内容。正确做法是先做问题改写结合历史对话把用户的追问补全成完整、自包含的问题例如“退货时运费由谁承担”。问题改写可以用一个小规模的Prompt让大模型完成也可以用专门的Query改写模型。我在Agent项目里用的是Prompt方案把对话历史和用户最新问题一起发给模型让它输出“用于检索的独立问题”。这步开销不大但对检索质量提升非常明显。记得把改写后的query和原始query都记录下来方便后面排查线上问题。上下文压缩则是为了处理“召回内容多但有效信息少”的情况。有时检索返回的Top-5 chunk里真正相关的可能只有一个。我的做法是在召回之后、生成之前加一步轻量过滤——对每个chunk和改写后的query重新算一次Embedding相似度低于固定阈值就丢弃。这一步看似多余实际能防止模型被无关内容带偏也让最终进入Prompt的Token数更可控。4.2 Prompt组装与引用溯源生成阶段的Prompt模板我踩过不少坑最后沉淀下来一个相对稳定的结构。它分为四层系统指令角色与回答规则、检索上下文命中chunk正文按相关性排序、用户问题、输出格式要求包括引用标注规则。系统指令里最关键的一句话是“只能依据提供的资料回答问题当资料无法回答时明确说明知识库中缺少相关信息禁止编造。”这句话看似简单却能极大降低幻觉。我在一个金融合规问答项目里做过对比加了这句话之后答案里出现“可能”“推测”“我不确定”这类校准表达的比例明显上升编造法条的情况基本杜绝。模型的生成自由度是需要约束的不给边界它就默认往最流畅的方向发挥。引用溯源是很加分的一步。组装Prompt时给每个chunk赋予编号比如[1]、[2]并告诉模型“回答时在对应句末标注引用编号”。这样生成的答案天然带可追溯性用户能点开看到底依据了哪些资料。这个特性在企业内部知识库场景几乎被客户当硬性需求——管理员要审答案没引用来源根本没法审核。4.3 生成参数控制与幻觉兜底生成阶段的采样参数也需要单独调。RAG场景下温度建议设在0到0.3之间。过高的温度会让模型在组织语句时“自由发挥”即使参考资料就摆在那里也可能说出资料里没有的内容。我在测试中对比过temperature0.2和0.8在同一批检索结果下的输出0.8版本确实更“生动”但出现了三处对参考资料的过度发挥这在知识问答场景完全无法接受。另外一个常用手段是top_p我一般保持在0.9左右配合低温度使用。另外业界越来越流行在生成后加一道“忠实度校验”把模型生成的答案和检索到的chunk分别向量化检查答案中的关键陈述是否能在chunk里找到近似对应。如果找不到对应依据就降级回复“无法给出确切回答”。这相当于给生成结果加了一道保险丝。想做得更严格还可以从答案里提取关键实体和数字逐一和资料比对发现不一致就触发重写或拒答。我在一个医疗咨询类Agent项目里做了简化版校验——只检查答案里的数字、日期、药名是否能在资料中原样找到无法找到时返回“该问题涉及专业信息请咨询线下医生”。上线三个月用户投诉里的“瞎说”类问题下降了七成。5. Agentic RAG当RAG从问答工具变成Agent的认知层如果你只做一个“输入问题、召回答”的问答机器人前面四章基本够用。但在真正的Agent开发中RAG往往需要升级为更灵活的形态因为Agent的任务不是单轮问答而是多步骤的推理与执行。这也是Agentic RAG最近火起来的原因。5.1 从Naive RAG到Agentic RAG传统Naive RAG的流程是固定的查询、召回、生成三步走中间没有任何决策节点。Agentic RAG的不同之处在于把“检索”这个环节交给Agent编排——Agent根据用户意图决定要不要检索、检索几次、从哪个知识库检索、检索结果是否足够回答用户问题。打个比方Naive RAG像图书馆前台你问什么它直接去书架检索对应书拿一本就回来。Agentic RAG像研究助理它会先判断问题需不需要查资料如果需要是查公司制度还是行业标准查完一轮信息不够再换关键词查第二轮甚至把多本书内容交叉印证后才给你答复。这种灵活性在Agent实际应用场景里至关重要。比如一个企业HR Agent用户问“新员工年假规则是什么”Naive RAG直接查制度库返回即可但如果用户问“我入职半年想休年假经理说只能请事假怎么办”这个问题涉及制度、流程、常见案例多个层面Agent需要先拆解问题分别检索制度相关条款、请假流程再综合生成回答必要时还要反问用户补充信息。5.2 多跳检索与路由决策实现Agentic RAG目前主流做法是在Agent框架里定义多个“检索工具”每个工具对应一个知识库或一种检索策略。Agent根据组合型问题自行决定先调用哪个工具、再调用哪个工具。这就是技术路由Routing。我在项目中做的路由规则大致分两类基于关键词或分类的硬路由和基于语义嵌入的软路由。硬路由逻辑简单可控比如问题包含“请假”“考勤”就走HR知识库包含“报销”“差旅”就走财务知识库软路由则把每个知识库的目录描述向量化让Agent根据意图与目录描述的相似度决定走哪个库。两者可以结合先硬路由缩小范围软路由兜底处理没命中规则的边缘问题。多跳检索最考验对检索结果的重组能力。一次检索可能只拿到“制度第X条”但这个条款本身引用了另一个更细的流程文档——Agent需要识别出这个“未闭合的引用”主动发起第二轮检索补齐引用内容才能生成完整答案。这个能力用LangGraph里的ToolNode加条件边可以搭出来也可以用AgentScope这类国产框架里的Workflow能力编排。核心思路是一样的检索不是一次性的动作而是可以多次触发的决策链。5.3 我实测的几个AgentRAG组合方案最后分享我在实际Agent项目里验证过、能稳定运行的三种组合方案。第一种是“RAG as a Tool”把知识库检索封装成一个标准工具Agent在ReAct循环里按需调用。实现最简单LangChain、LangGraph、Coze、Dify里都能做适合大多数内部知识问答Agent。缺点是Agent偶尔会在不需要检索的时候也去检索白白增加延迟。解决办法是在System Prompt里强调“只有问题涉及知识库内容时才调用检索工具”能缓解不少。第二种是“RAG 工作流编排”用流程图显式定义“意图分类—路由—检索—生成—校验”各个节点节点跳转由条件判断决定。这种方案响应稳定、行为可预期适合那些需要严格审核流程的客服类Agent。代价是灵活性偏低新场景要手动改编排。我的使用感受是当业务方明确要求“这个问题必须先查A库再查B库”时工作流编排远比让Agent自由决定更靠谱。第三种是“多知识库RAG 元数据融合”几个垂直知识库各自建索引Agent先定位走哪个子库再检索并汇总多个库的结果生成前做去重与冲突消解。这种方案适合企业级Agent——运维、销售、HR、财务知识库并存时冲突消解是必然要面对的问题。实测中我发现两个库对同一问题的描述有出入时直接把两段都丢给模型它经常无所适从。正确做法是让模型在生成前先指出冲突再由规则判定哪个库权威性更高。6. 从建库到上线的性能优化与踩坑清单前面聊的都是正确性但真实项目上线后你会发现正确性只是入场券性能和稳定性才是决定能否落地的关键。这半年来我不断迭代RAG链路踩过一堆坑这里挑几个最有代表性的讲讲给大家当个参考。6.1 四个最影响体验的瓶颈第一个瓶颈是文档更新。知识库不是一建了之业务文档每周都在改。最开始我做全量重建几万份文档每次都要重新解析、切分、向量化耗时几十分钟索引服务还得停机。后来改成增量更新用文档的hash值判断文件是否变化只对变化的文档做解析和向量化再删除旧chunk写入新chunk更新时间从几十分钟降到两分钟以内。增量更新的另一个好处是能保留旧版本出问题可以快速回滚。第二个瓶颈是向量化耗时。Embedding模型推理速度慢大批量文本向量化经常卡很久。解决思路是批量提交、异步化把切分好的chunk按批次并发请求Embedding服务同时把向量化过程做成离线任务与在线检索彻底解耦。建库是离线批量工作没必要让用户等。我目前的做法是Celery异步队列加批量调用一万个chunk大概几分钟能完成完全够用。第三个瓶颈是检索延迟。一次查询从请求发出到生成首字延迟主要由三部分构成问题改写约200到500毫秒、向量检索加重排序约100到300毫秒、模型生成几百毫秒到几秒。如果单轮问答觉得卡先看Reranker是不是每次都在调。高频场景下可以把重排序改成异步旁路只在需要高准确率的Query类型上启用。第四个瓶颈是缓存缺失。用户问的问题大量是重复的尤其在企业内部场景同一句话可能一天被问几百次。我第一次上线完全没做缓存一天下来API账单吓人。后来在检索层加了一层语义缓存把问题做Embedding如果缓存里找到相似度超过0.95的历史问题直接复用其答案命中率能做到40%以上成本和延迟双双大幅下降。注意缓存键不能只存原始问题用户ID或会话上下文也要考虑进去否则不同用户会看到彼此的答案。6.2 一份可以直接抄的RAG项目配置单基于反复测试的经验我整理了一份适合中小型RAG项目的初始配置单大家实际部署时按自己的数据量调整即可。文档切分选用递归结构切分中文章节分隔符用[\n\n, \n, 。, , ]chunk_size500overlap80切分前统一清理页眉页脚和多余空行。Embedding模型首选bge-m3纯中文场景或text-embedding-3-small中英混合且可用API向量维度视模型而定。向量数据库个人项目用Chroma团队项目用Milvus或Qdrant索引参数默认HNSW M16、efConstruction200。检索模式采用BM25关键词检索挂IK分词与向量检索混合召回阶段各取Top-20RRF融合后取Top-8进重排序Reranker用bge-reranker-v2-m3精排后取Top-5输入生成环节。生成环节大模型选支持8K以上上下文的中文模型即可温度设0.1系统指令明确“只在资料范围内回答资料不足时如实说明”要求答案标注引用编号。评测指标记录三类检索命中率Top-5是否包含正确答案来源、生成答案的事实一致性人工抽查加关键词校验、端到端响应延迟P95小于3秒为及格线。6.3 三十天真实运行后的调优记录这份配置单不是一次定稿的是跑了三十天、看了大量badcase后一步步调出来的。最开始Top-8直接进生成、不过Reranker答案经常出现“相关的废话”——检索结果里确实有相关内容但排在前面的是一大段背景介绍真正的结论句子排在后面。给检索结果按“答案匹配可能性”重新排序后生成质量才拉上来。这个badcase让我认识到检索结果的排序质量直接影响生成质量不能只看召回有没有命中。另一个调优点是chunk_size。最初用800字发现模型经常把“第3条”的条款细节和“第4条”的内容混在一起因为它们在同一个chunk里。调到350到500字后这种情况明显减少。但chunk变小之后一些需要完整上下文背景才能回答的追问又变差了所以最终保留500字。这个经验说明切分参数没有普适最优值一定要结合领域文档的句式结构和常见问题类型反复试验。还有一次踩坑是在多知识库场景里两个库同时命中了一段内容但表述不同。我最初让模型自行判断结果模型把两个版本缝合在一起造出了一个两边都不准确的说法。改成“先让模型在回答前输出冲突提示再按知识库优先级选择”之后才稳定下来。这件事让我确定了一个原则RAG链路上凡是能用显式规则决策的就不要交给模型隐式判断——模型擅长生成语言不擅长仲裁事实。写到这里这篇学习笔记差不多该收尾了。回顾这半年从零搭建RAG的过程最大的感触是RAG不难入门难在每一个环节都要较真。切分参数、检索融合、上下文管理、缓存策略每一个看似不起眼的细节最后都会在真实问答准确率上体现出来。如果你也在做Agent开发我建议不要直接去买那种号称“开箱即用”的RAG服务而是把自己的数据跑一遍完整的建库、检索、生成链路亲手调一次参数。那些教程上没有写明白的“为什么”只有自己踩过坑才能建立真实的体感。下一篇笔记我打算聊聊Agent的记忆机制这个话题和RAG的边界很有意思到时继续分享。