LlamaIndex 学习笔记

LlamaIndex (原名 GPT Index) 学习笔记

文档版本: 2025年6月


1. 什么是 LlamaIndex?

LlamaIndex (原名 GPT Index) 是一个数据框架 (Data Framework) ,旨在帮助开发者构建基于大型语言模型 (LLM) 的应用程序,特别是那些需要处理私有、专有或领域特定数据的应用程序。

核心问题:虽然 LLM 在通用领域展现了强大的能力,但它们通常无法直接访问最新的、内部的或特定领域的数据。当用户的问题涉及这些外部知识时,LLM 会因为训练数据的限制而"幻觉"(hallucinate)或给出错误答案。

LlamaIndex 的解决方案:

LlamaIndex 提供了一套工具,使得 LLM 能够 摄取 (ingest)、索引 (index) 和检索 (retrieve) 各种数据源,然后将这些数据注入到 LLM 的上下文中,从而使其能够基于这些外部知识进行回答。

关键理念:LlamaIndex 的核心在于连接你的数据和 LLM。它将你的非结构化数据(如文档、PDF、数据库记录)转化为 LLM 可以理解并利用的结构化表示,实现 LLM 的知识增强 (Knowledge Augmentation)。

2. LlamaIndex 的核心概念与工作流程

处理流程

  1. 文档预处理阶段

    • 支持多种格式文档加载(PDF/Word/Markdown等)
    • 使用专用解析器提取结构化内容
    • 创建带有元数据的文档节点
    • 采用多种分块策略处理长文本
  2. 索引构建阶段

    • 使用嵌入模型生成向量表示
    • 构建多种索引类型:
      • 向量索引(稠密检索)
      • 关键词索引(稀疏检索)
      • 知识图谱索引(关系检索)
      • 组合索引(混合检索)
  3. 查询处理阶段

    • 查询解析和意图识别
    • 多策略检索:
      • 向量相似度搜索
      • 关键词匹配
      • 混合检索策略
    • 节点后处理(排序/过滤)
  4. 响应生成阶段

    • 多种结果合成模式:
      • 紧凑模式(节省token)
      • 树状汇总(层次化处理)
      • 渐进式摘要(流式生成)
    • 支持不同LLM后端
  5. 优化闭环

    • 持续评估检索效果
    • 动态调整索引参数
  • 支持在线更新索引
    S5: 持续评估与优化 S4: 答案合成策略 S3: 查询理解与检索 S2: 索引类型与结构 S1: 数据预处理与加载 持续改进 支持格式 解析器 策略 模型 NLP处理 策略选择 模式 LLM 命中率分析 评估反馈 相关性评分 调整分块策略 索引优化 更新嵌入模型 索引结构调整 紧凑模式 响应合成 树状汇总 渐进式摘要 GPT-4/Claude等 意图识别 查询解析 关键词提取 向量相似度 检索策略 关键词匹配 混合检索 Top-k节点 节点检索 向量索引 索引构建 关键词索引 知识图谱索引 组合索引 PDF/PPT/Word/HTML等 文档加载 PDF解析器/Markdown解析器等 文档解析 节点属性设置 节点创建 固定大小/语义分割 文本分块 OpenAI/BGE/Sentence-Transformer 嵌入生成 用户输入 向量存储 查询输入 结果输出

LlamaIndex 的工作流程两个主要阶段分别为:索引构建 (Indexing)查询 (Querying)

2.1. 索引构建 (Indexing)

LlamaIndex 会将你的原始数据转化为可供 LLM 理解和检索的格式。

  • 数据连接器 (Data Connectors / Loaders):

    LlamaIndex 提供了一系列预构建的数据连接器,用于从各种数据源加载数据。

    • 文件系统: SimpleDirectoryReader (TXT, PDF, DOCX, CSV等)
    • 数据库: PostgreSQL, MongoDB, MySQL 等
    • SaaS 应用: Notion, Slack, Google Docs, Confluence, Jira 等
    • API: 各种自定义 REST API
    • 更多: 社区贡献了大量的加载器,几乎可以覆盖所有常见数据源。
  • 文档 (Documents): 加载器读取数据后,LlamaIndex 会将其表示为 Document 对象。一个 Document 对象是 LlamaIndex 中的基本数据单元,包含原始文本内容和可选的元数据(如文件名、创建日期、作者等)。

  • 节点 (Nodes):Document 通常非常大,不适合直接放入 LLM 的上下文窗口。因此,LlamaIndex 会将 Document

    分割成更小的、可管理的块,称为 Node

    • 分块策略 (Chunking Strategies):

      如何分割 Document 非常关键,它决定了查询时能获取到的上下文质量。

      • 固定大小分块: 最简单,按固定字符数或 Token 数分割。
      • 递归字符文本分块 (RecursiveCharacterTextSplitter): 按段落、句子等语义边界递归分割,优先级高者优先。
      • 基于语义的分块: 结合嵌入模型,确保分割后的块语义完整。
      • 上下文增强: 可以配置 Node 包含前后段落、章节标题等额外上下文信息。
    • Node 是索引和检索的基本单位。每个 Node 通常都会有其对应的嵌入向量 (Embedding Vector),用于语义相似度搜索。

  • 索引 (Indexes):Node 被创建后,LlamaIndex 会组织这些 Node 以便高效检索。索引是 LlamaIndex 的核心。

    • 向量存储索引 (Vector Store Index): 最常用。将每个 Node 的嵌入向量存储在向量数据库中。查询时,通过计算查询文本的嵌入向量与 Node 嵌入向量的相似度来查找最相关的 Node
      • 支持的向量数据库: Chroma, Pinecone, Milvus, Weaviate, Qdrant, FAISS (本地) 等。
    • 树索引 (Tree Index):Node 构建成树状结构。叶节点是原始 Node,父节点是其子节点内容的总结。查询时可以从根节点开始遍历,向下钻取以获取更详细信息。
    • 关键词表索引 (Keyword Table Index): 为每个 Node 提取关键词,并构建关键词到 Node 的映射。查询时,通过匹配关键词来查找相关 Node
    • 文档摘要索引 (Summary Index): 将所有 Node 串联起来,形成一个完整的文档链。查询时,通常会对整个文档进行总结或顺序遍历。
    • 知识图谱索引 (Knowledge Graph Index):Node 中提取实体和关系,构建知识图谱。查询时,可以进行图遍历来获取结构化知识。

2.2. 查询 (Querying)

这是用户提问并获取答案的阶段,LlamaIndex 利用构建好的索引来增强 LLM 的能力。

  • 查询引擎 (Query Engine): 这是用户与 LlamaIndex 交互的主要接口。它接收用户查询,并协调检索和 LLM 生成答案的过程。

  • 检索器 (Retriever):

    负责根据用户查询从索引中检索最相关的 Node。不同的索引类型会对应不同的检索策略。

    • 向量检索: 计算查询嵌入与 Node 嵌入的相似度。
    • 关键词检索: 匹配查询中的关键词。
    • 混合检索 (Hybrid Retrieval): 结合多种检索策略(如关键词+向量)。
    • 子查询检索: 将复杂查询分解为多个子查询。
  • 节点后处理器 (Node Postprocessors):在检索到 Node后,但在发送给 LLM 之前,可以对这些 Node进行后处理,以优化上下文。

    • 相似度排名过滤器: 过滤掉相似度低于阈值的 Node
    • 重新排名器 (Re-ranker): 使用一个更小的、更精确的模型(如 Sentence Transformers)对检索到的 Node 进行二次排序,以找到最相关的 Node
    • 去重: 移除重复的 Node
    • 上下文裁剪: 确保上下文不超过 LLM 的 Token 限制。
  • 响应合成器 (Response Synthesizer):

    接收检索到的 Node 和原始用户查询,将其打包成一个 Prompt,然后发送给 LLM,并解析 LLM 的响应。

    • refine 迭代地细化答案,尤其适用于处理大量 Node
    • compact (默认): 将所有 Node 压缩到单个 Prompt 中。
    • tree_summarize 递归地总结 Node,生成一个摘要。
    • simple_summarize 将所有 Node 作为一个大文本块进行总结。
  • LLM (Large Language Model): LlamaIndex 支持多种 LLM,包括 OpenAI (GPT-3.5/4), Anthropic (Claude), Google (PaLM/Gemini), 以及通过 Hugging Face 或本地部署的开源 LLM (如 Llama2, Mistral, Qwen)。

  • 嵌入模型 (Embedding Model): 用于将文本(文档、节点、查询)转换为数值向量(嵌入)。LlamaIndex 支持 OpenAI Embeddings, Hugging Face Embeddings, Sentence Transformers 等。

3. 核心代码示例 (基础 RAG 流程)

如何使用 LlamaIndex 构建一个简单的 RAG系统,从本地文档中回答问题。

python 复制代码
import os
from llama_index.core import VectorStoreIndex, SimpleDirectoryReader, ServiceContext, Settings
from llama_index.llms.openai import OpenAI # 或其他 LLM 提供商
from llama_index.embeddings.openai import OpenAIEmbedding # 或其他嵌入模型

# --- 配置环境 ---
# 确保设置了 OpenAI API 密钥,或者配置其他LLM和嵌入模型
# os.environ["OPENAI_API_KEY"] = "YOUR_OPENAI_API_KEY"

# LlamaIndex >= 0.10.0 版本推荐使用 Settings 配置
Settings.llm = OpenAI(model="gpt-3.5-turbo", temperature=0.1)
Settings.embed_model = OpenAIEmbedding(model="text-embedding-ada-002")
Settings.chunk_size = 1024 # 默认块大小
Settings.chunk_overlap = 20 # 块之间的重叠,提供更多上下文

# --- 1. 准备数据 ---
# 创建一个 'data' 文件夹,并在其中放入一些 .txt 或 .pdf 文件
# 例如:
# data/
#   - my_document_1.txt
#   - my_document_2.pdf

# 加载数据
print("Loading documents from './data'...")
documents = SimpleDirectoryReader("./data").load_data()
print(f"Loaded {len(documents)} documents.")

# --- 2. 构建索引 ---
# 最常用的是 VectorStoreIndex
# LlamaIndex 会自动分块、生成嵌入并存储到内存中的向量存储
print("Building VectorStoreIndex...")
index = VectorStoreIndex.from_documents(documents)
print("Index built successfully.")

# --- 3. 创建查询引擎 ---
# QueryEngine 是与索引交互的主要接口
query_engine = index.as_query_engine(
    similarity_top_k=2 # 检索最相似的 2 个节点
)

# --- 4. 执行查询 ---
query = "What is the main topic of the documents?" # 替换为你想问的问题
print(f"\nQuerying: '{query}'")

response = query_engine.query(query)

# --- 5. 打印响应 ---
print("\n--- Response ---")
print(response)

# 打印源节点信息,查看LLM使用了哪些原文片段来生成答案
print("\n--- Source Nodes ---")
for source_node in response.source_nodes:
    print(f"Node ID: {source_node.id_}")
    print(f"Text (first 200 chars): {source_node.text[:200]}...")
    print(f"Metadata: {source_node.metadata}")
    print("-" * 20)

核心模块 (概念性) 代码解释:

  1. SimpleDirectoryReader("./data").load_data():

    • 功能: 从指定目录加载所有支持格式的文档。
    • 输出: 一个 list,其中包含多个 Document 对象。每个 Document 存储原始文本及其元数据。
  2. VectorStoreIndex.from_documents(documents):

    • 功能: 这是索引构建的核心。它负责将原始 Document 转换为可查询的索引。
    • 内部流程:
      • 分块 (Chunking): 将每个 Document 分割成多个较小的 Node(默认通过 Settings.chunk_sizeSettings.chunk_overlap 控制)。
      • 嵌入 (Embedding): 使用配置好的 Settings.embed_model 为每个 Node 的文本内容生成一个高维向量(嵌入)。
      • 存储 (Storage):Node 对象(包括其文本、嵌入和元数据)存储在一个向量存储中。默认是内存中的 FAISS 向量存储。
    • 输出: 一个 VectorStoreIndex 对象。
  3. index.as_query_engine(similarity_top_k=2):

    • 功能: 基于构建好的 index 创建一个 QueryEngine
    • similarity_top_k: 指定在检索阶段,从向量存储中查找与查询最相似的 K 个 Node
    • 输出: 一个 QueryEngine 对象。
  4. query_engine.query(query):

    • 功能: 执行实际的查询操作。

    • 内部流程:

      • 查询嵌入: 将用户 query 通过 Settings.embed_model 转换为嵌入向量。

      • 检索 (Retrieval): 使用查询嵌入在 index 的向量存储中进行相似度搜索,找到 similarity_top_k 个最相关的 Node

      • 响应合成 (Response Synthesis): 将检索到的 Node 的文本内容和原始用户查询打包成一个 Prompt。

        • Prompt

          示例如下(LlamaIndex 会自动构建):

          bash 复制代码
          "Context information is below.\n"
          "---------------------\n"
          "{retrieved_node_1_text}\n"
          "{retrieved_node_2_text}\n"
          "---------------------\n"
          "Given the context information and not prior knowledge, answer the query.\n"
          "Query: {user_query}\n"
          "Answer:"
        • 将此 Prompt 发送给 Settings.llm

      • LLM 推理: LLM 基于 Prompt 生成答案。

    • 输出: 一个 Response 对象,包含 LLM 生成的答案以及用于生成答案的源节点信息。

4. LlamaIndex 的高级特性

LlamaIndex 提供了许多高级功能来应对更复杂的应用场景:

  • 持久化存储 (Persistence):将索引保存到磁盘,避免每次运行时都重新构建。

    python 复制代码
    # 保存索引
    index.storage_context.persist(persist_dir="./storage")
    # 加载索引
    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)
  • 集成外部向量数据库 (Vector Stores):

    • 除了内存中的 FAISS,LlamaIndex 可以轻松集成 Pinecone, Chroma, Milvus, Weaviate 等生产级向量数据库。
    • 这对于大规模数据和高并发场景至关重要。
    python 复制代码
    # 示例:使用 ChromaDB 作为向量存储
    from llama_index.vector_stores.chroma import ChromaVectorStore
    import chromadb
    
    # 创建或连接 Chroma 客户端
    db = chromadb.PersistentClient(path="./chroma_db")
    chroma_collection = db.get_or_create_collection("my_documents")
    vector_store = ChromaVectorStore(chroma_collection=chroma_collection)
    
    # 构建索引时指定向量存储
    index = VectorStoreIndex.from_documents(
        documents,
        vector_store=vector_store,
        # service_context=service_context # 旧版本用法,新版本用 Settings
    )
  • 自定义分块策略 (Custom Chunking):

    • LlamaIndex 允许使用不同的文本分割器,如 SentenceSplitter, TokenTextSplitter, MarkdownTextSplitter 等。
    • 可以自定义 chunk_sizechunk_overlap
    • 高级分块:例如,为代码文件和普通文本使用不同的分块策略。
  • 节点后处理器 (Node Postprocessors):

    • SimilarityPostprocessor: 根据相似度阈值过滤。
    • KeywordNodePostprocessor: 基于关键词过滤。
    • MetadataReplacementPostProcessor: 动态替换节点元数据。
    • LongContextReorder: 在检索结果中,将最相关的节点放到中间,提升长上下文 LLM 的表现。
    • LLMRerank: 使用一个专门的 Re-ranker 模型(如 Cohere Rerank, BGE Rerank)对检索到的节点进行重新排序,进一步提高相关性。
    Python 复制代码
    from llama_index.core.postprocessor import SimilarityPostprocessor
    # 在 query_engine 中添加后处理器
    query_engine = index.as_query_engine(
        similarity_top_k=5,
        node_postprocessors=[
            SimilarityPostprocessor(similarity_cutoff=0.7) # 过滤掉相似度低于0.7的节点
        ]
    )
  • 多种查询引擎模式:

    • as_query_engine() 最常用,适用于标准 RAG。
    • as_chat_engine() 用于构建有记忆的多轮对话机器人。
    • as_retriever() 仅返回检索到的节点,不经过 LLM 合成答案,用于构建高级检索管道。
  • 高阶查询引擎 (Advanced Query Engines):

    • 路由查询引擎 (Router Query Engine): 根据用户查询的意图,动态地选择合适的索引或子查询引擎来处理查询。例如,文档查询去文档索引,数据库查询去数据库工具。
    • 递归查询引擎 (Recursive Query Engine): 当查询需要多步骤推理时,可以递归地调用查询引擎。
    • 子查询查询引擎 (SubQuery Query Engine): 将一个复杂问题分解为多个子问题,每个子问题由独立的查询引擎处理。
    • SQL 查询引擎: 将自然语言查询转换为 SQL 查询,然后执行并利用结果。
    • 知识图谱查询引擎: 利用知识图谱进行结构化推理。
  • 代理 (Agents):

    LlamaIndex 提供了构建 LLM Agents 的能力,这些 Agent 可以利用工具(包括查询引擎)来完成复杂任务。

    • Agent 能够理解任务、分解步骤、调用工具、观察结果并迭代。
    • 工具 (Tools): 可以将 LlamaIndex 的 QueryEngine 封装成一个工具,供 Agent 调用。
  • 自定义 LLM 和嵌入模型:

    • 除了 OpenAI,LlamaIndex 提供了丰富的 LLMEmbedding 抽象接口,可以轻松集成 Hugging Face 上的任何模型、本地模型 (如 ollama, llama_cpp) 或其他云服务提供商。
    Python 复制代码
    from llama_index.llms.huggingface import HuggingFaceLLM
    from llama_index.embeddings.huggingface import HuggingFaceEmbedding
    from transformers import AutoTokenizer, AutoModelForCausalLM
    
    # 加载本地/Hugging Face LLM
    # model_name = "mistralai/Mistral-7B-Instruct-v0.2"
    # llm_model = AutoModelForCausalLM.from_pretrained(model_name)
    # tokenizer_hf = AutoTokenizer.from_pretrained(model_name)
    
    # llm = HuggingFaceLLM(
    #     model=llm_model,
    #     tokenizer=tokenizer_hf,
    #     max_new_tokens=512,
    #     generate_kwargs={"temperature": 0.1, "do_sample": True},
    #     device_map="auto"
    # )
    # Settings.llm = llm
    
    # 加载 Hugging Face 嵌入模型
    # embed_model = HuggingFaceEmbedding(model_name="BAAI/bge-small-en-v1.5")
    # Settings.embed_model = embed_model
  • 可观测性 (Observability): 集成 LlamaIndex 的调用链到 Tracing 工具(如 LangChain's LangSmith, OpenAI Evals),便于调试和性能分析。

  • RAG Fusion / Multi-Query Retrieval: 生成多个查询,并行检索,然后合并结果。

  • 知识图谱抽取与查询: 从非结构化文本中构建知识图谱,并进行结构化查询。

5. LlamaIndex 的架构原理 (更深层次)

LlamaIndex 内部维护着几个核心组件:

  • ServiceContext (在 LlamaIndex 0.10.0+ 版本中被 Settings 模块替代): 包含了 LLM 模型、嵌入模型、文本分割器、节点解析器等核心服务配置。它是 LlamaIndex 内部运行的基础。
  • NodeParser: 负责将 Document 解析成 Node。可以配置分块大小、重叠、元数据提取等。
  • Embedding 模型: 负责将文本转化为向量。
  • LLM 模型: 负责文本生成。
  • IndexStore 用于存储索引的元数据(如节点ID、文档ID)。
  • VectorStore 存储 Node 的嵌入向量,用于相似度搜索。
  • GraphStore 存储知识图谱(如果使用知识图谱索引)。

这些组件协同工作,形成一个可插拔、可扩展的 RAG 管道。

6. LlamaIndex 与 LangChain 的比较

LlamaIndex 和 LangChain 都可以构建 LLM 应用的热门框架,这里做一下对比:

特性/框架 LlamaIndex LangChain
核心侧重 数据摄取、索引和查询 (RAG 核心) 链式应用、代理和工具使用 (LLM 编排核心)
数据管理 强大,提供丰富的加载器、索引类型和节点管理。 较弱,主要集中于 Retriever 抽象,数据管理不如 LlamaIndex 丰富。
检索增强 专注于此,提供多种高级检索器、节点处理器、响应合成器。 RAG 只是其功能之一,但 Retriever 抽象也较完善。
LLM 编排 提供 Query Engine, Agent 等高级抽象,可调用工具。 极其强大,以 Chain、Agent 为核心,鼓励多步骤、多工具协作。
工具集成 主要通过 Tool 封装 QueryEngine,供 Agent 使用。 丰富的工具集,易于定义和集成各种外部工具(API、计算器、Python REPL等)。
学习曲线 相对更直接,RAG 流程清晰。 抽象层级较多,灵活性强但也可能更复杂。
协作关系 1. LlamaIndex 构建索引; 2. LlamaIndex 提供数据增强能力。 1.LangChain 调用 LlamaIndex 的 QueryEngine 作为工具;2.LangChain 管理整体对话/代理流
相关推荐
HEY_FLYINGPIG42 分钟前
Flask应用中处理异步事件(后台线程+事件循环)的方法(2)
后端·python·flask
虾条_花吹雪1 小时前
5、Spring AI(MCPServer+MCPClient+Ollama)开发环境搭建_第一篇
数据库·人工智能·学习·spring·ai
知舟不叙2 小时前
基于OpenCV实现实时颜色检测
人工智能·opencv·计算机视觉·颜色检测
勤奋的知更鸟3 小时前
深度学习神经网络架构Transformer深刻理解
深度学习·神经网络·transformer
蓑雨春归3 小时前
探索Agent的发展潜力:大模型与具身智能的融合
人工智能
每日新鲜事4 小时前
Lavazza拉瓦萨再度牵手兰博基尼汽车 百年咖啡注入超跑速度
人工智能
说私域4 小时前
传统企业数字化转型:以定制开发开源 AI 智能名片 S2B2C 商城小程序源码为核心的销售环节突破
大数据·人工智能·开源
geneculture5 小时前
社会应用融智学的人力资源模式:潜能开发评估;认知基建资产
人工智能·课程设计·融智学的重要应用·三级潜能开发系统·人力资源升维·认知基建·认知银行
uyeonashi6 小时前
【QT系统相关】QT文件
开发语言·c++·qt·学习
鹏码纵横7 小时前
已解决:java.lang.ClassNotFoundException: com.mysql.jdbc.Driver 异常的正确解决方法,亲测有效!!!
java·python·mysql