LlamaIndex 索引类型详解
前言
LlamaIndex 是一个强大的大语言模型数据框架,其核心能力之一是通过各种索引类型对非结构化数据进行组织和检索。不同的索引类型采用不同的数据结构和检索策略,适用于不同的应用场景。本文将基于 LlamaIndex 源码中实际导出的索引类型,全面详细地讲解每一种索引的原理、特点和适用场景。
一、向量语义类 — VectorStoreIndex
核心原理
VectorStoreIndex 是 LlamaIndex 最核心、最常用的索引类型。它的工作流程:
- 文档拆分:将原始文档分割成多个小块(Chunk),每个块称为一个 Node
- 向量嵌入:通过嵌入模型(Embedding Model)将每个 Node 的文本转为固定维度的向量
- 向量存储:将所有向量存入向量数据库(如 Chroma、Qdrant、Pinecone、Milvus 等)
- 语义检索:用户查询时,将查询转为向量,然后在向量库中计算余弦相似度,召回最相似的 Top-K 文档
核心特点
- ✅ 基于语义相似度,而非关键词匹配,理解能力强
- ✅ 检索速度快,向量数据库优化到毫秒级搜索
- ✅ 适合大规模文档,支持增量更新
- ⚠️ 依赖嵌入模型质量,长文档可能丢失局部信息
适用场景
- 绝大多数通用 RAG 应用
- 问答系统、知识库
- 语义文档搜索
- 当你不确定用什么索引时,先用它
使用示例
from llama_index.core import SimpleDirectoryReader, VectorStoreIndex
# 加载文档
documents = SimpleDirectoryReader("./data").load_data()
# 创建索引
index = VectorStoreIndex.from_documents(documents)
# 查询
query_engine = index.as_query_engine()
response = query_engine.query("你的问题是什么?")
二、列表/摘要类 — SummaryIndex
核心原理
SummaryIndex 原名 ListIndex,是最基础的索引结构:
- 将所有 Node 简单保存为一个线性列表
- 查询时,遍历整个列表,将所有 Node 内容一起送给 LLM 进行回答
- 可以选择性地设置 chunk 大小,避免上下文窗口溢出
核心特点
- ✅ 实现简单,结构清晰
- ✅ LLM 能看到所有文档内容,不会漏信息
- ⚠️ 文档越多,Token 消耗越大,容易超限
- ⚠️ 大文档集合检索速度慢
适用场景
- 全局摘要汇总:需要对所有文档做整体性总结
- 少量文档的完整浏览
- 邮件汇总、日报周报汇总
- 需要 LLM 综合多个文档内容回答的场景
使用示例
from llama_index.core import SummaryIndex
index = SummaryIndex.from_documents(documents)
# 获取全局摘要
query_engine = index.as_query_engine()
response = query_engine.query("请总结所有文档的主要内容")
三、树状结构类
3.1 TreeIndex
核心原理
TreeIndex 将文档组织成一棵树状结构:
- 叶子节点是原始文档块
- 从底层叶子开始,逐层向上合并,每一层生成摘要节点
- 根节点是整个文档集合的顶级摘要
- 查询时,从根节点开始,向下选择分支,逐步逼近最相关叶子
核心特点
- ✅ 层次化结构,支持摘要引导的检索
- ✅ 适合非常大规模的文档集合
- ⚠️ 构建慢,每层都需要 LLM 生成摘要
- ⚠️ 上层摘要可能丢失底层细节
适用场景
- 大规模文档集合(数万篇文档)
- 需要分层浏览的知识库
- 书籍、手册等层级化内容
3.2 ComposableGraph
核心原理
ComposableGraph 允许你将多个已有索引组合成一个更大的图结构:
- 可以在粗粒度索引之上再构建细粒度索引
- 通常先用一个粗索引(如关键词索引)做路由,找到相关分支后,再进入分支内的向量索引做精细检索
- 支持任意多级组合
核心特点
- ✅ 分级检索,解决大规模文档的"先粗筛后精搜"问题
- ✅ 灵活组合,不同层级用不同索引策略
- ⚠️ 实现复杂度高,调试麻烦
适用场景
- 多级路由检索:百万级文档库,先按分类/关键词粗筛,再做语义检索
- 多部门知识库,每个部门维护自己的向量索引,顶层做路由
- 需要组合多种检索策略的场景
四、关键词匹配类
4.1 KeywordTableIndex
核心原理
从每个 Node 中提取关键词,建立关键词 → Node 列表的倒排索引表:
- 构建时:每个 Node → 提取关键词 → 映射到表
- 查询时:从查询中提取关键词 → 查表得到匹配的 Node → 送给 LLM 回答
核心特点
- ✅ 关键词精确匹配,符合传统搜索习惯
- ✅ 检索速度快,倒排索引直接查找
- ⚠️ 不理解语义,同义词问题严重
- ⚠️ 关键词提取质量直接影响效果
适用场景
- 关键词驱动的精确查找
- FAQ 系统
- 需要严格匹配关键词的场景
4.2 SimpleKeywordTableIndex
这是 KeywordTableIndex 的简化版本:
- 使用简单的规则(如 GPT 提取后取 top N,或者正则匹配)提取关键词
- 特点:轻量、速度快
- 适用:对关键词提取要求不高,追求简单快速
4.3 RAKEKeywordTableIndex
使用 RAKE (Rapid Automatic Keyword Extraction) 算法自动提取关键词:
- RAKE 是一个经典的无监督关键词提取算法
- 基于词频和共现分析,不需要 LLM 参与
- 特点:快,不需要模型调用
- 适用:纯文本关键词提取,成本敏感场景
五、图结构类
5.1 KnowledgeGraphIndex
核心原理
从文档中抽取三元组 (主体实体, 关系, 对象实体),构建知识图谱:
- 节点:实体
- 边:关系
- 查询时,从查询中识别实体,在图谱中沿关系路径遍历,找到相关实体和文档,再送给 LLM 回答
核心特点
- ✅ 能捕捉实体之间的关系,支持多跳推理
- ✅ 适合回答"什么实体和什么实体有什么关系"这类问题
- ⚠️ 抽取三元组需要 LLM 调用,构建成本高
- ⚠️ 抽取错误会传播到整个图谱
适用场景
- 关系密集型领域知识问答
- 知识图谱构建与问答
- 人物关系、企业关系等复杂关系查询
5.2 PropertyGraphIndex
PropertyGraphIndex 是 KnowledgeGraphIndex 的增强版:
- 在知识图谱基础上,允许节点和边上存储属性键值对
- 例如:节点
张三可以有属性年龄: 30, 职位: 工程师 - 支持基于属性过滤和查询
- 适用:需要对实体附加更多结构化属性的复杂场景
六、文档/长文本类 — DocumentSummaryIndex
核心原理
针对长文档集合优化的两阶段检索:
- 第一阶段:为每整篇文档生成一个摘要,对摘要做 embedding,基于摘要 embedding 做相似度检索,粗筛出最相关的几篇文档
- 第二阶段:只对粗筛出来的文档做内部细粒度 chunk 检索,召回最终片段
核心特点
- ✅ 大大减少 embedding 和相似度计算量
- ✅ 先筛选文档再检索,减少噪声
- ✅ 适合文档数量多、文档本身也长的场景
- ⚠️ 如果摘要写得不好,第一阶段可能漏掉正确文档
适用场景
- 论文库、专利库、法律文书库
- 每篇文档都很长(几十页),文档数量也多(上千篇)
- 检索资源有限,需要优化速度和成本
七、结构化数据类
7.1 PandasIndex
核心原理
将 Pandas DataFrame 作为数据源:
- 将表格数据转为 LlamaIndex 可检索的格式
- 自然语言查询 → 转成 Pandas 操作 → 执行 → 返回结果
适用场景
- CSV、Excel 文件加载的表格数据
- 让用户用自然语言查询结构化表格
- 快速数据分析、报表查询
7.2 SQLStructStoreIndex
核心原理
对接关系型数据库:
- 根据数据库 schema 和用户自然语言问题,生成 SQL 查询
- 执行 SQL 得到结果,再转自然语言回答
- 支持各种主流关系型数据库:MySQL、PostgreSQL、SQLite 等
适用场景
- NL2SQL(自然语言转 SQL)应用
- 让业务人员用自然语言查询数据库
- 企业内部数据自助查询
八、多模态类 — MultiModalVectorStoreIndex
核心原理
支持文本和图像的跨模态检索:
- 文本有文本嵌入模型
- 图像有图像嵌入模型(如 CLIP)
- 文本和图像嵌入到同一个向量空间
- 支持:
- 以文搜图
- 以图搜文
- 图文混合检索
核心特点
- ✅ 真正的多模态能力
- ✅ 支持图文混合知识库
- ⚠️ 需要多模态嵌入模型,资源消耗大
适用场景
- 电商商品图文检索
- 文档含大量图片的知识库(如设计手册、教材)
- 多模态问答系统
九、特殊类 — EmptyIndex
核心原理
EmptyIndex 是一个空壳索引:
- 不预设任何结构
- 完全由开发者自由组装 Node 和检索逻辑
- 适合实验和定制化开发
适用场景
- 高度定制化索引需求
- 研究和实验新的检索算法
- 特殊业务场景,现有索引都不满足
十、Legacy 命名对照表
LlamaIndex 在发展过程中对索引类名做了统一重命名,旧名称仍保留兼容:
| Legacy 旧名称 | 当前新名称 |
|---|---|
GPTVectorStoreIndex |
VectorStoreIndex |
GPTListIndex / ListIndex |
SummaryIndex |
GPTTreeIndex |
TreeIndex |
GPTKeywordTableIndex |
KeywordTableIndex |
GPTSimpleKeywordTableIndex |
SimpleKeywordTableIndex |
GPTRAKEKeywordTableIndex |
RAKEKeywordTableIndex |
GPTDocumentSummaryIndex |
DocumentSummaryIndex |
GPTPandasIndex |
PandasIndex |
GPTSQLStructStoreIndex |
SQLStructStoreIndex |
GPTEmptyIndex |
EmptyIndex |
💡 建议:新项目一律使用新名称,便于维护。
索引选型决策树
开始
│
├─ 你有很多图片,需要图文检索?
│ └─ → MultiModalVectorStoreIndex
│
├─ 数据在 Pandas/DataFrame?
│ └─ → PandasIndex
│
├─ 数据在 SQL 数据库?
│ └─ → SQLStructStoreIndex
│
├─ 需要知识推理/关系问答?
│ ├─ 只有三元组关系? → KnowledgeGraphIndex
│ └─ 需要属性信息? → PropertyGraphIndex
│
├─ 大量长文档(每篇都长,文档数也多)?
│ └─ → DocumentSummaryIndex
│
├─ 需要关键词精确匹配?
│ ├─ 需要 RAKE 自动提取 → RAKEKeywordTableIndex
│ └─ 简单关键词匹配 → SimpleKeywordTableIndex / KeywordTableIndex
│
├─ 需要对所有文档做全局摘要?
│ └─ → SummaryIndex
│
├─ 大规模文档分层组织?
│ └─ → TreeIndex
│
├─ 需要多级路由检索?
│ └─ → ComposableGraph
│
└─ 通用场景、语义搜索 → VectorStoreIndex(默认首选)
总结汇总表
| 分类 | 索引名称 | 适用场景 | 检索速度 | 构建成本 |
|---|---|---|---|---|
| 向量语义 | VectorStoreIndex | 通用语义搜索、RAG | 快 | 中 |
| 列表摘要 | SummaryIndex | 全局汇总、少量文档 | 慢 | 低 |
| 树结构 | TreeIndex | 大规模分层文档 | 中 | 高 |
| 树结构 | ComposableGraph | 多级路由检索 | 中 | 高 |
| 关键词 | KeywordTableIndex | 关键词精确查找 | 快 | 中 |
| 关键词 | SimpleKeywordTableIndex | 轻量关键词匹配 | 快 | 低 |
| 关键词 | RAKEKeywordTableIndex | RAKE 自动关键词 | 快 | 低 |
| 图结构 | KnowledgeGraphIndex | 关系推理、知识问答 | 中 | 高 |
| 图结构 | PropertyGraphIndex | 带属性的知识图谱 | 中 | 高 |
| 长文档 | DocumentSummaryIndex | 长文档集合检索 | 快 | 中 |
| 结构化 | PandasIndex | DataFrame 查询 | 中 | 低 |
| 结构化 | SQLStructStoreIndex | 数据库 NL2SQL | 中 | 低 |
| 多模态 | MultiModalVectorStoreIndex | 图文跨模态检索 | 快 | 高 |
| 特殊 | EmptyIndex | 高度自定义 | - | - |
结语
LlamaIndex 提供了丰富多样的索引类型,覆盖了从简单到复杂、从文本到多模态、从非结构化到结构化的各种场景。选择索引的原则是:
- 先简单后复杂:刚开始先用 VectorStoreIndex 验证流程
- 按需选型:根据你的数据类型和查询特点选择对应索引
- 组合使用:通过 ComposableGraph 可以组合多种索引策略扬长避短
希望本文能帮助你全面理解 LlamaIndex 的各种索引类型,在实际项目中做出合适的选择。
评论区