进阶 11 分钟Stack

LlamaIndex 在 pratique

直接回答

LlamaIndex 是一个 Python 框架,可管理 RAG 的完整流程:文档加载、分块、嵌入、索引以及带来源的查询。本地使用时,它可以连接 Ollama 和 BGE-M3 等嵌入模型,但默认设置会调用 OpenAI:请在建立索引前设置 Settings.llm 和 Settings.embed_model,并配置 context_window 和 request_timeout。

LlamaIndex 只需几行代码就能搭建 RAG,但其默认设置(OpenAI、上下文窗口、30 秒超时)会让本地部署踩坑,而且旧版智能体教程已无法使用。您将学会搭建完全本地运行的处理流程,选择查询模式,添加重排序器,并使用当前 API 编写智能体。

作者: Mohamed Meguedmi·更新于 2026-09-30·已在 Windows、macOS 和 Linux 上测试

#LlamaIndex 实践指南:它有什么作用,何时使用

LlamaIndex 是一个 Python 框架,支持 RAG 的完整流程:加载文档、将其切分为块(nodes)、转换为向量、建立索引,再通过会引用来源的 LLM 查询索引。0.14.25 版本于 2026 年 9 月 21 日发布在 PyPI 上,要求 Python 3.10 或更高版本。一个最简 RAG 用十行左右的代码就能实现;当需要使用不同的数据源、切换回答模式、添加重排序器或接入智能体时,这个框架就能体现出价值。在本地运行时,它可以使用 Ollama 提供 LLM,并搭配您选择的嵌入模型,前提是关闭会调用 OpenAI 的默认设置。本指南将搭建一个完全在本地运行的 RAG,介绍关键设置,并修正网上仍然存在的多个过时示例。

清晰的抽象设计
Document、Node、VectorStoreIndex、检索器、查询引擎:RAG 的每个步骤都有一个专用且可替换的对象。
数据连接器
SimpleDirectoryReader 可读取 PDF、Word、PowerPoint、Markdown、图片或音频;其他读取器支持 Notion、Google Docs、Slack 或 Discord。
查询模式
多种答案综合策略,以及更复杂的引擎(子问题、索引间路由),让查询不再局限于简单的向量检索。
本地可用
Ollama,以及 Hugging Face 或 Ollama 提供的嵌入功能,都可以通过专用集成包接入。

#LlamaIndex RAG的各步骤及其默认设置

本地 RAG 套件

你的文档,你的 AI:基于你的 PDF、笔记和邮件的可靠本地 RAG——无需向云端发送任何内容。

  • 在线空间,终身可用
  • PDF + 文件
  • 终身更新

在编写代码之前,请先了解这条处理流程,尤其是它的默认值:本地运行时,大多数意外情况就隐藏在这些地方。

LlamaIndex 流水线:对象与默认值
步骤对象或设置需了解的默认值
分段处理SentenceSplitter, Settings.chunk_size块大小为 1024 个 token,重叠部分为 20 个 token
EmbeddingsSettings.embed_modelOpenAI的text-embedding-ada-002,根据文档信息
LLMSettings.llmOpenAI的gpt-3.5-turbo,根据入门教程
存储VectorStoreIndex, StorageContext在内存中;需显式持久化到磁盘
综合生成response_modecompact:在上下文窗口允许的范围内拼接尽可能多的文本块
LLM Ollamarequest_timeout默认为 30 秒,本地运行时通常太短
!
未进行配置时,LlamaIndex 会调用 OpenAI
文档明确指出,LlamaIndex 默认使用 OpenAI API 来调用 LLM 和生成嵌入向量。如果环境中存在 OPENAI_API_KEY 密钥,您的文档就会被发送到 OpenAI 进行向量化,且不会出现警告提示。对于需要保密的 RAG,请务必在建立索引前设置 Settings.llm 和 Settings.embed_model,具体做法见下一节。

#100% 本地 RAG:安装

命令 pip install llama-index 会安装一组入门软件包,其中包含 llama-index-core、用于 LLM 和嵌入的 OpenAI 集成,以及文件读取器。若要使用本地模型,请另外安装 Ollama 和嵌入集成(如果您更喜欢 OllamaEmbedding,可安装 llama-index-embeddings-ollama);入门软件包中的 OpenAI 包仍会保留,但只要配置好 Settings,就不会被使用。

终端
pip install llama-index \
            llama-index-llms-ollama \
            llama-index-embeddings-huggingface

ollama pull mistral

包名可以指示导入路径:llama-index-llms-ollama 对应 llama_index.llms.ollama。计算内存需求时,需要计入 LLM 权重(7–8B 模型采用 Q4 量化时约为 5 GB,这是本站提供的参考值)、嵌入模型和上下文:配备 16 GB 内存的电脑适合小型语料库,更多内存则能提供更充裕的余量。

#十行代码实现 RAG(检索增强生成)(使用其默认的 OpenAI 设置)

Python
from llama_index.core import VectorStoreIndex, SimpleDirectoryReader

docs = SimpleDirectoryReader("./docs").load_data()
index = VectorStoreIndex.from_documents(docs)

query = index.as_query_engine()
print(query.query("Résume les points clés du contrat X"))

这段代码有效,但使用的是 OpenAI 的默认模型:没有密钥时会运行失败,有密钥时则会将您的文本发送给服务提供商。它是一个代码框架。下一节会添加几行代码,使其能够在本地运行。

#切换至本地运行,使用 Ollama 和法语嵌入向量

仅需三个配置模块:语言模型(LLM)、嵌入模型和分块处理。对于法语场景,BGE-M3 是常见选择:其文档显示支持超过100种语言,最大输入长度可达8192个token。模型文件大小约为2.3 GB(Hugging Face仓库中的pytorch_model.bin文件),仅需下载一次。

Python
from llama_index.core import VectorStoreIndex, SimpleDirectoryReader, Settings
from llama_index.llms.ollama import Ollama
from llama_index.embeddings.huggingface import HuggingFaceEmbedding

# Configuration globale : tout est local
Settings.llm = Ollama(
    model="mistral",
    base_url="http://localhost:11434",
    request_timeout=120.0,   # le défaut est de 30 s
    context_window=8000,     # transmis à Ollama comme num_ctx
)
Settings.embed_model = HuggingFaceEmbedding(model_name="BAAI/bge-m3")
Settings.chunk_size = 700
Settings.chunk_overlap = 100

# Pipeline
docs = SimpleDirectoryReader("./docs").load_data()
index = VectorStoreIndex.from_documents(docs, show_progress=True)

# Persister sur disque
index.storage_context.persist(persist_dir="./storage")

# Requêter
query_engine = index.as_query_engine(similarity_top_k=5)
reponse = query_engine.query("Quels sont les risques identifiés ?")
print(reponse)
for src in reponse.source_nodes:
    print(f"  - {src.metadata.get('file_name')} ({src.score:.2f})")
Python
from llama_index.core import load_index_from_storage, StorageContext

storage = StorageContext.from_defaults(persist_dir="./storage")
index = load_index_from_storage(storage)

#context_window 和 request_timeout 为何需要考虑

LlamaIndex 的 Ollama 集成源码会将 context_window 的值以 num_ctx 的名称传给 Ollama。否则,Ollama 会使用默认上下文窗口;根据其文档,显存低于 24 GiB 时,默认窗口约为 4 000 个 token。计算很简单:五段各含 700 个 token 的文本合计 3 500 个 token,这还没有算上问题、提示词模板中的指令以及回答。窗口为 4 000 个 token 时,提示词会超出容量,上下文会被截断,而且往往没有明显的错误提示。窗口为 8 000 个 token 时,就有余量了。

超时时间是另一个容易踩的坑:LlamaIndex 的 Ollama 客户端默认设为 30 秒。首次调用需要将模型加载到内存并处理较长的提示词,可能会超过这个时限。示例中的 120 秒只是一个起点,需要根据您的硬件调整。

→
通过 Ollama 实现嵌入向量,而非 Hugging Face
如果您不想为了生成嵌入向量而安装 PyTorch,LlamaIndex 提供了 OllamaEmbedding:它使用已经启动的 Ollama 服务器,嵌入模型通过 ollama pull 下载。Ollama 模型库提供 bge-m3。更换嵌入模型后,必须重新为所有文档建立索引,因为两个不同模型生成的向量无法直接比较。

#加载文件:SimpleDirectoryReader设置

SimpleDirectoryReader可读取整个文件夹,并支持多种格式:PDF、Word、PowerPoint、Markdown、图片、音频和视频。通过一些参数可避免索引无关内容。

Python
from llama_index.core import SimpleDirectoryReader

docs = SimpleDirectoryReader(
    input_dir="./docs",
    required_exts=[".pdf", ".docx"],  # ne charger que ces formats
    num_files_limit=100,              # plafond pour un premier essai
).load_data()

连接 Notion、Google Docs、Slack、Discord 等服务的连接器会在线获取数据:这是不可避免的,因为数据就存储在那里。文档加载后,索引和查询仍在本地进行,使用您的嵌入向量和通过 Ollama 运行的 LLM。先用几个文件做一次测试:没有文本层的扫描 PDF 在经过 OCR 处理之前无法提供可用内容,具体如 Tesseract 指南所述。

#选择请求模式及其LLM调用成本

综合生成模式决定 LLM 的调用次数,进而决定本地响应时间。表格列出了文档中介绍的模式及其成本,并以五个各含 700 个 token 的文本片段和一个 8 000 token 的上下文窗口为例进行估算。

响应模式及对 LLM 的调用次数
模式原理(文档)示例中的调用
compact(默认)将窗口允许的尽可能多的块进行拼接后进行查询1 次调用:3,500 个 token 可容纳在 8,000 个 token 的窗口内
refine逐块遍历,每块调用一次连续5次调用
tree_summarize分组提问,然后递归汇总回答如果所有内容都能容纳在上下文窗口内,则调用 1 次;否则调用多次,最后生成摘要
simple_summarize为适应单个提示的长度,一律截断内容1次调用,细节丢失
no_text仅执行检索器,不调用LLM0 次调用;适用于调试搜索流程

对于事实性问题,保留 compact 模式。要总结长文档,可使用专为此设计的 tree_summarize,但代价是需要多次调用:在本地机器上,应预留简单回答所需时间的数倍。no_text 很适合用来检查检索返回的内容,无需等待 LLM。

#添加本地重排序器

当正确答案位于前 20 个段落中但不在前 5 个段落时,重排序器(reranker)会在发送给 LLM 之前对候选段落进行重新排序。LlamaIndex 文档建议,在无 API 密钥且本地执行的情况下,默认使用 SentenceTransformerRerank,这是一种基于 sentence-transformers 的交叉编码器,并提及 Qwen3-Reranker-0.6B 可提升多语言质量。

Python
from llama_index.core.postprocessor import SentenceTransformerRerank

reranker = SentenceTransformerRerank(
    model="cross-encoder/ms-marco-MiniLM-L2-v2",
    top_n=3,
)
query_engine = index.as_query_engine(
    similarity_top_k=15,             # large pour rattraper la bonne réponse
    node_postprocessors=[reranker],  # puis resserre à 3
)

这里给出的模型来自官方示例,因速度快而被选用;它是为英语设计的:对于法语文档,请测试多语言重排序模型。专题指南详细介绍了如何选择和评估。

#子问题与路由

SubQuestionQueryEngine
将复杂问题分解为多个子问题,分别发送至检索工具,再进行综合整合。例如,‘比较 2024 和 2025 年的策略’将被拆解为两次独立检索。
RouterQueryEngine
为每个问题从多个引擎中选择最合适的(例如摘要索引或向量索引)。

这两个引擎会增加对 LLM 的调用次数:将问题分解为三个子问题,需要生成子问题、分别回答三个子问题,再进行最终综合,至少需要五次调用。在本地硬件上,只将它们用于确有必要的问题。

#智能体:当前 API 已不同于旧教程中的 API

许多教程使用 ReActAgent.from_tools。这个类在当前源码中已不存在:曾包含它的 agent/react/base.py 模块已从仓库中移除。如今,智能体采用异步工作流:FunctionAgent(调用函数或工具的智能体)、工作流版本的 ReActAgent,以及用于编排多个智能体的 AgentWorkflow。官方的本地运行教程使用 AgentWorkflow.from_tools_or_functions 构建智能体,并通过 await agent.run 执行。

Python
import asyncio
from llama_index.core import Settings
from llama_index.core.agent.workflow import AgentWorkflow

async def search_documents(query: str) -> str:
    """Répond aux questions sur les contrats clients."""
    response = await query_engine.aquery(query)
    return str(response)

agent = AgentWorkflow.from_tools_or_functions(
    [search_documents],
    llm=Settings.llm,
    system_prompt="Tu réponds uniquement à partir des contrats indexés.",
)

async def main():
    reponse = await agent.run("Y a-t-il une clause de non-concurrence chez Acme Corp ?")
    print(str(reponse))

asyncio.run(main())

函数的名称、描述和参数(其文档字符串)会传递给 LLM,由它决定是否调用该函数,因此请认真撰写描述。FunctionAgent 的运行依赖原生函数调用;使用本地模型时,请选择在 Ollama 中支持工具调用的模型。如果您的模型不具备这种能力,就保持 RAG 流程简单。

#LlamaIndex、LangChain 或自研RAG:如何选择

本地RAG的三种方法
标准自建 RAG(ChromaDB,嵌入向量)LlamaIndexLangChain
主要目标理解每个步骤,拥有完全控制权采用现成组件的文档处理流水线工具与智能体的编排
搭建所需时间耗时更长:所有内容都要自己编写适用于初次RAG的简短版本单链路较短,完整RAG链路较长
个性化无限制,费用由您承担模块化设置,可替换对象非常灵活,但输出较为冗长
主要风险重新从头实现已有的处理流程OpenAI 的缺陷,API 更新迅速API 更新迅速

经验法则:使用 LlamaIndex,可以快速构建一个引用来源、支持多种格式并提供少量查询选项的文档 RAG 系统。如果您想先理解其工作机制,可以亲自编写一次自己的实现:ChromaDB 指南展示了各个步骤。对于需要调用众多外部工具的智能体,可以根据您的使用习惯比较 LangChain 和 LlamaIndex 的工作流。

#会耗费时间的陷阱

每次运行时重新索引
未启用持久化时,索引仅存在于内存中,脚本关闭后即消失。请启用持久化,然后通过 load_index_from_storage 加载索引。
不重新索引就切换模型
不同嵌入模型生成的向量不能相互比较:修改 embed_model 或文本切分方式,都必须重建索引。
上下文静默截断
提示词长度超过 Ollama 的上下文窗口时会被截断:如果回复忽略了末尾的内容,请检查 context_window。
复制旧教程
智能体 API 已发生变化:请检查示例中导入的模块或对象是否存在于已安装的版本中(撰写时版本为 0.14.25)。
从不评估
不做评估,RAG 就会在您不知情的情况下逐渐偏离:Ragas 指南介绍了如何对此进行量化。
FAQ
LlamaIndex 是否完全本地运行?+
可以,前提是在建立索引之前设置 Settings.llm(例如 Ollama)和 Settings.embed_model(Hugging Face 或 Ollama)。否则,文档指出,LlamaIndex 默认使用 OpenAI 的模型。只有连接 Notion、Slack 等在线服务的连接器,才必然需要访问本机之外的服务来获取数据。
为法语文档选择何种嵌入模型?+
BGE-M3 是一个常见选择:其模型说明宣称支持超过 100 种语言,输入长度可达 8 192 个 token,下载大小约为 2.3 GB。具体表现因您的文档而异:先用您自己的问题进行测试,再推广使用,并参阅法语嵌入模型指南,比较其他方案。
为什么我的 LlamaIndex RAG 会遗漏某些段落?+
通常是因为上下文被截断:显存低于24 GiB时,Ollama默认使用约4,000个token的上下文窗口,而五个各含700个token的片段就已占用3,500个token。请在Ollama对象中设置context_window,必要时增加可用内存,或降低similarity_top_k。
如何避免每次启动都重新索引?+
通过 index.storage_context.persist(persist_dir="./storage") 保存索引,然后使用 StorageContext.from_defaults 和 load_index_from_storage 重新加载。默认情况下,LlamaIndex 会将数据保留在内存中,脚本关闭后数据将丢失。若更换嵌入模型或分块大小,计算出的向量会发生变化,此时需重新构建索引并再次保存。
ReActAgent.from_tools已失效,该如何处理?+
旧教程中的这个 API 已不再出现在当前源码中。请使用工作流智能体:AgentWorkflow.from_tools_or_functions 或 FunctionAgent,配合异步函数和 await agent.run。请确认您的 Ollama 模型支持工具调用;否则,请保留不使用智能体的简单 RAG 方案,或尝试 ReActAgent 工作流,它不要求模型原生支持函数调用。
本地 RAG 应该选择 LlamaIndex 还是 LangChain?+
LlamaIndex 专注于数据和 RAG:加载、索引、查询模式。LangChain 则侧重于工具和智能体的编排。如果要与文档对话,使用 LlamaIndex 能更快上手;如果要构建使用多种工具的智能体,请在实际案例中比较两者,并选择您掌握其 API 的那个。
这份指南对您有帮助吗?

有反馈、发现了错误,或想补充说明?请告诉我们,让这份指南对每个人都更有帮助。