
我一直在构建和探索基于 RAG 的 AI 解决方案,并尝试了大多数为改进 RAG 而开发的方法。但传统的 RAG 系统存在局限性。PageIndex 提供了一种不同的方法,并创建了一种不同的文档和文本分块以及检索方式。
PageIndex 是一个开源的文档索引和基于推理的检索框架,它能够在没有向量数据库或分块的情况下实现类似人类的文档理解和问答。它将文档转换为分层树索引,并使用 LLM 推理来找到相关部分,克服了传统 RAG 系统的局限性,如上下文丢失和对语义相似性搜索的依赖。
仓库链接:https://github.com/VectifyAI/PageIndex
1、什么是 PageIndex?
Pageindex 是一个基于推理的 RAG 框架,它。
- 构建文档的分层树索引
- 使用多步骤 LLM 推理来导航树
- 以可跟踪和可解释的方式检索信息
- 消除对向量嵌入和外部数据库的依赖
- 在保持结构和上下文的同时处理长文档。
PageIndex 的核心功能:
- 不需要向量数据库,不像传统的基于 RAG 的方法
- 不需要人工分块
- 类似人类的检索
- 分层树索引
- 对复杂文档有更好的精度
2、PageIndex 与传统 RAG 的比较
传统 RAG 的工作方式如下:
-
将文档分割成固定大小的块
-
为每个块生成向量嵌入
-
将它们存储在向量数据库中
-
基于语义搜索检索相似的块来回答查询
上述方法的问题是:
-
分块在某些情况下会破坏上下文
-
RAG 中使用的相似性 ≠ 相关性
-
向量索引可能昂贵/复杂
-
难以将答案追溯到真实结构
Pageindex 相反遵循不同的方法:
-
它生成一个语义树
-
使用推理来探索该树
-
保留真实的文档结构
-
以人类的方式找到相关部分。
3、如何设置 PageIndex 并为其构建 API
让我们继续使用 pageindex 构建一个简单的问答引擎
3.1 环境设置
先决条件
确保你有:
-
Python 3.10+ 已安装
-
OpenAI API 密钥(ChatGPT / GPT-4 / Gemini 支持)
-
git 和 shell 访问权限
然后使用终端克隆共享的仓库。git clone https://github.com/VectifyAI/PageIndex.git
cd PageIndex
克隆仓库后,安装依赖项
pip install --upgrade -r requirements.txt

Pageindex 仓库克隆和依赖项安装
这将安装 PageIndex 和所需的包,例如:
- OpenAI 或 LLM SDK
- 语言处理工具
- 各种索引和 CLI 工具
3.2 从文档生成 PageIndex
PageIndex 期望结构化文档(PDF、Markdown 等),它将把这些文档转换为树。
创建一个文件夹 docs/,并将你的文档放在 pageindex 文件夹内的 docs/ 文件夹中。
然后在项目根目录创建一个 .env 文件,并添加 open api 密钥
OPENAI_API_KEY="your_openai_api_key_here"
然后运行下面的命令来重新索引脚本
python3 run_pageindex.py --pdf_path docs/pdfname.pdf

命令中的可选字段:

示例:
python3 run_pageindex.py --pdf_path docs/annual_report.pdf --max-pages-per-node 5
3.3 构建你的文档上传和问答 API
现在 PageIndex 已经生成了一个索引,让我们把它包装在一个简单的 API 后面,该 API 允许上传文档并基于该文档回答问题
# 安装 FaseAPI 和 Uvicorn
pip install fastapi uvicorn python-multipart
使用下面的代码创建一个文件 main.py
from fastapi import FastAPI, UploadFile
import subprocess
import uuid
import os
app = FastAPI()
UPLOAD_DIR = "uploaded_docs"
os.makedirs(UPLOAD_DIR, exist_ok=True)
@app.post("/upload")
async def upload_document(file: UploadFile):
# 保存上传的文件
file_id = uuid.uuid4().hex
path = os.path.join(UPLOAD_DIR, f"{file_id}.pdf")
with open(path, "wb") as f:
f.write(await file.read())
# 在此文件上运行 PageIndex
subprocess.run([
"python3", "run_pageindex.py",
"--pdf_path", path,
"--output_path", f"indexes/{file_id}.json"
])
return {"id": file_id, "status": "indexed"}
@app.get("/answer/{doc_id}")
async def answer_question(doc_id: str, question: str):
# 加载索引
index_file = f"indexes/{doc_id}.json"
# 这里调用 PageIndex 的内部 API 执行推理检索
# 伪代码
answer = query_pageindex(index_file, question)
return {"question": question, "answer": answer}
3.4 部署你的应用
uvicorn main:app --reload --host 0.0.0.0 --port 8000
测试端点:
上传:
curl -X POST -F "file=@docs/doc.pdf" http://localhost:8000/upload
上传时,你会得到一个文档 id,类似于下面显示的:9f5bb9f2e6c94d299e84b9dd1e9bb571

提问:
curl "http://localhost:8000/answer/{file_id}?question=What is the revenue?"
你可以添加的其他功能
- 支持 markdown 上传( --- md_path)
- 保存和服务多个索引
- 用于上传和提问的浏览器 UI
- 最近查询的知识缓存
- 与前端框架(如 React)的集成