LlamaIndex 是什么
LlamaIndex(原名 GPT Index)是一个专注于数据索引和查询的 AI 框架。如果说 LangChain 是一个通用的 LLM 应用框架,LlamaIndex 则更专注于一件事:让 LLM 能高效地理解和查询你的数据。
LlamaIndex 的设计哲学是”数据优先”。它提供了丰富的数据连接器、多种索引类型和灵活的查询引擎,让你可以快速构建基于私有数据的 AI 应用。
LlamaIndex vs LangChain
这是很多人的第一个问题,我们先说清楚:
| 维度 | LlamaIndex | LangChain |
|---|---|---|
| 核心定位 | 数据索引和查询 | 通用 LLM 应用框架 |
| 擅长场景 | RAG、知识库问答 | Agent、工作流、工具调用 |
| 学习曲线 | 较平缓 | 较陡峭 |
| 抽象层级 | 高(开箱即用) | 中(灵活但需要更多配置) |
| 数据连接器 | 非常丰富 | 丰富 |
| 索引类型 | 多种专用索引 | 主要依赖向量检索 |
| 可组合性 | 中等 | 高 |
简单来说:如果你的主要需求是基于文档的问答,LlamaIndex 上手更快。如果你需要构建复杂的 AI 工作流,LangChain 更灵活。两者也可以一起使用。
安装与配置
# 安装核心包
pip install llama-index
# 安装模型提供商(按需)
pip install llama-index-llms-openai
pip install llama-index-llms-anthropic
pip install llama-index-embeddings-openai
# 安装向量数据库(按需)
pip install llama-index-vector-stores-chroma
配置 API Key:
import os
os.environ["OPENAI_API_KEY"] = "your-api-key"
快速开始:5 行代码构建问答系统
LlamaIndex 最大的优势是简洁。看看这个最小示例:
from llama_index.core import VectorStoreIndex, SimpleDirectoryReader
# 1. 加载文档
documents = SimpleDirectoryReader("./docs").load_data()
# 2. 构建索引
index = VectorStoreIndex.from_documents(documents)
# 3. 创建查询引擎
query_engine = index.as_query_engine()
# 4. 查询
response = query_engine.query("项目的技术架构是什么?")
print(response)
就这么简单。LlamaIndex 在背后自动完成了文档切分、Embedding 生成、向量存储和检索。
数据连接器(Data Connectors)
LlamaIndex 通过 LlamaHub 提供了大量数据连接器。
内置连接器
from llama_index.core import SimpleDirectoryReader
# 自动识别文件类型(PDF、TXT、Markdown、DOCX 等)
reader = SimpleDirectoryReader(
input_dir="./docs",
recursive=True, # 递归子目录
required_exts=[".pdf", ".md", ".txt"], # 指定文件类型
exclude=["*.tmp"] # 排除文件
)
documents = reader.load_data()
LlamaHub 连接器
LlamaHub 提供了 100+ 数据连接器:
# 安装特定连接器
# pip install llama-index-readers-web
from llama_index.readers.web import SimpleWebPageReader
# 加载网页
reader = SimpleWebPageReader()
documents = reader.load_data(
urls=["https://docs.python.org/3/tutorial/classes.html"]
)
常用连接器
| 连接器 | 数据源 | 安装包 |
|---|---|---|
| SimpleDirectoryReader | 本地文件 | 内置 |
| SimpleWebPageReader | 网页 | llama-index-readers-web |
| DatabaseReader | SQL 数据库 | llama-index-readers-database |
| GithubRepositoryReader | GitHub 仓库 | llama-index-readers-github |
| NotionPageReader | Notion | llama-index-readers-notion |
| SlackReader | Slack | llama-index-readers-slack |
| GoogleDocsReader | Google Docs | llama-index-readers-google |
自定义连接器
from llama_index.core import Document
# 从任何数据源创建 Document
documents = [
Document(
text="这是文档内容...",
metadata={
"source": "custom",
"author": "张三",
"date": "2026-03-11"
}
)
]
索引类型
LlamaIndex 提供了多种索引类型,每种适合不同的查询场景。
1. VectorStoreIndex(向量索引)
最常用的索引类型,基于向量相似度检索:
from llama_index.core import VectorStoreIndex
index = VectorStoreIndex.from_documents(documents)
# 查询时会找到语义最相似的文档块
query_engine = index.as_query_engine(similarity_top_k=5)
response = query_engine.query("什么是微服务架构?")
适用场景:通用问答、语义搜索。
2. SummaryIndex(摘要索引)
遍历所有文档块生成回答,适合需要全局理解的问题:
from llama_index.core import SummaryIndex
index = SummaryIndex.from_documents(documents)
query_engine = index.as_query_engine()
# 会遍历所有文档块
response = query_engine.query("总结这份文档的主要内容")
适用场景:文档摘要、全局性问题。
3. TreeIndex(树索引)
将文档组织成树形结构,从根节点开始逐层查询:
from llama_index.core import TreeIndex
index = TreeIndex.from_documents(documents)
query_engine = index.as_query_engine()
response = query_engine.query("项目的整体架构是什么?")
适用场景:层次化的文档、需要从概览到细节的查询。
4. KeywordTableIndex(关键词索引)
基于关键词匹配的索引:
from llama_index.core import KeywordTableIndex
index = KeywordTableIndex.from_documents(documents)
query_engine = index.as_query_engine()
response = query_engine.query("数据库配置")
适用场景:精确的关键词查询、术语搜索。
索引类型对比
| 索引类型 | 检索方式 | 速度 | 适用场景 |
|---|---|---|---|
| VectorStoreIndex | 语义相似度 | 快 | 通用问答 |
| SummaryIndex | 遍历所有 | 慢 | 摘要、全局问题 |
| TreeIndex | 树形遍历 | 中等 | 层次化查询 |
| KeywordTableIndex | 关键词匹配 | 快 | 精确搜索 |
查询引擎(Query Engine)
基本查询
# 创建查询引擎
query_engine = index.as_query_engine(
similarity_top_k=5, # 检索 top 5 相关文档
response_mode="compact", # 响应模式
streaming=False # 是否流式
)
response = query_engine.query("如何部署应用?")
print(response.response) # 回答文本
print(response.source_nodes) # 来源文档
print(response.metadata) # 元数据
响应模式
| 模式 | 说明 | 适用场景 |
|---|---|---|
refine | 逐个文档块精炼回答 | 需要综合多个来源 |
compact | 合并文档块后一次生成 | 通用(默认) |
tree_summarize | 树形摘要 | 长文档摘要 |
simple_summarize | 简单摘要 | 快速摘要 |
no_text | 只返回检索结果 | 只需要检索 |
流式查询
query_engine = index.as_query_engine(streaming=True)
streaming_response = query_engine.query("解释微服务架构")
for text in streaming_response.response_gen:
print(text, end="", flush=True)
带过滤的查询
from llama_index.core.vector_stores import MetadataFilters, ExactMatchFilter
filters = MetadataFilters(
filters=[
ExactMatchFilter(key="source", value="architecture.md"),
]
)
query_engine = index.as_query_engine(
similarity_top_k=5,
filters=filters
)
response = query_engine.query("架构设计原则是什么?")
Response Synthesizer(响应合成器)
响应合成器决定了如何将检索到的文档块组合成最终回答。
from llama_index.core import get_response_synthesizer
# 创建自定义响应合成器
synthesizer = get_response_synthesizer(
response_mode="compact",
use_async=False
)
# 在查询引擎中使用
from llama_index.core.query_engine import RetrieverQueryEngine
query_engine = RetrieverQueryEngine(
retriever=index.as_retriever(similarity_top_k=5),
response_synthesizer=synthesizer
)
自定义模型
使用 Anthropic Claude
from llama_index.llms.anthropic import Anthropic
from llama_index.core import Settings
Settings.llm = Anthropic(
model="claude-sonnet-4-20250514",
temperature=0
)
# 之后创建的索引和查询引擎都会使用这个模型
index = VectorStoreIndex.from_documents(documents)
使用本地模型(Ollama)
from llama_index.llms.ollama import Ollama
from llama_index.embeddings.ollama import OllamaEmbedding
from llama_index.core import Settings
Settings.llm = Ollama(model="llama3", request_timeout=120)
Settings.embed_model = OllamaEmbedding(model_name="nomic-embed-text")
index = VectorStoreIndex.from_documents(documents)
自定义 Embedding 模型
from llama_index.embeddings.openai import OpenAIEmbedding
from llama_index.core import Settings
Settings.embed_model = OpenAIEmbedding(
model="text-embedding-3-small",
dimensions=512 # 可以降低维度以节省存储
)
持久化存储
保存索引
# 保存到磁盘
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)
使用外部向量数据库
import chromadb
from llama_index.vector_stores.chroma import ChromaVectorStore
from llama_index.core import StorageContext
# 创建 Chroma 客户端
chroma_client = chromadb.PersistentClient(path="./chroma_db")
chroma_collection = chroma_client.get_or_create_collection("my_docs")
# 创建向量存储
vector_store = ChromaVectorStore(chroma_collection=chroma_collection)
storage_context = StorageContext.from_defaults(vector_store=vector_store)
# 构建索引
index = VectorStoreIndex.from_documents(
documents,
storage_context=storage_context
)
完整示例:构建文档问答系统
"""
基于 LlamaIndex 的文档问答系统
"""
import os
from llama_index.core import (
VectorStoreIndex,
SimpleDirectoryReader,
StorageContext,
load_index_from_storage,
Settings
)
from llama_index.llms.openai import OpenAI
from llama_index.embeddings.openai import OpenAIEmbedding
os.environ["OPENAI_API_KEY"] = "your-api-key"
# 全局配置
Settings.llm = OpenAI(model="gpt-4o-mini", temperature=0)
Settings.embed_model = OpenAIEmbedding(model="text-embedding-3-small")
Settings.chunk_size = 1024
Settings.chunk_overlap = 128
STORAGE_DIR = "./storage"
DOCS_DIR = "./docs"
def build_index():
"""构建索引"""
print("加载文档...")
documents = SimpleDirectoryReader(DOCS_DIR, recursive=True).load_data()
print(f"加载了 {len(documents)} 个文档")
print("构建索引...")
index = VectorStoreIndex.from_documents(documents)
print("保存索引...")
index.storage_context.persist(persist_dir=STORAGE_DIR)
print("完成!")
return index
def load_index():
"""加载已有索引"""
storage_context = StorageContext.from_defaults(persist_dir=STORAGE_DIR)
return load_index_from_storage(storage_context)
def main():
# 检查是否已有索引
if os.path.exists(STORAGE_DIR):
print("加载已有索引...")
index = load_index()
else:
print("首次运行,构建索引...")
index = build_index()
# 创建查询引擎
query_engine = index.as_query_engine(
similarity_top_k=5,
response_mode="compact"
)
# 交互式问答
print("\n文档问答系统已就绪!输入 q 退出。\n")
while True:
question = input("问题: ")
if question.lower() == 'q':
break
response = query_engine.query(question)
print(f"\n回答: {response}\n")
# 显示来源
if response.source_nodes:
print("来源:")
for node in response.source_nodes:
source = node.metadata.get("file_name", "unknown")
score = node.score
print(f" - {source} (相关度: {score:.3f})")
print()
if __name__ == "__main__":
main()
实用技巧
1. 调整切分参数
from llama_index.core import Settings
from llama_index.core.node_parser import SentenceSplitter
Settings.text_splitter = SentenceSplitter(
chunk_size=1024,
chunk_overlap=128,
paragraph_separator="\n\n"
)
2. 添加元数据
from llama_index.core.extractors import TitleExtractor, SummaryExtractor
from llama_index.core.ingestion import IngestionPipeline
pipeline = IngestionPipeline(
transformations=[
SentenceSplitter(chunk_size=1024),
TitleExtractor(),
SummaryExtractor(summaries=["self"]),
]
)
nodes = pipeline.run(documents=documents)
index = VectorStoreIndex(nodes)
3. 评估检索质量
from llama_index.core.evaluation import RelevancyEvaluator
evaluator = RelevancyEvaluator()
query = "什么是微服务?"
response = query_engine.query(query)
eval_result = evaluator.evaluate_response(
query=query,
response=response
)
print(f"相关性: {eval_result.passing}")
print(f"反馈: {eval_result.feedback}")
数据是 AI 应用的燃料。LlamaIndex 帮你把数据变成 AI 能理解的知识,剩下的就是提出好问题。
相关文章
评论
加载中...
评论
加载中...