Appearance
PageIndex:层次化树索引重构 RAG 范式。LLM 驱动目录检测 + 六阶段流水线 + 物理索引映射,FinanceBench 准确率 98.7%。
背景:向量检索的天然缺陷
RAG(检索增强生成)系统已经在很多企业落地了,但有一个根本性问题始终困扰着开发者:
为什么向量相似性检索经常返回「相似但不相关」的结果?
核心原因在于传统 RAG 的处理方式——将文档切割成固定大小的 chunk,这一步实际上破坏了文档的自然结构。
传统向量RAG的问题
| 问题 | 说明 |
|---|---|
| 章节边界被切断 | 原本连贯的内容被强制切分 |
| 上下文语义断裂 | 相关的内容被分散到不同 chunk |
| 检索结果碎片化 | 用户需要的是系统性阐述,得到的是零散片段 |
本质问题
向量相似性搜索基于「词向量距离」,用户查询却基于「主题相关性」。
典型案例:
- 用户查询:"美联储如何通过货币政策影响就业市场"
- 向量检索返回:所有包含"美联储""货币""就业"的 chunk,散落在文档各处
- 用户实际需要:某个特定章节的系统性阐述
这里缺的不是更多的数据,而是更好的结构。
PageIndex 核心思路
PageIndex 的核心思路很简单:既然文档本身就是有结构的,为什么检索时不直接用这个结构?
系统架构
┌─────────────────────────────────────────────────────────────────┐
│ PageIndex 整体架构 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ 原始文档 │ ──→ │ 文档解析 │ ──→ │ 结构识别 │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
│ │ │
│ ↓ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ 用户查询 │ ←── │ 层次检索 │ ←── │ 树索引构建 │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘六阶段流水线
PageIndex 的完整处理流程分为六个阶段:
| 阶段 | 名称 | 功能 |
|---|---|---|
| 1 | 页面分割 | 将文档按页面分割 |
| 2 | 块合并 | 将相关块合并 |
| 3 | 目录检测 | 识别文档目录结构 |
| 4 | 树节点构建 | 构建层次化树结构 |
| 5 | 语义标注 | 为节点添加语义标签 |
| 6 | 物理索引 | 建立物理位置映射 |
阶段一:页面分割
python
# 页面分割伪代码
def page_split(document):
pages = []
for section in document.sections:
if is_page_boundary(section):
pages.append(Page(section))
return pages阶段二:块合并
python
# 块合并:基于语义连贯性合并
def chunk_merge(pages):
chunks = []
current_chunk = []
for page in pages:
if semantic_continuity(page, current_chunk):
current_chunk.append(page)
else:
chunks.append(merge(current_chunk))
current_chunk = [page]
return chunks阶段三:目录检测
两种模式:
| 模式 | 原理 | 适用场景 |
|---|---|---|
| LLM 驱动 | LLM 直接分析文档结构 | 结构复杂的文档 |
| 规则匹配 | 基于标题格式匹配 | 结构规范的文档 |
python
# LLM 驱动目录检测
prompt = """
分析以下文档的目录结构,识别:
1. 章节标题(1级、2级、3级)
2. 章节之间的层级关系
3. 章节的页码范围
文档内容:
{content}
"""阶段四:树节点构建
TreeNode 结构:
python
class TreeNode:
def __init__(self, title, level, page_range):
self.title = title # 标题
self.level = level # 层级(1-3)
self.page_range = page_range # 页码范围
self.children = [] # 子节点
self.content = [] # 物理内容块
def add_child(self, child):
self.children.append(child)阶段五:语义标注
python
# 为节点添加语义标签
def semantic_annotation(node):
node.semantic_tags = LLM.analyze(f"""
分析以下章节的核心主题和关键词:
标题:{node.title}
内容:{node.content}
输出:主题标签、核心概念、相关术语
""")阶段六:物理索引
python
# 建立物理索引映射
physical_index = {
"tree_node_1": ["page_1", "page_2", "page_3"],
"tree_node_2": ["page_4", "page_5"],
...
}层次检索流程
当用户发起查询时,PageIndex 的检索流程:
┌─────────────────────────────────────────────────────────────┐
│ 层次检索流程 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 用户查询:"美联储货币政策对就业的影响" │
│ ↓ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 阶段1:语义解析 │ │
│ │ → 识别核心主题:货币政策、就业、美联储 │ │
│ └─────────────────────────────────────────────────────┘ │
│ ↓ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 阶段2:树索引定位 │ │
│ │ → 找到"货币政策"和"就业市场"相关节点 │ │
│ └─────────────────────────────────────────────────────┘ │
│ ↓ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 阶段3:物理索引映射 │ │
│ │ → 定位到对应页面范围 │ │
│ └─────────────────────────────────────────────────────┘ │
│ ↓ │
│ 返回:完整章节内容 + 相关子章节 │
│ │
└─────────────────────────────────────────────────────────────┘PageIndex vs 传统向量检索
| 维度 | 传统向量RAG | PageIndex |
|---|---|---|
| 检索基础 | 词向量距离 | 主题层次 |
| 结构保留 | ❌ 破坏结构 | ✅ 保持结构 |
| 语义理解 | 表面相似 | 深层相关 |
| 返回形式 | 碎片片段 | 完整章节 |
| 准确性 | 70-80% | 98.7% |
| 适用场景 | 简单查询 | 复杂主题 |
FinanceBench 测试结果
| 指标 | 传统向量RAG | PageIndex |
|---|---|---|
| 准确率 | 73.2% | 98.7% |
| 召回率 | 81.5% | 97.3% |
| F1分数 | 77.2% | 98.0% |
实际应用场景
适用场景
| 场景 | 推荐原因 |
|---|---|
| 金融文档分析 | 结构化报告、研报分析 |
| 法律文档检索 | 条款、案例、法规 |
| 学术论文问答 | 章节、引用、方法论 |
| 技术文档问答 | 章节、API文档 |
不适用场景
| 场景 | 原因 |
|---|---|
| 简单问答 | 传统RAG更快 |
| 非结构化内容 | 无法识别结构 |
| 实时性要求高 | 处理流程较长 |
核心优势总结
| 优势 | 说明 |
|---|---|
| 结构保留 | 完整保留文档的章节层级 |
| 语义连贯 | 检索结果基于主题而非词汇 |
| 完整性高 | 返回完整章节而非碎片 |
| 准确性高 | FinanceBench 测试 98.7% |
| 可解释 | 检索路径清晰可追溯 |
一句话总结
PageIndex = 用文档天然结构做检索,而不是用向量距离猜相关性。
核心创新:LLM 驱动目录检测 + 六阶段流水线 + 物理索引映射。
实际价值:从"相似但不相关"到"真正回答问题"。
