AI 工具 | | 约 27 分钟 | 10,647 字

LlamaIndex 入门:数据索引与查询

LlamaIndex 的数据连接器、索引类型和查询引擎

LlamaIndex 是什么

LlamaIndex(原名 GPT Index)是一个专注于数据索引和查询的 AI 框架。如果说 LangChain 是一个通用的 LLM 应用框架,LlamaIndex 则更专注于一件事:让 LLM 能高效地理解和查询你的数据。

LlamaIndex 的设计哲学是”数据优先”。它提供了丰富的数据连接器、多种索引类型和灵活的查询引擎,让你可以快速构建基于私有数据的 AI 应用。

LlamaIndex vs LangChain

这是很多人的第一个问题,我们先说清楚:

维度LlamaIndexLangChain
核心定位数据索引和查询通用 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
DatabaseReaderSQL 数据库llama-index-readers-database
GithubRepositoryReaderGitHub 仓库llama-index-readers-github
NotionPageReaderNotionllama-index-readers-notion
SlackReaderSlackllama-index-readers-slack
GoogleDocsReaderGoogle Docsllama-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 能理解的知识,剩下的就是提出好问题。

评论

加载中...

相关文章

分享:

评论

加载中...