使用方法

什么是 LlamaIndex 以及它的核心设计

LlamaIndex(原名 GPT Index)是一个专门为大型语言模型(LLM)构建数据索引和检索的工具框架。它解决的问题很直接:LLM 本身没有长期记忆,也无法直接访问私有或实时数据。LlamaIndex 通过将你的数据(文档、数据库、API 返回值等)转化为索引结构,让 LLM 能够高效地检索并理解这些信息,从而实现问答、摘要、数据分析等场景。官方将这一过程称为“数据增强生成”(Data Augmented Generation)。

安装与基础环境配置

在开始之前,确保你的 Python 环境版本在 3.9 以上。使用 pip 安装 LlamaIndex 非常简单:pip install llama-index。这个命令会安装核心库以及默认的依赖项,包括 OpenAI 的 API 客户端(如果你打算使用 GPT 模型)。如果你希望使用其他模型(比如本地模型或 Anthropic、Cohere 等),需要额外安装对应的集成包。安装完成后,建议先设置 API 密钥。最常用的方式是将 OpenAI API Key 写入环境变量:export OPENAI_API_KEY="你的密钥"。如果你使用其他模型提供方,请参考官方文档设置相应的环境变量。

第一步:加载文档并构建索引

LlamaIndex 的核心工作流分为三步:加载、索引、查询。首先,你需要将数据加载到框架中。LlamaIndex 内置了多种数据加载器(称为 Reader),支持 PDF、TXT、CSV、Markdown、Notion、Google Docs 等常见格式。最简单的例子是加载一个文本文件:

from llama_index.core import SimpleDirectoryReader

documents = SimpleDirectoryReader("你的文件夹路径").load_data()

如果你的数据在数据库或 API 中,可以使用对应的 Reader,比如 DatabaseReaderNotionPageReader。加载完成后得到一组 Document 对象。接下来,将这些文档切分成更小的块(Chunks),因为 LLM 的上下文长度有限。LlamaIndex 默认使用基于词数(token)的分块策略,你也可以自定义分块大小和重叠量。然后,对这些文档块创建嵌入向量并构建索引:

from llama_index.core import VectorStoreIndex

index = VectorStoreIndex.from_documents(documents)

这一步会自动调用 LLM 的嵌入模型(默认是 OpenAI 的 text-embedding-ada-002)将每个文档块转化为向量,并存储到内存中的向量索引中。如果你想持久化索引,可以指定存储路径:

index.storage_context.persist(persist_dir="存储目录")

第二步:执行查询与检索

索引构建完成后,就可以用自然语言进行查询了。LlamaIndex 会将你的问题转换为向量,在索引中检索最相关的文档块,然后将这些块连同原始问题一起发送给 LLM 生成答案。创建查询引擎非常简单:

query_engine = index.as_query_engine()
response = query_engine.query("你的问题是什么?")
print(response)

默认情况下,检索策略是基于向量相似度的 top-k 检索。你可以调整参数,比如每次检索返回的文档块数量(similarity_top_k),或者切换到其他检索模式,比如关键词检索或混合检索。对于更复杂的场景,LlamaIndex 支持多种查询引擎类型,例如树索引(TreeIndex)适用于总结类问题,关键词表索引(KeywordTableIndex)适用于精确匹配。

进阶用法:自定义检索与合成策略

实际项目中,你往往需要微调检索和生成逻辑。LlamaIndex 的核心组件包括 Retriever(检索器)和 Synthesizer(合成器)。你可以分别定义它们,然后组合成更灵活的查询管道。例如,使用 VectorIndexRetriever 获取原始文档块,再通过 ResponseSynthesizer 指定是否要求 LLM 在生成答案时引用原文:

from llama_index.core import get_response_synthesizer
from llama_index.core.retrievers import VectorIndexRetriever
from llama_index.core.query_engine import RetrieverQueryEngine

retriever = VectorIndexRetriever(index=index, similarity_top_k=3)
synthesizer = get_response_synthesizer(response_mode="compact")
query_engine = RetrieverQueryEngine(retriever=retriever, response_synthesizer=synthesizer)

其中 response_mode 参数可选 compact(将检索结果压缩后发送)、refine(逐步优化答案)、tree_summarize(树状总结)等。这些模式直接影响回答质量和 token 消耗。

处理结构化与非结构化数据

LlamaIndex 不仅支持纯文本,还能处理表格、JSON、甚至是代码仓库。对于 CSV 或 Excel 文件,可以使用 PandasCSVReaderSimpleExcelReader 加载,框架会自动将每一行视为一个文档。对于 SQL 数据库,LlamaIndex 提供了 DatabaseReader,你可以直接写 SQL 查询,然后将结果作为上下文。最实用的场景之一是结合数据库和文档:先通过 SQL 查询获取最新的数据行,再结合说明文档让 LLM 给出综合回答。你只需要在构建索引时混合不同类型的 Document 即可,LlamaIndex 会自动处理异构数据。

选择不同的 LLM 与嵌入模型

不满足于默认的 OpenAI 模型?LlamaIndex 提供了完善的模型抽象层。你可以通过 Settings 全局配置来切换 LLM 和嵌入模型。例如,使用本地运行的开源模型(通过 Ollama 或 Hugging Face):

from llama_index.core import Settings
from llama_index.llms.ollama import Ollama
from llama_index.embeddings.huggingface import HuggingFaceEmbedding

Settings.llm = Ollama(model="llama3", request_timeout=60.0)
Settings.embed_model = HuggingFaceEmbedding(model_name="BAAI/bge-small-en-v1.5")

这样,后续所有索引构建和查询都会使用指定的模型。注意不同的嵌入模型对检索质量影响很大,建议根据你的语言和领域选择合适的中文嵌入模型,例如 shibing624/text2vec-base-chineseBAAI/bge-base-zh-v1.5。LlamaIndex 也支持多模态,但需要额外的集成包。

调试与观察:使用 Callback 和 Tracing

当查询结果不理想时,你需要了解内部流程。LlamaIndex 内置了观察(Observability)工具,可以记录每次查询的检索文档、LLM 调用次数、token 消耗等。你可以启用 SimplePromptTracker 或连接更强大的全家桶工具如 Langfuse、Weights & Biases。例如,在代码开头设置:

from llama_index.core import Settings
import llama_index.core.instrumentation as instrument

instrument.instrument(provider_name="简单输出")

默认会在控制台输出每个步骤的日志。如果你想更详细地查看检索到的文档块具体内容,可以在查询引擎中设置 verbose=True。这些工具对于调整分块大小、top-k 数量以及 prompt 模板非常有帮助。

常见问题与性能优化

使用过程中可能会遇到几个典型问题。第一,索引构建速度慢:如果文档量很大(超过几万页),建议使用批量嵌入或利用 GPU 加速。LlamaIndex 支持异步加载和嵌入,你也可以将文档分批次处理。第二,回答内容不准确:检查分块大小是否合适,过大的块会稀释关键信息,过小的块会丢失上下文。一般建议块大小在 512-1024 token 之间,重叠量 100-200 token。第三,内存占用过高:如果存储索引在内存中,可以考虑使用后备存储,例如 Chroma、Pinecone 或 Weaviate 作为向量数据库,LlamaIndex 原生支持这些集成。只需要在 from_documents 时指定 storage_context 并传入对应的向量存储即可。