
1. 先把“流水线”这个词掰开看做RAG的人越来越多随便搜一下教程出来的都是同一套东西加载文档、切块、向量化、存库、召回、拼Prompt、喂给大模型。一套流程跑下来demo三天能出效果能不能扛住真实场景那就是另一回事了。标题里那句话说得挺扎心——烂大街的不是RAG是那条谁都能跑的流水线。真正的分水岭从来不在“跑通”而在跑通之后你还有没有能力回答这几个问题文档解析丢没丢信息切块切得合不合理召回准不准知识库形态选得对不对上下文组织得好不好系统能不能持续变好我把这些年的实践经验捋了一遍真正的差距基本集中在六个地方源头文件解析、切分策略、混合检索与重排、知识库形态选择、上下文组织与智能体协同、评测与迭代闭环。这六处每一样都足够让同一个RAG项目的效果差出一大截。这篇就把它们逐一拆开讲清楚顺便回答几个高频问题——比如RAG知识库到底能不能存图片、本地有没有靠谱的文本拆解工具、知识图谱和普通向量库到底怎么选。适合谁来读呢给两类人。一类是已经用现成框架跑通RAG但觉得效果不理想的人你能在这里找到排查方向另一类是正准备从零搭一套RAG系统的开发者读完你会知道哪些地方值得投入精力而不是把时间浪费在重复造流水线上。2. 分水岭一源头解析决定知识库质量的“第一道闸门”很多人做RAG第一步就是把文件一股脑丢进去PDF转个文本、Word抽个内容就完事了。这个习惯会让知识库从源头就带着伤。源头解析做得好不好直接决定了后面所有环节的上限。解析阶段丢掉的信息检索阶段是找不回来的。2.1 解析PDF不是“把文字提取出来”那么简单以最常见的PDF为例。用PyMuPDF或者pdfplumber直接抽文本看起来简单但你遇到的真实文档很少是干干净净的纯文本页。技术手册有双栏排版合同有表格论文有公式扫描件根本就是一张图片——不同情况要用不同的处理策略绝不能一把梭。双栏PDF直接按阅读顺序抽文本抽出来的内容会左右两栏交叉混在一起切块之后每个chunk里都是两段不相关的文字召回时匹配到一半内容答案自然乱七八糟。遇到这种文档正确做法是先做版面分析识别出每一栏的区域再按栏为单位提取文字。表格的问题更常见。PDF里的表格在纯文本提取后通常变成一堆以空格分隔的数字和文字语义关系全丢了。比如一个“参数对照表”原始表格中“电压”和“220V”是同行的关系转成文本后若切块把它们切开了你问“额定电压是多少”检索系统能找到“电压”这个词但返回的chunk里根本没有“220V”答案自然给不出来。对表格密集型文档要么按表格整体作为一个块处理要么在解析阶段就做表格结构还原把每一行转成“字段值”的文本描述。还有一个容易被忽略的问题页眉页脚。页眉里的公司名、页脚里的页码在大规模文档里几乎每个chunk都会混入这些噪音。它们会影响向量相似度吗单看文本量不大影响有限但检索结果做重排时这些重复文本会干扰打分更麻烦的是它们可能在切块时制造大量无意义的相似片段拉低检索精度。解析阶段顺手把页眉页脚滤掉后面的路会好走很多。2.2 图片和图表到底能不能进知识库热搜里有一条“rag知识库能存储图片嘛”这是个好问题直接回答能但方式有讲究取决于你用的模型能力。第一种方式把图片本身作为多模态数据存储检索时直接用多模态模型理解图片内容。这种方式要求你的生成模型也支持图像输入属于完整的多模态RAG路线成本和技术门槛都高但对图表类、界面截图类知识非常有效。第二种方式更通用用视觉模型比如带视觉能力的开源模型把图片内容转成结构化描述再作为文本向量化存储。比如一张产品结构图可以先用视觉模型识别出“外壳、电池、主板分别位于什么位置”生成一段详细文字描述然后存入向量库。用户问“电池在哪个位置”时检索命中这段描述大模型就能给出答案。这样做的好处是兼容纯文本RAG链路坏处是识别质量直接影响知识库质量需要加一道人工抽检。第三种方式是一种折中把原始图片存下来图片的路径或ID作为metadata挂在文本chunk上。回答问题时如果文本答案里关联了图片就把图片路径一并输出前端展示。我实测下来这种方式在很多实际项目里性价比最高——既保留视觉信息又不打乱纯文本RAG的体系。至于本地文本拆解工具我在Mac上实操下来比较顺手的一套组合是文档解析用Unstructured或者Docling本地可部署版面分析用开源模型做PDF布局识别OCR场景用PaddleOCR或Tesseract表格还原可以交给Camelot或者直接用多模态模型。组合起来常见文档类型基本都能覆盖。2.3 解析质量怎么验收解析完不是直接入库就完事得做一次质量抽检。我的习惯是从每个文档类型里抽一到两页人工看一眼解析出来的文本有没有乱码、表格有没有变成天书、公式或特殊符号还在不在、顺序对不对。这一步花不了多少时间但能提前拦下大量后面会反复折磨你的问题。另外一个容易踩的坑metadata在解析阶段就要带上。文件名、页码、章节路径、文档类型、日期、来源这些字段在解析阶段顺手提取存放后面做过滤、做归因、做权限控制全靠它们。许多项目前期忽略了metadata做到后期想按部门、按日期过滤时发现根本没有数据可用只能回头重新解析全库那感觉真的是欲哭无泪。3. 分水岭二切分策略召回率的天花板在这里文档解析完了下一步是切块。这是RAG系统里最“四两拨千斤”的一环。很多项目召回率上不去换了更好用的embedding模型也没用根源就在切分策略上。3.1 固定大小切块为什么不够用默认的切法是按固定字符数切比如每512个字符一块相邻块之间重叠64个字符。这种策略简单、跑得通但它对内容的语义完整性完全无感。一个倒霉的句子可能被从中间截断一个完整的概念可能被劈成两半一个多行表格被拆成碎片。举个例子。一份产品说明书里写“本产品最大支持功率为2200W超过该功率可能导致保险丝熔断”如果这句恰好跨越两块第一块结尾是“本产品最大支持功率为”第二块开头是“2200W超过该功率可能导致保险丝熔断”。用户问“最大支持功率是多少”第一块里有“最大支持功率”但没数值第二块里有数值但没有完整的问法两块的向量相似度都不会很高召回结果自然就差。切块大小对检索质量的影响也很微妙。chunk太小信息碎片化召回后上下文不完整大模型缺乏足够背景chunk太大单块语义变模糊向量表示会被多个主题稀释检索精度下降而且喂给大模型时浪费token。没有绝对最优的固定值一切都取决于你的文档类型和查询特点。更关键的是query的长度和chunk的大小之间存在匹配关系。用户的query通常是一句话可能五十到一百个字。你要让这个query向量和chunk向量在语义空间中有足够高的相似度chunk就不能太大太大了向量会被“平均”掉语义焦点也不能太小太小了上下文不够召回的片段往往只是擦边。从经验看常见文档手册、合同、制度文件chunk在256到512个token之间是相对稳妥的区间但必须结合文档结构动态调整。3.2 结构感知切分让边界跟着文档走比固定大小更靠谱的是“结构感知切分”。核心思路是文档自己已经有完整的结构——标题、章节、段落、表格、列表——切分的时候尊重这些边界而不是按字符数硬切。按Markdown标题切分是我最常用的策略。把文档转成Markdown格式后按标题层级切块让每个chunk对应一个完整的小节。这样切出来的块天然语义内聚而且切分之后保留标题路径作为metadata非常重要。比如一个技术支持知识库按“产品线-型号-功能模块”三级标题切用户问某个型号的功能召回结果会精确到具体小节且metadata里带着完整的路径信息归因非常清晰。表格和列表单独处理。表格是整个块列表则尽量保持列表完整而不是把一个有十项的列表切成五块碎片。有一种做法是把结构化数据转成“文本描述”——比如把表格的每一行转成“字段A是xxx字段B是yyy”的陈述句再用语义切分合并相邻行。这种转换会让文本好理解检索命中率明显提升因为自然语言query和自然语言描述之间的语义匹配远比query和原始表格文本之间的匹配容易。更进一步的语义切分是用embedding模型对相邻句子或段落做相似度计算相似度低于某个阈值时切开。这种方式实现起来也不复杂先按句子预切分然后逐句计算与当前块尾部的语义距离距离过大就另起一块。它对那种行文结构松散、没有明显标题的文档比如聊天记录、会议纪要、技术博客有奇效。3.3 切分参数怎么调来自实践的经验值参数调节上我的一个经验是不要一次性调全套。先固定其他变量只动chunk_size跑一遍评测记录召回率和答案命中率再换chunk_overlap最后再根据结果调整top_k和重排策略。一次只动一个变量就不会在出问题时说不清是谁导致的。关于overlap我的体会是有重叠比没重叠好但没到救命的地步。重叠主要是用来缓解“句子恰好被边界切开”的问题但如果你的切分策略本身是结构感知的需要重叠的场景会少很多。把overlap设在chunk大小的10%到20%就已经足够没必要堆太多。真正让召回效果变好的永远是切分边界和语义边界尽量对齐。如果你用的是LangChain或者LlamaIndex这类框架切分器选MarkdownHeaderTextSplitter或RecursiveCharacterTextSplitter并配置自定义分隔符优先级。我在生产项目里一般会写一个简单的自定义切分器先用标题定位章节边界再对超大章节做语义切分最后对表格做整体处理。三种策略组合起来效果比单一策略好一个档次。4. 分水岭三混合检索与重排召回之后的精准打击切分做好之后检索阶段是下一个关键分水岭。纯向量检索在不少场景下表现还行但离“可靠”还有相当距离。4.1 纯向量检索的三个盲区第一个盲区专有名词和精确匹配。产品型号、报错代码、合同编号这类字符串本身没有太多语义向量化之后相似度往往表现不稳定。你问“错误码E-3021怎么解决”向量检索可能返回一堆包含“错误”“解决”字样但根本不提E-3021的内容。但用BM25做关键词匹配“E-3021”这个词项能精确定位到包含它的文档片段。这种场景下传统的稀疏检索反而更可靠。第二个盲区短查询。用户只输入“发票流程”四个字向量化之后这个词组的信息量很低检索结果容易跑偏。BM25在短查询上的表现通常更稳定因为它直接做词项匹配不需要语义扩展。第三个盲区低频词和新词。向量模型训练时没见过的专业缩略词或者企业内部的黑话、缩写embedding效果很差。而BM25不受此困扰词项匹配是字面上的只要文档里有这个词就能命中。4.2 混合检索的正确融合方式混合检索hybrid search的思路就是让向量检索和关键词检索各干各的再合并结果。听起来简单融合才是真正的坑。最简单的融合是分数加权final_score alpha * 向量相似度 (1 - alpha) * BM25分数。但这种方式有一个麻烦向量相似度和BM25分数的量纲完全不同——一个是0到1的余弦相似度一个是几十上百的原始权重分直接加权需要做归一化。而且不同文档集合下的分布也不一样alpha0.7在这个库里效果不错换一个库可能就要调到0.3。我更推荐的做法是RRFReciprocal Rank Fusion倒数排名融合。它不需要对不同检索器的分数做归一化只用排名信息。计算方式很简单对每个文档在其出现的每个检索结果列表中取排名位置从1开始计分公式为score Σ(1 / (k rank))k是常数经验值通常取60。然后用这个分数重新排序所有召回文档。RRF的好处是鲁棒不受不同检索器分数尺度影响实现也就二十行代码值得放进工具箱。还有一点容易被忽略混合检索里关键词部分的自定义词表。企业内部文档里有大量专属词汇比如产品代号“A7-X2”、系统名称“星枢平台”把这些词加进分词器的自定义词典BM25的命中率会有肉眼可见的提升。否则分词器会把“A7-X2”切成一堆碎片根本无法匹配。4.3 重排模型最后一道筛选混合检索之后top_k如果取50到100直接把这么多文本块全部塞给大模型token开销大且信息混杂大模型很容易被噪音干扰。所以中间要加一道重排rerank用更精细的模型把真正相关的段落排到最前面。重排的核心是cross-encoder结构query和文档可以同时输入模型做深度交互精度远高于用于向量化的bi-encoder。常见的开源重排模型有bge-reranker系列也有多语言版本。在实测中重排对最终答案质量的提升通常是所有优化里最立竿见影的一项很多时候能把准确率从60%拉到80%以上。一个实践细节重排阶段不要只看第一名的结果。推荐的做法是取重排后前3到5名作为上下文送入大模型因为答案信息可能分散在多个段落中。如果只取第一名遇到信息跨越多个chunk的情况就会遗漏。当然具体取多少个取决于你的上下文窗口和chunk大小。一个常见的配置是召回50条→重排取前4条→送入生成模型。这组数字代表了检索广度和上下文深度之间的平衡点具体场景还需要自己微调。另外要提醒的是混合检索和重排是有配合的。如果你在重排阶段已经做了精细排序那么向量检索阶段的top_k可以适当放宽一点比如从50调到80或100这样重排的候选集更大更有可能捞回那些排名靠后但实际上相关的文本块。5. 分水岭四知识库形态的选择别一上来就只做向量库聊“RAG知识库”“结构知识库”和“知识图谱”的区别是近期热词里被问得最多的点。很多人一上来就默认向量库一刀切但知识库形态选择错了后续怎么优化都别扭。5.1 三种知识库形态的适用边界向量库RAG适合的是非结构化文档产品手册、制度文件、技术博客、聊天记录。它的核心价值在于语义检索你描述一个问题它帮你找到语义上相关的段落。它不擅长精确计算不擅长多跳推理也不擅长回答“哪些合同在2024年7月之后到期”这种需要明确筛选条件的查询。结构知识库结构化数据库或表格型知识库适合的恰恰是这类精确查询订单状态、库存数量、用户信息、财务报表。它有严格的模式查询用SQL或API完成速度和确定性都很高。RAG在这里的正确姿势是“Text-to-SQL”——大模型把用户问题翻译成SQL查询然后从数据库拿到精确答案最后再用自然语言组织回复。注意这一步里大模型不负责回答事实本身只负责把意图翻译成查询语句大大降低了幻觉风险。知识图谱适合的是关系密集型场景组织架构、权限关系、供应链上下游、产品兼容性矩阵、代码依赖关系。它的优势在于多跳查询——“找到所有使用A模块且B型号不在兼容列表中的设备”。这类问题在文本RAG里几乎是灾难因为信息分散在大量文档中且关系是隐含的在知识图谱里则一条Cypher或SPARQL查询就能解决。再补充一个有趣的对比wiki和RAG。Wiki站点的内容天然高度链接概念之间互相引用适合用知识图谱来表示概念关联。而RAG更适合私有文档、非公开资料。两者并不对立实际项目经常先把wiki内容解析成结构化知识图谱再和文档向量库配合使用。5.2 知识图谱本体不只是“加个关系”提到知识图谱就绕不开“ontology”本体这个热词。本体是知识图谱的模式层它定义了什么类型的实体存在、它们之间可以有什么类型的关系、关系有没有约束。比如“员工”属于“人员”“员工”和“部门”之间存在“属于”关系。没有本体的知识图谱只是一堆散乱的三元组有了本体图谱才有结构、可校验、可推理。在RAG场景中引入知识图谱最常见的方式是GraphRAG——先抽取文档中的实体和关系构建图谱然后在问答时通过图遍历来获取上下文。这种方法对“多跳问题”、对实体间复杂关系的回答效果显著尤其适合企业内部的制度关系分析、项目依赖查询等。但它的问题也很现实构建知识图谱需要大量的实体抽取和关系抽取工作错误率控制不容易维护成本远比向量库高。我的建议是普通项目从向量库起步遇到明确的多跳关系需求时再考虑把高频查询涉及的核心实体构建成图谱而不是一开始就全量建图。把图谱做成“窄而深”的专项库比做成“宽而浅”的全量大而全要实用得多。5.3 不同场景下的形态选择思路我的选择逻辑总结了三条。第一如果你要检索的是一堆文档用户问题大多围绕“是什么”“怎么解决”选向量库混合检索。第二如果你需要处理精确数值查询、统计类问题在向量库之外加一张或几张结构化表走Text-to-SQL。第三如果你发现用户问题里有大量“A和B是什么关系”“哪些实体满足多层条件”的类型这是知识图谱的信号该认真考虑GraphRAG了。很多项目真正的问题是形态混搭没做好。我曾经接手过一个项目客户一开始把全量合同文本塞进向量库问“我们总共签了多少份合同”时模型只能从文本里猜答案经常不对。后来在边上加了一张合同汇总表专门跑Text-to-SQL准确率直接从50%拉到接近100%。RAG从来不是唯一正确答案它会和结构化方案共存你的架构应该为这种共存留好接口。6. 分水岭五上下文组织与智能体协同别让检索结果毁了生成质量前面解决了“能不能找到”这里要解决“找来的怎么用”。很多系统召回其实没问题但生成质量依然差根因在上下文组织。6.1 检索结果不是越多越好去重与裁剪把top_k调得很大再一股脑塞给大模型是新手最容易犯的错。上下文塞满了几百行内容其中夹杂着大量重复信息、低相关度信息大模型的注意力被稀释反而会忽略真正关键的内容。另外token成本也是实打实的一个top_k50且chunk_size512的请求上下文光是检索结果就有两万多token。裁剪策略有几个方向。一是冗余去重召回的chunk之间往往有大量重叠内容尤其是同义改写过的片段。可以用简单的embedding相似度计算做合并相似度超过阈值的chunk只保留得分高的一个。二是位置去重如果两个chunk在原始文档中属于同一章节且内容高度重叠只保留一个。三是按需裁剪根据问题类型预估需要的上下文量。简单的是非类问题一两个chunk足够综合对比类问题可以给四到六个。另一个技巧是MMRMaximal Marginal Relevance采样。它在相关性之外引入了多样性惩罚选下一个chunk时既要和query相关又要和已经选中的chunk不够相似。直观感受就是上下文里内容更分散覆盖面更广。这和重排的目标不完全一样——重排优化的是相关性排序MMR优化的是多样性选择。两者可以配合使用也可以根据任务类型选择。如果你发现系统经常在同一个意思上反复解释而错过其他信息那多半需要引入MMR。6.2 引用归因让回答可信可查一个容易被忽略但实际价值极高的点是归因。每个送入大模型的chunk都要带上它的来源信息——文档名、页码、章节路径。生成阶段要求模型在输出中标注它所依据的引用来源编号。实现方式是在Prompt里明确要求“基于引用[1][2]的内容回答并在句末标注引用来源”。这样用户在界面上看到每个回答都能点击查看原始文档出处。归因的价值不只是让用户“感觉专业”它能直接拦截幻觉。我在实践中发现一个规律当模型被明确要求标注引用来源时它编造内容的概率会明显降低。原因是这个约束迫使模型只从给定上下文中抽取信息——如果答案无法标注来源模型要么明确说“根据现有资料无法回答”要么引用来源编号时出现错位你就有机会抓出来并修正。更精细的做法是在生成之后跑一遍“答案-引用”一致性校验用LLM判断答案中的每个论断是否都能在上文引用处找到依据。这一步准确率没有那么完美但作为辅助审计手段足够有用。6.3 RAG与智能体的协作方式“RAG智能体”最近很火但我见过太多为了智能体而智能体的案例。一个本质上是检索问答的任务非要去搞Agent循环结果问题没变简单反而多了无数不可控的环节。智能体的核心价值在于“动态决定下一步行动”。当任务序列会因中间结果而变化时Agent才有意义。比如一个技术客服机器人收到用户描述后它可以决定是直接检索知识库还是需要先向用户追问型号和场景还是需要调用一个查询接口获取设备配置再决定要不要检索知识库。这种分支结构固定流程的RAG做不到Agent才有必要。但在工程实现上我的经验是先用最少的Agent循环达到效果再逐步增加智能行为。一个直白的顺序是先做一个单轮的“检索-生成”看效果不够再引入“检索-判断-再检索”的两步模式还不行再考虑引入多工具调度。在每一步都要评估是否是当前瓶颈。很多人一上手就是AutoGPT式的无限循环Agent结果一个小问题要花两分钟、五六次LLM调用才能答出来用户早跑了。另一个实践细节Agent的工具定义和RAG是耦合的。如果有多个知识库分属不同业务域建议把每个知识库注册成独立工具工具描述里写清楚什么情况下用这个库。让Agent自己去选知识库比一次性把所有库的结果都召回来效果更好——避免跨库噪音也节省token。但需要提示词设计得足够清晰否则Agent会选择困难。7. 分水岭六评测与迭代没有评估就没有持续变好的可能这是我最想强调的一点。太多RAG项目停留在“demo效果看着不错”就上线了上线后遇到badcase也不知道该怎么优化。没有评测体系你对系统的改造成果就永远只能靠感觉。7.1 评测集比模型更重要的资产评测集是RAG系统里最值得投入的资产。不要用几十条手工案例太容易过拟合到自己的预期上。建议从真实使用场景里收集用户query至少一百条起步覆盖不同的业务域和问题类型。每条query配一个参考答案答案给出关键事实点方便后续自动打分。每年或每季度更新一次评测集把新出现的query类型加进去。评测集的构建需要注意分布。我一般会把query分成几类事实型“XX产品的保修期是多久”、操作型“怎么配置XX功能”、对比型“A和B有什么区别”、分析型“结合文档分析XX方案的风险”。不同类型的query系统表现可能天差地别分开统计才看得出短板。7.2 核心指标怎么测、怎么看召回和生成的指标要分开看。召回层面看Recallk和命中率推荐做法是在每个评测样本上检索top_k人工判断是否包含正确答案所在的chunk然后统计整体比率。这个指标反映你的检索链路有没有问题。生成层面看三项答案相关性回答是否切题、忠实度是否严格依据上下文有没有幻觉、完整性关键信息有没有遗漏。相关性可以用LLM打分忠实度用上面提到的“答案-引用”一致性校验来评估完整性则需要用评测集里的关键事实点逐条比对。关于LLM打分建议使用你主链路的同一家大模型打分但为了避免系统性偏差最好做一次人工抽检校准。另外打分Prompt要具体不要让模型给一个模糊分要求它给出理由或者按维度拆开打分这样哪怕分打得不准你还能从理由里看到优化方向。7.3 badcase闭环让系统越用越好评测的意义不在打分本身而在发现问题后能定位、能改进。每个badcase都应该落到具体环节如果是召回阶段没找到相关chunk问题在切分或检索如果召回了相关chunk但答案错了问题在上下文组织或生成如果答案和引用对不上问题在提示词或模型本身。我的标准流程是收集badcase→按环节分类打标签→针对每一类制定优化方案→修改后重跑评测集→观察整体指标而不是单个case的表现。这里要控制住一个冲动不要为一个badcase做过度特化修改否则新case可能变好但原有准确率悄悄下降。评测集的价值就是让你发现这种“局部优化、全局恶化”的问题。我见过最靠谱的团队把评测集跑进CI/CD流程里。每次知识库变更、模型切换、提示词调整都自动跑一遍评测输出指标对比。这样任何改动都有数据支撑而不是“感觉好像变好了”。这么做需要一点工程投入但RAG系统的可维护性全靠它撑起来。8. 常见问题与排查技巧实录最后按惯例整理一些高频问题。这些是我在多个项目里真实踩过、排查过的坑每一条都对应着一个“想当然”的误区。8.1 召回率为零或召回不准怎么定位先确认检索链路各环节的状态。第一步检查embedding生成是否正常有时候文档里的文字是特殊字体或编码向量化后全是噪音。第二步检查切分结果把一个chunk打印出来看看内容是否完整、是否属于同一主题。第三步检查query是否太“口语化”很多系统的问题是用户query里用了业务黑话而文档里是正式表述语义距离太大导致召回失败。这种情况就需要在query理解阶段做改写——用一个小的LLM把用户问题改写成更适合检索的表达然后再embedding。这是我实测中提分最明显的一个技巧。8.2 答案幻觉严重怎么压下去幻觉有两个主要来源。一是检索到的chunk本身就不相关模型只能硬编压掉幻觉的方法是提高召回质量配合重排把真正相关的片段放进来。二是Prompt约束不够简单粗暴但有用的做法是在系统提示词里明确写“只能基于提供的材料回答材料不足时直接回答‘资料不足无法确认’”。再配合引用归因机制幻觉率会显著下降。还有一种隐藏来源是chunk里混入了噪音文本页眉、版权声明模型把这些当成了事实来源这就要回到源头解析时把噪音清理干净。8.3 常见问题速查表症状可能原因排查方向检索结果明显不相关切分粒度不当或query意图理解偏差检查chunk语义完整性尝试query改写答案张冠李戴相似文档太多且切分过程丢失了区分性信息检查metadata、增加关键词过滤条件好回答但引用对不上上下文给了太多不相关chunk模型被干扰精简上下文加强引用约束表格数据答不对表格在解析或切分时被拆碎表格按整体块处理或转成结构化描述特定领域术语召不回向量模型不认识低频词启用混合检索维护自定义词表文档越多效果越差没有做过滤或路由全库无差别检索按metadata过滤、按知识域路由偶发性幻觉但检索看起来没毛病切块时信息被切断上下文不完整增大chunk或引入overlap结构性切分8.4 几个值得记住的工程细节第一知识库变更后一定要全量重新向量化但不要一把梭重建索引用“增量更新定期全量”的组合。很多向量库原生支持upsert但metadata的变动容易出问题上线前一定要验证旧doc更新了新doc插入都能被检索到。第二向量库选型不要盲目追新。主流方案比如开源的Milvus、Qdrant或者更轻量的Chroma、LanceDB在常规体量下差别不大反而是运维复杂度、生态成熟度更影响实际体验。项目早期用轻量方案数据量真的上来了再迁成本是可控的。第三给所有非文本内容留一条后路。如果某类文档始终解析不干净不要让它影响整个链路。可以把这类文档标记为“降级文档”走纯关键词检索哪怕效果差也先保证能回答而不是让用户永远得到“抱歉我还没学会这份文档的内容”这种让人抓狂的回复。在我实际接手过的项目里把上面这六个分水岭逐一捋了一遍后效果提升通常是体系性的召回准了生成就稳了归因清了幻觉就少了评测建了迭代就不再靠猜。RAG这条流水线确实人人都会搭但搭完之后如何打磨、如何定位瓶颈、如何让系统在真实数据上一天天变可靠这些才是真正拉开差距的地方。如果你现在正对着一个“看起来能跑但总差点意思”的RAG项目别急着换模型也别急着加功能先从这六处逐项体检一遍大概率能找到症结所在。