news 2026/5/9 23:45:37

RAG 文档切分、索引优化与 Reranker 学习笔记

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
RAG 文档切分、索引优化与 Reranker 学习笔记

RAG 文档切分、索引优化与 Reranker 学习笔记

记录一次询问GPT的完整过程 :从业务场景到工程落地的一次完整梳理


前言:这次讨论在解决什么问题

这次对话围绕 RAG 系统中的三个关键问题展开:

  1. 文档到底应该如何切分?
  2. 索引应该如何优化?
  3. 为什么还需要 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 splitter=RecursiveCharacterTextSplitter(chunk_size=600,chunk_overlap=80,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

但是它们要共享同一组 metadata:

movie_id movie_name genre year country score

也就是说,Excel / 数据库类 RAG 的重点不是 chunk_size,而是:

实体建模 + 字段 metadata + 过滤检索

二、不同业务场景下应该如何切分


1. 客服 FAQ / 售后知识库

典型问题:

怎么退款? 怎么修改手机号? 为什么订单被取消? 会员怎么续费?

推荐切分:

一个问题 + 一个答案 = 一个 chunk

示例:

Q: 如何申请退款? A: 用户可以在订单详情页点击申请退款...

推荐配置:

项目建议
chunk 粒度一个问答对
chunk_size100 - 300 tokens
overlap基本不需要,或者很小
检索方式BM25 + Vector + Reranker

推荐 metadata:

product business_line question_type user_type version effective_date

客服场景里 BM25 很重要,因为用户的问题中经常有精确业务词,例如:

退款 发票 手机号 订单号 会员

2. 企业制度 / 政策 / 合同文档

典型问题:

试用期离职工资怎么算? 这个合同里违约责任是什么? 甲方有哪些义务? 年假规则是什么?

推荐切分:

按章、节、条、款切分

例如:

第二章 请假制度 第 5 条 年假规则 5.1 员工连续工作满一年... 5.2 年假不可折现...

推荐配置:

项目建议
chunk 粒度一个条款 / 相邻条款
chunk_size300 - 800 tokens
overlap50 - 120 tokens
检索方式条款级向量索引 + BM25 + parent-child retrieval

推荐 metadata:

doc_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

推荐 metadata:

module 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_sizeoverlap
FAQ / 客服一个问答对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% FAQ:0% - 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 5

Reranker 的作用是判断:

这个 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 里,挑出最适合回答问题的 chunk

1. Reranker 在 RAG 流程中的位置

完整流程:

用户问题 ↓ 第一阶段:粗召回 - 向量检索 top 50 - BM25 检索 top 50 ↓ 候选文档合并去重 ↓ 第二阶段:Reranker 重排 - 判断每个 chunk 和问题的相关性 - 重新打分 - 重新排序 ↓ 取 top 3 / top 5 给 LLM ↓ 生成答案

可以理解成:

Retriever:海选 Reranker:复试 LLM:写最终答案

2. 向量检索和 Reranker 的区别

向量检索

向量检索通常是:

query → embedding 向量 chunk → embedding 向量 比较两个向量的相似度

特点:

速度快 适合大规模召回 能处理语义相似 但是判断比较粗
Reranker

Reranker 通常会把:

用户问题 + 候选 chunk

一起输入模型,让模型判断:

这个 chunk 能不能回答这个问题? 相关性有多高?

示例:

Query: 为什么 Redis 限流要用 Lua 脚本? Document A: Redis 是一种基于内存的 key-value 数据库。 Score: 0.31 Document B: Redis + Lua 脚本可以保证令牌判断和扣减操作的原子性。 Score: 0.94

Reranker 会把 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 只能重排已经召回的候选内容。

如果第一阶段根本没有召回正确 chunk,Reranker 也救不了。

所以要记住:

Retriever 负责“有没有” Reranker 负责“排不排前”

八、Reranker 通常有哪些做法

接着讨论的问题是:

Reranker 通常有哪些做法?

常见做法可以分成六类:

1. 规则打分型 Reranker 2. RRF / 分数融合型 Reranker 3. Cross-Encoder Reranker 4. LLM-as-Reranker 5. Learning-to-Rank 6. Late Interaction,例如 ColBERT

1. 规则打分型 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 / 分数融合型 Reranker

RRF 全称 Reciprocal Rank Fusion,更准确地说,它是 rank fusion,但在工程里常被放进 rerank 流程。

假设有两路检索:

BM25 检索 top 10 向量检索 top 10

BM25 排名:

A, B, C, D

向量检索排名:

C, A, E, F

RRF 会综合两个排名,让同时在多个检索器中排名靠前的文档得分更高。

简单公式:

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 给 LLM

4. 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,例如 ColBERT

Late 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-Encoder
FAQ 客服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 Search

vector search top 5

优点:简单。
问题:容易召回半相关内容,排序不稳定。


第二版:BM25 + Vector + RRF

BM25 top 20 Vector top 20 RRF 融合 top 10

效果通常比纯向量检索稳定很多。


第三版:加入 Cross-Encoder Reranker

BM25 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 filter:

score >= 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 expansion

3. 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 给 LLM

5. RAG 工程化的整体认知

真正好的 RAG 不是:

文档 → 固定切分 → embedding → vectorDB

而是:

业务问题分析 ↓ 知识单元建模 ↓ 结构化切分 ↓ metadata 设计 ↓ 多路索引 ↓ 混合检索 ↓ 重排 ↓ 上下文扩展 ↓ 可评估优化

最终可以用一句话概括:

切分决定知识有没有被正确表达,索引决定正确知识能不能被准确召回,重排决定正确知识能不能排到前面。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/9 23:45:36

基于物理信息神经网络的山火预测:融合科学计算与深度学习

1. 项目概述:当山火遇上科学计算与深度学习山火,或者说野火,是自然界最具破坏力的力量之一。传统的预测模型,无论是基于气象数据的统计模型,还是基于物理方程的数值模拟,都面临着各自的瓶颈。统计模型难以捕…

作者头像 李华
网站建设 2026/5/9 23:45:34

如何将短信从 iPhone 传输到 Mac?

把 iPhone 短信传输到 Mac 已经成为一项刚需,无论是想在 Mac 上便捷收发信息、在大屏查看消息,还是为了备份或打印。本指南介绍4 种有效方法,帮你轻松在 Mac 上传输与管理短信数据。第一部分:使用 iCloud 将 iPhone 短信传输到 Ma…

作者头像 李华
网站建设 2026/5/9 23:42:31

泰山派3M-RK3576-系统功能-Buildroot-网口上网

Buildroot系统以太网和互联网连接 下载对应镜像 使用 网盘🚀 在 系统镜像/Buildroot/ 这个目录中下载我们提供的 .img 镜像文件。 本文档使用的镜像是:TaishanPi-3M-RK3576_Buildroot_AP6256-mSATA.img 基本上所有的镜像默认都支持以太网连接功能&…

作者头像 李华
网站建设 2026/5/9 23:36:49

一文搞懂:共享锁、排它锁、乐观锁、悲观锁——它们到底是什么关系?

📌 写在前面在学习Java并发编程和数据库事务的过程中,“锁”这个概念几乎无处不在。共享锁、排它锁、互斥锁、读锁、写锁、乐观锁、悲观锁……光是听到这些名字就已经让人一头雾水了。更让人困惑的是,这些锁的名称还经常互相混用——读锁就是…

作者头像 李华
网站建设 2026/5/9 23:36:48

长期戴假发,头皮怎么护理?

天天戴假发的朋友,这篇你得多看两眼。第一条铁律:每天让头皮透口气不管多忙,每天至少摘下来一小时。你想想,头皮一整天闷在假发里,汗出不去,油排不掉,时间长了毛囊不出问题才怪。这一小时&#…

作者头像 李华
网站建设 2026/5/9 23:36:35

全国青少年人工智能辅助生成数字艺术创作者大赛

官网 全国青少年人工智能辅助生成数字艺术创作者大赛 http://www.aigcnyacc.com/www/index.html?v0507 文档 https://www.mcasc.com.cn/Uploads/Picture/2026/04/29/u69f1718e43b37.pdf https://www.mcasc.com.cn/Uploads/Picture/2026/04/29/u69f1726b33890.pdf

作者头像 李华