跳转至

LlamaIndex 知识引擎

为什么要学

LlamaIndex(原 GPT Index)是最专注于"数据连接+索引+查询"的 AI 框架:

  • 数据连接:160+ 数据源连接器(PDF、数据库、API、网页等)
  • 智能索引:多种索引策略优化检索质量
  • 查询引擎:从简单 QA 到复杂的多步推理
  • 生产就绪:LlamaCloud 提供托管的解析和索引服务
  • Agent 支持:基于数据的 Agent 和工作流

如果你的核心需求是"让 AI 理解和查询你的数据",LlamaIndex 是最专业的选择。

核心概念

白话解释

LlamaIndex 解决的问题链: 1. 连接:你的数据在各种地方(文件/数据库/API)→ 统一读取 2. 索引:数据太多,AI 看不完 → 建立索引加速查找 3. 查询:用户提问 → 找到相关信息 → AI 生成回答

核心概念对照表

概念说明类比
Document数据源的原始内容一个文件/网页
Node文档拆分后的块段落/小节
Index对Nodes的组织结构图书馆索引
VectorStoreIndex向量索引(最常用)语义搜索引擎
QueryEngine查询执行器搜索接口
Retriever检索器(从Index中找相关Node)图书管理员
ResponseSynthesizer将检索结果合成回答写作助手
Reader/Loader数据读取器文件打开器
Embedding文本向量化语义编码
LLM大语言模型AI大脑

安装配置

安装

# 核心包
pip install llama-index

# 或按需安装
pip install llama-index-core
pip install llama-index-llms-openai
pip install llama-index-embeddings-openai
pip install llama-index-vector-stores-chroma

# 常用Reader
pip install llama-index-readers-file  # PDF/DOCX等
pip install llama-index-readers-web   # 网页
pip install llama-index-readers-database  # 数据库

环境配置

import os
os.environ["OPENAI_API_KEY"] = "sk-..."

# 或在代码中配置
from llama_index.core import Settings
from llama_index.llms.openai import OpenAI
from llama_index.embeddings.openai import OpenAIEmbedding

Settings.llm = OpenAI(model="gpt-4o-mini", temperature=0.1)
Settings.embed_model = OpenAIEmbedding(model="text-embedding-3-small")

快速上手

5 行代码构建 RAG

from llama_index.core import VectorStoreIndex, SimpleDirectoryReader

# 1. 读取文档
documents = SimpleDirectoryReader("./data/").load_data()

# 2. 创建索引
index = VectorStoreIndex.from_documents(documents)

# 3. 查询
query_engine = index.as_query_engine()
response = query_engine.query("这份文档的主要内容是什么?")
print(response)

从不同数据源加载

from llama_index.core import SimpleDirectoryReader

# 支持多种文件格式
documents = SimpleDirectoryReader(
    input_dir="./docs/",
    required_exts=[".pdf", ".md", ".txt", ".docx"],
    recursive=True
).load_data()

# 从URL加载
from llama_index.readers.web import SimpleWebPageReader
web_docs = SimpleWebPageReader().load_data(
    urls=["https://docs.example.com/guide"]
)

# 从数据库加载
from llama_index.readers.database import DatabaseReader
db_reader = DatabaseReader(uri="postgresql://localhost/mydb")
db_docs = db_reader.load_data(query="SELECT content FROM articles")

持久化索引

# 保存索引到磁盘
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)

进阶用法

1. 自定义分块策略

from llama_index.core.node_parser import (
    SentenceSplitter,
    SemanticSplitterNodeParser,
    HierarchicalNodeParser
)

# 按句子分块
splitter = SentenceSplitter(
    chunk_size=512,
    chunk_overlap=50,
    separator="\n"
)

# 语义分块(按语义边界切分)
from llama_index.embeddings.openai import OpenAIEmbedding
semantic_splitter = SemanticSplitterNodeParser(
    embed_model=OpenAIEmbedding(),
    breakpoint_percentile_threshold=95
)

# 层级分块(大块→小块)
hierarchical_splitter = HierarchicalNodeParser.from_defaults(
    chunk_sizes=[2048, 512, 128]
)

# 使用自定义分块
from llama_index.core import VectorStoreIndex
from llama_index.core.ingestion import IngestionPipeline

pipeline = IngestionPipeline(
    transformations=[
        splitter,
        OpenAIEmbedding()
    ]
)

nodes = pipeline.run(documents=documents)
index = VectorStoreIndex(nodes)

2. 混合检索 + 重排序

from llama_index.core.retrievers import VectorIndexRetriever
from llama_index.retrievers.bm25 import BM25Retriever
from llama_index.core.query_engine import RetrieverQueryEngine
from llama_index.core.postprocessor import SentenceTransformerRerank

# 向量检索器
vector_retriever = VectorIndexRetriever(index=index, similarity_top_k=10)

# BM25检索器
bm25_retriever = BM25Retriever.from_defaults(index=index, similarity_top_k=10)

# 融合检索
from llama_index.core.retrievers import QueryFusionRetriever

fusion_retriever = QueryFusionRetriever(
    retrievers=[vector_retriever, bm25_retriever],
    similarity_top_k=10,
    num_queries=3,  # 生成3个变体查询
    mode="reciprocal_rerank"
)

# 重排序
reranker = SentenceTransformerRerank(
    model="cross-encoder/ms-marco-MiniLM-L-6-v2",
    top_n=5
)

# 组合查询引擎
query_engine = RetrieverQueryEngine.from_args(
    retriever=fusion_retriever,
    node_postprocessors=[reranker]
)

response = query_engine.query("解释系统的认证机制")

3. 子问题查询引擎

from llama_index.core.query_engine import SubQuestionQueryEngine
from llama_index.core.tools import QueryEngineTool, ToolMetadata

# 为不同文档创建不同的查询引擎
api_engine = api_index.as_query_engine()
arch_engine = arch_index.as_query_engine()

# 定义工具
tools = [
    QueryEngineTool(
        query_engine=api_engine,
        metadata=ToolMetadata(name="api_docs", description="API文档,包含接口定义和使用方法")
    ),
    QueryEngineTool(
        query_engine=arch_engine,
        metadata=ToolMetadata(name="architecture", description="架构文档,包含系统设计和模块说明")
    )
]

# 子问题引擎会自动拆解复杂问题
sub_question_engine = SubQuestionQueryEngine.from_defaults(query_engine_tools=tools)

response = sub_question_engine.query(
    "这个系统的认证API是怎么设计的?它与整体架构是什么关系?"
)
# AI会自动将问题拆成:1.查API文档找认证API  2.查架构文档找相关设计  3.综合回答

4. Agent(工具使用)

from llama_index.core.agent import ReActAgent
from llama_index.core.tools import FunctionTool

# 定义工具
def search_code(query: str) -> str:
    """在代码库中搜索相关代码片段"""
    # 实现搜索逻辑
    return f"找到关于'{query}'的代码..."

def run_sql(query: str) -> str:
    """执行SQL查询获取数据"""
    # 实现SQL执行
    return f"SQL结果: ..."

tools = [
    FunctionTool.from_defaults(fn=search_code),
    FunctionTool.from_defaults(fn=run_sql),
    # 也可以用QueryEngine作为工具
    QueryEngineTool.from_defaults(
        query_engine=doc_engine,
        name="documentation",
        description="查询项目文档"
    )
]

# 创建Agent
agent = ReActAgent.from_tools(
    tools=tools,
    llm=OpenAI(model="gpt-4o"),
    verbose=True
)

response = agent.chat("数据库中有多少活跃用户?文档中对活跃用户的定义是什么?")

5. 向量存储集成

# ChromaDB
from llama_index.vector_stores.chroma import ChromaVectorStore
import chromadb

chroma_client = chromadb.PersistentClient(path="./chroma_db")
collection = chroma_client.get_or_create_collection("my_docs")
vector_store = ChromaVectorStore(chroma_collection=collection)

# 使用外部向量存储创建索引
from llama_index.core import StorageContext
storage_context = StorageContext.from_defaults(vector_store=vector_store)
index = VectorStoreIndex.from_documents(documents, storage_context=storage_context)

# Qdrant
from llama_index.vector_stores.qdrant import QdrantVectorStore
vector_store = QdrantVectorStore(
    url="http://localhost:6333",
    collection_name="my_docs"
)

# PostgreSQL (pgvector)
from llama_index.vector_stores.postgres import PGVectorStore
vector_store = PGVectorStore.from_params(
    database="mydb",
    host="localhost",
    password="...",
    table_name="embeddings"
)

6. Workflow(新一代编排)

from llama_index.core.workflow import Workflow, step, Context, Event, StartEvent, StopEvent

class QueryEvent(Event):
    query: str

class RetrieveEvent(Event):
    nodes: list

class RAGWorkflow(Workflow):
    @step
    async def rewrite_query(self, ev: StartEvent) -> QueryEvent:
        """查询改写"""
        # 用LLM优化查询
        rewritten = await self.llm.acomplete(f"优化搜索查询: {ev.query}")
        return QueryEvent(query=str(rewritten))

    @step
    async def retrieve(self, ev: QueryEvent) -> RetrieveEvent:
        """检索文档"""
        nodes = await self.retriever.aretrieve(ev.query)
        return RetrieveEvent(nodes=nodes)

    @step
    async def synthesize(self, ev: RetrieveEvent) -> StopEvent:
        """生成回答"""
        response = await self.synthesizer.asynthesize(
            query=ev.query,
            nodes=ev.nodes
        )
        return StopEvent(result=str(response))

# 运行Workflow
workflow = RAGWorkflow()
result = await workflow.run(query="什么是向量数据库?")

7. 使用本地模型

from llama_index.llms.ollama import Ollama
from llama_index.embeddings.huggingface import HuggingFaceEmbedding
from llama_index.core import Settings

# 本地LLM
Settings.llm = Ollama(model="llama3.2", request_timeout=120)

# 本地Embedding
Settings.embed_model = HuggingFaceEmbedding(
    model_name="BAAI/bge-small-zh-v1.5"
)

# 后续正常使用即可
index = VectorStoreIndex.from_documents(documents)

常见问题

Q1: 和 LangChain 的区别?

方面LlamaIndexLangChain
核心能力数据索引+检索通用LLM编排
RAG质量更专业(多种索引策略)基础
Agent基本支持更丰富
数据连接160+连接器较少
学习曲线中等陡峭

Q2: 如何提升 RAG 质量?

  1. 分块优化:使用语义分块而非固定大小
  2. 混合检索:向量 + BM25 关键词
  3. 重排序:用 Cross-Encoder 精排
  4. 查询改写:让 LLM 优化用户查询
  5. 元数据过滤:利用文档元数据预过滤

Q3: 索引很大时性能问题?

  • 使用外部向量存储(Qdrant/Pinecone)
  • 利用元数据预过滤减小搜索范围
  • 使用分层索引(先粗筛后精排)
  • 考虑 LlamaCloud 托管服务

Q4: 如何处理大文档?

# 使用层级索引
from llama_index.core.node_parser import HierarchicalNodeParser
from llama_index.core.retrievers import AutoMergingRetriever

# 大块概览 + 小块详情
parser = HierarchicalNodeParser.from_defaults(chunk_sizes=[2048, 512, 128])
nodes = parser.get_nodes_from_documents(documents)

Q5: 更新文档后如何刷新索引?

# 增量更新
index.insert(new_document)

# 删除旧文档
index.delete_ref_doc(doc_id)

# 完全重建
index.refresh_ref_docs(documents)

参考资源