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协作框架让团队效率翻倍!
相关阅读
正文完