快速开始 #

第一个 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