LlamaIndex:从文档索引到 RAG 应用的完整构建指南——基于官方 README 与 core 源码解读
【免费下载链接】llama_indexLlamaIndex is the leading document agent and OCR platform项目地址: https://gitcode.com/GitHub_Trending/ll/llama_index
本文以 LlamaIndex 根目录 README 为骨架,系统讲解这个开源 LLM 数据框架的两种安装方式(starter / customized)、基于命名空间的 import 规则、从零构建向量索引的完整代码路径(OpenAI 与 Ollama 本地模型两套示例)、索引持久化与加载,并深入 llama-index-core 源码印证Settings、from_documents、StorageContext等核心机制,读完即可独立搭好一个可查询、可落盘的 RAG 原型。
项目定位:数据框架 + 文档智能平台
README 开篇给出 LlamaIndex 的双线定位(见 README.md):
- LlamaIndex OSS:构建 agentic 应用的开源框架;
- Parse(LlamaParse):企业级文档智能平台,覆盖 agentic OCR 解析(支持 130+ 格式)、结构化抽取(Extract)、摄取与 RAG 管线(Index)、文档切分(Split)、以及基于 Workflows 与 Agent Builder 构建端到端文档 Agent(LlamaAgents)。
README 中 “Context / Proposed Solution” 一节阐明了框架的设计动机:LLM 预训练语料公开且固定,要把私有数据接入 LLM,需要一个覆盖“摄取—结构化—检索—集成”全链路的数据框架。LlamaIndex 提供四类能力:
- 数据连接器(data connectors):摄取 API、PDF、文档、SQL 等各类数据源与格式;
- 数据结构化:以索引(indices)、图(graphs)等形式组织数据;
- 高级检索/查询接口:输入任意 LLM prompt,返回检索上下文与知识增强输出;
- 外部框架集成:与 LangChain、Flask、Docker 等自由组合。
README 强调这是双轨 API 设计:高层 API 让初学者“5 行代码完成摄取与查询”,低层 API 允许高级用户替换 data connectors、indices、retrievers、query engines、reranking 等任意模块。
一个需要注意的提示:README 明确说明“本 README 更新频率低于官方文档”,最新的教程与参考请以官方文档站点为准(链接见 README.md)。
两种安装方式:starter 与 customized
LlamaIndex 的 Python 生态采用核心包 + 集成包的分层结构,README 给出两条起步路径:
| 方式 | 包 | 说明 |
|---|---|---|
| Starter | llama-index | 起步包,包含 LlamaIndex core 加一组精选集成 |
| Customized | llama-index-core+ 自选集成包 | 仅装核心,再从 300+ 个集成包中按需挑选 LLM、Embedding、向量库等提供商 |
README 的推荐示例是 customized 方式,只安装业务需要的集成(见 README.md):
# 按需选择与 core 配合的集成 pip install llama-index-core pip install llama-index-llms-openai pip install llama-index-llms-ollama pip install llama-index-embeddings-huggingface这些集成包在本仓库中均能对应到实际目录,例如 llama-index-llms-ollama、llama-index-embeddings-huggingface,全部位于llama-index-integrations/下按llms/、embeddings/、vector_stores/、readers/等类别组织的数百个独立包中。
运行环境方面,从 llama-index-core/pyproject.toml 可以确认:当前 core 版本为0.14.24,Python 要求>=3.10,<4.0,关键依赖包括pydantic>=2.8.0、tiktoken>=0.7.0、nltk>=3.9.3、networkx>=3.0、llama-index-workflows>=2.14.0等。
命名空间规则:import 语句里的 “core” 约定
这是使用 LlamaIndex 最容易踩坑的约定(README 原文见 README.md):import 路径中含core表示使用核心包,不含core表示使用集成包:
# 典型模式 from llama_index.core.xxx import ClassABC # core 的 xxx 子模块 from llama_index.xxx.yyy import ( SubclassABC, ) # xxx 子模块对应的 yyy 集成 # 具体示例 from llama_index.core.llms import LLM from llama_index.llms.openai import OpenAI这一点在源码中可以直接印证:llama_index/core/init.py 的__all__导出了VectorStoreIndex、SimpleDirectoryReader、Settings、StorageContext、load_index_from_storage等全部 README 示例用到的符号;而llama_index.llms.ollama、llama_index.embeddings.huggingface这类不含core的命名空间则分别由对应集成包提供。
快速上手:5 行代码构建向量索引(OpenAI 示例)
README 的第一个完整示例是构建一个基于 OpenAI 的简单向量存储索引(README.md):
import os os.environ["OPENAI_API_KEY"] = "YOUR_OPENAI_API_KEY" from llama_index.core import VectorStoreIndex, SimpleDirectoryReader documents = SimpleDirectoryReader("YOUR_DATA_DIRECTORY").load_data() index = VectorStoreIndex.from_documents(documents)三步分别对应框架的三大环节:
SimpleDirectoryReader(...).load_data():读取目录下的文件,产出Document对象列表(SimpleDirectoryReader定义于llama-index-core/llama_index/core/readers/,并由 core 顶层导出);VectorStoreIndex.from_documents(documents):对文档执行切分、向量化并建立向量索引;- 之后即可查询。
源码视角:from_documents到底做了什么?查看 indices/base.py 的BaseIndex.from_documents实现,完整流程是:
- 未指定
storage_context时使用StorageContext.from_defaults()——这就是 README 所说“默认数据保存在内存中”的由来; - 将每个文档的 hash 写入 docstore(
docstore.set_document_hash),用于后续增量更新去重; - 调用
run_transformations(documents, transformations, ...),其中transformations默认取Settings.transformations,默认即[Settings.node_parser](SentenceSplitter),完成 Document → Node 的切分; - 将得到的 nodes 传入索引构造函数,最终落到
build_index_from_nodes(对VectorStoreIndex即完成 embedding 与向量存储写入),并把index_struct登记进 index_store。
该构造函数还显式约束了新旧 API 的边界:如果误把Document列表直接传给nodes=参数会抛出ValueError,提示“请使用from_documents”(见 indices/base.py),避免旧版 API 误用。
本地模型方案:Ollama + HuggingFace Embedding
README 的第二个示例展示了如何把整个栈切换到非 OpenAI 提供商——用 Ollama 托管的 Llama 3.1 作为 LLM、HuggingFace 本地 embedding(README.md):
from llama_index.core import Settings, VectorStoreIndex, SimpleDirectoryReader from llama_index.embeddings.huggingface import HuggingFaceEmbedding from llama_index.llms.ollama import Ollama from transformers import AutoTokenizer # 设置 LLM Settings.llm = Ollama( model="llama-3.1:latest", request_timeout=360.0, ) # 设置 tokenizer,与 LLM 保持一致 Settings.tokenizer = AutoTokenizer.from_pretrained( "meta-llama/Llama-3.1-8B-Instruct" ) # 设置 embedding 模型 Settings.embed_model = HuggingFaceEmbedding( model_name="BAAI/bge-small-en-v1.5" ) documents = SimpleDirectoryReader("YOUR_DATA_DIRECTORY").load_data() index = VectorStoreIndex.from_documents(documents)Settings的机制值得深入理解,它是整个框架的“全局配置单例”。查看 settings.py:
Settings是_Settingsdataclass 的单例(Settings = _Settings()),所有字段延迟初始化:llm、embed_model、node_parser、prompt_helper、transformations等首次访问时才解析;- 惰性解析:
llm属性未设置时调用resolve_llm("default")按默认规则选择(如依据环境变量推断 OpenAI),embed_model同理走resolve_embed_model(见 settings.py);显式赋值后则立即通过 setter 固化实例; - tokenizer 特判:
Settings.tokenizer的 setter 会检测传入对象是否为PreTrainedTokenizerBase(transformers 类型),若是则自动包装成partial(tokenizer.encode, add_special_tokens=False)再全局注册(见 settings.py)——这解释了 README 示例中直接传AutoTokenizer实例即可工作的原因; - node_parser 默认值:
node_parser未设置时默认SentenceSplitter(),chunk_size/chunk_overlap属性会透传到当前 node parser(见 settings.py),因此调分块大小可以直接写Settings.chunk_size = 512。
prompt_helper与chat_prompt_helper还会依据已配置 LLM 的 metadata(上下文窗口等)自动构建,从而保证 prompt 组装不超出模型上下文预算。
为什么示例要显式设置 tokenizer?
示例中“set tokenizer to match LLM”一行是关键实践:索引构建、token 预算估算(PromptHelper)依赖 tokenizer 计算 token 数。若使用 Ollama 的 Llama 3.1,就用 Llama 3.1 的 tokenizer;用 OpenAI 模型时 core 会默认使用 tiktoken。README 的注释“set tokenizer to match LLM”即提醒保持三者(LLM、tokenizer、embedding)相互匹配。
查询与持久化:内存、落盘、重载
构建索引后即可得到查询引擎并发起提问(README.md):
query_engine = index.as_query_engine() query_engine.query("YOUR_QUESTION")as_query_engine定义于 indices/base.py,它内部组装 retriever + response synthesizer 形成标准 RAG 查询链路,支持传入llm等参数覆盖默认。
持久化到磁盘。默认数据保存在内存,调用persist()将存储上下文写入./storage(README.md):
index.storage_context.persist()StorageContext聚合了 docstore、index_store、vector_store、graph_store 四类存储(见 core 顶层导出),其from_defaults(persist_dir=...)与persist()实现在 storage/storage_context.py。
从磁盘重载。不重新建索引,直接恢复(README.md):
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)load_index_from_storage同样由 core 顶层导出(见 core 顶层导出),重载后可直接as_query_engine()继续查询,避免了重复执行切分与向量化。
构建资产验证:_static目录与 GitHub Attestation
README 中一个较少被注意但很实用的部分是Build Assets 验证(README.md):llama-index-core自带一个_static目录,内置 nltk 与 tiktoken 的缓存文件,使包在安装后即可在运行时磁盘权限受限的环境中直接运行(无需联网下载语料)。构建时通过attest-build-provenanceaction 校验 wheel 内_static与仓库llama-index-core/llama_index/core/_static内容一致。这一打包策略可在 pyproject.toml 的 hatch 构建配置中印证:sdist 与 wheel 均显式包含nltk_cache/corpora/stopwords/**、nltk_cache/tokenizers/punkt_tab/**、tiktoken_cache/**。
用户侧可用如下脚本(指向已安装包路径)逐文件校验构建溯源(README 原文脚本):
#!/bin/bash STATIC_DIR="venv/lib/python3.13/site-packages/llama_index/core/_static" REPO="run-llama/llama_index" find "$STATIC_DIR" -type f | while read -r file; do echo "Verifying: $file" gh attestation verify "$file" -R "$REPO" || echo "Failed to verify: $file" done示例、文档与社区资源
- 更多可运行示例位于
docs/examples目录(按 agent、ingestion、vector_stores、workflow 等主题组织的数百个 notebook,README 中 Example Usage 一节 指向该目录); - 官方完整文档(教程、How-to、API 参考)链接见 README.md,README 特别注明文档更新比本文件更及时;
- 贡献入口为 CONTRIBUTING.md:README 说明 core 与集成两条线的贡献均被接受,但新集成必须“meaningfully integrate with existing framework components”,维护者保留拒绝权(见 README.md);
- 社区渠道包括 Discord、Reddit、X/LinkedIn,入口集中在 README.md 的 Important Links 一节。
引用(Citation)
若在论文中使用 LlamaIndex,README 提供的引用条目为(README.md):
@software{Liu_LlamaIndex_2022, author = {Liu, Jerry}, doi = {10.5281/zenodo.1234}, month = {11}, title = {{LlamaIndex}}, url = {https://github.com/jerryjliu/llama_index}, year = {2022} }小结:一条可复现的落地路径
结合 README 与 core 源码,LlamaIndex 的入门路径可以归纳为:
- 选安装方式:快速试用装
llama-indexstarter;生产按需装llama-index-core+ 少量集成包(llms/、embeddings/、vector_stores/各一); - 遵守命名空间约定:
llama_index.core.*走核心,llama_index.<category>.<provider>走集成; - 用
Settings统一配置:Settings.llm/Settings.embed_model/Settings.tokenizer(及可选的Settings.chunk_size),所有惰性默认值与解析逻辑见 settings.py; - 三行建索引:
SimpleDirectoryReader().load_data()→VectorStoreIndex.from_documents()(内部为“hash 登记 → transformations 切分 → 建索引”,见 indices/base.py); - 查询与持久化:
as_query_engine().query(...),需要落盘时index.storage_context.persist(),恢复时用StorageContext.from_defaults(persist_dir="./storage")+load_index_from_storage。
这条路径全部基于当前仓库 core 0.14.24 版本的实际代码结构,可直接在本地环境复现验证。
【免费下载链接】llama_indexLlamaIndex is the leading document agent and OCR platform项目地址: https://gitcode.com/GitHub_Trending/ll/llama_index
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考