RAG 文档切分、索引优化与 Reranker 学习笔记记录一次询问GPT的完整过程 从业务场景到工程落地的一次完整梳理前言这次讨论在解决什么问题这次对话围绕 RAG 系统中的三个关键问题展开文档到底应该如何切分索引应该如何优化为什么还需要 Reranker以及 Reranker 通常有哪些做法一开始讨论的是文档切分和索引优化后来进一步引出了 RAG 检索链路中的排序问题也就是即使向量检索能找出一批看起来相关的 chunk系统仍然需要判断哪些 chunk 最能回答用户问题。于是自然进入了 Reranker 的讨论。这份笔记不是简单罗列概念而是按照这次对话中的思考路径来整理文档切分与索引优化 ↓ 为什么需要 Reranker ↓ Reranker 是什么 ↓ Reranker 通常有哪些做法 ↓ 如何把整个 RAG 检索链路串起来一、文档切分到底应该怎么做最开始关注的问题是在文档切分和索引优化部分如何具体切分文档如何根据不同业务场景切分以及如何做索引优化这个问题的核心并不是简单问chunk_size应该设成多少而是在问RAG 系统中的文档切分如何从业务问题出发设计出真正适合检索和问答的知识单元1. 为什么不能直接按固定长度切分很多 RAG 初学者会直接采用固定长度切分例如每 500 tokens 切一块overlap 设置为 50 tokens这种方式实现简单但是问题也很明显它不理解文档结构也不理解业务语义。例如一段退款规则退款条件在 chunk A 退款例外情况在 chunk B 退款到账时间在 chunk C如果用户问退款多久能到账系统可能只召回 chunk C却丢失了前面的退款条件和审核规则最终导致回答不完整。所以固定长度切分只能作为兜底方案不应该作为所有业务文档的默认最优方案。2. 文档切分的本质让 chunk 粒度匹配用户问题粒度文档切分的核心不是“把文档切碎”而是让每一个 chunk 尽可能成为一个独立、完整、可被检索的问题答案单元。也就是说chunk 的大小应该由用户问题决定而不是由文档长度决定。例如用户问题类型合适的 chunk 粒度怎么申请退款一个 FAQ 问答对合同里甲方有哪些义务一个或多个合同条款这个接口怎么调用一个完整接口说明这个 Java 方法为什么报错一个方法体 类名 上下文推荐几部高分国产剧情片一部电影作为一个实体 chunk这篇论文方法是什么一个章节或语义段所以切分之前应该先问用户通常会怎么问 回答这个问题最小需要多少上下文 这个上下文在原文中的自然边界是什么3. 切分文档时应该先看结构再看语义最后才看长度比较合理的文档处理流程是原始文档 ↓ 文本清洗 / OCR / 表格解析 / Markdown 解析 / HTML 解析 ↓ 识别结构标题、章节、段落、表格、代码块、列表、页码 ↓ 按业务语义切分 ↓ 控制 chunk_size 和 overlap ↓ 补充 metadata ↓ embedding index换句话说切分顺序应该是先看结构 再看语义 最后才看长度不推荐这样做拿到文档 → 直接每 500 字切一次 → embedding → 入库更推荐这样做拿到文档 ↓ 识别标题、章节、表格、代码块、条款、业务实体 ↓ 按自然语义边界切分 ↓ 过长的部分再用长度或语义切分兜底4. 常见切分方式对比4.1 固定长度切分固定长度切分就是按字符数或 token 数硬切。例如chunk_size 500 chunk_overlap 50优点实现简单成本低对无明显结构的长文本比较方便缺点容易切断语义不理解标题、条款、表格、代码块可能导致召回内容不完整适合日志文本流水记录无结构长文本粗粒度全文搜索不适合合同政策FAQ技术文档代码Excel / 表格数据4.2 RecursiveCharacterTextSplitter 递归切分递归切分的思路是优先按照更自然的分隔符切分如果切出来的块仍然太长再继续使用更细粒度的分隔符。例如先按章节切 如果太长再按段落切 如果还太长再按句子切 如果还太长最后按字符切中文场景下可以设置类似分隔符fromlangchain_text_splittersimportRecursiveCharacterTextSplitter splitterRecursiveCharacterTextSplitter(chunk_size600,chunk_overlap80,separators[\n## ,\n### ,\n\n,。,,,,\n, ,])它适合普通知识库博客文章产品说明课程讲义Markdown 文档这个方法比固定长度切分更自然因为它会尽量保留段落和句子的完整性。4.3 按标题和章节切分对于结构明显的文档标题和章节通常就是最自然的切分边界。例如1. 产品介绍 2. 登录流程 3. 权限说明 4. 常见问题可以先按一级、二级、三级标题切成 parent chunk再对过长的章节继续切成 child chunk。结构可以是Parent Chunk: 第 3 章权限说明 Child Chunk 1: 3.1 普通用户权限 Child Chunk 2: 3.2 管理员权限 Child Chunk 3: 3.3 内部成员权限检索时可以采用 small-to-big retrieval用小 chunk 做精确检索 返回时带上 parent chunk 或相邻 chunk这样做的好处是小 chunk 检索更精准 大 chunk 回答更完整适合技术文档项目文档产品手册安装说明课程讲义Markdown / HTML 文档4.4 语义切分 Semantic Chunking语义切分不是按固定长度切而是根据句子之间的语义相似度来判断哪里应该断开。例如A 段讲登录 B 段讲注册 C 段讲密码重置 D 段讲支付语义切分可能会把登录、注册、密码重置放在一组把支付单独切出去。适合长文章学术论文访谈稿会议纪要法律解释文档业务分析报告缺点成本更高切分速度更慢有时会切出过大的 chunk需要设置最大 token 限制比较稳妥的做法是先按标题 / 段落粗切 再对长段落做语义切分 最后加最大 token 限制4.5 Sentence Window 切分Sentence Window 的思路是embedding 时只嵌入一句话 生成答案时带上这句话前后的上下文例如原文句子 1用户可以上传资源。 句子 2只有管理员可以删除资源。 句子 3普通用户只能下载公开资源。 句子 4内部成员可以访问本州资源。索引时chunk 句子 2 metadata.window 句子 1 句子 2 句子 3检索时用句子 2 精准命中回答时把窗口一起交给 LLM。适合FAQ客服知识库制度问答细粒度事实查询它解决的是小粒度检索精准但上下文不足4.6 表格 / Excel 数据切分表格和 Excel 不能简单当成普通长文本切。例如电影数据电影名 | 类型 | 地区 | 上映时间 | 评分 | 简介 | 演员 | 评论对于这种数据更合理的方式是一行 一个业务实体 一个 chunk例如chunk_id: movie_001 movie_name: 霸王别姬 genre: 剧情 score: 9.6 actors: 张国荣, 巩俐 summary: ...如果简介、剧情、评论很长可以继续拆成movie_001_summary movie_001_plot_1 movie_001_plot_2 movie_001_review_summary但是它们要共享同一组 metadatamovie_id movie_name genre year country score也就是说Excel / 数据库类 RAG 的重点不是 chunk_size而是实体建模 字段 metadata 过滤检索二、不同业务场景下应该如何切分1. 客服 FAQ / 售后知识库典型问题怎么退款 怎么修改手机号 为什么订单被取消 会员怎么续费推荐切分一个问题 一个答案 一个 chunk示例Q: 如何申请退款 A: 用户可以在订单详情页点击申请退款...推荐配置项目建议chunk 粒度一个问答对chunk_size100 - 300 tokensoverlap基本不需要或者很小检索方式BM25 Vector Reranker推荐 metadataproduct business_line question_type user_type version effective_date客服场景里 BM25 很重要因为用户的问题中经常有精确业务词例如退款 发票 手机号 订单号 会员2. 企业制度 / 政策 / 合同文档典型问题试用期离职工资怎么算 这个合同里违约责任是什么 甲方有哪些义务 年假规则是什么推荐切分按章、节、条、款切分例如第二章 请假制度 第 5 条 年假规则 5.1 员工连续工作满一年... 5.2 年假不可折现...推荐配置项目建议chunk 粒度一个条款 / 相邻条款chunk_size300 - 800 tokensoverlap50 - 120 tokens检索方式条款级向量索引 BM25 parent-child retrieval推荐 metadatadoc_type chapter article_no clause_no effective_date company department version page_no合同和制度类文档特别需要上下文扩展因为一个问题可能涉及多个条款违约责任条款 赔偿条款 解除合同条款 争议解决条款所以推荐先召回条款级 chunk 再扩展同一章节下的相邻条款 最后让 LLM 基于证据回答3. 技术文档 / API 文档 / 开发手册典型问题这个接口怎么调用 这个参数是什么意思 如何配置 Redis 这个错误码怎么解决推荐切分一个接口说明 一个完整 chunk 一个配置项说明 一个 chunk 一个错误码说明 一个 chunk接口文档不应该被硬切开。比如下面内容应该尽量作为一个整体POST /api/user/login 描述 用户登录接口 请求参数 username password 响应 token expireTime 错误码 401 403推荐 metadatamodule api_path method version language framework error_code heading_path技术文档一定要重视关键词检索因为里面有大量精确符号RedisTemplate MessageWindowChatMemory PostMapping 401 NullPointerException /api/user/login推荐策略精确符号 / API path / 类名 → BM25 权重大 自然语言问题 → 向量权重大 最后 reranker 重排4. 源码 RAG / 代码问答典型问题这个方法是干什么的 这个类在哪里被调用 为什么这里会空指针 如何修改这段逻辑代码不能用普通文本切法。推荐切分类级别 方法级别 函数级别 接口级别 配置文件级别Java 项目可以这样切UserService.java - class metadata - method getLoginUser() - method updateUser() - method deleteUser()每个方法 chunk 应该包含方法签名 注解 方法体 关键 import 所在类名 包名 调用关系 metadata源码 RAG 最好不是单纯向量搜索而是symbol index BM25 vector search AST / call graph例如问题getLoginUser 在哪里被调用这个问题应该优先走符号索引和引用关系而不是向量搜索。如果问题是用户登录后权限是怎么校验的这类问题才更适合向量检索 调用链扩展5. 学术论文 / 长报告 / 项目文档典型问题这篇论文的方法是什么 实验结果说明了什么 这个项目的风险有哪些 报告里对市场趋势怎么看推荐切分标题层级切分 摘要单独索引 结论单独索引 图表说明单独索引 长段落语义切分可以建立多个索引summary_index: 摘要、结论、章节摘要 detail_index: 正文段落 table_index: 表格、实验结果 figure_index: 图注、图表说明推荐流程先查 summary_index 判断相关章节 再查 detail_index 找证据 最后查 table_index 补充数据6. 商品、电商、招聘、简历匹配典型问题推荐适合 Java 后端的岗位 找 3 年经验 Spring Boot 岗位 这款商品适合学生吗 有哪些 500 元以内的耳机这类业务最重要的是结构化字段过滤 向量语义召回不要把所有字段拼成一段文本后只做向量搜索。例如岗位数据应该有结构化字段job_id title city salary_min salary_max experience skills description company用户问重庆 Java 后端 15k 以上要求 Spring Boot 和 Redis应该先过滤city 重庆 salary_max 15000 skills contains Java / Spring Boot / Redis再做语义匹配。7. 新闻 / 公告 / 时效性知识库典型问题最近有什么政策变化 最新公告是什么 这个项目最近进展如何推荐切分一条新闻 / 一条公告 一个主 chunk 长公告按小标题切metadata 必须包含publish_time effective_time source region topic status索引优化重点时间衰减排序 增量索引 旧版本归档 同主题聚合否则用户问“最新政策”系统可能召回旧政策。8. 扫描 PDF / 表格 / 图片型文档这类文档最重要的问题不是 chunk而是解析质量。需要处理OCR 页眉页脚 脚注 双栏排版 表格 图片 图注推荐流程1. OCR 2. 去除页眉页脚 3. 保留页码 4. 表格转 Markdown table 或 JSON 5. 图片生成 caption 6. 图表和正文建立引用关系表格可以按以下方式切一个表格 一个 chunk 一行 一个 chunk 一组业务行 一个 chunk选择哪种取决于用户怎么问。例如财务报表用户问某一年营收 → 行级 chunk 用户问整体趋势 → 表级 chunk三、chunk_size 和 overlap 应该怎么设置经验表如下场景推荐 chunk 粒度chunk_sizeoverlapFAQ / 客服一个问答对100-300 tokens0-30普通知识库一个段落 / 小节300-700 tokens50-100技术文档一个接口 / 一个配置项 / 一个小节400-1000 tokens80-150合同 / 制度一个条款 / 相邻条款300-800 tokens50-120学术论文一个小节 / 语义段500-1200 tokens80-150代码一个函数 / 一个类片段40-100 行10-20 行Excel / 商品 / 岗位一个实体 / 一行记录不按固定 token通常不需要新闻公告一条公告 / 一个小标题300-800 tokens50-100需要注意overlap 不是越大越好。它的作用是防止语义断裂但过大的 overlap 会带来索引膨胀 重复召回 成本增加 上下文里重复内容变多推荐普通文档10% - 20% FAQ0% - 10% 代码按行 overlap 合同按条款上下文 overlap四、metadata 为什么比 chunk_size 更重要一个高质量 chunk 不应该只有 text还应该包含丰富的 metadata。例如{chunk_id:policy_2026_leave_005,doc_id:policy_2026_leave,parent_id:policy_2026_leave_chapter_2,title:员工请假制度,heading_path:第二章/第五条/年假规则,text:员工连续工作满一年后可享受带薪年假...,doc_type:policy,department:HR,effective_date:2026-01-01,version:v3,page:12,tenant_id:company_a,permission:[employee,hr_admin]}metadata 可以解决很多问题权限过滤 租户隔离 版本过滤 时间过滤 业务线过滤 文档类型过滤 精确定位引用在真实系统里metadata 往往比 chunk_size 更关键。五、索引优化应该怎么做进一步讨论索引优化时核心结论是索引优化不是只调向量数据库参数而是优化整个检索链路。可以分成四层数据层优化 检索层优化 排序层优化 上下文扩展1. 数据层优化让 chunk 更容易被召回数据层优化包括清洗噪声 去重 补标题 补 metadata 补关键词 补摘要 补同义词例如原始 chunk支持该操作。这个 chunk 几乎没有检索价值。可以改造成【资源管理 / 权限控制 / 删除资源】 管理员可以删除资源普通用户只能查看和下载公开资源。这样 embedding 后的语义会更明确也更容易被召回。2. 检索层优化BM25 Vector 混合检索不要只做向量搜索。更推荐BM25 / keyword dense vector metadata filter原因是很多业务场景里有大量精确词类名 接口名 错误码 合同编号 产品型号 岗位技能 疾病名称 药品名称纯向量搜索可能会召回语义相似但关键词不准确的内容。例如技术文档里用户搜NullPointerException /api/user/login RedisTemplate这些内容应该优先依赖 BM25 或符号索引。3. 排序层优化引入 Reranker第一阶段召回通常是粗召回。流程可以是BM25 top 50 Vector top 50 ↓ 合并去重 ↓ RRF 融合 ↓ Reranker 重排 ↓ 取 top 3 / top 5Reranker 的作用是判断这个 chunk 是否真的能回答用户的问题它不是负责从全量知识库找内容而是负责从候选内容中挑出最相关的部分。4. 上下文扩展小 chunk 检索大 chunk 回答推荐做法检索时用小 chunk 回答时扩展 parent / neighbor chunk例如命中chunk_12可以同时取chunk_11 chunk_12 chunk_13 parent_section这样可以兼顾小 chunk 的精准召回 大上下文的完整回答5. 向量索引本身如何优化如果使用 Qdrant、Milvus、Weaviate、FAISS、Elasticsearch、OpenSearch常见底层索引是 ANN 近似最近邻。常见优化点HNSW 参数 向量维度 索引分片 payload filter tenant 隔离 量化压缩 冷热数据分层以 HNSW 为例常见参数包括m ef_construct ef_search大致理解m 越大 图连接越多召回更好但内存更高 ef_construct 越大 建索引更慢但索引质量更好 ef_search 越大 查询更准但延迟更高工程上的取舍低延迟场景 topK 小 ef_search 低一些 reranker 处理较少候选 高准确率场景 topK 大 ef_search 高一些 reranker 重排更多候选 多租户场景 tenant_id 建 payload index 或者使用多 collection 强过滤场景 常用 filter 字段必须建索引六、为什么会进一步讨论 Reranker在讨论完文档切分和索引优化后自然出现了一个问题即使系统通过 BM25 和向量检索召回了一批 chunk怎么保证真正有用的内容排在最前面这就是 Reranker 要解决的问题。向量检索可以找到“语义相关”的内容但它不一定能判断“哪个内容最能回答问题”。例如用户问为什么 Redis 限流要用 Lua 脚本向量检索可能召回Redis 基础介绍 令牌桶算法 RedisTemplate 使用方式 Redis Lua 原子性 分布式锁 setnx这些都和 Redis 或限流有关系但真正直接回答问题的是Redis Lua 可以保证判断令牌和扣减令牌这两个操作的原子性。Reranker 的价值就在于把真正能回答问题的 chunk 排到前面。七、Reranker 是什么接着进一步讨论的问题是Reranker 是什么Reranker中文通常叫“重排模型”或“重排序器”。它的作用是第一阶段先粗略召回一批可能相关的文档第二阶段再让 Reranker 重新判断这些文档和用户问题的真实相关性把最有用的内容排到最前面。Reranker 不是负责“从全库找资料”的而是负责从已经召回的候选 chunk 里挑出最适合回答问题的 chunk1. Reranker 在 RAG 流程中的位置完整流程用户问题 ↓ 第一阶段粗召回 - 向量检索 top 50 - BM25 检索 top 50 ↓ 候选文档合并去重 ↓ 第二阶段Reranker 重排 - 判断每个 chunk 和问题的相关性 - 重新打分 - 重新排序 ↓ 取 top 3 / top 5 给 LLM ↓ 生成答案可以理解成Retriever海选 Reranker复试 LLM写最终答案2. 向量检索和 Reranker 的区别向量检索向量检索通常是query → embedding 向量 chunk → embedding 向量 比较两个向量的相似度特点速度快 适合大规模召回 能处理语义相似 但是判断比较粗RerankerReranker 通常会把用户问题 候选 chunk一起输入模型让模型判断这个 chunk 能不能回答这个问题 相关性有多高示例Query: 为什么 Redis 限流要用 Lua 脚本 Document A: Redis 是一种基于内存的 key-value 数据库。 Score: 0.31 Document B: Redis Lua 脚本可以保证令牌判断和扣减操作的原子性。 Score: 0.94Reranker 会把 Document B 排到前面。3. 为什么 Reranker 通常更准普通向量检索多采用 bi-encoder 思路query 单独编码 document 单独编码 然后比较两个向量距离它速度快因为 document embedding 可以提前算好。但它没有真正逐字逐句比较 query 和 document。Reranker 常见方式是 cross-encoder输入 [用户问题, 候选文档] 输出 相关性分数它把问题和文档放在一起理解所以判断更细。类比向量检索 看两个人的整体画像像不像 Reranker 让两个人坐下来详细对话看他们到底匹不匹配4. Reranker 能解决哪些问题4.1 解决“看起来相关但不能回答”的问题比如用户问Java 中 CompletableFuture 和 Future 有什么区别向量检索可能召回Future 基础介绍 线程池基础介绍 CompletableFuture 异步编排 Runnable 和 Callable 区别Reranker 会更倾向于把真正比较 Future 和 CompletableFuture 区别的文档排到前面。4.2 解决关键词相似但语义不匹配的问题例如苹果公司的创始人是谁知识库里可能有苹果是一种水果... 苹果公司由 Steve Jobs 等人创立...Reranker 会根据完整问题判断用户问的是 Apple Inc.而不是水果。4.3 解决长文档 chunk 排序不准的问题长文档切成很多 chunk 后向量搜索常常会召回一堆半相关片段。Reranker 可以进一步判断哪个 chunk 最直接支持答案 哪个 chunk 只是背景信息 哪个 chunk 完全跑偏5. Reranker 的局限性Reranker 有用但不能解决所有问题。它的主要局限有更慢 更贵 不能替代第一阶段召回最重要的一点是Reranker 只能重排已经召回的候选内容。如果第一阶段根本没有召回正确 chunkReranker 也救不了。所以要记住Retriever 负责“有没有” Reranker 负责“排不排前”八、Reranker 通常有哪些做法接着讨论的问题是Reranker 通常有哪些做法常见做法可以分成六类1. 规则打分型 Reranker 2. RRF / 分数融合型 Reranker 3. Cross-Encoder Reranker 4. LLM-as-Reranker 5. Learning-to-Rank 6. Late Interaction例如 ColBERT1. 规则打分型 Reranker规则打分型 Reranker 不一定使用模型而是根据业务规则重新加权。例如用户问重庆 Java 后端 15k 以上岗位可以设计最终分数 语义相似度 * 0.4 城市匹配 * 0.2 技能匹配 * 0.2 薪资匹配 * 0.1 更新时间 * 0.1候选岗位岗位 A重庆 Java Spring Boot 18k 岗位 B上海 Java Spring Boot 30k 岗位 C重庆 Python 16k如果只看向量相似度岗位 B 可能也很高。但业务规则会把岗位 A 排到最前面。适合招聘系统 商品推荐 电影推荐 本地生活 企业知识库权限过滤 新闻公告时效排序优点快 可控 容易解释 不需要额外模型缺点需要人工设计规则 语义判断能力弱 规则多了维护成本高2. RRF / 分数融合型 RerankerRRF 全称 Reciprocal Rank Fusion更准确地说它是 rank fusion但在工程里常被放进 rerank 流程。假设有两路检索BM25 检索 top 10 向量检索 top 10BM25 排名A, B, C, D向量检索排名C, A, E, FRRF 会综合两个排名让同时在多个检索器中排名靠前的文档得分更高。简单公式score(d) Σ 1 / (k rank_i(d))其中rank_i(d) 表示文档 d 在第 i 个检索器里的排名 k 通常取 60 左右用来平滑分数适合技术文档 API 文档 代码检索 合同条款 FAQ 企业知识库优点实现简单 速度快 不需要训练模型 比单独向量检索更稳定缺点只是融合排名 不能真正理解 query 和 chunk 的细节关系3. Cross-Encoder Reranker这是 RAG 中最常见、效果也很好的做法。输入用户问题 候选 chunk输出相关性分数示例Query: 为什么 Redis 限流要用 Lua 脚本 Document A: Redis 是一个高性能 key-value 数据库。 Document B: Redis Lua 可以保证令牌判断和扣减操作的原子性。Cross-Encoder 输出Query Document A → score 0.31 Query Document B → score 0.94适合通用 RAG 问答 企业知识库 技术文档 法律合同 论文问答 客服问答优点相关性判断准确 效果通常明显好于纯向量检索 接入简单缺点比向量检索慢 候选 chunk 太多时成本高 通常只适合重排 top 20 - top 100典型流程向量 / BM25 先召回 top 50 ↓ Cross-Encoder reranker 重排 ↓ 取 top 5 给 LLM4. LLM-as-Reranker也可以直接让大模型来做重排。例如 prompt用户问题 为什么 Redis 限流要用 Lua 脚本 下面有 10 个候选文档请判断哪些最能回答问题 按照相关性从高到低排序并说明原因。LLM 可能输出1. chunk C直接解释 Lua 保证原子性 2. chunk B介绍令牌桶算法背景 3. chunk D介绍 RedisTemplate相关性较弱适合复杂分析类问题 多文档综合判断 项目文档分析 法律条款综合判断 论文综述 商业报告分析优点理解能力强 能处理复杂推理 可以解释为什么这样排序缺点慢 贵 输出可能不稳定 候选数量不能太多所以一般不建议直接让 LLM rerank 100 个 chunk。更推荐BM25 Vector 召回 top 50 普通 Reranker 排到 top 10 LLM 从 top 10 中选择最有用证据5. Learning-to-Rank 排序模型Learning-to-Rank 是搜索推荐系统里更传统、也更工程化的一类方法。它会把多个特征放进排序模型向量相似度 BM25 分数 标题是否匹配 关键词命中数量 文档更新时间 用户权限 点击率 历史采纳率 业务类型匹配 chunk 长度然后训练排序模型输入query document features 输出排序分数常见模型LambdaMART XGBoost Ranker LightGBM Ranker 神经网络排序模型适合搜索系统 电商推荐 招聘匹配 广告排序 内容推荐 大规模企业知识搜索优点可以融合大量业务特征 适合大规模生产系统 可以通过用户反馈持续优化缺点需要训练数据 工程复杂度高 冷启动比较难6. Late Interaction Reranker例如 ColBERTLate Interaction 介于普通向量检索和 Cross-Encoder 之间。普通向量检索是一个 query → 一个向量 一个 document → 一个向量Late Interaction 的思路是query 里的每个 token 有自己的向量 document 里的每个 token 也有自己的向量 最后做细粒度匹配可以理解成普通向量检索 看整体像不像 Cross-Encoder 把 query 和 document 放一起深度理解 Late Interaction 保留 token 级别匹配能力但尽量保持检索效率适合大规模搜索 技术文档检索 长文档检索 需要兼顾速度和准确率的 RAG优点比普通向量检索精细 比 Cross-Encoder 更容易扩展到大规模缺点实现复杂 索引成本更高 工程接入门槛更高7. 多阶段 Reranker 组合方案真实业务里往往不是只用一种 Reranker而是多阶段组合。一个成熟链路可以是用户问题 ↓ Query Rewrite / Query Expansion ↓ 第一阶段粗召回 - BM25 top 50 - Vector top 50 - Metadata filter ↓ RRF 融合 ↓ Cross-Encoder Reranker ↓ 业务规则加权 ↓ 上下文扩展 - parent chunk - neighbor chunk ↓ LLM 生成答案最终分数可以设计成final_score reranker_score * 0.6 bm25_score * 0.1 vector_score * 0.1 business_score * 0.15 freshness_score * 0.05不同业务场景权重不同。九、不同业务场景应该选择哪种 Reranker场景推荐做法普通知识库问答Vector / BM25 Cross-EncoderFAQ 客服BM25 Cross-Encoder 类目规则技术文档BM25 Vector RRF Cross-Encoder代码问答Symbol Search BM25 Vector 规则重排法律合同条款召回 Cross-Encoder parent chunk 扩展招聘匹配结构化过滤 业务规则 Learning-to-Rank商品推荐结构化过滤 业务分数 向量语义新闻公告语义相关性 时间衰减学术论文Summary index detail index Cross-Encoder复杂分析普通 reranker 后再用 LLM reranker十、把整个 RAG 检索链路串起来最终完整流程可以这样理解用户问题 ↓ Query Rewrite / Query Expansion ↓ Metadata Filter ↓ Hybrid Retrieval - BM25 - Vector Search - Symbol Search ↓ Merge Deduplicate ↓ RRF / Score Fusion ↓ Cross-Encoder Reranker ↓ Business Rule Reranker ↓ Context Expansion - parent chunk - neighbor chunk - sentence window ↓ LLM Generate Answer ↓ Answer with citations / evidence这条链路里每一层职责不同模块作用文档切分把知识变成适合检索的单元metadata支持过滤、权限、版本、溯源BM25解决关键词和精确匹配Vector Search解决语义召回RRF融合多路召回结果Reranker判断哪些候选最能回答问题Context Expansion补充上下文避免答案不完整LLM基于证据生成最终回答十一、推荐的工程落地路线如果从 0 到 1 做 RAG可以按这个顺序升级。第一版Vector Searchvector search top 5优点简单。问题容易召回半相关内容排序不稳定。第二版BM25 Vector RRFBM25 top 20 Vector top 20 RRF 融合 top 10效果通常比纯向量检索稳定很多。第三版加入 Cross-Encoder RerankerBM25 top 50 Vector top 50 RRF top 30 Cross-Encoder rerank top 5这是大多数 RAG 项目中性价比很高的方案。第四版加入业务规则和权限过滤reranker_score 权限 时间 版本 业务字段适合真实业务上线。第五版基于反馈做 Learning-to-Rank当系统有用户点击、点赞、采纳、人工标注数据后可以训练排序模型让排序效果持续优化。十二、结合电影 Excel RAG 场景的落地设计前面对话中也结合了电影 Excel 数据进行说明。这类数据通常长这样电影名 | 类型 | 地区 | 上映时间 | 评分 | 简介 | 演员 | 评论不能简单把整个 Excel 拼成文本后固定切分。1. summary_docs 应该如何设计一部电影一个 summary chunk电影名xxx 类型剧情 / 喜剧 地区中国 年份2020 评分8.7 主演xxx 简介xxx适合回答推荐电影 找评分高的电影 某类型电影有哪些 某演员出演过哪些电影metadata{movie_name:xxx,genre:剧情,country:中国,year:2020,score:8.7,sheet_name:xxx}2. content_docs 应该如何设计如果电影有长简介、剧情、影评可以继续切movie_id xxx chunk_type plot / review / analysis例如霸王别姬_plot_1 霸王别姬_review_summary 霸王别姬_actor_info适合回答这部电影讲了什么 为什么评分高 适合什么人看 主题是什么3. 查询时如何结合 filter、vector search 和 reranker如果用户问推荐几部 9 分以上的国产剧情片不要只走向量搜索。应该先做 metadata filterscore 9 country 中国 genre 剧情然后再结合向量搜索query 推荐 高质量 电影如果用户问有没有类似《霸王别姬》的电影可以先找到《霸王别姬》的 summary embedding 再向量搜索相似电影 再用 genre / country / theme 过滤如果用户问这部电影为什么评分高应该先用 movie_name 精确过滤 再查 content_docs 里的 plot / review / analysis如果用户问推荐几部适合学习英语口语的电影Reranker 可以根据以下维度重新排序对话是否生活化 台词是否多 语速是否适中 发音是否清晰 是否适合模仿而不是只看评分高低。十三、最终总结1. 文档切分的核心结论文档切分不是把文本切碎而是设计检索单元。可以这样记FAQ一个问答一块 合同一个条款一块 技术文档一个接口 / 一个配置项一块 代码一个函数 / 一个类一块 Excel一个业务实体 / 一行一块 论文一个小节 / 一个语义段一块 新闻一条新闻 / 一个公告一块2. 索引优化的核心结论不要只做 vector search。更合理的是metadata filter BM25 keyword search dense vector search RRF fusion Reranker parent / neighbor chunk expansion3. Reranker 的核心结论Reranker 负责把第一阶段召回出来的候选内容重新排序。一句话Retriever 负责“有没有” Reranker 负责“排不排前” LLM 负责“怎么回答”4. Reranker 常见做法1. 规则重排 2. RRF / 分数融合 3. Cross-Encoder 重排 4. LLM 重排 5. Learning-to-Rank 6. Late Interaction例如 ColBERT工程上最常用、性价比最高的是BM25 Vector 召回 ↓ RRF 融合 ↓ Cross-Encoder Reranker ↓ 业务规则加权 ↓ 取 topK 给 LLM5. RAG 工程化的整体认知真正好的 RAG 不是文档 → 固定切分 → embedding → vectorDB而是业务问题分析 ↓ 知识单元建模 ↓ 结构化切分 ↓ metadata 设计 ↓ 多路索引 ↓ 混合检索 ↓ 重排 ↓ 上下文扩展 ↓ 可评估优化最终可以用一句话概括切分决定知识有没有被正确表达索引决定正确知识能不能被准确召回重排决定正确知识能不能排到前面。