LlamaIndex 知识引擎¶
为什么要学¶
LlamaIndex(原 GPT Index)是最专注于"数据连接+索引+查询"的 AI 框架:
- 数据连接:160+ 数据源连接器(PDF、数据库、API、网页等)
- 智能索引:多种索引策略优化检索质量
- 查询引擎:从简单 QA 到复杂的多步推理
- 生产就绪:LlamaCloud 提供托管的解析和索引服务
- Agent 支持:基于数据的 Agent 和工作流
如果你的核心需求是"让 AI 理解和查询你的数据",LlamaIndex 是最专业的选择。
核心概念¶
白话解释¶
LlamaIndex 解决的问题链: 1. 连接:你的数据在各种地方(文件/数据库/API)→ 统一读取 2. 索引:数据太多,AI 看不完 → 建立索引加速查找 3. 查询:用户提问 → 找到相关信息 → AI 生成回答
核心概念对照表¶
| 概念 | 说明 | 类比 |
|---|---|---|
| Document | 数据源的原始内容 | 一个文件/网页 |
| Node | 文档拆分后的块 | 段落/小节 |
| Index | 对Nodes的组织结构 | 图书馆索引 |
| VectorStoreIndex | 向量索引(最常用) | 语义搜索引擎 |
| QueryEngine | 查询执行器 | 搜索接口 |
| Retriever | 检索器(从Index中找相关Node) | 图书管理员 |
| ResponseSynthesizer | 将检索结果合成回答 | 写作助手 |
| Reader/Loader | 数据读取器 | 文件打开器 |
| Embedding | 文本向量化 | 语义编码 |
| LLM | 大语言模型 | AI大脑 |
安装配置¶
安装¶
# 核心包
pip install llama-index
# 或按需安装
pip install llama-index-core
pip install llama-index-llms-openai
pip install llama-index-embeddings-openai
pip install llama-index-vector-stores-chroma
# 常用Reader
pip install llama-index-readers-file # PDF/DOCX等
pip install llama-index-readers-web # 网页
pip install llama-index-readers-database # 数据库
环境配置¶
import os
os.environ["OPENAI_API_KEY"] = "sk-..."
# 或在代码中配置
from llama_index.core import Settings
from llama_index.llms.openai import OpenAI
from llama_index.embeddings.openai import OpenAIEmbedding
Settings.llm = OpenAI(model="gpt-4o-mini", temperature=0.1)
Settings.embed_model = OpenAIEmbedding(model="text-embedding-3-small")
快速上手¶
5 行代码构建 RAG¶
from llama_index.core import VectorStoreIndex, SimpleDirectoryReader
# 1. 读取文档
documents = SimpleDirectoryReader("./data/").load_data()
# 2. 创建索引
index = VectorStoreIndex.from_documents(documents)
# 3. 查询
query_engine = index.as_query_engine()
response = query_engine.query("这份文档的主要内容是什么?")
print(response)
从不同数据源加载¶
from llama_index.core import SimpleDirectoryReader
# 支持多种文件格式
documents = SimpleDirectoryReader(
input_dir="./docs/",
required_exts=[".pdf", ".md", ".txt", ".docx"],
recursive=True
).load_data()
# 从URL加载
from llama_index.readers.web import SimpleWebPageReader
web_docs = SimpleWebPageReader().load_data(
urls=["https://docs.example.com/guide"]
)
# 从数据库加载
from llama_index.readers.database import DatabaseReader
db_reader = DatabaseReader(uri="postgresql://localhost/mydb")
db_docs = db_reader.load_data(query="SELECT content FROM articles")
持久化索引¶
# 保存索引到磁盘
index.storage_context.persist(persist_dir="./storage/")
# 从磁盘加载
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)
进阶用法¶
1. 自定义分块策略¶
from llama_index.core.node_parser import (
SentenceSplitter,
SemanticSplitterNodeParser,
HierarchicalNodeParser
)
# 按句子分块
splitter = SentenceSplitter(
chunk_size=512,
chunk_overlap=50,
separator="\n"
)
# 语义分块(按语义边界切分)
from llama_index.embeddings.openai import OpenAIEmbedding
semantic_splitter = SemanticSplitterNodeParser(
embed_model=OpenAIEmbedding(),
breakpoint_percentile_threshold=95
)
# 层级分块(大块→小块)
hierarchical_splitter = HierarchicalNodeParser.from_defaults(
chunk_sizes=[2048, 512, 128]
)
# 使用自定义分块
from llama_index.core import VectorStoreIndex
from llama_index.core.ingestion import IngestionPipeline
pipeline = IngestionPipeline(
transformations=[
splitter,
OpenAIEmbedding()
]
)
nodes = pipeline.run(documents=documents)
index = VectorStoreIndex(nodes)
2. 混合检索 + 重排序¶
from llama_index.core.retrievers import VectorIndexRetriever
from llama_index.retrievers.bm25 import BM25Retriever
from llama_index.core.query_engine import RetrieverQueryEngine
from llama_index.core.postprocessor import SentenceTransformerRerank
# 向量检索器
vector_retriever = VectorIndexRetriever(index=index, similarity_top_k=10)
# BM25检索器
bm25_retriever = BM25Retriever.from_defaults(index=index, similarity_top_k=10)
# 融合检索
from llama_index.core.retrievers import QueryFusionRetriever
fusion_retriever = QueryFusionRetriever(
retrievers=[vector_retriever, bm25_retriever],
similarity_top_k=10,
num_queries=3, # 生成3个变体查询
mode="reciprocal_rerank"
)
# 重排序
reranker = SentenceTransformerRerank(
model="cross-encoder/ms-marco-MiniLM-L-6-v2",
top_n=5
)
# 组合查询引擎
query_engine = RetrieverQueryEngine.from_args(
retriever=fusion_retriever,
node_postprocessors=[reranker]
)
response = query_engine.query("解释系统的认证机制")
3. 子问题查询引擎¶
from llama_index.core.query_engine import SubQuestionQueryEngine
from llama_index.core.tools import QueryEngineTool, ToolMetadata
# 为不同文档创建不同的查询引擎
api_engine = api_index.as_query_engine()
arch_engine = arch_index.as_query_engine()
# 定义工具
tools = [
QueryEngineTool(
query_engine=api_engine,
metadata=ToolMetadata(name="api_docs", description="API文档,包含接口定义和使用方法")
),
QueryEngineTool(
query_engine=arch_engine,
metadata=ToolMetadata(name="architecture", description="架构文档,包含系统设计和模块说明")
)
]
# 子问题引擎会自动拆解复杂问题
sub_question_engine = SubQuestionQueryEngine.from_defaults(query_engine_tools=tools)
response = sub_question_engine.query(
"这个系统的认证API是怎么设计的?它与整体架构是什么关系?"
)
# AI会自动将问题拆成:1.查API文档找认证API 2.查架构文档找相关设计 3.综合回答
4. Agent(工具使用)¶
from llama_index.core.agent import ReActAgent
from llama_index.core.tools import FunctionTool
# 定义工具
def search_code(query: str) -> str:
"""在代码库中搜索相关代码片段"""
# 实现搜索逻辑
return f"找到关于'{query}'的代码..."
def run_sql(query: str) -> str:
"""执行SQL查询获取数据"""
# 实现SQL执行
return f"SQL结果: ..."
tools = [
FunctionTool.from_defaults(fn=search_code),
FunctionTool.from_defaults(fn=run_sql),
# 也可以用QueryEngine作为工具
QueryEngineTool.from_defaults(
query_engine=doc_engine,
name="documentation",
description="查询项目文档"
)
]
# 创建Agent
agent = ReActAgent.from_tools(
tools=tools,
llm=OpenAI(model="gpt-4o"),
verbose=True
)
response = agent.chat("数据库中有多少活跃用户?文档中对活跃用户的定义是什么?")
5. 向量存储集成¶
# ChromaDB
from llama_index.vector_stores.chroma import ChromaVectorStore
import chromadb
chroma_client = chromadb.PersistentClient(path="./chroma_db")
collection = chroma_client.get_or_create_collection("my_docs")
vector_store = ChromaVectorStore(chroma_collection=collection)
# 使用外部向量存储创建索引
from llama_index.core import StorageContext
storage_context = StorageContext.from_defaults(vector_store=vector_store)
index = VectorStoreIndex.from_documents(documents, storage_context=storage_context)
# Qdrant
from llama_index.vector_stores.qdrant import QdrantVectorStore
vector_store = QdrantVectorStore(
url="http://localhost:6333",
collection_name="my_docs"
)
# PostgreSQL (pgvector)
from llama_index.vector_stores.postgres import PGVectorStore
vector_store = PGVectorStore.from_params(
database="mydb",
host="localhost",
password="...",
table_name="embeddings"
)
6. Workflow(新一代编排)¶
from llama_index.core.workflow import Workflow, step, Context, Event, StartEvent, StopEvent
class QueryEvent(Event):
query: str
class RetrieveEvent(Event):
nodes: list
class RAGWorkflow(Workflow):
@step
async def rewrite_query(self, ev: StartEvent) -> QueryEvent:
"""查询改写"""
# 用LLM优化查询
rewritten = await self.llm.acomplete(f"优化搜索查询: {ev.query}")
return QueryEvent(query=str(rewritten))
@step
async def retrieve(self, ev: QueryEvent) -> RetrieveEvent:
"""检索文档"""
nodes = await self.retriever.aretrieve(ev.query)
return RetrieveEvent(nodes=nodes)
@step
async def synthesize(self, ev: RetrieveEvent) -> StopEvent:
"""生成回答"""
response = await self.synthesizer.asynthesize(
query=ev.query,
nodes=ev.nodes
)
return StopEvent(result=str(response))
# 运行Workflow
workflow = RAGWorkflow()
result = await workflow.run(query="什么是向量数据库?")
7. 使用本地模型¶
from llama_index.llms.ollama import Ollama
from llama_index.embeddings.huggingface import HuggingFaceEmbedding
from llama_index.core import Settings
# 本地LLM
Settings.llm = Ollama(model="llama3.2", request_timeout=120)
# 本地Embedding
Settings.embed_model = HuggingFaceEmbedding(
model_name="BAAI/bge-small-zh-v1.5"
)
# 后续正常使用即可
index = VectorStoreIndex.from_documents(documents)
常见问题¶
Q1: 和 LangChain 的区别?¶
| 方面 | LlamaIndex | LangChain |
|---|---|---|
| 核心能力 | 数据索引+检索 | 通用LLM编排 |
| RAG质量 | 更专业(多种索引策略) | 基础 |
| Agent | 基本支持 | 更丰富 |
| 数据连接 | 160+连接器 | 较少 |
| 学习曲线 | 中等 | 陡峭 |
Q2: 如何提升 RAG 质量?¶
- 分块优化:使用语义分块而非固定大小
- 混合检索:向量 + BM25 关键词
- 重排序:用 Cross-Encoder 精排
- 查询改写:让 LLM 优化用户查询
- 元数据过滤:利用文档元数据预过滤
Q3: 索引很大时性能问题?¶
- 使用外部向量存储(Qdrant/Pinecone)
- 利用元数据预过滤减小搜索范围
- 使用分层索引(先粗筛后精排)
- 考虑 LlamaCloud 托管服务
Q4: 如何处理大文档?¶
# 使用层级索引
from llama_index.core.node_parser import HierarchicalNodeParser
from llama_index.core.retrievers import AutoMergingRetriever
# 大块概览 + 小块详情
parser = HierarchicalNodeParser.from_defaults(chunk_sizes=[2048, 512, 128])
nodes = parser.get_nodes_from_documents(documents)
Q5: 更新文档后如何刷新索引?¶
# 增量更新
index.insert(new_document)
# 删除旧文档
index.delete_ref_doc(doc_id)
# 完全重建
index.refresh_ref_docs(documents)
参考资源¶
- LlamaIndex 文档 - 官方文档
- LlamaIndex GitHub - 源代码
- LlamaHub - 数据连接器市场
- LlamaCloud - 托管服务
- Cookbook - 示例集
- Discord - 社区