Agent框架横评(三):LlamaIndex我的RAG知识库专家

7次阅读
没有评论

Agent框架横评(三):LlamaIndex我的RAG知识库专家

一、开场:LlamaIndex是什么

大家好,我是老金。

构建知识库问答系统,LlamaIndex是首选。

它专注于检索增强生成(RAG),让LLM基于私有知识回答问题。

今天聊聊LlamaIndex的Agent能力。

二、LlamaIndex是什么

2.1 定位

LlamaIndex(原GPT Index)是一个数据框架,专注于:

  • 加载外部数据
  • 构建索引
  • 检索增强
  • Agent问答

核心优势:知识检索

2.2 与LangChain对比

方面 LlamaIndex LangChain
定位 数据检索专家 应用开发框架
核心能力 索引/检索 Chain/Agent
RAG支持 ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐
Agent能力 ⭐⭐⭐⭐ ⭐⭐⭐⭐⭐
学习曲线 较平缓 较陡峭

2.3 架构

┌─────────────────────────────────────────────────────────┐
│                  LlamaIndex架构                        │
├─────────────────────────────────────────────────────────┤
│                                                         │
│  ┌─────────────────────────────────────────────────┐   │
│  │              数据层                              │   │
│  │  • 数据连接器 (Loaders)                         │   │
│  │  • 文档解析 (Parsers)                           │   │
│  │  • Node节点                                      │   │
│  └────────────────────┬────────────────────────────┘   │
│                       ↓                                 │
│  ┌─────────────────────────────────────────────────┐   │
│  │              索引层                              │   │
│  │  • VectorIndex                                  │   │
│  │  • SummaryIndex                                 │   │
│  │  • TreeIndex                                    │   │
│  │  • KeywordTableIndex                            │   │
│  └────────────────────┬────────────────────────────┘   │
│                       ↓                                 │
│  ┌─────────────────────────────────────────────────┐   │
│  │              查询层                              │   │
│  │  • Retriever                                    │   │
│  │  • Query Engine                                 │   │
│  │  • Chat Engine                                  │   │
│  │  • Agent                                        │   │
│  └─────────────────────────────────────────────────┘   │
│                                                         │
└─────────────────────────────────────────────────────────┘

三、数据加载

3.1 多种数据源

from llama_index import download_loader

# PDF
PDFReader = download_loader("PDFReader")
loader = PDFReader()
documents = loader.load_data(file='./data/report.pdf')

# Notion
NotionPageReader = download_loader("NotionPageReader")
loader = NotionPageReader(api_key="secret_xxx")
documents = loader.load_data(page_ids=["xxx", "yyy"])

# Slack
SlackDocumentReader = download_loader("SlackDocumentReader")
loader = SlackDocumentReader(
    slack_token="xoxb-xxx",
    channel_ids=["C12345"]
)
documents = loader.load_data()

# Discord, GitBook, Wikipedia, Database...

3.2 文档解析

from llama_index import Document

# 简单文档
doc = Document(
    text="这是一段文本内容",
    metadata={"source": "manual", "author": "老金"}
)

# 批量解析
from llama_index import SimpleDirectoryReader

reader = SimpleDirectoryReader(
    input_dir="./data",
    recursive=True,  # 递归子目录
    exclude=["*.exe", "*.zip"],
    file_metadata=lambda x: {"file_name": x}  # 自定义元数据
)

documents = reader.load_data()
print(f"加载了 {len(documents)} 个文档")

3.3 节点解析

from llama_index.node_parser import SimpleNodeParser

# 简单节点解析
parser = SimpleNodeParser.from_defaults(
    chunk_size=1024,      # 块大小
    chunk_overlap=200,    # 重叠大小
    metadata_separator="n---metadata---n"
)

nodes = parser.get_nodes_from_documents(documents)

# 语义分块(更智能)
from llama_index.node_parser import SemanticSplitterNodeParser
from llama_index.embeddings import OpenAIEmbedding

parser = SemanticSplitterNodeParser(
    embed_model=OpenAIEmbedding(),
    buffer_size=1,
    breakpoint_percentile_threshold=95
)

nodes = parser.get_nodes_from_documents(documents)

四、索引构建

4.1 向量索引

from llama_index import VectorStoreIndex

# 构建向量索引
index = VectorStoreIndex.from_documents(
    documents,
    embed_model="text-embedding-ada-002"
)

# 保存/加载
index.save_to_disk("./index_store.json")
# index = VectorStoreIndex.load_from_disk("./index_store.json")

# 自定义配置
index = VectorStoreIndex.from_documents(
    documents,
    embed_model=OpenAIEmbedding(model="text-embedding-3-small"),
    service_context=ServiceContext.from_defaults(
        chunk_size=512,
        chunk_overlap=50
    )
)

4.2 多索引组合

from llama_index import VectorStoreIndex, SummaryIndex
from llama_index.composability import QASummaryComposableGraph

# 多文档索引
graph = QASummaryComposableGraph.from_documents(
    documents,
    index_cls=VectorStoreIndex,
    summary_template="请总结以下文档的核心内容:n{context}nn总结:"
)

# 查询
response = graph.query("文档的主要观点是什么?")

4.3 索引类型选择

索引类型 适用场景 特点
VectorStoreIndex 语义检索 通用
SummaryIndex 总结
TreeIndex 层级查询 复杂文档
KeywordTableIndex 关键词检索 精确

五、查询引擎

5.1 基础查询

# 创建查询引擎
query_engine = index.as_query_engine(
    similarity_top_k=3,  # 返回Top3
    response_mode="compact"  # compact/TreeSummarize/Accumulate
)

# 查询
response = query_engine.query("项目的主要目标是什么?")
print(response)
print(response.source_nodes)  # 查看引用来源

5.2 检索器配置

from llama_index.retrievers import VectorIndexRetriever
from llama_index.query_engine import RetrieverQueryEngine

# 自定义检索器
retriever = VectorIndexRetriever(
    index=index,
    similarity_top_k=5,
    filters=MetadataFilters([
        EqualFilter(key="source", value="manual")
    ])
)

# 构建查询引擎
query_engine = RetrieverQueryEngine(retriever=retriever)

5.3 高级查询模式

# 子问题查询(把复杂问题拆成多个简单问题)
from llama_index.query_engine import SubQuestionQueryEngine

query_engine = SubQuestionQueryEngine.from_defaults(
    query_engine_tools=[
        {
            "name": "project_docs",
            "query_engine": project_index.as_query_engine(),
            "description": "项目文档"
        },
        {
            "name": "api_docs",
            "query_engine": api_index.as_query_engine(),
            "description": "API文档"
        }
    ]
)

response = query_engine.query(
    "项目如何部署?API有哪些端点?"
)  # 会自动拆分为两个问题

六、Chat Engine

6.1 对话引擎

# 创建Chat引擎
chat_engine = index.as_chat_engine(
    chat_mode="condense_plus_context",  # 保留上下文
    similarity_top_k=3,
    system_prompt="你是一个专业的技术助手,基于提供的文档回答问题。"
)

# 对话
response = chat_engine.chat("如何部署这个应用?")
print(response)

# 继续对话
response = chat_engine.chat("需要哪些前置条件?")
print(response)

# 重置
chat_engine.reset()

6.2 上下文Chat

# Condense模式:压缩历史,保留关键上下文
chat_engine = index.as_chat_engine(
    chat_mode="condense",
    condense_prompt_template="""
给定以下对话历史和用户新问题,重新组织一个独立的问题:

对话历史:
{chat_history}

新问题:{question}

独立问题:"""
)

七、Agent能力

7.1 OpenAI Agent

from llama_index.agent import OpenAIAgent
from llama_index.tools import QueryEngineTool

# 定义工具
query_engine = index.as_query_engine(similarity_top_k=3)

tools = [
    QueryEngineTool(
        query_engine=query_engine,
        metadata=ToolMetadata(
            name="knowledge_base",
            description="查询知识库中关于项目的信息"
        )
    )
]

# 创建Agent
agent = OpenAIAgent.from_tools(
    tools=tools,
    system_prompt="你是一个技术助手,可以回答关于项目的问题。",
    verbose=True
)

# 运行
response = agent.chat("项目使用的技术栈是什么?")

7.2 ReAct Agent

from llama_index.agent import ReActAgent

# ReAct模式
agent = ReActAgent.from_tools(
    tools=tools,
    system_prompt="你是一个技术助手。",
    max_iterations=10
)

7.3 自定义Agent

from llama_index.agent import Agent
from llama_index.tools import Tool

class MyCustomAgent(Agent):
    def __init__(self, tools: List[Tool], **kwargs):
        super().__init__(tools=tools, **kwargs)
        self.llm = OpenAI(model="gpt-4")

    async def query(self, user_input: str) -> Response:
        # 1. 理解意图
        intent = await self.understand_intent(user_input)

        # 2. 选择工具
        if intent.needs_tool:
            tool = self.select_tool(intent)
            result = await tool.call(intent.tool_input)
            return await self.generate_response(result)
        else:
            return await self.generate_response(user_input)

    async def understand_intent(self, user_input: str):
        # 调用LLM理解意图
        pass

    async def select_tool(self, intent):
        # 选择工具
        pass

八、知识图谱索引

8.1 知识图谱构建

from llama_index import KnowledgeGraphIndex
from llama_index.storage.storage_context import StorageContext

# 构建知识图谱索引
kg_index = KnowledgeGraphIndex.from_documents(
    documents,
    max_triplet_clause_depth=2,
    storage_context=StorageContext.from_defaults(
        persist_dir="./graph_store"
    )
)

# 查询
query_engine = kg_index.as_query_engine(
    include_start_response=True,
    response_mode="tree_generate"
)

response = query_engine.query("老金的技术栈是什么?")

8.2 混合检索

from llama_index.retrievers import QueryFusionRetriever

# 混合检索:向量+关键词+知识图谱
retriever = QueryFusionRetriever(
    retrievers=[
        vector_retriever,
        keyword_retriever,
        kg_retriever
    ],
    mode="reciprocal_rerank",  # 重排序
    top_k=5
)

query_engine = RetrieverQueryEngine(retriever=retriever)

九、优缺点分析

9.1 优点

优点 说明
RAG专注 检索能力最强
文档解析强 支持多种格式
索引丰富 向量/树/图多种
与LangChain兼容 可组合使用

9.2 缺点

缺点 说明
Agent能力弱 不如LangChain
组件封装 灵活性受限
文档质量 部分文档陈旧

9.3 最佳实践

# 最佳实践:RAG + Agent组合
# 用LlamaIndex做检索,LangChain做Agent

from llama_index import VectorStoreIndex
from langchain.chains import ConversationalRetrievalChain

# LlamaIndex索引
index = VectorStoreIndex.from_documents(documents)

# LangChain检索链
retriever = index.as_retriever()
qa_chain = ConversationalRetrievalChain.from_llm(
    llm=ChatOpenAI(),
    retriever=retriever
)

十、总结

适用场景

场景 推荐度
RAG知识库 ⭐⭐⭐⭐⭐
文档问答 ⭐⭐⭐⭐⭐
客服系统 ⭐⭐⭐⭐
Agent开发 ⭐⭐⭐

框架评分

维度 评分
易用性 8/10
RAG能力 10/10
Agent能力 7/10
文档解析 9/10
性能 8/10

下期预告

下一篇:CrewAI——Multi-Agent协作框架让团队效率翻倍!


相关阅读

正文完
 0
技术老金
版权声明:本站原创文章,由 技术老金 于2026-04-03发表,共计7199字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(没有评论)