
做自研RAG项目最怕的不是写代码而是把弯路完整地走一遍。文档解析、分块、向量化、检索、重排、提示词装配任何一环拍脑袋最后都要在问答效果上还债。我自己带团队做RAG落地时踩过一轮坑之后才意识到与其闭门造车不如把市面上成熟的开源RAG产品当成免费教材一件件逆向拆解再拼出适合自己业务的自研底座。这篇内容想做的事情很简单从六款有代表性的开源RAG产品里逐层抽出值得复用的设计最终汇成一套可直接参考的自研RAG蓝图。不管你是刚接手RAG相关需求、团队里正在选型还是自研到一半发现效果不对这篇都能给你一个相对完整的参照系。1. 先回答一个核心问题为什么自研RAG要先逆向开源产品1.1 自研RAG最常见的三种弯路先说我在实际项目里看到的三类典型失败路径。第一类是重检索、轻前处理。团队一上来就调Embedding模型、换向量库、优化召回策略但文档根本没处理好。拿到的PDF是扫描件OCR没做表格被当成普通文字切碎章节标题和正文混在一个chunk里。结果检索阶段无论怎么调召回的内容都是碎片LLM生成答案时自然只能瞎编。这类项目通常会在上线后一到两周被业务方用几个常识问题问倒。第二类是重实现、轻评估。代码写得很嗨召回接口、重排服务、知识库管理后台全都有但没有一套评估集。上线之后怎么判断效果变好还是变差全靠感觉。RAG这个系统链路长任何一环微调都可能让另一半更差没有指标几乎是盲人摸象。第三类是重功能、轻成本。把各家开源产品的功能全部缝合到自己系统里实体抽取、意图识别、多轮改写、图谱构建全都上。功能列表很漂亮但每个模块都在增加延迟和算力成本最后用户问一个问题要等十几秒而且复杂模块之间的互相干扰很难排查。这三种弯路的共同根源是缺少一个从全局视角出发的、别人已经验证过的参考架构。而开源RAG产品恰好提供了这个参考。1.2 逆向工程在软件领域为什么可行逆向工程之所以在RAG领域尤其有效是因为RAG本身并不是一个全新算法而是多个成熟技术的工程化组合。它涉及解析、存储、检索、排序、生成、评估等多个环节。每个环节单独看都不神秘但组合起来却有大量工程细节。这些细节论文里通常不会写官方文档也往往一带而过——比如分块时保留文档原始层级比如查询改写要维护一个独立于知识库的提示词体系比如重排模型的得分不能直接和相似度阈值比较。但开源产品的代码里全是答案它们是开发团队用真实业务数据和线上反馈一点点调出来的。所以从六款开源产品里逆向出公共骨架本质上是在吸收一群资深工程师踩坑后的沉淀。这比从零开始自己摸索要高效得多。2. 六款开源产品怎么选它们的架构差异在哪里2.1 选样标准覆盖完整链路而不是只看名气选这六款不是因为它们最火而是因为它们各自解决了RAG链路里一个关键卡点并且互相之间有明显差异。我的筛选标准有三个完整覆盖RAG关键链路不是只有其中一两环技术路线有差异能从不同角度提供启发社区活跃、有大量真实部署案例避免纸面产品。我选了RAGFlow、Dify、FastGPT、QAnything、MaxKB、LightRAG/GraphRAG这两个图谱增强路线其中LightRAG和GraphRAG归为一类来讲因为它们解决的问题相同思路也相近。加上它们刚好是六个维度。2.2 五条不同的技术路线这六类产品背后的路线差异我用一张表来总结产品主打定位核心差异化设计最值得自研借鉴的点RAGFlow深度文档理解版面分析结构化解析后再分块文档解析的完整流水线DifyLLM应用平台知识库管理可视化编排API化检索规则与知识库生命周期治理FastGPT知识库问答问题分类知识库路由清晰引用让路由环节独立于生成QAnything两阶段检索离线向量召回在线重排重排模型作为独立服务层MaxKB轻量可嵌入式RAG一键部署、函数调用、嵌入业务系统轻量化交付与对话内检索GraphRAG/LightRAG知识图谱增强LLM抽取实体关系社群社区化检索全局性问题的图谱方案这五条路线的本质差别在于对文档上下文的组织方式不同。RAGFlow和MaxKB更重视文档进来之后怎么处理Dify更重视知识库和上层应用怎么衔接QAnything更重视召回之后怎么精排图谱方案则走了一条完全不同的路——不再依赖向量相似度而是用实体关系网络来做推理。这提醒我们自研时不要一开始就锁定某一种路线而是先想清楚自己业务里的瓶颈在哪一环再去对号入座。3. 逐款拆解每一款产品最值得偷师的模块3.1 RAGFlow文档解析的尽头是版面理解RAGFlow给我最大的启发是它把文档解析从预处理步骤提升到了核心能力的高度。大多数开源产品对PDF的处理还停留在按页抽文字、按字符切分而RAGFlow在进入分块前先做了一套完整的版面分析识别标题层级、段落边界、表格区域、图片位置还原文档的原始阅读顺序。这套设计对自研的启发有两层第一解析结果的粒度决定了后续检索质量的上限。如果文档解析时就把表格硬拆成一行行散文本那后续分块和向量化做得再好检索出来的也是断裂内容。RAGFlow的做法是表格先以结构化单元Markdown或HTML保存正文按语义段落保存图片通过视觉模型生成描述文字再统一进入切块流程。第二版面分析可以大幅提升引用溯源的准确性。当用户问这个数据来自哪个章节RAGFlow能定位到原始版面区块而不是只抛出一段拼接文本。自研RAG如果不想一上来就做完整的版面分析可以先从保留标题路径开始——让切出来的每个chunk都带着章、节、小节的路径信息这在召回展示时帮助很大。3.2 Dify知识库管理和检索编排的样板Dify给我的感觉是平台味最重的一个。它不只是RAG引擎更是一套围绕知识库的管理和编排层。它把知识库生命周期的各个环节都做成了可配置项数据导入方式、分段规则、索引方式、检索设置、召回策略、重排模型。这里有两个点对自研特别有参考价值。一是检索设置的精细化。同一套文档不同场景对检索的容忍度完全不同。业务问答里用户直接要答案召回精度优先知识库内部检索管理员想尽可能多地找到相关内容召回率优先。Dify把这些差异做成了知识库级别和检索参数配置top_k大小、相似度阈值、Score阈值、召回策略等。自研时把这些参数做成系统可配置项而不是写死在代码里能省掉大量后续调优沟通成本。二是分段Chunking规则的半自动化。Dify的系统默认分段并不复杂但提供了很强的自定义空间包括文本分段标识符、最大分段长度、重叠长度还支持父子分块模式——父块负责上下文语义子块负责精确匹配。这让知识库管理员可以根据文档类型去微调而不需要动代码。Dify的另一个可借鉴点是它的知识库隔离思路。多个知识库之间可以设置独立权限和独立检索范围问答时可以指定检索某一个或某几个。这种设计在自研系统里很容易被忽略——往往一个库打天下后续权限、合规问题全冒出来。3.3 FastGPT问题分类与知识库路由FastGPT这个名字暗示了它的路线快、直接、以问答为目标。它最打动我的功能是问题分类器和知识库路由。RAG问答系统里有一种常见场景用户的问题根本不需要走向量检索。比如用户问的是你们支持哪些格式这个问题的答案可能在系统配置里再比如用户问的是你是谁这属于闲聊还有一些流程类问题需要走工作流而不是查知识库。FastGPT通过一个前置分类模块把问题先做意图分流再决定是否触发知识库检索以及检索哪个知识库。这个设计解决了一个被很多人忽略的问题不是所有问题都适合向量检索。对于一个垂直业务的自研RAG来说问题路由的价值比想象中大得多。它可以避免把闲聊问题送进检索链路省掉无效计算把不同领域的问题路由到对应知识库缩小检索范围提升精度为兜底回复留出空间当所有知识库的置信度都低时走人工转接。自研时不必做一个独立的模型来做路由。一个轻量分类提示词让LLM判断问题类型并输出JSON结构就足够覆盖大多数场景。关键是把这个环节放在检索之前并让它可配置。3.4 QAnything把重排当一等公民QAnything是网易有道开源的项目。它的核心思路是两阶段检索第一阶段同时使用向量检索和BM25关键词检索做多路召回第二阶段用一个专门的Rerank模型对召回结果统一打分排序。这个设计在RAG产品里不算稀奇但QAnything把它做到了极致。回看业界实践许多自研RAG项目把重排当成可选项甚至上线之初完全不加重排。这会带来一个明显问题向量检索的Top-K结果和用户真正相关的尾部内容之间经常存在错位。缩小chunk可以缓解但会引入更多的噪音chunk单纯加大Top-K又会让生成阶段返回太多无关内容挤占上下文窗口。QAnything把重排做成了标准服务并配套了双向的Embedding和Rerank模型其中最值得借鉴的是召回重排的指标分工召回阶段看召回率尽量别漏重排阶段看精度把最相关的内容顶到前面。自研链路里重排并不一定要自研模型从HuggingFace上选一个合适的Rerank模型比如BGE系列封装成独立服务就能获得极大的效果提升。3.5 MaxKB轻量嵌入与对话内检索MaxKB走的是另一条路线把RAG能力做得足够轻、足够易嵌入让它可以作为模块被现有业务系统快速调用。它的默认架构不依赖庞大组件支持一键部署同时提供了函数调用能力和对话流程编排能力。对自研团队的启发是边界意识。很多自研项目容易把系统越做越重——为了支持某个边缘功能拆出一个独立服务然后这个服务又需要额外运维。MaxKB的克制提醒我们RAG核心链路之外的功能能通过配置、函数、编排解决的问题尽量不要做成核心模块。MaxKB的对话内检索也很有意思。它不是一次性把知识库结果全塞进上下文而是允许在多轮对话中动态追加检索。这对应了真实场景里用户逐步明确需求的过程——第一轮问你们产品的定价第二轮追问那企业版呢。如果每次都是全量重检索不仅成本高而且容易丢失对话焦点。3.6 GraphRAG与LightRAG让RAG拥有全局视野图谱方案针对的是普通向量RAG的一个硬伤局部强、全局弱。当你问这几类产品之间的关联是什么或如果A不成立B和C会怎样这类问题上纯向量检索几乎无能为力因为答案不藏在某一段文本里而是要通过多段知识之间的连接关系推理出来。GraphRAG的路线是用LLM从文档中抽取实体和关系构建知识图谱再做社区聚类和社区摘要回答问题时先在实体网络上做局部搜索再结合社区摘要做全局推理。LightRAG在此基础上做了简化通过局部全局双层检索用更低的算力成本拿到类似的效果。从自研角度看图谱不是用来替代向量检索的而是用来补位关系密集型问题。它适合的组织结构大致是知识库内容之间有强关联、问题普遍涉及多实体比较、需要推理链。如果只是做简单的FAQ问答图谱带来的额外成本和复杂性可能不值得。更务实的做法是向量为主、图谱为辅的融合架构先向量召回一批相关内容再用图谱补充实体关系层面的信息最后一起交给LLM生成。这样不会为了图谱而牺牲时效性和简洁性。4. 六款产品背后的公共骨架自研RAG的五层结构拆完六款产品我发现它们虽然形态各异但骨架高度一致。这个公共骨架可以浓缩成五层结构这也是自研RAG时值得照抄的部分。4.1 文档接入层解析、清洗、结构化、分块文档接入层的目标是把原始文件变成干净的、语义完整的文本单元。它由四个步骤组成解析根据文件类型选择不同解析器。PDF要处理扫描件识别与版面分析Word/HTML要提取正文和结构表格要按行列结构保存而不要拍平。清洗去掉页眉页脚、目录、重复文案、无意义空白、水印文本。页眉页脚如果不去掉会变成每个chunk都带一段重复噪音严重干扰向量相似度。结构化保留标题路径、章节层级、表格Markdown表示、图片描述。这步决定了后续引用溯源能力。分块在结构化基础上按语义边界切块设置合适的分块大小和重叠区间。父块保存上下文子块承担精确匹配。这层的质量基本决定了整个系统的上限。RAGFlow、Dify、FastGPT都在这层投入了大量工程但它们的实现思路可以各自借鉴。自研时可以先用成熟解析器比如Unstructured、PyMuPDF、Tika搭建流水线不要纠结于自研解析核心。4.2 索引层稠密向量稀疏关键词的混合索引索引层负责把chunk变成可检索的结构。公共骨架里几乎所有产品都在用混合索引而不是单纯的向量索引。稠密向量索引chunk文本经过Embedding模型转成向量在向量数据库里按相似度检索。负责语义级召回。稀疏关键词索引用BM25这类算法按词频检索。负责精确关键词召回尤其适用于人名、产品型号、特殊代码等向量模型覆盖不好的场景。自研时落地方案很多Elasticsearch既有BM25又有向量检索能力Qdrant、Milvus可以搭配外置BM25服务最简单的方案是先用SQLite一个向量库一个倒排索引把链路跑通。关键不是选哪个库而是两条召回路径必须都存在最终的召回结果要合并、去重、重排。4.3 检索层多路召回、查询改写与重排检索层是六款产品差异最大的地方之一但思路的一致性很高不能让第一次向量检索的结果直接进入生成阶段。标准做法可以总结为三步查询改写用户的原始问题往往口语化、有指代、缺少上下文。LightRAG和Dify都有类似的查询改写机制——先把问题扩充成多组检索词同时保留原始问题。比如用户问它的性能怎么样需要先想办法确认它指代哪个产品再展开检索。多路召回向量检索、BM25关键词检索、图谱检索并行或串联进行每路召回Top-N然后合并。重排用交叉编码器模型对合并的候选重新打分。交叉编码器的精度高于向量相似度但速度慢只适合在候选集上做精排。一个可以立刻用的查询改写提示词模板我放在下面这也是我在项目里实际用过的你是检索词改写助手。根据用户问题和对话历史生成最多三个独立的检索词。 要求检索词面向知识库检索系统必须具体、完整、包含关键实体名称。 输出格式JSON数组如[检索词1,检索词2,检索词3]。 用户问题{question} 对话历史{history}4.4 生成层上下文窗口管理、提示词模板与引用溯源生成层决定了检索出来的内容是否能被正确使用。这里有几个常见的坑把整个检索结果一股脑塞给LLM不顾上下文窗口。正确做法是设置检索结果的最大字数占比保留给LLM推理的空间。比如限制最终进入上下文的检索片段不超过1500字超出部分宁可截断。提示词模板太简单只写根据以下内容回答。效果更好的模板会明确要求优先使用检索内容不编造信息不足时明确回答不知道引用的序号必须与检索片段对应。忘记引用溯源。用户使用RAG产品时最需要的东西是他能回去翻原文。在生成结果时带上引用序号并最终映射到原文页和具体段落这个能力是所有评测里用户满意度最高的一个。4.5 评估优化层离线指标与线上反馈闭环最后一个公共模块是评估。Dify、FastGPT都有相对完整的调试和质检界面QAnything也有评测报告模块。真正让我把它当成必做项的是RAG系统在迭代中的特征任何一次修改效果都可能朝不同方向漂移离线不能评估就完全没法迭代。做评估可以分两步起步第一步做一套低成本人工评估集。选50-100条真实问题标注标准答案、支持性引用文档、正确回答把忠实度、相关性、答案完整性三个维度做成打分表。第二步接入RAGAS这类开源评估框架让LLM充当裁判对回答质量做自动化评估。RAGAS提供了Faithfulness、Answer Relevancy、Context Precision等指标可以直接对测试集批量评估。评估不是上线前一次性的动作而是要固化在知识库更新和检索参数调优的全流程里。没有评估集后面所有优化都像在黑夜里调音量。5. 逆向成果落地一套可复用的自研RAG蓝图5.1 分层架构与数据流设计我基于上面五层结构整理出一个较完整的自研RAG分层架构。这里尽量保持简单强调可落地性。接入层文件上传 → 解析 → 清洗 → 结构化 → 分块 ↓ 索引层Embedding向量化 ↵ BM25倒排索引 → 写入向量库/索引库 ↓ 检索层查询改写 → 多路召回 → 合并去重 → 重排 ↓ 生成层上下文组装 → 提示词模板 → LLM生成 → 引用溯源 ↓ 应用层问答接口 → 管理后台 → 反馈收集 → 评估闭环各层之间通过标准接口连接接入层输出统一的文档单元对象包含内容、标题路径、元数据和分块关系检索层输出带评分和来源的候选片段生成层只消费候选片段和提示词参数。这种数据流设计有两大好处每一层可以由不同组件实现后续替换成本低。今天用PostgreSQL的pgvector明天换Qdrant不需要动其他层。每一层可以独立验证。接入层可以单独测试某一个PDF的切块质量检索层可以单独压测召回率生成层可以单独评测回答忠实度。5.2 组件选型对照自研与替换的边界组件选型是自研团队每天都会面临的问题。我按踩过的坑给一份比较务实的选型对照表模块可选方案自研边界建议文档解析PyMuPDF、Unstructured、Tika、RAGFlow的解析引擎优先用现成库只有在特定文档格式合同扫描件、图纸等时才自研专用解析器Embedding模型BGE-M3、Qwen-Embedding、OpenAI text-embedding-3先跑内置测试集对比不要只看MTEB榜单分数向量数据库Qdrant、Milvus、pgvector、Chroma数据量小于百万级时pgvector或Chroma足够不必引入分布式数据库稀疏检索Elasticsearch、Typesense、自建倒排索引中小知识库可以直接用SQLite FTS5成本极低重排模型BGE-Reranker、Cohere Rerank封装成独立HTTP服务方便替换模型版本LLM本地Ollama部署开源模型或调用商业API先跑通链路再优化模型选择避免一开始被模型选型拖住编排框架LangChain、LlamaIndex或纯手写纯Python实现对链路把控更稳框架只用来做胶水很多人会在选型上纠结很久。我的经验是选型的核心不是哪个最好而是替换成本够不够低。只要接口统一先随便选一个跑通再根据评测结果替换才是最快路线。5.3 最小可用版本的实现路线如果从零开始做一个自研RAG的MVP版我会按这个顺序推进先用Python脚本接入开源解析库实现PDF/Word/HTML → 清洗 → 递归字符分块的流水线。分块参数先用经验值500字左右重叠100字。用BGE-M3生成向量写入pgvector或Chroma同时用SQLite FTS5存一遍原文关键词索引。实现一个检索接口改写查询 → 向量召回Top-20 → BM25召回Top-20 → 合并去重 → 用BGE-Reranker重排取Top-5。写一个生成接口把Top-5片段按提示词模板发给LLM输出时以[1]-[5]标注引用序号。用RAGAS框架搭建离线评测导入50-100条业务问答跑基准效果。再根据评测结果回头调分块策略、召回数量、提示词。按这个顺序走通常两周内就能跑出一个效果初步可用的RAG基础版。如果团队里有人之前完全没接触过RAG这个MVP过程本身就是最好的学习路径。6. 自研落地必须跨过的四个实操坑6.1 分块大小该定多少从RAG知识库谈起的参数调优在看了大量开源项目的讨论和实际案例后我可以说根本不存在一个适用于所有场景的分块大小。常见建议从200到800字都有关键是看你的文档类型和用户问题的特点。如果文档是产品说明书每段本身语义完整直接按段落分块优于按固定字数硬切。chunk大小可以放宽到800字。如果文档是合同或制度文件条款之间有强引用关系更适合父子分块。父块是整个条款段落子块是条款内的句子。如果用户问题偏短、偏实体化比如型号A和型号B的区别chunk太大容易把答案淹没在其他信息里需要更小的chunk配合重排。一个可行的经验法则是先用固定字数400-500字跑一遍基线再用评测集观察失败case然后针对失败类型调整策略而不是一开始就追求最优参数。6.2 图片和表格到底能不能存进RAG知识库这个问题在RAG知识库相关讨论里的出现频率很高。我的回答是可以但不能用常规方式。纯文本向量化对图片天然失效。正确做法是有两条路图片辅助路径用OCR或视觉语言模型比如Qwen-VL、MiniCPM-V提取图片中的文字信息生成详细的图注和描述文本再把描述文本向量化。用户后续的问句中只要涉及图片内容就能通过描述文本检索到。表格结构化路径表格不要转成纯文本行流要保留成Markdown表格或HTML按行列关系保存。检索时把表格对应的文字说明作为主检索单元表格本身作为附件随候选片段一起返回。自研时最好设计一个多模态文档单元一个单元可以同时包含文字块和图片/表格对象。这样检索只作用于文字描述生成时再按需携带图片或表格进上下文。6.3 知识图谱不是银弹kg与向量检索的适用范围边界自打kg知识库ontology rag这类热度起来之后不少人也在问我要不要给自研RAG直接上知识图谱方案我的判断标准是看问题的密度。如果业务里的典型问题都是XX是什么XX和YY谁更适合我怎么做XX这类局部查询向量RAG足够了。但如果你经常遇到为什么这个环节影响了那个环节哪些因素共同决定了这个结果这类跨实体推理问题知识图谱才有必要引进来。另外还需要考虑成本。GraphRAG构建图谱的算力开销比普通向量索引高很多倍而且需要定期随文档更新重建。更合理的起步方式是在向量检索召回之后叠加一个关系补充环节对召回片段做一次轻量实体链接顺便抽取相邻实体关系补进上下文。先用小成本验证图谱对效果的增量再做完整图谱模块。6.4 macOS本机搭建RAG环境的可行性方案很多人习惯用自己的Mac本机先搭RAG试验环境。这事完全可行但要提前跳过几个坑。最稳的本地方案是Ollama跑Embedding和LLM模型搭配Chroma或Qdrant作为向量库再用FastGPT或MaxKB作为界面和管理层。具体到Mac上实践时有几个经验可以分享内存是硬约束。7B量级的量化和13B量化模型在同一台机器上同时跑Embedding和生成内存16GB会比较吃紧。建议Embedding用轻量模型如BGE-Small生成时才切换大模型或者用远程API做生成。Python环境建议直接用虚拟环境管理工具不要直接在系统Python上装依赖别问我是怎么知道的。分块、向量化、评测这些依赖一旦冲突排查起来特别费时间。macOS上跑PDF解析注意扫描版PDF需要额外装OCR相关库。如果不装解析出来全是空文本检索结果会非常迷惑。如果在Mac上先把这套MVP跑通了后续迁移到服务器环境基本就是换一个向量库连接字符串的事。最后再聊一点个人的实际感受。逆向这六款开源产品时我最大的体会是自研RAG真正难的地方不是某个算法环节有多高深而是如何把解析、切块、索引、召回、精排、生成、评估这些看起来都会的模块以正确的顺序和正确的边界组合在一起。开源产品把组合方式直接摆在了代码里这是信息密度极高的参考素材。如果你现在正准备自研RAG我的建议很明确不要从写第一个函数开始先从拆第一份开源代码开始。选一款和你业务最接近的产品把它的数据流画一遍再对照这篇的五层结构和选型表决定哪些环节自研、哪些环节用现成组件。先跑通MVP再谈优化。这样走至少不会把弯路完整地走一遍。