跳转到内容

为什么需要 LlamaIndex?

在开始写任何代码之前,我想先回答一个很多开发者都会有的疑问:我已经学了 LangChain,里面不是已经有 RAG(检索增强生成)相关的功能了吗?为什么还需要再学一个叫 LlamaIndex 的框架?

这是一个非常好的问题。要理解 LlamaIndex 的价值,我们需要先回到 RAG 本身——看看在实际项目中,一个"能用的"RAG 系统到底需要解决哪些问题,以及 LangChain 在哪些方面做得不够好。

从一个真实的痛点说起

假设你正在为一家公司构建内部知识库问答系统。公司的知识散落在各种地方:Wiki 平台上有几千篇产品文档、Confluence 里有一堆技术方案、共享文件夹里存着 PDF 格式的政策文件、数据库里跑着客户数据,甚至还有一些团队用 Notion 写了会议纪要。

你的任务很简单:让员工能用自然语言提问,然后从所有这些来源中找到准确答案并返回。

如果你用 LangChain 来做这件事,大概会写出这样的代码:

python
from langchain_community.document_loaders import DirectoryLoader
from langchain_text_splitter import RecursiveCharacterTextSplitter
from langchain_openai import OpenAIEmbeddings, ChatOpenAI
from langchain_chroma import Chroma

loader = DirectoryLoader("./knowledge_base", glob="**/*.md")
documents = loader.load()
splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
chunks = splitter.split_documents(documents)
embeddings = OpenAIEmbeddings()
vectorstore = Chroma.from_documents(chunks, embeddings=embeddings)
retriever = vectorstore.as_retriever(search_kwargs={"k": 5})
llm = ChatOpenAI(model="gpt-4o-mini")
prompt = """根据以下信息回答问题。如果信息不足,请诚实地说不知道。
{context}
"""
chain = (
    {"context": retriever | format_docs}
    | prompt
    | llm
    | StrOutputParser()
)

这段代码能跑通,也能回答一些基本问题。但当你把它部署到生产环境后,很快会发现一堆让人头疼的问题:

第一,检索质量不稳定。 有时候用户问"退款流程是什么",系统返回的答案很完美;但换个问法"我怎么申请退款",系统可能就找不到相关文档了。原因是纯向量搜索对语义变化的鲁棒性不够——同一个意思换种说法,向量距离就差了很多。

第二,文档格式处理粗糙。 公司的知识库里有 PDF 表格、Word 文档里的嵌套标题结构、HTML 页面中混杂的广告和导航栏。RecursiveCharacterTextSplitter 按固定字符数切分,很容易把一个完整的表格切成两半,或者把 HTML 标签混进文本内容。

第三,无法连接数据库。 客户的最新订单信息存在 PostgreSQL 里,但上面的代码只能搜索文件系统中的 Markdown。你想把数据库也纳入检索范围,却发现 LangChain 的 SQLDatabase 工具只支持执行 SQL,不支持"把数据库表作为 RAG 知识源"这种用法。

第四,答案没有引用来源。 用户看到回复后问"这个信息来自哪份文档?",系统答不上来——因为它在生成过程中丢失了元数据。

第五,当文档量增长到万级以上时,性能急剧下降。 单次检索返回 top-5 可能耗时数秒,而且准确率明显下降。

这些问题不是 bug——它们是 LangChain 在 RAG 领域的设计边界。LangChain 是一个通用框架,RAG 只是它众多能力中的一个;而 LlamaIndex 是一个专门为数据和 RAG 设计的框架,它在每一个上述痛点上都有深入的解决方案。

LlamaIndex 的核心定位

如果用一句话概括两者的关系:

LangChain 像是一个万能工具箱,LlamaIndex 则是一把专攻数据与 RAG 的瑞士军刀。

更具体地说,LlamaIndex 在以下几个维度上做了深度的差异化:

维度LangChain RAGLlamaIndex
设计哲学"给你工具,自己组装""RAG 最佳实践已经内置"
数据加载几十种 Loader数百种 Connector
文档解析按字符切分层级化解析(保留结构)
索引策略一种(VectorStore)6 种索引类型可组合
检索方式相似度匹配混合检索 + 重排序 + 路由查询
响应合成一次性生成Refine / Tree Summarize / 多模式
评估体系需自建或用 RAGAS内置 Evaluator

这不是说 LangChain 不好——恰恰相反,在 Agent 编排、工具链管理、多模态交互等方面 LangChain 依然是王者。但在 以数据为中心的 RAG 场景 中,LlamaIndex 提供了更专业、更深度的能力。

LlamaIndex 的核心架构

在深入细节之前,让我们先建立对 LlamaIndex 整体架构的认知。理解了这个架构图,后面所有章节的内容都能找到自己的位置:

┌─────────────────────────────────────────────────────┐
│                   用户问题 (Query)                      │
└──────────────────────┬──────────────────────────────┘


┌─────────────────────────────────────────────────────┐
│              Query Engine (查询引擎)                 │
│                                                     │
│   ┌─────────────┐  ┌──────────────┐  ┌─────────────┐    │
│   │ Sub-Question │  │ Transformed  │  │ Router     │    │
│   │ Router       │  │ Query        │  │ Query      │    │
│   └──────┬──────┘  └──────┬───────┘  └──────┬──────┘    │
│          │                │                │             │
│          ▼                ▼                ▼             │
│   ┌──────────────────────────────────────────────────┐     │
│   │              Index (索引层)                    │     │
│   │                                               │     │
│   │  ┌──────────┐ ┌──────────┐ ┌──────────────┐   │     │
│   │  │ Vector   │ │ Keyword  │ │ Summary     │   │     │
│   │  │ Store    │ │ Table    │ │ Index       │   │     │
│   │  └──────────┘ └──────────┘ └──────────────┘   │     │
│   └───────────────────┬──────────────────────────────┘     │
│                      │                               │
│                      ▼                               │
│   ┌──────────────────────────────────────────────────┐     │
│   │           Node Parser (节点解析器)            │     │
│   │                                           │     │
│   │  Documents → Nodes → Relationships        │     │
│   └───────────────────┬──────────────────────────────┘     │
│                      │                               │
│                      ▼                               │
│   ┌──────────────────────────────────────────────────┐     │
│   │         Document Loader (数据加载器)         │     │
│   │                                           │     │
│   │  PDF / MD / HTML / DB / API / Cloud / Code     │     │
│   └──────────────────────────────────────────────────┘     │
│                                                      │
└──────────────────────────────────────────────────────┘


┌─────────────────────────────────────────────────────┐
│           Response Synthesizer (响应合成)              │
│                                                     │
│   Refine / Compact-and-Refine / Tree Summarize       │
│   + 引用来源标注 + 结构化输出                        │
└─────────────────────────────────────────────────────┘

这个架构图看起来层次很多,但别被它吓到——我们会在后续章节逐一拆解每个组件。现在你需要建立的直觉是:LlamaIndex 把"从数据到答案"这条路拆成了清晰的阶段,每个阶段都有多种可选策略,你可以像搭积木一样组合出最适合你场景的方案。

LlamaIndex 的适用场景

基于上面的介绍,以下场景特别适合使用 LlamaIndex:

首选 LlamaIndex 的场景:

  • 你的应用核心就是 RAG——围绕数据检索和答案生成展开
  • 数据来源多样且复杂(不只是几个 Markdown 文件)
  • 需要企业级的检索质量(不能接受"偶尔答错")
  • 文档量较大(千份以上,需要高效的索引策略)
  • 团队中有非技术人员参与知识库维护(需要低代码的数据接入方式)

继续用 LangChain 更合适的场景:

  • 你的应用核心是 Agent / 工具链(RAG 只是其中一个环节)
  • 主要在做对话式交互、多轮工具调用
  • 需要与多种外部服务集成(API 调用、消息推送等)
  • 团队规模小,快速原型验证比深度优化更重要

当然,实际项目中两者经常结合使用——用 LlamaIndex 处理数据层 RAG,用 LangChain 处理上层 Agent 编排。这也是完全可行且常见的做法。

常见误区

误区一:"LlamaIndex 可以替代 LangChain"。 不可以。两者是互补关系而非替代关系。LlamaIndex 擅长的是数据和 RAG,LangChain 擅长的是编排和 Agent。最好的策略是根据项目需求选择或组合使用。

误区二:"学 LlamaIndex 必须先精通 LangChain"。 不需要。虽然本教程假设你有基本的 LLM 应用概念,但 LlamaIndex 自身有完整的学习路径,即使没接触过 LangChain 也能直接上手。两套术语体系有差异但核心思想相通。

误区三:"LlamaIndex 只能做 RAG"。 不止于此。它的数据连接能力使其非常适合做数据分析、知识图谱构建、文档自动化处理等任务。RAG 只是它最著名的应用场景之一。

误区四:"LlamaIndex 只能用于 Python"。 核心库是 Python 的,但它提供了 TypeScript/JavaScript 的 SDK(@llamaindex/core@llamaindex/community),也有 Rust 社区实现。多语言支持正在快速发展中。

基于 MIT 许可发布