主题
为什么需要 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 RAG | LlamaIndex |
|---|---|---|
| 设计哲学 | "给你工具,自己组装" | "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 社区实现。多语言支持正在快速发展中。