本节摘要:LlamaIndex 的关键特性可以浓缩为六个核心抽象——数据连接器、文档/节点模型、索引、检索器、查询引擎/聊天引擎、智能体与工具。本节逐个说明每个抽象"解决了什么痛点",并用一段代码验证它们之间的咬合关系,为后续六章立好名词表。
读框架文档最痛的是名词风暴。LlamaIndex 的名词其实只有两层六个,理解它们的最好方式是问"没有它会怎样"。
连接器(Reader/Connector):没有它,每种数据源你都得手写解析——PDF 的表格、Notion 的分页、数据库的类型转换。连接器把"读取"统一成 load_data() 一个约定。生态里有上百个现成实现,覆盖 S3、Google Drive、网页、数据库等。
Document 与 Node:Document 是完整源文件的容器(正文 + 元数据),Node 是从 Document 切出的最小检索单元(一块文本 + 它的出身信息)。没有这层模型,"这块碎片来自哪个文件第几页"这类出处问题无从谈起。
Index(索引):把 Node 组织成可查询的结构——向量索引、树索引、知识图谱索引等。不同组织方式对应不同查询能力,第 3 章专门解剖。
Retriever(检索器):给定查询,从索引里取回候选节点。它是"召回质量"的直接负责人,可配置数量、相似度阈值、混合策略。
QueryEngine / ChatEngine:把检索器、后处理器、合成器装配成"一问一答"或"多轮对话"的成品接口。QueryEngine 无记忆,ChatEngine 带对话历史压缩。
Agent 与 Tool:让大模型自己决定调用哪个工具(某个查询引擎、某个函数)。静态管道变成动态决策,第 5 章的主角。
# 验证六个抽象的咬合:同一批数据,从连接器一路走到智能体 from llama_index.core import SimpleDirectoryReader, VectorStoreIndex from llama_index.core.tools import QueryEngineTool, ToolMetadata from llama_index.core.agent import ReActAgent # ①连接器:读入文档成为 Document docs = SimpleDirectoryReader(input_files=["handbook.pdf"]).load_data() print(type(docs[0]).__name__) # Document:正文+元数据容器 # ②③索引:内部已切分为 Node 并组织结构 index = VectorStoreIndex.from_documents(docs, show_progress=False) # ④检索器:独立可用的召回接口 retriever = index.as_retriever(retrieval_similarity_top_k=4) nodes = retriever.retrieve("年假天数规定") print(len(nodes), type(nodes[0]).__name__) # 4 NodeWithScore # ⑤查询引擎:装配后的成品 engine = index.as_query_engine(similarity_top_k=4) # ⑥把查询引擎包装成工具,交给智能体按需调用 tool = QueryEngineTool(query_engine=engine, metadata=ToolMetadata(name="hr_handbook", description="回答员工手册相关问题")) agent = ReActAgent.from_tools([tool], verbose=True) print(agent.chat("入职满三年的员工一年有几天年假?"))
这段代码的要点不是功能,而是层次感:每层都能单独拿出来用(检索器可以脱离查询引擎直接用),层与层之间靠接口咬合,这正是"可解剖"的前提。
数据连接器之广是有代价的:官方维护几十个,社区维护上百个,质量参差。工程上我更倾向:核心数据源用官方维护的连接器,长尾数据源宁可手写一个返回 Document 列表的函数(第 2 章 2.4 节展开)。
默认值偏"演示友好"而非"生产友好":默认分块 1024 token、默认召回 2 个节点、默认不重排——这些默认让你五分钟跑通,但生产中几乎都要改。这不是缺陷,是框架的立场:先让你看到全貌,再请你逐段调优。
两套引擎的分野:QueryEngine 是"一次性问答",每次调用互相独立;ChatEngine 维护对话记忆,会做历史压缩与条件化改写。新手常见错误是用 QueryEngine 循环拼接历史,重复 token 花双倍钱还容易超窗。
QueryEngine 和 ChatEngine 到底该用哪个? 一次性问答(文档查询、API 后端)用 QueryEngine,多轮对话(客服、助手)用 ChatEngine。最常见的错误是拿 QueryEngine 循环调用来模拟对话——每次都把历史手动拼进问题,token 翻倍且改写质量差。ChatEngine 的 condense 模式把"历史压缩成独立问题"这件事内建了。
Node 的 relationships 字段有什么实际用途? 它记录了每个节点的前驱、后继与来源文档。句子窗口检索靠它把"命中的句子"扩展成"句子加前后文";自动合并检索靠它把多个命中的小块换成父块。没有这层关系信息,这些进阶检索模式都无从实现——所以切分别只看文本,关系字段也是资产。
智能体和查询引擎能混用吗? 不仅能,而且是推荐做法:智能体把查询引擎当作一个工具来调用。第 5 章会看到,把多个领域的查询引擎注册成工具,智能体按问题分诊,比单一引擎硬扛所有问题更稳。