LlamaIndex 的核心命题

LlamaIndex 的定位是 “LLM 的数据框架”——解决 LLM 与私有数据之间的鸿沟。如果说 LangChain 是 LLM 应用的"胶水层",那 LlamaIndex 就是 “数据管道+检索引擎”。

核心理念:不是所有数据都要塞进 Prompt,关键在于如何高效检索最相关的片段

核心架构

三层抽象

数据层 (Data Connectors + Documents + Nodes)
索引层 (Index: Vector / List / Tree / Keyword / Knowledge Graph)
查询层 (Query Engine / Retriever / Response Synthesizer)

数据连接器(LlamaHub)

LlamaHub 提供了 200+ 数据连接器:

from llama_index.core import download_loader

# 加载 Notion 数据
NotionPageReader = download_loader("NotionPageReader")
loader = NotionPageReader(integration_token="your-token")
documents = loader.load_data(page_ids=["page-id-1", "page-id-2"])

# 加载 GitHub 仓库
GithubRepositoryReader = download_loader("GithubRepositoryReader")
loader = GithubRepositoryReader(owner="owner", repo="repo")
documents = loader.load_data(branch="main")

Document 与 Node

from llama_index.core import Document, VectorStoreIndex
from llama_index.core.node_parser import SentenceSplitter

# Document 是原始数据单元
doc = Document(text="...", metadata={"source": "hr-handbook.pdf", "page": 42})

# Node 是切分后的最小检索单元
splitter = SentenceSplitter(chunk_size=512, chunk_overlap=64)
nodes = splitter.get_nodes_from_documents([doc])

# Node 携带元数据关系
print(nodes[0].relationships)  # {Source: doc, Next: node[1], Previous: None}

索引类型详解

LlamaIndex 提供了最丰富的索引类型:

索引类型原理适用场景检索复杂度
VectorStoreIndex向量相似度通用 RAGO(log N)
SummaryIndex遍历所有节点小数据集全文总结O(N)
TreeIndex层次化摘要长文档/层级数据O(log N)
KeywordTableIndex关键词倒排精确匹配场景O(1)
KnowledgeGraphIndex实体关系图多跳推理O(关系数)
DocumentSummaryIndex摘要+原文先粗筛后精读O(摘要数)

TreeIndex:层次化检索

from llama_index.core import TreeIndex

# 自动构建摘要树
index = TreeIndex.from_documents(documents, summary_template=template)

# 查询时从根节点逐层下钻
query_engine = index.as_query_engine(
    child_branch_factor=2  # 每层选 2 个最相关子节点
)
response = query_engine.query("总结这份报告的核心观点")

KnowledgeGraphIndex:图谱检索

from llama_index.core import KnowledgeGraphIndex

index = KnowledgeGraphIndex.from_documents(
    documents,
    max_triplets_per_chunk=5,
    include_embeddings=True
)

# 支持多跳推理
query_engine = index.as_query_engine(embedding_mode="hybrid")
response = query_engine.query("张三的直属上级是谁?")

查询引擎:高级技巧

子问题查询引擎

将复杂问题分解为子问题,分别检索后合并:

from llama_index.core.tools import QueryEngineTool, ToolMetadata
from llama_index.core.query_engine import SubQuestionQueryEngine

# 为不同数据源创建独立引擎
hr_engine = hr_index.as_query_engine(similarity_top_k=5)
finance_engine = finance_index.as_query_engine(similarity_top_k=5)

tools = [
    QueryEngineTool(query_engine=hr_engine, metadata=ToolMetadata(
        name="hr_docs", description="人力资源政策文档"
    )),
    QueryEngineTool(query_engine=finance_engine, metadata=ToolMetadata(
        name="finance_docs", description="财务报告数据"
    )),
]

# 子问题分解
sub_engine = SubQuestionQueryEngine.from_defaults(query_engine_tools=tools)
response = sub_engine.query(
    "对比去年的招聘预算和实际招聘支出"
)

检索后处理

from llama_index.core.postprocessor import (
    SimilarityPostprocessor,
    KeywordNodePostprocessor,
    LLMRerank,
    SentenceEmbeddingOptimizer,
)

query_engine = index.as_query_engine(
    similarity_top_k=20,
    node_postprocessors=[
        SimilarityPostprocessor(similarity_cutoff=0.7),
        KeywordNodePostprocessor(required_keywords=["2024"]),
        LLMRerank(choice_batch_size=5, top_n=5),
        SentenceEmbeddingOptimizer(embed_model=embed_model, percentile_cutoff=0.85),
    ]
)

混合检索

from llama_index.core.query_engine import RetrieverQueryEngine
from llama_index.core.retrievers import QueryFusionRetriever

vector_retriever = index.as_retriever(similarity_top_k=10)
bm25_retriever = bm25_index.as_retriever(similarity_top_k=10)

fusion_retriever = QueryFusionRetriever(
    retrievers=[vector_retriever, bm25_retriever],
    num_queries=3,  # 生成查询变体
    mode="reciprocal_rerank",
    use_async=True,
)

engine = RetrieverQueryEngine.from_args(fusion_retriever)

Agent 模式

LlamaIndex 的 Agent 体系基于 ReAct 模式:

from llama_index.core.agent import ReActAgent
from llama_index.core.tools import FunctionTool

def search_database(query: str) -> str:
    """搜索企业数据库"""
    return db.search(query)

def send_email(to: str, subject: str, body: str) -> str:
    """发送邮件"""
    return f"已发送至 {to}"

tools = [
    FunctionTool.from_defaults(fn=search_database),
    FunctionTool.from_defaults(fn=send_email),
    QueryEngineTool(query_engine=rag_engine, metadata=ToolMetadata(
        name="knowledge_base", description="企业知识库检索"
    )),
]

agent = ReActAgent.from_tools(tools, llm=llm, verbose=True)
agent.chat("查找上季度销售数据并发送摘要邮件给 zhang@company.com")

Workflows(LlamaIndex 1.x 新特性)

from llama_index.core.workflow import Workflow, step, Event, StartEvent, StopEvent

class RAGWorkflow(Workflow):
    @step
    async def retrieve(self, ev: StartEvent) -> RetrieveEvent:
        query = ev.query
        nodes = await self.retriever.aretrieve(query)
        return RetrieveEvent(nodes=nodes, query=query)

    @step
    async def synthesize(self, ev: RetrieveEvent) -> StopEvent:
        response = await self.synthesizer.asynthesize(ev.query, ev.nodes)
        return StopEvent(result=str(response))

workflow = RAGWorkflow(timeout=30)
result = await workflow.run(query="公司年假政策是什么?")

与 LangChain 对比

维度LlamaIndexLangChain
核心专注数据索引与检索通用 LLM 编排
索引类型6+ 种,业界最全主要是 VectorStore
数据连接器200+ (LlamaHub)100+
查询引擎丰富(子问题/融合/路由)基础
AgentReAct + WorkflowsLangGraph(更强)
文档处理内置切分/摘要/元数据基础
评估Ragas 集成LangSmith
适合深度RAG 深度优化广度覆盖

生产实战建议

1. 索引选择决策树

数据量 < 50 条?→ SummaryIndex
长文档需要层级理解?→ TreeIndex
需要精确关键词匹配?→ KeywordTableIndex
多跳推理?→ KnowledgeGraphIndex
通用场景?→ VectorStoreIndex + 混合检索

2. 性能优化

# 异步批量索引
import asyncio
from llama_index.core import VectorStoreIndex

async def batch_index(documents, batch_size=100):
    index = VectorStoreIndex()
    for i in range(0, len(documents), batch_size):
        batch = documents[i:i+batch_size]
        await index.abuild_index_from_nodes(batch)  # 异步
    return index

# 缓存嵌入结果
from llama_index.core import StorageContext, load_index_from_storage
storage_context = StorageContext.from_defaults(persist_dir="./storage")
index = load_index_from_storage(storage_context)  # 恢复索引无需重算嵌入

3. 元数据过滤

from llama_index.core.vector_stores import MetadataFilters, MetadataFilter

filters = MetadataFilters(filters=[
    MetadataFilter(key="department", value="engineering"),
    MetadataFilter(key="year", value=2024, operator=">="),
])

query_engine = index.as_query_engine(filters=filters)

不足与风险

问题影响缓解方案
API 变动频繁1.x 仍有破坏性变更锁定版本
Agent 不如 LangGraph复杂多 Agent 协作弱RAG 用 LI,Agent 用 LC
学习曲线陡索引类型多从 VectorStoreIndex 开始
框架较重依赖多按需安装 extras

适用场景判断

选 LlamaIndex 如果你:

  • 核心需求是 RAG / 知识库
  • 需要多种索引策略(非纯向量检索)
  • 数据源多样(需要丰富连接器)
  • 愿意深度优化检索质量

不选 LlamaIndex 如果你:

  • 需要复杂多 Agent 协作
  • 场景与数据检索无关
  • 团队已在 LangGraph 上投入

总结

LlamaIndex 是 RAG 深度优化的首选框架。它的索引类型丰富度、查询引擎灵活性、数据连接器数量都是同类最佳。如果你的应用核心是"让 LLM 基于私有数据回答问题",LlamaIndex 比 LangChain 提供了更精细的工具。Workflows 机制的引入让它向通用编排迈进了一步,但在 Agent 领域仍不及 LangGraph。RAG 选 LlamaIndex,Agent 选 LangGraph 是当前最务实的组合。

加入讨论

这篇文章有姊妹讨论帖在硅基AGI论坛 — 全球首个碳基硅基认知交流平台。

碳基与硅基的智慧碰撞,认知差异创造无限可能。