跳到主要内容

LlamaIndex — 架构与原理

30 秒导读: LlamaIndex 是一个「数据框架」,帮你把私有数据(PDF、网页、SQL……)接到 LLM 上做问答。核心是一条流水线:把文档切成带关系的小块(Node),灌进索引/向量库;查询时先检索出相关 Node,再让 LLM 在有限的上下文窗口内把它们合成成答案。本文按「数据砖 → 灌库 → 检索 → 合成」四步,带你读透 llama-index-core 的真实源码。

1. 这是什么(零基础也能懂)

  • 一句话定义: LlamaIndex 是 RAG(Retrieval-Augmented Generation,检索增强生成)框架——让 LLM 「带着你的资料」回答问题,而不是只靠它预训练时记住的东西。

  • 解决什么问题 / 给谁用: 假设你有一堆公司内部文档,想做个「问它任何问题、它从文档里找答案」的机器人。直接把全部文档塞进 LLM 不现实(上下文窗口装不下、也贵)。LlamaIndex 帮你:把文档切块、建索引、查询时只捞最相关的几块、再让 LLM 据此作答。给 RAG 应用开发者用。

  • 它能做什么(功能):

    • 读入 300+ 种数据源(connectors / readers)。
    • 把文档切成块、抽元数据、算嵌入(ingestion)。
    • 多种索引:向量索引、关键词表、树、知识图谱 / 属性图。
    • 多种检索 + 重排 + 多路融合。
    • 多种答案合成策略(refine / tree summarize / compact……)。
    • 之上还能搭 chat engine、agent、workflow。
  • 用起来什么样: 经典「5 行代码」:

# 示意,非源码(贴近 README 的标准用法)
from llama_index.core import VectorStoreIndex, SimpleDirectoryReader

docs = SimpleDirectoryReader("data").load_data() # 1) 读文档
index = VectorStoreIndex.from_documents(docs) # 2) 切块+嵌入+建索引
qe = index.as_query_engine() # 3) 变成问答引擎
print(qe.query("作者上大学前做了什么?")) # 4) 提问 → 检索 → 合成答案
  • 一句话直觉 / 类比: 把它想成图书馆 + 研究助理。建索引 = 把书拆成卡片、按内容贴上「相似度坐标」归档;查询 = 助理先按主题抽出最相关的几张卡片(检索),再读着卡片给你写一段答案(合成)。LLM 只是那个「会读卡片写答案」的助理,真正的知识在卡片(Node)里。

2. 顶层全景(它大概怎么转)

RAG 分两个阶段:离线灌库(把数据变成可检索的 Node)和 在线查询(检索 + 合成)。一张图看全:

离线:灌库(index time)
Documents ──切块/抽元数据/嵌入──▶ Nodes ──存──▶ ┌─ vector store(向量+文本)
(Reader) (transformations) ├─ docstore(Node 正本)
└─ index_store(索引结构)

在线:查询(query time)
query ─▶ Retriever ─▶ NodeWithScore[] ─▶ NodePostprocessor ─▶ ResponseSynthesizer ─▶ Response
(向量召回) (带分数的Node) (重排/过滤,可选) (refine/tree…喂给LLM)

主要部件一句话职责:

部件干什么在哪个文件(符号)
Document / Node数据的「砖」:一段文本 + 元数据 + 关系 + 嵌入schema.py(BaseNode/TextNode/Document)
TransformComponent对一批 Node 做一步变换(切块、抽元数据、嵌入)schema.py(TransformComponent)
IngestionPipeline串起若干 transformation + 去重 + 缓存ingestion/pipeline.py(IngestionPipeline)
BaseIndex索引基类:from_documents / as_query_engine / insertindices/base.py(BaseIndex)
VectorStoreIndex最常用索引:把 Node 嵌入后存进向量库indices/vector_store/base.py(VectorStoreIndex)
BaseRetriever给 query 召回一批 NodeWithScorebase/base_retriever.py(BaseRetriever)
RetrieverQueryEngine把「检索 → 后处理 → 合成」编排成一次 query()query_engine/retriever_query_engine.py
BaseSynthesizer把召回的 Node 文本喂给 LLM 生成答案response_synthesizers/base.py
PromptHelper算 token 预算、repack/truncate 文本块indices/prompt_helper.py(PromptHelper)
StorageContext三件套存储:docstore + index_store + vector_storestorage/storage_context.py
Settings全局默认(llm / embed_model / node_parser…)settings.py(_Settings)

主线走一遍(高层):

  1. 灌库:VectorStoreIndex.from_documents(docs) → 跑 run_transformations(默认 SentenceSplitter + embed_model)把 Document 切成带嵌入的 Node → 存进 vector store(文本随之存),Node 关系/正本视情况存进 docstore(indices/base.py:111-129indices/vector_store/base.py:286-309)。

  2. 查询:index.as_query_engine().query(q)

    • as_query_engine 把 retriever 包进 RetrieverQueryEngine(indices/base.py:491-516);
    • _queryretrieve(q) 召回 Node、过 postprocessor,再 synthesize 让 LLM 作答(query_engine/retriever_query_engine.py:202-215)。
  3. 检索内部:VectorIndexRetriever 把 query 嵌入 → 查向量库拿 top-k → 必要时回 docstore 取正本 → 返回 NodeWithScore(indices/vector_store/retrievers/retriever.py:227-246)。

  4. 合成内部:Refine/CompactAndRefine/TreeSummarize 先用 PromptHelper.repack 把多块文本塞满上下文窗口,再决定调几次 LLM(response_synthesizers/*)。

3. 怎么读这套文档

这是个大项目,本套文档拆成 4 章,建议按顺序读(每章都先点题、配图、给例,再上源码引用):

  1. 01 数据模型 — 先认识那块到处流动的「砖」:Node / Document、关系图、嵌入、MetadataMode。这是后面所有章节的基础词汇。
  2. 02 灌库与切块 — 文档怎么变成 Node:SentenceSplitter 的递归切分、IngestionPipeline 的转换链 + 缓存 + 去重(upsert/dedup)。
  3. 03 检索 — 查询期怎么召回:向量检索、docstore 回填、递归检索(IndexNode)、多路融合(RRF)。
  4. 04 合成 — 召回之后怎么让 LLM 作答:PromptHelper 的 token 预算、repack、refine / tree_summarize / compact 等模式取舍。

4. 边界与定位(诚实)

  • 本套文档聚焦 llama-index-core 的 RAG 主干(area = rag-context):数据模型 + 灌库 + 检索 + 合成。llama-index-integrations/ 下 300+ 集成(各家 LLM / 向量库 / reader)、chat engine、agent/workflow、LlamaParse 云平台不在本套深入范围,仅在相关处点到。
  • 全部引用 as-of commit 5891d5f4f3e934973c18334902ca8ea4eb6a2e12

5. 代码地图(导航索引)

主题文件关键符号
数据砖 / 关系 / 元数据llama-index-core/llama_index/core/schema.pyBaseNode, TextNode, Document, NodeRelationship, MetadataMode, NodeWithScore
索引基类 / 入口llama-index-core/llama_index/core/indices/base.pyBaseIndex.from_documents, as_query_engine, insert
向量索引llama-index-core/llama_index/core/indices/vector_store/base.pyVectorStoreIndex, _add_nodes_to_index
灌库流水线llama-index-core/llama_index/core/ingestion/pipeline.pyIngestionPipeline, run_transformations, DocstoreStrategy
切块llama-index-core/llama_index/core/node_parser/text/sentence.pySentenceSplitter._split, _merge
检索基类llama-index-core/llama_index/core/base/base_retriever.pyBaseRetriever.retrieve, _handle_recursive_retrieval
向量检索llama-index-core/llama_index/core/indices/vector_store/retrievers/retriever.pyVectorIndexRetriever._get_nodes_with_embeddings
多路融合llama-index-core/llama_index/core/retrievers/fusion_retriever.pyQueryFusionRetriever._reciprocal_rerank_fusion
查询引擎编排llama-index-core/llama_index/core/query_engine/retriever_query_engine.pyRetrieverQueryEngine._query
合成llama-index-core/llama_index/core/response_synthesizers/Refine, CompactAndRefine, TreeSummarize, get_response_synthesizer
token 预算llama-index-core/llama_index/core/indices/prompt_helper.pyPromptHelper.repack, truncate, _get_available_chunk_size