LlamaIndex 完全教程(入门到进阶)
这份 LlamaIndex 教程从"它和 LangChain 有什么不同"讲起,循序渐进到进阶检索优化和 Agent。每个概念都配解说和可运行代码。
用的是 LlamaIndex 0.10+ 的现代写法(包已模块化拆分),比老教程的
GPTSimpleVectorIndex那套新很多。
LlamaIndex 完全教程(入门到进阶)
一、先搞懂:LlamaIndex 是什么
一句话:LlamaIndex 是一个专门做 RAG / 数据检索的框架——如果说 LangChain 是"全能工具箱",LlamaIndex 就是"数据检索专家"。
和 LangChain 的区别(小白最关心)
LangChain:什么都能做(链、Agent、工具、RAG...),大而全
LlamaIndex:专注"把你的数据喂给LLM"这一件事,做到极致
类比:
LangChain = 瑞士军刀(功能多)
LlamaIndex = 专业菜刀(切菜这件事更顺手)
什么时候选谁:
| 需求 | 选 |
|---|---|
| 重度 RAG、知识库问答、文档检索 | LlamaIndex |
| 复杂 Agent 编排、多步流程 | LangChain/LangGraph |
| 两者结合 | 很常见,LlamaIndex 做检索 + LangGraph 做编排 |
对照你的 Java 项目:LlamaIndex 把
RagAnswerAdvisor那一整套(切分、向量化、检索、生成)封装成了开箱即用的组件,而且比手写强大得多。
二、安装与"5 行跑通 RAG"
# 核心包 + OpenAI 的 LLM 和 Embedding
pip install llama-index-core llama-index-llms-openai llama-index-embeddings-openai
# 简便起见也可以装全家桶
pip install llama-index
最简示例——感受 LlamaIndex 的"丝滑":
import os
from llama_index.core import VectorStoreIndex, SimpleDirectoryReader
os.environ["OPENAI_API_KEY"] = "sk-xxx"
# 1. 读取 data 文件夹里的所有文档
documents = SimpleDirectoryReader("data").load_data()
# 2. 一行建索引(自动完成:切分 + 向量化 + 存储)
index = VectorStoreIndex.from_documents(documents)
# 3. 一行创建查询引擎
query_engine = index.as_query_engine()
# 4. 提问
response = query_engine.query("文档里讲了什么?")
print(response)
对比前面 LangChain 的 RAG:LangChain 要你手动写加载、切分、向量化、检索、拼提示词;LlamaIndex 把这些全藏在 from_documents 和 as_query_engine 里了。这就是它"数据检索专家"的体现。
三、核心概念逐个拆解
理解 LlamaIndex,记住这条数据流:
Documents → Nodes → Index → Retriever → Query Engine → Response
原始文档 切成块 建索引 检索器 查询引擎 答案
3.1 Document 与 Node(文档与节点)
from llama_index.core import Document
# Document = 一份原始文档
doc = Document(
text="员工年假政策:满一年享5天年假。",
metadata={"source": "HR手册", "category": "福利"} # 附加信息
)
# Node = Document 切分后的小块(LlamaIndex 的检索单位)
# 类比:Document是整本书,Node是撕下来的一页页
小白要点:Document 是你给的原始资料,Node 是框架切分后的小块。检索时检索的是 Node,不是整个 Document。
3.2 数据加载(Loaders)
from llama_index.core import SimpleDirectoryReader
# 读整个文件夹(自动识别 txt/pdf/word/md 等格式)
documents = SimpleDirectoryReader("data").load_data()
# 只读特定文件
documents = SimpleDirectoryReader(
input_files=["report.pdf", "notes.txt"]
).load_data()
# 递归读子文件夹 + 过滤格式
documents = SimpleDirectoryReader(
"data",
recursive=True,
required_exts=[".pdf", ".txt"],
).load_data()
LlamaHub(杀手锏):LlamaIndex 有几百个数据连接器,几乎任何数据源都能读:
pip install llama-index-readers-database # 数据库
pip install llama-index-readers-web # 网页
# 例:从网页加载
from llama_index.readers.web import SimpleWebPageReader
documents = SimpleWebPageReader().load_data(["https://example.com"])
3.3 全局配置(Settings)——小白必看
LlamaIndex 用一个全局 Settings 统一配置模型,设一次到处生效:
from llama_index.core import Settings
from llama_index.llms.openai import OpenAI
from llama_index.embeddings.openai import OpenAIEmbedding
# 配置 LLM(生成答案用)
Settings.llm = OpenAI(
model="gpt-4o-mini",
api_key="sk-xxx",
api_base="https://api.xxx.com/v1", # 自定义端点(如你项目的)
temperature=0,
)
# 配置 Embedding(向量化用)
Settings.embed_model = OpenAIEmbedding(
model="text-embedding-3-small",
api_key="sk-xxx",
)
# 配置切分参数(对照你 Java 项目的 chunk_size)
Settings.chunk_size = 512
Settings.chunk_overlap = 50
小白要点:配好 Settings 后,后面所有 VectorStoreIndex、query_engine 自动用这套配置,不用重复传。
3.4 索引(Index)——核心
Index 是 LlamaIndex 的心脏,把 Node 组织起来方便检索。
from llama_index.core import VectorStoreIndex
# 最常用:向量索引(语义检索)
index = VectorStoreIndex.from_documents(documents)
四种索引类型(进阶要懂):
| 索引类型 | 原理 | 适合 |
|---|---|---|
| VectorStoreIndex | 向量语义检索 | 90%场景,默认选它 |
| SummaryIndex | 遍历所有节点总结 | 需要全文总结时 |
| TreeIndex | 树状层级结构 | 长文档分层摘要 |
| KnowledgeGraphIndex | 知识图谱 | 实体关系查询 |
入门期记住 VectorStoreIndex 就够了,其他用到再学。
3.5 检索器(Retriever)
从索引里捞出相关 Node。
# 从索引创建检索器
retriever = index.as_retriever(similarity_top_k=4) # 取最相关的4个(top-k)
# 检索(只检索,不生成答案)
nodes = retriever.retrieve("年假几天?")
for node in nodes:
print(node.text) # 节点内容
print(node.score) # 相似度分数(越高越相关)
3.6 查询引擎(Query Engine)——一问一答
检索 + 生成的组合,最常用:
# 创建查询引擎
query_engine = index.as_query_engine(
similarity_top_k=4, # 检索几个
)
# 提问(自动:检索 → 拼提示词 → LLM生成)
response = query_engine.query("公司年假有几天?")
print(response) # 答案
print(response.source_nodes) # 答案来源的节点(可溯源!防幻觉)
小白要点:response.source_nodes 能看到"答案是根据哪些资料生成的",对照你 Java 项目里 RagAnswerAdvisor 的来源标注。
3.7 对话引擎(Chat Engine)——多轮对话
Query Engine 是一问一答(无记忆),Chat Engine 带记忆:
# 创建对话引擎(自动维护对话历史)
chat_engine = index.as_chat_engine(chat_mode="condense_plus_context")
# 多轮对话
response = chat_engine.chat("公司年假几天?")
print(response)
response = chat_engine.chat("那病假呢?") # 它记得上下文
print(response)
# 重置对话
chat_engine.reset()
chat_mode 几种模式(小白了解):
condense_plus_context → 最常用,结合历史改写问题 + 检索
context → 每次都检索 + 带历史
react → 用 ReAct Agent 方式(能调工具)
四、持久化(存储索引,避免重复建库)
每次重新建索引很慢很贵,要存下来:
from llama_index.core import StorageContext, load_index_from_storage
# 保存索引到本地
index.storage_context.persist(persist_dir="./storage")
# 下次直接加载(不用重新向量化)
storage_context = StorageContext.from_defaults(persist_dir="./storage")
index = load_index_from_storage(storage_context)
小白要点:建库是"离线一次性"的事,存下来后,服务启动直接加载,秒级可用。
五、接入真实向量库(生产级)
默认索引存内存,生产要用专业向量库(对照你 Java 项目的 pgvector):
pip install llama-index-vector-stores-chroma
import chromadb
from llama_index.core import VectorStoreIndex, StorageContext
from llama_index.vector_stores.chroma import ChromaVectorStore
# 1. 创建 Chroma 客户端(持久化到磁盘)
chroma_client = chromadb.PersistentClient(path="./chroma_db")
chroma_collection = chroma_client.get_or_create_collection("my_knowledge")
# 2. 包装成 LlamaIndex 的向量库
vector_store = ChromaVectorStore(chroma_collection=chroma_collection)
storage_context = StorageContext.from_defaults(vector_store=vector_store)
# 3. 建索引时指定用这个向量库
index = VectorStoreIndex.from_documents(
documents,
storage_context=storage_context,
)
# 之后查询照常
query_engine = index.as_query_engine()
pgvector 同理(你 Java 项目用的就是它):
pip install llama-index-vector-stores-postgres
from llama_index.vector_stores.postgres import PGVectorStore
vector_store = PGVectorStore.from_params(
database="vectordb", host="localhost", port=5432,
user="postgres", password="xxx", table_name="my_vectors",
embed_dim=1536,
)
六、进阶:检索质量优化
基础 RAG 效果一般,LlamaIndex 提供强大的优化手段。
6.1 节点后处理(Node Postprocessors)
检索后、生成前,对节点二次加工:
from llama_index.core.postprocessor import SimilarityPostprocessor
# 过滤掉相似度太低的节点(去噪)
query_engine = index.as_query_engine(
similarity_top_k=10,
node_postprocessors=[
SimilarityPostprocessor(similarity_cutoff=0.7) # 只留分数>0.7的
],
)
6.2 重排(Rerank)——提升精度的利器
pip install llama-index-postprocessor-cohere-rerank
from llama_index.postprocessor.cohere_rerank import CohereRerank
# 先粗检索10个,再用重排模型精选3个
rerank = CohereRerank(api_key="xxx", top_n=3)
query_engine = index.as_query_engine(
similarity_top_k=10, # 粗检索捞10个
node_postprocessors=[rerank], # 重排精选3个
)
类比:海选 10 人 → 评委精选 3 人。重排能显著提升答案相关性。
6.3 混合检索(向量 + 关键词)
# 向量检索懂语义,关键词检索擅长精确匹配(如型号"X-200")
from llama_index.core.retrievers import QueryFusionRetriever
# 结合两种检索器,融合结果
retriever = QueryFusionRetriever(
[vector_retriever, keyword_retriever],
similarity_top_k=4,
num_queries=1,
)
6.4 元数据过滤(对照你的 knowledge_tag)
from llama_index.core.vector_stores import MetadataFilters, ExactMatchFilter
# 只在特定类别里检索
filters = MetadataFilters(filters=[
ExactMatchFilter(key="category", value="HR政策")
])
query_engine = index.as_query_engine(filters=filters)
这正是你 Java 项目
filterExpression: "knowledge == '知识库名称'"的对应实现。
6.5 自定义切分策略
from llama_index.core.node_parser import SentenceSplitter, MarkdownNodeParser
# 按句子智能切分
Settings.node_parser = SentenceSplitter(chunk_size=512, chunk_overlap=50)
# Markdown 按标题结构切分(更聪明)
Settings.node_parser = MarkdownNodeParser()
七、进阶:LlamaIndex 的 Agent
LlamaIndex 不只是 RAG,也能做 Agent(把查询引擎当工具):
from llama_index.core.tools import QueryEngineTool, FunctionTool
from llama_index.core.agent import ReActAgent
# 1. 把知识库查询引擎包装成工具
hr_tool = QueryEngineTool.from_defaults(
query_engine=hr_query_engine,
name="hr_knowledge",
description="查询公司HR政策(年假、病假、报销等)",
)
# 2. 普通函数也能当工具
def calculator(a: int, b: int) -> int:
"""计算两数之和"""
return a + b
calc_tool = FunctionTool.from_defaults(fn=calculator)
# 3. 创建 ReAct Agent(自动决定调哪个工具)
agent = ReActAgent.from_tools(
[hr_tool, calc_tool],
verbose=True, # 打印思考过程
)
# 4. 提问(Agent 自己判断:HR问题→查知识库,计算→调calculator)
response = agent.chat("公司年假几天?再帮我算 15+8")
print(response)
这就是 RAG + Agent 结合:多个知识库各自是一个工具,Agent 智能路由——这比你 Java 项目的单一 RAG 更进一步。
八、完整实战:企业知识库问答系统
整合所有知识,做一个可复用的系统:
import os
import chromadb
from llama_index.core import (
VectorStoreIndex, SimpleDirectoryReader, Settings,
StorageContext, load_index_from_storage,
)
from llama_index.llms.openai import OpenAI
from llama_index.embeddings.openai import OpenAIEmbedding
from llama_index.vector_stores.chroma import ChromaVectorStore
from llama_index.core.postprocessor import SimilarityPostprocessor
class EnterpriseKB:
"""企业知识库(对照你 Java 项目的 RagService,但更强大)"""
def __init__(self, api_key: str, db_path: str = "./chroma_db"):
# 全局配置
Settings.llm = OpenAI(model="gpt-4o-mini", api_key=api_key, temperature=0)
Settings.embed_model = OpenAIEmbedding(model="text-embedding-3-small", api_key=api_key)
Settings.chunk_size = 512
Settings.chunk_overlap = 50
# 持久化向量库
client = chromadb.PersistentClient(path=db_path)
collection = client.get_or_create_collection("enterprise_kb")
self.vector_store = ChromaVectorStore(chroma_collection=collection)
self.storage_context = StorageContext.from_defaults(vector_store=self.vector_store)
self.index = None
def build(self, data_dir: str):
"""从文件夹建知识库"""
documents = SimpleDirectoryReader(data_dir, recursive=True).load_data()
self.index = VectorStoreIndex.from_documents(
documents, storage_context=self.storage_context,
)
print(f"✅ 知识库构建完成,加载 {len(documents)} 份文档")
def load(self):
"""加载已有知识库(不重新建)"""
self.index = VectorStoreIndex.from_vector_store(
self.vector_store, storage_context=self.storage_context,
)
print("✅ 知识库已加载")
def ask(self, question: str, top_k: int = 4) -> dict:
"""提问(带来源溯源 + 低分过滤)"""
query_engine = self.index.as_query_engine(
similarity_top_k=top_k,
node_postprocessors=[SimilarityPostprocessor(similarity_cutoff=0.5)],
)
response = query_engine.query(question)
return {
"answer": str(response),
"sources": [
{"text": n.text[:80] + "...", "score": round(n.score, 3)}
for n in response.source_nodes
],
}
def chat_session(self):
"""交互式多轮对话"""
chat_engine = self.index.as_chat_engine(chat_mode="condense_plus_context")
print("进入对话(输入 exit 退出)")
while True:
q = input("\n你: ")
if q.lower() == "exit":
break
print("助手:", chat_engine.chat(q))
# ========== 使用 ==========
kb = EnterpriseKB(api_key="sk-xxx")
# 首次:建库
kb.build("./company_docs")
# 之后:直接加载
# kb.load()
# 单次问答(带来源)
result = kb.ask("公司年假有几天?")
print("答案:", result["answer"])
print("来源:", result["sources"])
# 多轮对话
# kb.chat_session()
九、LlamaIndex vs LangChain 对照速查
| 能力 | LlamaIndex | LangChain |
|---|---|---|
| 加载数据 | SimpleDirectoryReader |
TextLoader 等 |
| 建索引 | VectorStoreIndex.from_documents |
手动 splitter+vectorstore |
| 检索器 | index.as_retriever() |
vectorstore.as_retriever() |
| 一问一答 | as_query_engine() |
手搭 RAG 链 |
| 多轮对话 | as_chat_engine() |
RunnableWithMessageHistory |
| 来源溯源 | response.source_nodes 内置 |
需手动处理 |
| 上手难度 | RAG 更简单 | 更灵活但繁琐 |
核心差异:做 RAG,LlamaIndex 几行搞定且功能内置(溯源、重排、多索引);LangChain 要自己搭积木。所以重 RAG 选 LlamaIndex,重编排选 LangChain。
十、学习路径建议(小白到进阶)
入门(1-2天):
Settings配置 → VectorStoreIndex → as_query_engine
跑通"5行RAG",理解 Document→Node→Index→Response 数据流
基础(2-3天):
数据加载器 / 持久化 / Chat Engine / 接入Chroma
进阶(3-5天):
Rerank重排 / 混合检索 / 元数据过滤 / 节点后处理
→ 这些决定 RAG 效果好坏
高阶(按需):
多索引路由 / LlamaIndex Agent / 知识图谱索引
/ 接入 pgvector 生产部署
和你 Java 项目的对照总结
| 你的 Java 项目 | LlamaIndex |
|---|---|
RagAnswerAdvisor |
query_engine / EnterpriseKB.ask |
pgvector |
PGVectorStore |
TokenTextSplitter |
SentenceSplitter |
topK: 4 |
similarity_top_k=4 |
filterExpression |
MetadataFilters |
knowledge_tag |
Node 的 metadata |
| RAG 来源标注 | response.source_nodes |
你 Java 项目里手写的 RAG 逻辑,LlamaIndex 全部封装好了,而且多了重排、混合检索、多索引路由这些你项目还没有的进阶能力。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)