侧边栏壁纸
博主头像
毕业帮 博主等级

提供丰富的资源和服务,涵盖从论文写作、毕业设计、职业规划、就业准备等多个方面

  • 累计撰写 81 篇文章
  • 累计创建 18 个标签
  • 累计收到 3 条评论

目 录CONTENT

文章目录

LlamaIndex 全面技术详解

流苏
2026-03-11 / 0 评论 / 0 点赞 / 2 阅读 / 0 字 / 正在检测是否收录...
温馨提示:
部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

LlamaIndex 全面技术详解

构建生产级RAG应用的企业级框架


目录


一、LlamaIndex 概述

1.1 什么是LlamaIndex

LlamaIndex(前身为GPT Index)是一个专门为LLM应用设计的数据框架,核心解决私有数据接入LLM的问题。

核心定位

  • 数据连接层:连接私有数据(文档、数据库、API)与LLM
  • 索引构建层:将非结构化/结构化数据转换为LLM可高效检索的格式
  • 检索增强层:提供先进的检索策略,为LLM提供相关上下文

与LangChain的区别

LangChain: LLM应用开发全栈框架(Agent、Chain、Memory等)
    ↓
LlamaIndex: 专注数据接入与检索(RAG专家)

1.2 核心价值主张

  1. 简单性:5行代码完成RAG管道搭建
  2. 灵活性:可组合组件,自定义每个环节
  3. 性能:先进的检索算法,生产级性能
  4. 可扩展:插件化架构,支持任意数据源/向量库
  5. 生产就绪:监控、缓存、异步、错误处理

1.3 适用场景

  • 文档问答系统:公司知识库、客服FAQ
  • 数据分析助手:自然语言查询数据库
  • 研究助手:论文/专利检索与总结
  • 法律文件审查:合同条款检索
  • 代码搜索:代码库语义搜索
  • 多文档摘要:自动化报告生成

1.4 不支持场景

  • 通用Agent框架:不是替代LangChain,可配合使用
  • 复杂工作流编排:LangChain更适合多步骤推理
  • 模型托管:不提供模型服务,只提供数据服务
  • 实时流式处理:更适合批处理、近实时

二、核心架构设计

2.1 设计哲学

“数据先行”(Data-First)

原始数据 → 解析 → 分块 → 向量化 → 索引 → 检索 → 上下文组装 → LLM生成

每个环节都可自定义替换。

2.2 架构层次

┌─────────────────────────────────────────────────────────────┐
│                    Application Layer                        │
│      (QueryEngine / ChatEngine / Agent / Retriever)       │
└───────────────────────────┬─────────────────────────────────┘
                            │
┌───────────────────────────┴─────────────────────────────────┐
│                   Query Pipeline                           │
│  Query → Query Transform → Retrieval → Response Synthesis │
└───────────────────────────┬─────────────────────────────────┘
                            │
┌───────────────────────────┴─────────────────────────────────┐
│                   Index Layer                             │
│  ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌─────────────┐  │
│  │  Vector  │ │Keyword   │ │  Tree    │ │   Graph     │  │
│  │  Store   │ │  Index   │ │  Index   │ │   Index     │  │
│  └──────────┘ └──────────┘ └──────────┘ └─────────────┘  │
└───────────────────────────┬─────────────────────────────────┘
                            │
┌───────────────────────────┴─────────────────────────────────┐
│                   Data Layer                              │
│  ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌─────────────┐  │
│  │  Document│ │  Node    │ │Embedding │ │   Storage   │  │
│  │  Reader  │ │   Splitter│ │  Model   │ │   Context   │  │
│  └──────────┘ └──────────┘ └──────────┘ └────────────┘  │
└───────────────────────────┬─────────────────────────────────┘
                            │
┌───────────────────────────┴─────────────────────────────────┐
│                   Data Sources                            │
│  (Files, APIs, DB, Websites, SaaS, etc.)                 │
└───────────────────────────────────────────────────────────┘

2.3 关键抽象

  • Document:原始数据单元(文本、metadata、source)
  • Node:Document分块后的单元,含embedding、relationship
  • Index:组织Node的数据结构(VectorIndex、TreeIndex等)
  • Retriever:从Index检索相关Node
  • QueryEngine:Retriever + ResponseSynthesis
  • StorageContext:管理文档、索引、向量的持久化存储

三、核心组件详解

3.1 DocumentReader(文档读取器)

作用:从各种数据源读取原始数据,转换为Document对象

内置Reader

  • 文件系统
    • SimpleDirectoryReader:读取目录下所有文件(txt、md、pdf、docx等)
    • PDFReader:解析PDF(支持扫描OCR)
    • DocxReader:Word文档
    • PptxReader:PowerPoint
    • ImageReader:OCR识别图片文字
    • IPYNBReader:Jupyter Notebook
    • UnstructuredReader:通用解析器(支持多种格式)
  • 网页
    • BeautifulSoupWebReader:静态网页
    • SeleniumWebReader:动态渲染页面(JavaScript)
    • ReadabilityWebReader:只读文章正文
  • 数据库
    • SQLDatabaseReader:执行SQL查询
    • SimpleMongoReader:MongoDB查询
  • API
    • RssReader:RSS订阅
    • GoogleDocsReader:Google Docs
    • NotionReader:Notion页面
  • 云存储
    • S3Reader:AWS S3
    • AzureBlobStorageReader:Azure Blob
    • GCSReader:Google Cloud Storage
  • 自定义:实现BaseReader接口

示例

from llama_index import SimpleDirectoryReader

documents = SimpleDirectoryReader(
    input_dir="./data",
    recursive=True,
    exclude=["*.tmp"]
).load_data()

3.2 NodeParser(节点分块器)

作用:将Document拆分为更小的Node(Chunk),每个Node独立embedding和检索

内置分块策略

3.2.1 按大小分块

  • SentenceSplitter:按句子分割(最常用)
    • chunk_size=512(字符数或token数)
    • chunk_overlap=50(前后块重叠,保持上下文连贯)
    • 句子分割器(nltk、spacy、字符规则)
  • TokenTextSplitter:按token计数(使用tokenizer)
    • 适合GPT类模型,控制上下文窗口
  • CharacterTextSplitter:按字符数
    • separator="\n\n"(按段落)
    • keep_separator=True(保留分隔符)

3.2.2 语义分块

  • SemanticSplitterNodeParser
    • 计算相邻句子的embedding相似度
    • 相似度低于阈值则分割(语义 discontinuity)
    • 需要embedding模型,开销较大
  • MetadataAwareTextSplitter:根据metadata(如章节标题)分割

3.2.3 代码分块

  • CodeSplitter
    • 按函数/类分割(AST解析)
    • 支持Java、Python、JavaScript、Go等
    • 保留代码结构,适合代码搜索

3.2.4 递归分割

  • RecursiveCharacterTextSplitter
    • 尝试按["\n\n", "\n", " ", ""]顺序分割
    • 确保每块不超过chunk_size

示例

from llama_index.node_parser import SentenceSplitter

parser = SentenceSplitter(
    chunk_size=512,
    chunk_overlap=50,
    separator=" "
)
nodes = parser.get_nodes_from_documents(documents)

3.3 Embedding Model(嵌入模型)

作用:将文本转换为向量,用于语义检索

四类来源

  1. OpenAIOpenAIEmbedding(text-embedding-ada-002、text-embedding-3-*)
    • 高质量,费用按token计费
    • 支持batch请求,降低cost
  2. 本地模型(HuggingFace):
    • HuggingFaceEmbedding:任意sentence-transformers模型
    • InstructorEmbedding:Instruct风格模型(如’instructor-large’)
    • FastEmbedEmbedding:快速本地推理(Qdrant出品)
  3. 云服务
    • CohereEmbedding(cohere.embed-english-v3.0)
    • GoogleEmbedding(textembedding-gecko)
    • AzureOpenAIEmbedding
    • BaiduEmbedding(文心)
    • AliyunEmbedding(通义)
  4. 自定义
    • 实现BaseEmbedding接口
    • 支持业务特定领域embedding

选择建议

  • 中小规模、高质量:OpenAI embedding
  • 大规模、低成本:本地模型(bge-large-zh、all-MiniLM-L6-v2)
  • 中文优先:BGE中文系列、m3e-base
  • 多语言:paraphrase-multilingual-MiniLM-L12-v2

示例

from llama_index.embeddings.openai import OpenAIEmbedding

embed_model = OpenAIEmbedding(
    model="text-embedding-3-small",
    dimensions=1536
)

3.4 Vector Store(向量数据库)

作用:存储Node的embedding向量,支持相似度搜索

支持30+向量数据库

3.4.1 开源方案

  • Milvus:高性能、云原生(推荐生产)
    • 索引类型:HNSW、IVF_FLAT、IVF_PQ、SCANN
    • 支持过滤、多模态
      -集群版(Distributed)
  • Qdrant:Rust编写,性能好
    • HNSW索引、多向量、payload过滤
    • API友好(gRPC/HTTP)
  • Pinecone:托管服务,易用
    • 全托管,无需运维
    • 自动扩缩容
  • Weaviate:GraphQL接口,模块化
    • 内置vectorizer、混合搜索
  • Chroma:轻量级、本地首选
    • 内存模式、持久化模式
    • 适合原型开发、小规模
  • PGVector:PostgreSQL扩展
    • 与SQL生态整合好
    • HNSW、IVF索引
  • Elasticsearch:全文+向量混合
    • dense_vector字段
    • 结合BM25,实现混合检索
  • Redis:Redis Stack的向量搜索
    • 适合缓存+向量搜索一体化
  • ** Vespa**:完整搜索引擎,支持向量+全文
  • FAISS:Facebook库,非独立服务
  • ChromaDB:开源本地向量数据库

3.4.2 云服务

  • Azure AI Search
  • Google Vertex AI Matching Engine
  • AWS OpenSearch Serverless

Vector Store集成

from llama_index.vector_stores import ChromaVectorStore

vector_store = ChromaVectorStore(
    persist_dir="./chroma_db",
    collection_name="my_docs"
)

# 或从已有collection加载
import chromadb
chroma_client = chromadb.PersistentClient()
collection = chroma_client.get_or_create_collection("my_collection")
vector_store = ChromaVectorStore(chroma_collection=collection)

3.5 StorageContext(存储上下文)

作用:统一管理文档、向量、索引的持久化

配置

from llama_index import StorageContext

storage_context = StorageContext.from_defaults(
    doc_store=SimpleDocumentStore.from_persist_dir("./storage"),
    vector_store=ChromaVectorStore.from_persist_dir("./storage"),
    index_store=SimpleIndexStore.from_persist_dir("./storage")
)

存储类型

  • SimpleDocumentStore:文档原始内容(JSON文件)
  • SimpleIndexStore:索引元数据(JSON)
  • SimpleKVStore:键值存储(内存或文件)
  • 可自定义,实现BaseDocumentStoreBaseIndexStore接口

四、索引策略与选择

4.1 索引类型对比

索引类型 适用场景 检索方式 构建成本 查询速度 特点
VectorIndex 语义搜索 向量相似度 最常用,适合问答
KeywordIndex 关键词匹配 倒排索引(BM25) 精确匹配、过滤
TreeIndex 层级摘要 树遍历 文档总结、层次查询
ListIndex 顺序生成 线性扫描 列表式回答
GraphIndex 关系查询 图遍历 复杂关系
ComposableGraph 分布式 子索引聚合 超长文档、分布式

4.2 VectorStoreIndex(向量索引)

最基础、最常用

from llama_index import VectorStoreIndex, SimpleDirectoryReader

documents = SimpleDirectoryReader("./data").load_data()
index = VectorStoreIndex.from_documents(
    documents,
    storage_context=storage_context,
    embed_model=embed_model
)

# 持久化
index.storage_context.persist(persist_dir="./storage")

# 查询
query_engine = index.as_query_engine()
response = query_engine.query("什么是RAG?")
print(response)

工作原理

  1. 文档 → 分块(Node)→ embedding
  2. 所有Node存入Vector Store
  3. 查询时:query embedding → 向量搜索k个最相似Node
  4. 将Node的text作为context + query → LLM生成回答

参数调优

  • similarity_top_k=10:检索top-k个Node
  • embed_model=...:embedding模型
  • vector_store=...:向量库
  • show_progress=True:显示构建进度

4.3 KeywordTableIndex(关键词索引)

基于BM25的全文检索

from llama_index import KeywordTableIndex

index = KeywordTableIndex.from_documents(documents)
response = index.as_query_engine().query("xxx")

# 与vector混合(后期查看Hybrid)

适用场景

  • 精确匹配(专有名词、代码)
  • 过滤(metadata过滤)
  • 作为Vector的fallback

4.4 TreeIndex(树索引)

构建文档的层次化摘要

from llama_index import TreeIndex

index = TreeIndex.from_documents(documents)
# 查询时自动构建query-specific树
query_engine = index.as_query_engine()
response = query_engine.query("总结文档主要内容")

工作流程

  1. 将chunk summary→构建树(每层摘要合并)
  2. 查询时:从叶子节点开始检索,向根节点回溯
  3. 选择最相关的子节点,最终到根节点获得全局context

适用场景

  • 文档摘要
  • 需要全局理解的长文档
  • 层次化Q&A(从概览到细节)

4.5 ListIndex(列表索引)

将所有chunk作为列表,逐个查询LLM

from llama_index import ListIndex

index = ListIndex.from_documents(documents)
response = index.as_query_engine(
    response_mode="tree_summarize"  # 或"refine"
).query("xxx")

响应模式

  • "compact":合并chunk到单个prompt
  • "tree_summarize":递归树式总结(适合长文档)
  • "refine":顺序迭代,每次基于前一次结果
  • "simple_summarize":简单总结

适用场景

  • 文档摘要
  • 多文档综合
  • 不适合详细问答(缺少检索)

4.6 GraphIndex(图索引)

构建实体关系图

from llama_index import GraphIndex

index = GraphIndex.from_documents(documents)
# 子图查询、路径查询
query_engine = index.as_query_engine(
    response_mode="sub_questions"  # 子图遍历
)
response = query_engine.query("A和B的关系?")

特点

  • 自动抽取实体和关系(可选LLM提取)
  • 支持图遍历查询
  • 构建成本高,查询慢

适用场景

  • 知识图谱问答
  • 复杂关系推理

4.7 ComposableGraph(组合图)

多个索引的聚合

from llama_index import ComposableGraph

graph = ComposableGraph.from_indices(
    indices_list=[index1, index2, index3],
    index_summaries=["summary1", "summary2", "summary3"]
)
query_engine = graph.as_query_engine()

工作流程

  1. 先检索哪个sub-index相关(用summary)
  2. 再在该sub-index中检索具体chunk

适用场景

  • 超长文档(每章一个索引)
  • 跨文档集合查询

五、检索与查询引擎

5.1 Retriever(检索器)

核心接口retrieve(query_str: str) → List[NodeWithScore]

内置Retriever

  • VectorIndexRetriever:向量检索
    • similarity_top_k=10
    • vector_store.query_embedding(...)
  • KeywordTableSimpleRetriever:BM25检索
    • 支持AND/OR逻辑
  • TreeSelectLeafRetriever:树索引叶子检索
  • GraphRetriever:图遍历检索
  • HybridRetriever:混合检索(向量+关键词)
  • RouterRetriever:根据query选择retriever
  • QueryFusionRetriever:多检索器结果融合(RRF)

5.2 QueryEngine(查询引擎)

封装Retriever + ResponseSynthesis

query_engine = index.as_query_engine(
    retriever_mode="default",  # 或"hybrid"
    response_mode="compact"    # 或"tree_summarize"、"refine"
)
response = query_engine.query("xxx")

响应模式

  • compact:合并所有context到single prompt,适合top-k较小
  • tree_summarize:递归总结,适合长context(先summary中间结果)
  • refine:迭代精炼,每次基于前次结果更新,适合长context
  • simple_summarize:简单调用summarize API

5.3 ChatEngine(对话引擎)

支持多轮对话

from llama_index import ChatEngine

chat_engine = index.as_chat_engine(
    chat_mode="context"  # context/condense_question/react
)
response = chat_engine.chat("你好")
response = chat_engine.chat("上一问是什么?")  # 有记忆

对话模式

  • context:维护对话历史,拼接成context
  • condense_question:将历史condense成新query再检索(更准)
  • react:ReAct模式,支持工具调用
  • openai:完全使用OpenAI Assistant(有状态)

5.4 QueryTransform(查询转换)

在检索前对query进行转换

  • QueryRewrite:重写query,改善检索
    • 使用LLM自动重写,增加同义词、扩展
  • HybridTransformation:生成多个query(向量+关键词)
  • StepDecoQueryTransform:问题分解(子问题)

示例

from llama_index import QueryBundle
from llama_index.query_engine import TransformQueryEngine
from llama_index.query_engine.retriever_query_engine import RetrieverQueryEngine

retriever = index.as_retriever()
query_engine = RetrieverQueryEngine.from_args(
    retriever,
    query_transform=QueryRewrite(),
    response_synthesizer=...
)

六、数据连接器与文档处理

6.1 文件系统

支持的格式(30+)

  • 文本(txt、md、csv、json、xml、html)
  • Office(docx、pptx、xlsx)
  • PDF(text + image OCR)
  • 代码(py、java、js、go、cpp、h、rs)
  • ebook(epub、mobi)
  • audio(mp3、wav - 需Whisper转录)
  • 图像(png、jpg - OCR)

6.2 网页抓取

静态 vs 动态

# 静态(快速,无JS)
from llama_index.readers.web import BeautifulSoupWebReader
reader = BeautifulSoupWebReader()
documents = reader.load_data(["https://example.com"])

# 动态(渲染后)
from llama_index.readers.web import SeleniumWebReader
reader = SeleniumWebReader()
documents = reader.load_data(["https://spa-example.com"])

高级选项

  • extract_tables=True:提取表格
  • encoding="utf-8"
  • max_depth=2:爬取深度
  • prevent_duplicate_links=True

6.3 数据库集成

SQL数据库

from llama_index.readers.database import DatabaseReader

reader = DatabaseReader(
    scheme="postgresql",
    host="localhost",
    port=5432,
    user="user",
    password="password",
    database="dbname"
)

# 执行SQL,每行转为Document
documents = reader.load_data(
    query="SELECT * FROM table WHERE condition"
)

NoSQL

  • MongoDB:MongoDBReader
  • Elasticsearch:ElasticsearchReader

6.4 API集成

Notion

from llama_index.readers.notion import NotionPageReader

reader = NotionPageReader(
    integration_token="secret_xxx"
)
documents = reader.load_data(
    page_ids=["page-id-1", "page-id-2"]
)

Google Docs

from llama_index.readers.google import GoogleDocsReader

reader = GoogleDocsReader()
documents = reader.load_data(
    document_ids=["doc-id-1"],
    credentials_path="./credentials.json"
)

RSS

from llama_index.readers.web import RssReader

reader = RssReader()
documents = reader.load_data(
    urls=["https://rss.example.com/feed"]
)

6.5 自定义Reader

实现BaseReader

from llama_index.readers.base import BaseReader
from llama_index.schema import Document

class MyCustomReader(BaseReader):
    def load_data(self, source: str) -> List[Document]:
        # 读取逻辑
        content = my_custom_parse(source)
        metadata = {"source": source}
        return [Document(text=content, metadata=metadata)]

七、高级检索技术

7.1 混合检索(Hybrid Search)

结合向量检索(语义)与关键词检索(精确)

from llama_index.retrievers import HybridRetriever
from llama_index.indices.keyword_table import KeywordTableIndex

# 构建两个索引(共享同一Document)
vector_index = VectorStoreIndex.from_documents(documents)
keyword_index = KeywordTableIndex.from_documents(documents)

# 混合检索器
hybrid_retriever = HybridRetriever(
    vector_retriever=vector_index.as_retriever(similarity_top_k=10),
    keyword_retriever=keyword_index.as_retriever(similarity_top_k=10),
    mode="OR"  # AND/OR/OR-dedup(去重)
)

query_engine = RetrieverQueryEngine.from_args(
    retriever=hybrid_retriever,
    response_synthesizer=...
)

融合策略

  • OR:取并集
  • AND:取交集
  • OR-dedup:取并集并去重(推荐)

7.2 重排序(Reranking)

使用交叉编码器(Cross-encoder)对检索结果重排

from llama_index.postprocessor import SentenceTransformerRerank

rerank = SentenceTransformerRerank(
    model="cross-encoder/ms-marco-MiniLM-L-6-v2",
    top_n=5
)

query_engine = RetrieverQueryEngine.from_args(
    retriever=vector_retriever,
    node_postprocessors=[rerank]
)

流程

  1. 向量检索top-50
  2. 交叉编码器计算(query, doc)相关性分数
  3. 取top-5重排后结果

优势

  • 精度大幅提升( sacrificing recall)
  • 适合top-k精确召回场景

云服务

  • CohereRerank:Cohere rerank API
  • JinaRerank:Jina AI rerank
  • YouRerankYou.com rerank

7.3 元数据过滤

检索时添加metadata过滤条件

from llama_index import VectorStoreIndex

retriever = index.as_retriever(
    similarity_top_k=10,
    filters=MetadataFilters(
        filters=[
            MetadataFilter(
                key="author",
                value="John Doe",
                operator="=="
            ),
            MetadataFilter(
                key="date",
                value="2024-01-01",
                operator=">="
            )
        ]
    )
)

过滤操作符==!=>>=<<=innincontains

7.4 多查询检索(Multi-Query)

将单个query扩展为多个related queries,分别检索后合并

from llama_index.retrievers import QueryFusionRetriever

retriever = QueryFusionRetriever(
    [vector_retriever, keyword_retriever],
    similarity_top_k=10,
    num_queries=4,  # 生成4个query
    mode="reciprocal_rerank",  # RRF融合
    use_async=True
)

生成策略

  • 默认使用LLM生成相关query(添加多样性)
  • 可自定义query生成器

RRF算法

score = sum(1 / (k + rank_i)) for each retriever

7.5 查询路由(Query Routing)

根据query选择不同的Index/Retriever

from llama_index.retrievers import RouterRetriever
from llama_index.selectors.llm_selectors import LLMSingleSelector

router_retriever = RouterRetriever(
    selector=LLMSingleSelector.from_defaults(),
    retrievers={
        "vector": vector_retriever,
        "keyword": keyword_retriever,
        "graph": graph_retriever
    }
)

选择器类型

  • LLMSingleSelector:LLM选择最佳retriever
  • LLMMultiSelector:选择多个(并行)
  • PydanticMultiSelector:基于Pydantic模型
  • 自定义:实现BaseSelector

八、查询处理与后处理

8.1 上下文组装策略

如何将检索到的Node组织成LLM prompt

  • ContextFormatting:格式化template

    template = """Context information is below.
    ---------------------
    {context_str}
    ---------------------
    Given the context information and not prior knowledge, answer the query.
    Query: {query_str}
    Answer:"""
    
  • CompactAndRefine:先compact成短context再refine

  • TreeSummarize:递归tree摘要(长文档)

  • Refine:迭代精炼(适合长context、流式)

8.2 响应合成器(ResponseSynthesizer)

控制LLM生成回答的方式

from llama_index.response_synthesizers import RefineResponseSynthesizer

response_synthesizer = RefineResponseSynthesizer.from_defaults()
query_engine = RetrieverQueryEngine(
    retriever=retriever,
    response_synthesizer=response_synthesizer
)

合成模式

  • compact:默认,一次性prompt
  • refine:迭代,每次基于前次输出
  • tree_summarize:递归树式
  • simple_summarize:调用summarize endpoint

LLM配置

from llama_index.llms import OpenAI

llm = OpenAI(model="gpt-4-turbo-preview", temperature=0)
response_synthesizer = ResponseSynthesizer.from_defaults(llm=llm)

8.3 后处理(PostProcessors)

在生成前对检索的Node处理

  • SimilarityPostprocessor:按相似度分数过滤
    SimilarityPostprocessor(similarity_cutoff=0.7)
    
  • KeywordPostprocessor:关键词过滤
  • SentenceEmbeddingOptimizer:压缩context(删除冗余句子)
  • PrevNextNodePostprocessor:添加上下文(prev/next Node)
  • LongContextReorder:长context优化(把最相关放中间)
  • MetadataReplacementPostProcessor:用metadata替换text(如用file_path替换内容)

组合使用

from llama_index.postprocessor import (
    SimilarityPostprocessor,
    LongContextReorder
)

query_engine = index.as_query_engine(
    node_postprocessors=[
        SimilarityPostprocessor(similarity_cutoff=0.7),
        LongContextReorder()
    ]
)

九、存储与持久化

9.1 存储层抽象

三等分存储

  • Document Store:原始documents
  • Index Store:索引元数据(index结构)
  • Vector Store:向量数据(embedding + node)

持久化策略

# 方式1:一键持久化
storage_context.persist(persist_dir="./storage")

# 方式2:分别持久化
doc_store.persist(persist_path="./docs.json")
index_store.persist(persist_path="./index.json")
vector_store.persist(persist_path="./vectors/")

9.2 向量数据库持久化

不同vector store的持久化方式

  • Chroma
    vector_store = ChromaVectorStore(
        chroma_collection=collection,
        persist_directory="./chroma"
    )
    
  • Milvus
    vector_store = MilvusVectorStore(
        dim=1536,
        collection_name="my_collection",
        uri="http://localhost:19530"
    )
    # Milvus自身持久化,无需LlamaIndex额外persist
    
  • Pinecone
    vector_store = PineconeVectorStore(
        index_name="my-index",
        namespace="default"
    )  # 云服务自动持久化
    

9.3 增量更新

添加新文档

from llama_index import SimpleDirectoryReader, StorageContext

# 加载已有storage
storage_context = StorageContext.from_defaults(
    persist_dir="./storage"
)

# 加载新文档
new_docs = SimpleDirectoryReader("./new_data").load_data()

# 添加到原有index
index = VectorStoreIndex.from_documents(
    new_docs,
    storage_context=storage_context
)

# 再次持久化(合并)
storage_context.persist(persist_dir="./storage")

删除文档

# 1. 从vector store删除(需要doc_id)
vector_store.delete(document.doc_id)

# 2. 刷新index
index.refresh_ref_docs(documents)  # 增量更新

注意

  • 不是所有vector store支持删除
  • 删除后需要重新build index(某些store不支持)
  • 建议使用doc_id作为唯一标识

十、性能优化与调优

10.1 分块策略优化

影响检索质量的核心

原则

  • 块大小(chunk_size):512-1024 token为宜
    • 太小:语义不完整
    • 太大:噪声多,LLM上下文浪费
  • 重叠(chunk_overlap):50-100 token
    • 避免语义切断在关键信息
  • 分块依据:
    • 语义边界(句子/段落)优于固定字符
    • 代码按函数/类
    • Markdown按标题

实验方法

  1. 固定top-k,调chunk_size
  2. 评估检索精度(人工或自动)
  3. 找到sweet spot

10.2 Embedding模型选择

权衡质量 vs 速度 vs 成本

模型 维度 质量 速度 成本 适用
text-embedding-ada-002 1536 ★★★★★ $$$ 最高质量
text-embedding-3-small 1536 ★★★★☆ $$ 性价比
bge-large-zh 1024 ★★★★★ 0 中文
all-MiniLM-L6-v2 384 ★★★☆☆ 极快 0 原型
paraphrase-multilingual-MiniLM-L12-v2 384 ★★★★☆ 0 多语言

建议

  • 中文优先:BGE(智源)或 M3E(阿里)
  • 多语言:paraphrase-multilingual
  • 英文OpenAI最佳

10.3 向量索引优化

索引类型选择

HNSW(推荐):

  • 构建时间:中等
  • 查询速度:快(O(log N))
  • 内存占用:中
  • 参数:
    • M(连接数,默认16-64)
    • ef_construction(构建时候选集,默认200)
    • ef_search(查询时候选集,越大越准越慢)

IVF_FLAT

  • 构建时间:快
  • 查询速度:中(O(sqrt(N)))
  • 参数:nlist(聚类中心数,通常4*sqrt(N))

PQ(Product Quantization)

  • 内存占用:极低(压缩)
  • 精度损失:有
  • 适合超大规模(亿级)

Milvus示例

from llama_index.vector_stores import MilvusVectorStore

vector_store = MilvusVectorStore(
    dim=1536,
    collection_name="docs",
    index_params={
        "metric_type": "L2",
        "index_type": "HNSW",
        "params": {"M": 16, "efConstruction": 200}
    },
    search_params={
        "metric_type": "L2",
        "params": {"ef": 100}  # ef_search
    }
)

10.4 缓存策略

三层缓存

  1. Embedding缓存:相同text不重复embedding

    from llama_index.embeddings import CacheEmbedding
    
    embed_model = CacheEmbedding(
        embed_model=OpenAIEmbedding(),
        cache_path="./embed_cache.json"
    )
    
  2. 查询结果缓存

    from llama_index.query_engine import RetrieverQueryEngine
    from llama_index.response_synthesizers import CompactResponseSynthesizer
    
    query_engine = RetrieverQueryEngine(
        retriever=retriever,
        response_synthesizer=CompactResponseSynthesizer(),
        cache=Cache()  # 需实现或使用redis
    )
    
  3. LLM响应缓存:使用Redis缓存query→response

    from llama_index.llms import CacheLLM
    
    llm = CacheLLM(
        llm=OpenAI(),
        cache=RedisCache(redis_url="redis://localhost:6379")
    )
    

10.5 异步与并发

异步查询(提升吞吐):

import asyncio
from llama_index import SimpleDirectoryReader, VectorStoreIndex

async def async_query():
    index = await VectorStoreIndex.afrom_documents(documents)
    query_engine = index.as_query_engine()
    response = await query_engine.aquery("xxx")
    return response

asyncio.run(async_query())

并发检索

from llama_index.retrievers import QueryFusionRetriever
import asyncio

retriever = QueryFusionRetriever(
    [vector_retriever1, vector_retriever2],
    similarity_top_k=10,
    use_async=True  # 并发调用多个retriever
)

10.6 批量构建索引

批量处理大量文档

from llama_index.indices import SimpleIndexBuilder

# 分批次处理,避免内存溢出
builder = SimpleIndexBuilder(
    documents,
    embed_model=embed_model,
    vector_store=vector_store,
    chunk_size=512,
    show_progress=True
)
builder.build_index()

10.7 LlamaDebugger(调试)

查看中间步骤

from llama_index import set_global_handler
from llama_index.callbacks import LlamaDebugger

debugger = LlamaDebugger()
set_global_handler(debugger)

# 执行查询
response = query_engine.query("xxx")

# 查看调试信息
print(debugger.get_event_logs())

十一、评估与监控

11.1 评估框架(RAG评估)

11.1.1 内置评估模块

LlamaIndex提供评估数据集和评估器

from llama_index.evaluation import (
    DatasetGenerator,
    RelevancyEvaluator,
    FaithfulnessEvaluator,
    CorrectnessEvaluator
)

# 1. 生成评估数据集(从文档生成QA对)
generator = DatasetGenerator.from_documents(documents)
eval_dataset = generator.generate_dataset_from_nodes(num_questions=10)

# 2. 评估查询引擎
relevancy_evaluator = RelevancyEvaluator()
faithfulness_evaluator = FaithfulnessEvaluator()
correctness_evaluator = CorrectnessEvaluator()

results = []
for query_item in eval_dataset:
    response = query_engine.query(query_item.query)
    
    relevancy = relevancy_evaluator.evaluate(
        query=query_item.query,
        response=response,
        contexts=query_item.contexts  # 期望上下文
    )
    
    faithfulness = faithfulness_evaluator.evaluate(
        query=query_item.query,
        response=response,
        contexts=query_item.contexts
    )
    
    results.append({
        "query": query_item.query,
        "relevancy": relevancy.passing,
        "faithfulness": faithfulness.passing
    })

评估维度

  • Relevancy(相关性):检索到的context是否相关query
  • Faithfulness(忠实度):回答是否基于提供的context(无幻觉)
  • Correctness(正确性):回答是否正确(需参考答案)
  • Semantic Similarity:与参考答案的语义相似度
  • Guideline Adherence:是否符合风格指南

11.1.2 自动评估指标

使用LLM-as-a-Judge

  • 用GPT-4评估其他模型输出
  • Prompt:给定query、context、response,判断是否相关、忠实

传统指标

  • Recall@K:top-k中至少一个相关即召回
  • MRR(Mean Reciprocal Rank):第一个相关文档的排名的倒数均值
  • NDCG(Normalized Discounted Cumulative Gain):考虑排序的加权评分

11.2 监控指标

11.2.1 检索质量监控

  • 检索命中率:top-k中是否有相关doc
  • 平均相似度分数:检索结果平均分(分数分布)
  • 检索延迟:P50/P95/P99
  • 向量查询QPS:每秒查询数

11.2.2 LLM调用监控

  • Token使用量(Prompt + Completion)
  • LLM延迟分布
  • LLM错误率(429、500等)
  • 成本统计(每千token成本)

11.2.3 应用层监控

  • 端到端延迟(query→response)
  • 缓存命中率
  • 并发请求数

11.2.4 集成Prometheus

from llama_index.callbacks import CallbackManager
from llama_index.callbacks.open_inference_callback import OpenInferenceCallback
from llama_index.callbacks.base_handler import BaseCallbackHandler

callback_manager = CallbackManager([
    OpenInferenceCallback()  # 导出OpenTelemetry格式
])

query_engine = index.as_query_engine(callback_manager=callback_manager)

Prometheus指标

  • rag_query_total:总查询数
  • rag_query_duration_seconds:查询耗时
  • rag_retrieval_duration_seconds:检索耗时
  • rag_llm_duration_seconds:LLM耗时
  • rag_cache_hit_total:缓存命中

十二、与LangChain对比

12.1 核心差异

维度 LlamaIndex LangChain
定位 RAG专家 LLM应用全栈
数据层 强大(30+ Readers, Node分块) 中等(Document Loaders)
索引 多种索引(Vector/Keyword/Tree/Graph) 主要Vector
检索 高级(Hybrid、Rerank、Routing) 基础
Agent 不支持或弱 强(Tools、Chains、Agents)
Memory 不支持(需配合) 支持
多模态 部分支持
  • 学习曲线:LlamaIndex更简单(专精),LangChain更复杂(全能)
  • 生产适用性:LlamaIndex更适合纯RAG场景,LangChain适合复杂Agent

12.2 如何选择

选择LlamaIndex

  • 纯RAG应用(问答、搜索)
  • 数据源多样,需要复杂分块
  • 检索质量要求极高(需要rerank、hybrid)
  • 快速原型开发

选择LangChain

  • 需要Agent(工具调用、推理)
  • 需要Memory(对话历史)
  • 多模态应用(图像+文本)
  • 复杂工作流(多个Chain串并联)

两者结合

# 用LlamaIndex做Retriever,LangChain做Agent
from langchain.agents import AgentExecutor, Tool
from llama_index import VectorStoreIndex

index = VectorStoreIndex.from_documents(documents)
retriever = index.as_retriever()

# 包装为LangChain Tool
tool = Tool(
    name="KnowledgeBase",
    func=lambda q: retriever.retrieve(q),
    description="搜索知识库"
)

agent = initialize_agent(
    tools=[tool],
    llm=OpenAI(),
    agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION
)

十三、Java生态支持

13.1 LlamaIndex Java版现状

  • 项目com.llamaindex:llama-index-java(早期实验性质)
  • 状态:功能远少于Python版,社区活跃度低
  • 推荐:Java项目通过REST APIgRPC调用Python部署的LlamaIndex服务

13.2 Spring AI集成(推荐)

Spring AI 2.0+ 内置LlamaIndex支持:

@Configuration
public class LlamaIndexConfig {

    @Bean
    public VectorStore vectorStore() {
        return new SimpleVectorStore(
            new InMemoryEmbeddingStore()
        );
    }

    @Bean
    public EmbeddingClient embeddingClient() {
        return new OpenAIEmbeddingClient(
            new OpenAiApi(apiKey, baseUrl)
        );
    }
}

// 使用
@Autowired
private VectorStore vectorStore;

@Autowired
private EmbeddingClient embeddingClient;

public void buildIndex(List<Document> docs) {
    LlamaIndexVectorStoreAdapter adapter = 
        new LlamaIndexVectorStoreAdapter(vectorStore);
    
    // Document转为LlamaIndex Node
    List<Node> nodes = docs.stream()
        .map(doc -> new Node(doc.getContent(), doc.getMetadata()))
        .collect(Collectors.toList());
    
    // 构建索引
    VectorStoreIndex index = VectorStoreIndex.init(
        nodes, embeddingClient, adapter
    );
    
    // 查询
    QueryEngine queryEngine = index.asQueryEngine();
    Response response = queryEngine.query("What is RAG?");
}

注意:Spring AI的LLamaIndex支持尚在早期,建议:

  1. Python部署LlamaIndex服务
  2. Java通过HTTP/gRPC调用
  3. 使用简化版(Spring AI内置的简单RAG)

13.3 REST API部署方案

架构

Java App → HTTP API → Python LlamaIndex Service → Vector DB + LLM

FastAPI示例

from fastapi import FastAPI
from llama_index import VectorStoreIndex, StorageContext
from pydantic import BaseModel

app = FastAPI()

class QueryRequest(BaseModel):
    query: str
    top_k: int = 10

@app.post("/query")
async def query(request: QueryRequest):
    response = query_engine.query(request.query)
    return {
        "answer": response.response,
        "sources": [node.text for node in response.source_nodes]
    }

@app.post("/index/update")
async def update_index():
    # 增量更新索引
    ...

# 启动:uvicorn main:app --host 0.0.0.0 --port 8000

Java客户端

RestTemplate restTemplate = new RestTemplate();
String url = "http://llamaindex-service:8000/query";
Map<String, Object> request = Map.of("query", "xxx", "top_k", 10);
ResponseEntity<Map> response = restTemplate.postForEntity(url, request, Map.class);

十四、生产部署最佳实践

14.1 架构设计

推荐架构

┌─────────────┐
│   Java App  │ (Spring Boot/微服务)
└──────┬──────┘
       │ HTTP/gRPC
┌──────┴──────┐
│   LlamaIndex│ 部署为独立服务(FastAPI + Uvicorn)
│   Service   │ - 索引构建/更新服务(定时)
│  (Python)   │ - 查询服务(实时)
└──────┬──────┘
       │
┌──────┴──────┐
│   Vector DB │ (Milvus/Qdrant集群)
└──────┬──────┘
       │
┌──────┴──────┐
│  Embedding  │ (本地模型 or OpenAI API)
│   Service   │
└─────────────┘

分离部署

  • 索引构建:批量异步,低优先级集群
  • 查询服务:高可用,多副本,负载均衡
  • 向量DB:集群化,分片+副本
  • Embedding服务:GPU实例(本地模型)或OpenAI

14.2 索引更新策略

方案1:定期全量重建

  • 优点:简单,一致性保证
  • 缺点:资源消耗大,查询中断
  • 适用:数据变化不频繁(<1%

方案2:增量更新

  • 监听数据源变化(CDC、binlog、API webhook)
  • 只更新新增/修改文档
  • 删除:软删除标记,定期清理
  • 推荐:LlamaIndex refresh() API
# 增量更新示例
new_docs = get_new_documents_since(last_update)
index.refresh_ref_docs(new_docs)  # 增量嵌入

方案3:双写+切换

  • 新索引build在新collection
  • 原子切换(rename collection)
  • 零停机,但有短暂延迟

14.3 高可用与扩展

查询服务

  • 多副本(≥3)
  • Nginx/HAProxy负载均衡
  • 健康检查(/health端点)
  • 优雅关闭(处理完现有请求再退出)

向量数据库

  • 分片(Shard):数据量大时分片
  • 副本(Replica):查询负载均衡
  • 异地容灾:主从复制,跨可用区

Embedding服务

  • 本地模型:GPU实例横向扩展
  • OpenAI:调Bucket限制,使用多个API Key轮询

14.4 监控告警

关键指标

  • 查询QPS、错误率、延迟(P95<500ms)
  • 向量查询延迟、QPS
  • Embedding服务延迟、配额使用
  • LLM API调用延迟、错误率、成本
  • 向量DB连接数、内存、磁盘

告警阈值

  • 错误率 > 1%
  • P95延迟 > 2s
  • 可用性 < 99.9%

14.5 成本控制

Embedding成本

  • OpenAI embedding:$0.0001/1k tokens(ada-002)
  • 估算:1GB文本 ≈ 10M tokens ≈ $1
  • 优化:本地模型(bge)免费用,质量接近

LLM成本

  • 缓存高频query
  • 使用便宜模型(gpt-35-turbo替代gpt-4)
  • 压缩context(删除无关chunk)
  • 限制top-k(减少输入token)

向量DB成本

  • 开源vs托管:Milvus自建 vs Zilliz Cloud
  • 内存 vs 磁盘:HNSW需内存,PQ可磁盘
  • 保留策略:删除旧索引

十五、常见问题与解决方案

Q1: 检索不到相关内容?

  • 原因
    • embedding模型与领域不匹配(中文用英文模型)
    • chunk_size太大,语义模糊
    • 查询太长,未优化
  • 解决
    • 换用领域embedding(BGE中文)
    • 减小chunk_size(256-512)
    • 使用query rewrite

Q2: LLM回答幻觉?

  • 原因
    • 检索的context不包含答案
    • context未有效传递给LLM
    • LLM自身知识干扰
  • 解决
    • 增加top-k,使用rerank
    • 检查prompt模板,确保context明确
    • 添加"仅基于上下文回答"指令
    • 使用FaithfulnessEvaluator监控

Q3: 查询速度慢?

  • 优化
    • 向量DB索引优化(ef_search调小)
    • 减少top-k
    • 使用缓存(embedding cache、query cache)
    • 向量DB扩容(更多节点)
    • 使用更快的embedding模型

Q4: 内存溢出?

  • 原因
    • 文档太多,一次性加载
    • 向量数据在内存
    • LLM context过长
  • 解决
    • 分批构建索引
    • 使用Milvus/Pinecone(存储向量)
    • 减少chunk_size和top-k
    • 使用streaming generation

Q5: 多租户需求?

  • 方案
    • 按用户创建不同collection(向量DB层面隔离)
    • 查询时添加metadata filter
    • 索引命名空间:{tenant_id}_index
    • RBAC:应用层控制访问

Q6: 支持多模态?

  • 当前:文本为主,图像需OCR转文本
  • 方案
    • CLIP模型:图像+文本统一embedding
    • 多模态LLM(GPT-4V)直接处理
    • 自定义:图像OCR + 文本RAG

Q7: 实时数据更新?

  • 挑战:索引更新延迟
  • 方案
    • 流式更新:CDC → 消息队列 → LlamaIndex增量更新
    • 短TTL缓存:5-10分钟过期,强制重新查询
    • 混合:定期全量 + 实时增量

Q8: 评估RAG质量?

  • 自动评估:Relevancy、Faithfulness、Correctness
  • 人工评估:随机抽样,标注
  • A/B测试:新旧版本对比关键指标
  • 用户反馈:👍/👎按钮

Q9: 是否支持中文?

  • 完全支持,但需注意:
    • embedding模型:选中文优化(BGE、m3e)
    • 分词器:中文专用
    • LLM:GPT对中文支持好,开源中文模型(ChatGLM、Qwen)
    • 向量DB:无特殊,存储向量

Q10: 生产环境稳定性?

  • 异常处理:try-catch LLM/Embedding API超时
  • 降级策略:embedding失败回退到keyword检索
  • 熔断:Circuit Breaker保护下游API
  • 重试:指数退避重试
  • 监控:全链路监控,快速发现

十六、总结与展望

16.1 LlamaIndex核心优势

  1. 数据连接器最全(30+)
  2. 索引类型丰富(Vector/Keyword/Tree/Graph/Composable)
  3. 检索算法先进(Hybrid、Rerank、Routing、Fusion)
  4. 易用性极佳(几行代码完成RAG)
  5. 生产特性齐全(缓存、异步、监控)

16.2 适用场景

  • ✅ 文档问答
  • ✅ 知识库搜索
  • ✅ 数据分析助手
  • ✅ 研究助手
  • ❌ 复杂Agent(需LangChain)
  • ❌ 多模态(部分支持)
  • ❌ 流式实时处理

16.3 学习路径

  1. 入门:VectorStoreIndex + QueryEngine(2小时)
  2. 进阶:高级检索(Hybrid、Rerank)+ 评估(1周)
  3. 高级:自定义组件 + 生产部署(1月)
  4. 专家:源码阅读 + 二次开发(数月)

16.4 未来方向

  • 多模态索引:图像、音频向量统一
  • 实时索引更新:流式数据低延迟
  • Agent集成:更紧密支持ReAct等
  • 云原生:K8s Operator部署
  • 联邦学习:隐私保护下的联合索引
  • AutoML for RAG:自动选择索引策略

文档版本:v1.0
最后更新:2025年3月
参考:https://docs.llamaindex.ai

0
  1. 支付宝打赏

    qrcode alipay
  2. 微信打赏

    qrcode weixin

评论区