跳转到内容

LlamaIndex:RAG 记忆分层

  • 说清 RAG 的心智模型:记忆 = 检索,而不是让模型硬记
  • 理解 Document → Node → Index → Retriever → QueryEngine 的分层
  • 用 5 行代码跑通「问自己的数据」,再把 RAG 变成 Agent 的工具

LlamaIndex 的核心模式是 RAG(检索增强生成):索引你的数据,只把相关的部分随查询一起发给 LLM。心智模型是「查档案」而不是「背课文」——文档先切片、建索引,查询时按需检索。

数据链路的分层是这样的:

数据源 → Document(文档) → Node(切块) → Index(索引) → Retriever(检索) → QueryEngine(问答) → (可选)Agent 把 QueryEngine 当工具

5 行代码跑通「问自己的数据」:

# 安装: pip install llama-index (设置 OPENAI_API_KEY;先 mkdir data 放几个 txt)
from llama_index.core import VectorStoreIndex, SimpleDirectoryReader
# 1) 把 data/ 文件夹里的文档读进来(每个文件变成一个 Document)
documents = SimpleDirectoryReader("data").load_data()
# 2) 建索引:文档被切块(Node)并向量化
index = VectorStoreIndex.from_documents(documents)
# 3) 得到「查询引擎」——检索 + 生成一条龙
query_engine = index.as_query_engine()
# 4) 问问题!引擎先检索相关片段,再交给 LLM 作答
response = query_engine.query("What did the author do in college?")
print(response)

再把 RAG 变成 Agent 的一个「工具」,让 Agent 自己决定什么时候查文档:

import asyncio
from llama_index.core import VectorStoreIndex, SimpleDirectoryReader
from llama_index.core.agent.workflow import FunctionAgent
from llama_index.llms.openai import OpenAI
documents = SimpleDirectoryReader("data").load_data()
index = VectorStoreIndex.from_documents(documents)
query_engine = index.as_query_engine()
def multiply(a: float, b: float) -> float:
"""Useful for multiplying two numbers."""
return a * b
async def search_documents(query: str) -> str:
"""Useful for answering natural language questions about the documents."""
response = await query_engine.aquery(query)
return str(response)
# FunctionAgent = 极简工具调用 Agent:工具列表里有「算数」和「查文档」
agent = FunctionAgent(
tools=[multiply, search_documents],
llm=OpenAI(model="gpt-4o-mini"),
system_prompt="You are a helpful assistant that can perform calculations "
"and search through documents to answer questions.",
)
async def main():
response = await agent.run(
"What did the author do in college? Also, what's 7 * 8?"
)
print(response)
if __name__ == "__main__":
asyncio.run(main())

几个新手常踩的坑:不建索引就查询(检索空转);把 retriever.retrieve() 当问答用(它只返回原文片段,QueryEngine 才返回答案);函数 docstring 不写清楚(Agent 靠函数名和 docstring 理解工具);每次运行都重建索引(官方推荐 storage_context.persist() 持久化)。

先自己回答,再看答案:

  1. 「记忆 = 检索」是什么意思?
  2. Retriever 和 QueryEngine 的区别是什么?
  3. 为什么索引的最小单位是 Node 而不是整篇文档?
参考答案
  1. 模型不硬记所有内容,而是把数据切片建索引,查询时只把相关的片段随问题一起发给 LLM。
  2. Retriever 只「取回原文片段」(调试检索质量用),QueryEngine 是「检索 + 生成」的完整问答接口。
  3. 整篇文档太长且大部分无关,切块后检索才能精确命中相关片段,控制发给 LLM 的上下文量。
  • RAG 链路:Document → Node → Index → Retriever → QueryEngine
  • query_engine.query() 是完整问答,retriever.retrieve() 只是中间一步
  • FunctionAgent 可以把 RAG 变成 Agent 的工具,让 Agent 自主决定何时查文档
LlamaIndex 小测
x
1 / 3

RAG 的核心心智模型是?