快速开始 #
第一个 RAG 应用 #
让我们用最少的代码构建一个文档问答系统:
python
import os
from llama_index.core import VectorStoreIndex, SimpleDirectoryReader
os.environ["OPENAI_API_KEY"] = "sk-your-key"
documents = SimpleDirectoryReader("./data").load_data()
index = VectorStoreIndex.from_documents(documents)
query_engine = index.as_query_engine()
response = query_engine.query("文档的主要内容是什么?")
print(response)
完整示例 #
准备数据 #
首先创建一个数据目录并添加文档:
bash
mkdir -p ./data
echo "LlamaIndex 是一个用于构建 LLM 应用的数据框架。
它提供了数据连接器、索引构建和查询引擎等功能。
LlamaIndex 支持多种数据源,包括 PDF、Word、网页等。
使用 LlamaIndex 可以快速构建文档问答系统、聊天机器人等应用。" > ./data/intro.txt
完整代码 #
python
import os
from llama_index.core import VectorStoreIndex, SimpleDirectoryReader, Settings
from llama_index.llms.openai import OpenAI
from llama_index.embeddings.openai import OpenAIEmbedding
os.environ["OPENAI_API_KEY"] = "sk-your-key"
Settings.llm = OpenAI(model="gpt-4o-mini")
Settings.embed_model = OpenAIEmbedding(model="text-embedding-3-small")
documents = SimpleDirectoryReader("./data").load_data()
print(f"加载了 {len(documents)} 个文档")
index = VectorStoreIndex.from_documents(documents)
query_engine = index.as_query_engine()
questions = [
"LlamaIndex 是什么?",
"LlamaIndex 支持哪些数据源?",
"使用 LlamaIndex 可以构建什么应用?",
]
for question in questions:
response = query_engine.query(question)
print(f"\n问题: {question}")
print(f"回答: {response}")
工作流程详解 #
1. 数据加载 #
text
┌─────────────────────────────────────────────────────────────┐
│ 数据加载流程 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 文件系统 │
│ │ │
│ │ SimpleDirectoryReader │
│ ▼ │
│ ┌─────────────┐ │
│ │ Documents │ 原始文档对象 │
│ │ - text │ 包含文本内容和元数据 │
│ │ - metadata │ │
│ └─────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
python
from llama_index.core import SimpleDirectoryReader
reader = SimpleDirectoryReader(
input_dir="./data",
recursive=True,
required_exts=[".txt", ".pdf", ".md"],
exclude=["*.tmp"],
)
documents = reader.load_data()
for doc in documents:
print(f"文件: {doc.metadata.get('file_name')}")
print(f"内容长度: {len(doc.text)} 字符")
2. 文档分割 #
text
┌─────────────────────────────────────────────────────────────┐
│ 文档分割流程 │
├─────────────────────────────────────────────────────────────┤
│ │
│ Document │
│ │ │
│ │ NodeParser │
│ ▼ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Node 1 │ Node 2 │ Node 3 │ Node 4 │ ... │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ 每个 Node 是一个文本块,便于检索 │
│ │
└─────────────────────────────────────────────────────────────┘
python
from llama_index.core import VectorStoreIndex, Document
from llama_index.core.node_parser import SentenceSplitter
doc = Document(text="很长的文档内容..." * 100)
splitter = SentenceSplitter(
chunk_size=512,
chunk_overlap=50,
)
nodes = splitter.get_nodes_from_documents([doc])
print(f"分割成 {len(nodes)} 个节点")
for i, node in enumerate(nodes[:3]):
print(f"\n节点 {i+1}:")
print(node.text[:100] + "...")
3. 向量化 #
text
┌─────────────────────────────────────────────────────────────┐
│ 向量化过程 │
├─────────────────────────────────────────────────────────────┤
│ │
│ Node (文本) │
│ │ │
│ │ Embedding Model │
│ ▼ │
│ Embedding (向量) │
│ [0.123, -0.456, 0.789, ...] │
│ │
│ 文本被转换为高维向量,用于语义搜索 │
│ │
└─────────────────────────────────────────────────────────────┘
python
from llama_index.embeddings.openai import OpenAIEmbedding
embed_model = OpenAIEmbedding()
text = "LlamaIndex 是一个数据框架"
embedding = embed_model.get_text_embedding(text)
print(f"向量维度: {len(embedding)}")
print(f"前 5 个值: {embedding[:5]}")
4. 索引构建 #
text
┌─────────────────────────────────────────────────────────────┐
│ 索引构建 │
├─────────────────────────────────────────────────────────────┤
│ │
│ Nodes + Embeddings │
│ │ │
│ │ VectorStoreIndex │
│ ▼ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 向量存储 │ │
│ │ Node 1 ──→ Embedding 1 │ │
│ │ Node 2 ──→ Embedding 2 │ │
│ │ Node 3 ──→ Embedding 3 │ │
│ │ ... │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
python
from llama_index.core import VectorStoreIndex
index = VectorStoreIndex.from_documents(documents)
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)
5. 查询处理 #
text
┌─────────────────────────────────────────────────────────────┐
│ 查询处理流程 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 用户问题 │
│ │ │
│ ▼ │
│ ┌─────────────┐ │
│ │ 向量化问题 │ │
│ └─────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────┐ │
│ │ 相似度搜索 │ ←── 向量存储 │
│ └─────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────┐ │
│ │ 检索相关节点│ │
│ └─────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────┐ │
│ │ LLM 生成 │ │
│ └─────────────┘ │
│ │ │
│ ▼ │
│ 回答 │
│ │
└─────────────────────────────────────────────────────────────┘
查询引擎配置 #
基本配置 #
python
query_engine = index.as_query_engine()
query_engine = index.as_query_engine(
similarity_top_k=3,
response_mode="compact",
)
response = query_engine.query("你的问题")
流式输出 #
python
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)
指定检索数量 #
python
query_engine = index.as_query_engine(
similarity_top_k=5
)
response = query_engine.query("你的问题")
print(f"检索了 {len(response.source_nodes)} 个相关节点")
从文件创建索引 #
加载 PDF #
python
from llama_index.core import VectorStoreIndex, SimpleDirectoryReader
documents = SimpleDirectoryReader(
input_files=["./document.pdf"]
).load_data()
index = VectorStoreIndex.from_documents(documents)
加载多种格式 #
python
from llama_index.core import SimpleDirectoryReader
documents = SimpleDirectoryReader(
input_dir="./data",
required_exts=[".pdf", ".docx", ".txt", ".md"],
).load_data()
print(f"加载了 {len(documents)} 个文档")
使用检索器 #
python
retriever = index.as_retriever(
similarity_top_k=3
)
nodes = retriever.retrieve("LlamaIndex 是什么?")
for i, node in enumerate(nodes):
print(f"\n节点 {i+1} (相似度: {node.score:.4f}):")
print(node.text[:200])
自定义提示词 #
python
from llama_index.core import PromptTemplate
qa_prompt_tmpl = (
"上下文信息如下:\n"
"---------------------\n"
"{context_str}\n"
"---------------------\n"
"根据上下文信息回答问题,如果上下文中没有相关信息,请说不知道。\n"
"问题: {query_str}\n"
"回答: "
)
qa_prompt = PromptTemplate(qa_prompt_tmpl)
query_engine = index.as_query_engine()
query_engine.update_prompts(
{"response_synthesizer:text_qa_template": qa_prompt}
)
response = query_engine.query("你的问题")
添加元数据过滤 #
python
from llama_index.core import Document
from llama_index.core import VectorStoreIndex
from llama_index.core.vector_stores import MetadataFilters, MetadataFilter
doc1 = Document(
text="Python 是一种编程语言。",
metadata={"category": "programming", "language": "python"}
)
doc2 = Document(
text="JavaScript 是一种脚本语言。",
metadata={"category": "programming", "language": "javascript"}
)
doc3 = Document(
text="机器学习是人工智能的一个分支。",
metadata={"category": "ai", "topic": "ml"}
)
index = VectorStoreIndex.from_documents([doc1, doc2, doc3])
filters = MetadataFilters(
filters=[
MetadataFilter(key="category", value="programming"),
]
)
query_engine = index.as_query_engine(filters=filters)
response = query_engine.query("有哪些编程语言?")
print(response)
完整示例:文档问答 #
python
import os
from llama_index.core import VectorStoreIndex, SimpleDirectoryReader, Settings
from llama_index.llms.openai import OpenAI
from llama_index.embeddings.openai import OpenAIEmbedding
os.environ["OPENAI_API_KEY"] = "sk-your-key"
Settings.llm = OpenAI(model="gpt-4o-mini")
Settings.embed_model = OpenAIEmbedding(model="text-embedding-3-small")
Settings.chunk_size = 512
documents = SimpleDirectoryReader("./data").load_data()
print(f"加载了 {len(documents)} 个文档")
index = VectorStoreIndex.from_documents(
documents,
show_progress=True,
)
index.storage_context.persist(persist_dir="./storage")
query_engine = index.as_query_engine(
similarity_top_k=3,
streaming=True,
)
print("\n=== 文档问答系统 ===")
print("输入 'quit' 退出\n")
while True:
question = input("问题: ").strip()
if question.lower() == "quit":
break
if not question:
continue
print("\n回答: ", end="")
response = query_engine.query(question)
for text in response.response_gen:
print(text, end="", flush=True)
print("\n")
print("来源:")
for i, node in enumerate(response.source_nodes):
print(f" [{i+1}] {node.node.metadata.get('file_name', 'unknown')}")
print()
下一步 #
现在你已经掌握了 LlamaIndex 的基本使用,接下来学习 核心概念 深入理解 LlamaIndex 的架构!
最后更新:2026-03-30