RAG + Agent 架构
RAG(Retrieval-Augmented Generation)+ Agent 是将检索增强生成与智能体执行能力结合的架构模式。通过检索外部知识增强 Agent 的知识边界,同时保留 Agent 的规划和工具调用能力,实现知识密集型任务的智能处理。
一、核心原理
1.1 设计哲学
RAG + Agent 的核心思想是检索增强与执行能力的融合:
┌─────────────────────────────────────────────────────────────┐
│ RAG + Agent 设计哲学 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 纯 RAG 架构: │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ Query │ ──→ │ Retrieve│ ──→ │ Generate│ │
│ └─────────┘ └─────────┘ └─────────┘ │
│ 只能回答问题,无法执行操作 │
│ │
│ 纯 Agent 架构: │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ Query │ ──→ │ Agent │ ──→ │ Action │ │
│ └─────────┘ └─────────┘ └─────────┘ │
│ 可以执行,但知识有限 │
│ │
│ RAG + Agent 架构: │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ ┌─────────┐ │ │
│ │ │ Query │ │ │
│ │ └────┬────┘ │ │
│ │ │ │ │
│ │ ↓ │ │
│ │ ┌─────────┐ ┌─────────┐ │ │
│ │ │ Retrieve│ ──→ │ Context │ │ │
│ │ │ 检索 │ │ 增强 │ │ │
│ │ └─────────┘ └────┬────┘ │ │
│ │ │ │ │
│ │ ↓ │ │
│ │ ┌─────────────────────────────────────────┐ │ │
│ │ │ Agent 核心 │ │ │
│ │ │ │ │ │
│ │ │ Thought → Action → Observation │ │ │
│ │ │ │ │ │
│ │ │ 可调用工具 + 可引用检索内容 │ │ │
│ │ │ │ │ │
│ │ └─────────────────────────────────────────┘ │ │
│ │ │ │ │
│ │ ↓ │ │
│ │ ┌───────────┐ │ │
│ │ │ Output │ │ │
│ │ └───────────┘ │ │
│ │ │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ 核心价值:知识增强 + 执行能力 │
│ │
└─────────────────────────────────────────────────────────────┘1.2 核心组件
| 组件 | 职责 | 输入 | 输出 |
|---|---|---|---|
| Retriever | 检索相关文档 | Query | 相关文档列表 |
| Context Builder | 构建增强上下文 | 检索结果 + Query | 增强的 Prompt |
| Agent Core | 推理和决策 | 增强上下文 | Thought/Action |
| Tool Executor | 执行工具调用 | Action | 执行结果 |
| Memory | 存储对话历史 | 对话记录 | 历史上下文 |
1.3 三种融合模式
┌─────────────────────────────────────────────────────────────┐
│ RAG + Agent 三种融合模式 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 模式一:检索优先(Retrieve-First) │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ Query → 检索 → 注入上下文 → Agent 执行 │ │
│ │ │ │
│ │ 适用:知识查询类任务 │ │
│ │ 特点:检索内容作为背景知识 │ │
│ │ │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ 模式二:按需检索(On-Demand Retrieval) │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ Query → Agent 判断 → 需要检索? → 检索 → 执行 │ │
│ │ ↓ │ │
│ │ 不需要 → 直接执行 │ │
│ │ │ │
│ │ 适用:混合型任务 │ │
│ │ 特点:Agent 自主决定是否检索 │ │
│ │ │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ 模式三:工具化检索(Retrieval-as-Tool) │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ Query → Agent 执行 → 调用检索工具 → 获取结果 │ │
│ │ │ │
│ │ 适用:复杂推理任务 │ │
│ │ 特点:检索作为 Agent 可调用的工具之一 │ │
│ │ │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘1.4 与传统 RAG 对比
| 对比维度 | 传统 RAG | RAG + Agent |
|---|---|---|
| 执行能力 | 无 | 有(工具调用) |
| 知识来源 | 检索 | 检索 + 工具 + 推理 |
| 决策方式 | 直接生成 | 思考后决策 |
| 多步推理 | 不支持 | 支持 |
| 动态调整 | 不支持 | 支持 |
| 适用场景 | 知识问答 | 知识密集型任务 |
二、工作流程
2.1 完整工作流程图
┌─────────────────────────────────────────────────────────────────────┐
│ RAG + Agent 完整工作流程 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ │
│ │ 用户输入 │ │
│ │ (Query) │ │
│ └──────┬──────┘ │
│ │ │
│ ↓ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ 检索增强阶段 │ │
│ │ ┌───────────────────────────────────────────────────────┐ │ │
│ │ │ │ │ │
│ │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │
│ │ │ │ Query │ ──→ │ Embedding│ ──→ │ Vector │ │ │ │
│ │ │ │ 理解 │ │ 向量化 │ │ Search │ │ │ │
│ │ │ └──────────┘ └──────────┘ └────┬─────┘ │ │ │
│ │ │ │ │ │ │
│ │ │ ↓ │ │ │
│ │ │ ┌──────────┐ │ │ │
│ │ │ │ Top-K │ │ │ │
│ │ │ │ Chunks │ │ │ │
│ │ │ └────┬─────┘ │ │ │
│ │ │ │ │ │ │
│ │ │ ↓ │ │ │
│ │ │ ┌──────────┐ │ │ │
│ │ │ │ Context │ │ │ │
│ │ │ │ Builder │ │ │ │
│ │ │ └────┬─────┘ │ │ │
│ │ │ │ │ │ │
│ │ └────────────────────────────────────────┼─────────────┘ │ │
│ │ │ │ │
│ └────────────────────────────────────────────┼─────────────────┘ │
│ │ │
│ ↓ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ Agent 执行阶段 │ │
│ │ │ │
│ │ ┌──────────────────────────────────────────────────────┐ │ │
│ │ │ Agent 循环 │ │ │
│ │ │ │ │ │
│ │ │ ┌──────────┐ │ │ │
│ │ │ │ Thought │ ←─── 参考检索上下文 │ │ │
│ │ │ │ 思考 │ │ │ │
│ │ │ └────┬─────┘ │ │ │
│ │ │ │ │ │ │
│ │ │ ↓ │ │ │
│ │ │ ┌──────────┐ ┌──────────────────────────────┐ │ │ │
│ │ │ │ Action │ ──→ │ 工具选择 │ │ │ │
│ │ │ │ 行动 │ │ • search_tool │ │ │ │
│ │ │ └────┬─────┘ │ • database_query │ │ │ │
│ │ │ │ │ • api_call │ │ │ │
│ │ │ │ │ • retrieval_tool (按需) │ │ │ │
│ │ │ │ └──────────────────────────────┘ │ │ │
│ │ │ │ │ │ │
│ │ │ ↓ │ │ │
│ │ │ ┌──────────┐ │ │ │
│ │ │ │Observation│ │ │ │
│ │ │ │ 观察 │ │ │ │
│ │ │ └────┬─────┘ │ │ │
│ │ │ │ │ │ │
│ │ │ └────────────────── 循环 │ │ │
│ │ │ │ │ │
│ │ └───────────────────────────────────────────────────────┘ │ │
│ │ │ │ │
│ │ ↓ │ │
│ │ ┌───────────────┐ │ │
│ │ │ 完成判断 │ │ │
│ │ └───────┬───────┘ │ │
│ │ │ │ │
│ └────────────────────────────┼─────────────────────────────────┘ │
│ │ │
│ ↓ │
│ ┌─────────────────────┐ │
│ │ 生成最终回答 │ │
│ │ (Final Answer) │ │
│ └─────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘2.2 检索策略详解
"""
检索策略详解
"""
# 1. 语义检索
def semantic_retrieval(query: str, vector_store, top_k: int = 5):
"""基于向量相似度的语义检索"""
query_embedding = embed(query)
results = vector_store.similarity_search(
query_embedding,
k=top_k
)
return results
# 2. 混合检索
def hybrid_retrieval(query: str, vector_store, keyword_index, top_k: int = 5):
"""混合检索:语义 + 关键词"""
# 语义检索
semantic_results = vector_store.similarity_search(query, k=top_k)
# 关键词检索
keyword_results = keyword_index.search(query, k=top_k)
# 融合结果(RRF)
return reciprocal_rank_fusion(
semantic_results,
keyword_results
)
# 3. 多跳检索
def multi_hop_retrieval(query: str, vector_store, hops: int = 2):
"""多跳检索:递归检索相关文档"""
context = []
current_query = query
for _ in range(hops):
results = vector_store.similarity_search(current_query, k=3)
context.extend(results)
# 基于检索结果生成下一个查询
current_query = generate_next_query(query, results)
return context
# 4. 自适应检索
def adaptive_retrieval(query: str, agent):
"""Agent 自主决定是否检索"""
prompt = f"""
用户问题:{query}
请判断是否需要检索外部知识来回答这个问题。
输出:需要检索 / 不需要检索
"""
decision = agent.llm(prompt)
if "需要检索" in decision:
return retrieve(query)
else:
return None2.3 上下文构建
┌─────────────────────────────────────────────────────────────┐
│ 上下文构建示例 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 用户问题:公司最新的年假政策是什么? │
│ │
│ 检索结果: │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ [文档1] 公司员工手册 - 第3章 休假制度 │ │
│ │ ...年假规定:工作满1年享有5天年假,满3年享有10天... │ │
│ │ │ │
│ │ [文档2] 2024年休假政策更新通知 │ │
│ │ ...自2024年1月起,年假政策调整如下: │ │
│ │ 工作满1年:5天 → 7天 │ │
│ │ 工作满3年:10天 → 12天 │ │
│ │ 工作满5年:15天 → 18天... │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ 构建的增强 Prompt: │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 你是一个智能助手,请基于以下知识回答用户问题。 │ │
│ │ │ │
│ │ 【相关知识】 │ │
│ │ [1] 公司员工手册 - 第3章 休假制度 │ │
│ │ 年假规定:工作满1年享有5天年假,满3年享有10天... │ │
│ │ │ │
│ │ [2] 2024年休假政策更新通知 │ │
│ │ 自2024年1月起,年假政策调整: │ │
│ │ 工作满1年:7天;满3年:12天;满5年:18天 │ │
│ │ │ │
│ │ 【用户问题】 │ │
│ │ 公司最新的年假政策是什么? │ │
│ │ │ │
│ │ 【可用工具】 │ │
│ │ - search: 搜索更多信息 │ │
│ │ - database: 查询员工数据库 │ │
│ │ - calculator: 计算相关数值 │ │
│ │ │ │
│ │ 请回答问题,如需使用工具请注明。 │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘三、代码实现
3.1 基础实现
"""
RAG + Agent 基础实现
"""
from typing import List, Dict, Any, Optional
from dataclasses import dataclass
from langchain.vectorstores import VectorStore
from langchain.embeddings import Embeddings
from langchain.llms import BaseLLM
from langchain.tools import BaseTool
@dataclass
class RetrievedDocument:
"""检索到的文档"""
content: str
metadata: Dict[str, Any]
score: float
class Retriever:
"""检索器"""
def __init__(
self,
vector_store: VectorStore,
embeddings: Embeddings,
top_k: int = 5
):
self.vector_store = vector_store
self.embeddings = embeddings
self.top_k = top_k
def retrieve(self, query: str) -> List[RetrievedDocument]:
"""检索相关文档"""
# 向量检索
docs = self.vector_store.similarity_search_with_score(
query,
k=self.top_k
)
return [
RetrievedDocument(
content=doc.page_content,
metadata=doc.metadata,
score=score
)
for doc, score in docs
]
class ContextBuilder:
"""上下文构建器"""
CONTEXT_TEMPLATE = """
你是一个智能助手,请基于以下知识回答用户问题。
【相关知识】
{context}
【用户问题】
{query}
【可用工具】
{tool_descriptions}
请回答问题。如果需要使用工具,请说明要使用哪个工具和参数。
"""
def __init__(self, max_context_length: int = 4000):
self.max_context_length = max_context_length
def build(
self,
query: str,
documents: List[RetrievedDocument],
tools: List[BaseTool] = None
) -> str:
"""构建增强上下文"""
# 构建知识上下文
context_parts = []
current_length = 0
for i, doc in enumerate(documents):
doc_text = f"[{i+1}] {doc.metadata.get('source', '未知')}\n{doc.content}\n"
if current_length + len(doc_text) > self.max_context_length:
break
context_parts.append(doc_text)
current_length += len(doc_text)
context = "\n".join(context_parts)
# 构建工具描述
tool_descriptions = ""
if tools:
tool_descriptions = "\n".join([
f"- {tool.name}: {tool.description}"
for tool in tools
])
# 组装完整 Prompt
return self.CONTEXT_TEMPLATE.format(
context=context,
query=query,
tool_descriptions=tool_descriptions or "无可用工具"
)
class RAGAgent:
"""RAG + Agent"""
def __init__(
self,
llm: BaseLLM,
retriever: Retriever,
context_builder: ContextBuilder,
tools: List[BaseTool] = None,
verbose: bool = True
):
self.llm = llm
self.retriever = retriever
self.context_builder = context_builder
self.tools = {tool.name: tool for tool in (tools or [])}
self.verbose = verbose
def run(self, query: str) -> str:
"""运行 Agent"""
if self.verbose:
print(f"[查询] {query}")
# 1. 检索相关文档
if self.verbose:
print("[检索] 正在检索相关文档...")
documents = self.retriever.retrieve(query)
if self.verbose:
print(f"[检索] 找到 {len(documents)} 个相关文档")
# 2. 构建增强上下文
context = self.context_builder.build(
query,
documents,
list(self.tools.values())
)
# 3. LLM 生成回答
if self.verbose:
print("[生成] 正在生成回答...")
response = self.llm(context)
# 4. 检查是否需要工具调用
action = self._parse_action(response)
if action:
# 执行工具
if self.verbose:
print(f"[工具] 执行 {action['tool']}")
tool_result = self._execute_tool(action)
# 基于工具结果再次生成
final_context = f"{context}\n\n工具执行结果:{tool_result}\n\n请给出最终回答:"
response = self.llm(final_context)
return response
def _parse_action(self, text: str) -> Optional[Dict]:
"""解析工具调用"""
import re
# 简单的模式匹配
tool_pattern = r"使用工具[::]\s*(\w+)"
param_pattern = r"参数[::]\s*(.+)"
tool_match = re.search(tool_pattern, text)
if tool_match:
tool_name = tool_match.group(1)
param_match = re.search(param_pattern, text)
params = param_match.group(1) if param_match else ""
return {"tool": tool_name, "params": params}
return None
def _execute_tool(self, action: Dict) -> str:
"""执行工具"""
tool_name = action["tool"]
params = action["params"]
if tool_name not in self.tools:
return f"错误:未知工具 {tool_name}"
try:
return self.tools[tool_name].run(params)
except Exception as e:
return f"工具执行错误:{str(e)}"
# 使用示例
if __name__ == "__main__":
from langchain_openai import OpenAI, OpenAIEmbeddings
from langchain.vectorstores import FAISS
from langchain.tools import Tool
# 准备知识库
documents = [
"公司年假政策:工作满1年7天,满3年12天,满5年18天。",
"请假流程:提前3天申请,经直属领导批准。",
"病假规定:每年累计不超过30天,需提供医院证明。"
]
# 创建向量存储
embeddings = OpenAIEmbeddings()
vector_store = FAISS.from_texts(documents, embeddings)
# 创建组件
llm = OpenAI(temperature=0)
retriever = Retriever(vector_store, embeddings)
context_builder = ContextBuilder()
# 定义工具
def search_tool(query: str) -> str:
return f"搜索结果:{query}"
tools = [
Tool(name="search", func=search_tool, description="搜索网络信息")
]
# 创建 Agent
agent = RAGAgent(
llm=llm,
retriever=retriever,
context_builder=context_builder,
tools=tools,
verbose=True
)
# 运行
result = agent.run("公司年假政策是什么?")
print(f"\n回答:{result}")3.2 使用 LangChain 实现
"""
使用 LangChain 构建 RAG Agent
"""
from langchain.agents import AgentExecutor, create_openai_tools_agent
from langchain_openai import ChatOpenAI
from langchain.tools import Tool
from langchain.vectorstores import Chroma
from langchain.embeddings import OpenAIEmbeddings
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.prompts import ChatPromptTemplate
def create_rag_agent(
documents: List[str],
model_name: str = "gpt-4"
) -> AgentExecutor:
"""创建 RAG Agent"""
# 1. 构建向量存储
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=500,
chunk_overlap=50
)
chunks = text_splitter.create_documents(documents)
embeddings = OpenAIEmbeddings()
vector_store = Chroma.from_documents(
chunks,
embeddings,
persist_directory="./chroma_db"
)
# 2. 创建检索工具
def retrieval_tool(query: str) -> str:
"""检索知识库"""
docs = vector_store.similarity_search(query, k=3)
return "\n\n".join([doc.page_content for doc in docs])
# 3. 定义工具列表
tools = [
Tool(
name="knowledge_base",
func=retrieval_tool,
description="检索内部知识库,获取相关政策、流程等信息。输入:查询问题"
)
]
# 4. 创建 Agent
llm = ChatOpenAI(model=model_name, temperature=0)
prompt = ChatPromptTemplate.from_messages([
("system", "你是一个智能助手,可以使用工具检索知识库回答问题。"),
("user", "{input}"),
("placeholder", "{agent_scratchpad}")
])
agent = create_openai_tools_agent(llm, tools, prompt)
return AgentExecutor(
agent=agent,
tools=tools,
verbose=True,
max_iterations=5
)
# 使用示例
if __name__ == "__main__":
# 知识库文档
docs = [
"公司年假政策:工作满1年7天,满3年12天,满5年18天。",
"请假流程:提前3天申请,经直属领导批准后生效。",
]
# 创建 Agent
agent_executor = create_rag_agent(docs)
# 运行
result = agent_executor.invoke({
"input": "我想请假,应该怎么操作?"
})
print(result["output"])3.3 按需检索实现
"""
按需检索 RAG Agent
Agent 自主决定是否检索
"""
class OnDemandRAGAgent:
"""按需检索 RAG Agent"""
DECISION_PROMPT = """
用户问题:{query}
请判断回答这个问题是否需要检索外部知识库。
考虑因素:
1. 问题是否涉及公司内部政策、流程?
2. 问题是否涉及专业知识、技术文档?
3. 仅凭通用知识是否能回答?
输出:需要检索 / 不需要检索
理由:...
"""
def __init__(self, llm, retriever, tools=None):
self.llm = llm
self.retriever = retriever
self.tools = tools or []
def run(self, query: str) -> str:
"""运行 Agent"""
# 1. 决定是否检索
decision = self._should_retrieve(query)
context = ""
if decision["need_retrieve"]:
# 2. 执行检索
docs = self.retriever.retrieve(query)
context = self._format_docs(docs)
# 3. 生成回答
prompt = self._build_prompt(query, context)
return self.llm(prompt)
def _should_retrieve(self, query: str) -> dict:
"""判断是否需要检索"""
prompt = self.DECISION_PROMPT.format(query=query)
response = self.llm(prompt)
return {
"need_retrieve": "需要检索" in response,
"reason": response
}
def _format_docs(self, docs) -> str:
"""格式化文档"""
return "\n\n".join([
f"[文档{i+1}]\n{doc.content}"
for i, doc in enumerate(docs)
])
def _build_prompt(self, query: str, context: str) -> str:
"""构建 Prompt"""
if context:
return f"""基于以下知识回答问题:
知识:
{context}
问题:{query}
回答:"""
else:
return f"请回答问题:{query}"四、适用场景
4.1 最佳适用场景
| 场景类型 | 具体示例 | RAG + Agent 优势 |
|---|---|---|
| 企业知识库 | HR 政策问答、IT 支持 | 知识准确 + 可执行操作 |
| 客服系统 | 产品咨询、售后支持 | 知识检索 + 工单创建 |
| 技术文档 | API 文档查询、代码示例 | 检索文档 + 生成代码 |
| 智能助手 | 企业内部助手 | 知识问答 + 任务执行 |
4.2 场景详解
┌─────────────────────────────────────────────────────────────┐
│ RAG + Agent 适用场景详解 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 1. 企业知识库问答 │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 用户:公司的报销流程是什么? │ │
│ │ │ │
│ │ 检索:[报销流程文档] [财务制度] │ │
│ │ │ │
│ │ Agent: │ │
│ │ 1. 检索知识库获取报销流程 │ │
│ │ 2. 整理并回答用户 │ │
│ │ 3. [可选] 提供报销单模板下载链接 │ │
│ │ │ │
│ │ 优势:知识准确、可追溯、可执行 │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ 2. 智能客服系统 │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 用户:我的订单为什么还没发货? │ │
│ │ │ │
│ │ Agent: │ │
│ │ 1. 检索知识库了解发货政策 │ │
│ │ 2. 调用订单系统查询订单状态 │ │
│ │ 3. 检索常见问题找到解决方案 │ │
│ │ 4. 回答用户并创建工单(如需要) │ │
│ │ │ │
│ │ 优势:知识检索 + 系统操作一体化 │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ 3. 技术文档助手 │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 用户:如何使用 Python 调用你们的 API? │ │
│ │ │ │
│ │ Agent: │ │
│ │ 1. 检索 API 文档 │ │
│ │ 2. 检索 SDK 使用说明 │ │
│ │ 3. 基于文档生成代码示例 │ │
│ │ 4. [可选] 运行代码验证正确性 │ │
│ │ │ │
│ │ 优势:文档检索 + 代码生成验证 │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘4.3 不适用场景
| 场景 | 原因 | 推荐替代方案 |
|---|---|---|
| 通用知识问答 | 不需要检索外部知识 | 纯 Agent |
| 简单规则任务 | 检索价值低 | 状态机 |
| 实时数据查询 | 知识库可能过期 | API 直接调用 |
| 创意生成任务 | 不依赖知识库 | 直接 LLM |
五、局限性与优化
5.1 主要局限性
| 局限性 | 具体表现 | 影响 |
|---|---|---|
| 检索质量 | 检索结果不相关 | 生成质量下降 |
| 上下文长度 | 检索内容过多 | Token 消耗大 |
| 知识时效性 | 知识库过时 | 答案不准确 |
| 检索延迟 | 向量检索耗时 | 响应时间增加 |
5.2 优化策略
┌─────────────────────────────────────────────────────────────┐
│ RAG + Agent 优化策略 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 1. 检索质量优化 │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ • 混合检索:语义 + 关键词 │ │
│ │ • 重排序:使用 Cross-Encoder 重排序 │ │
│ │ • 查询改写:扩展或优化原始查询 │ │
│ │ • 元数据过滤:按时间、类型等过滤 │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ 2. 上下文管理 │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ • 智能截断:保留最相关的内容 │ │
│ │ • 摘要压缩:压缩长文档 │ │
│ │ • 滑动窗口:动态管理上下文长度 │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ 3. 知识库维护 │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ • 定期更新:自动或手动更新知识库 │ │
│ │ • 版本管理:保留历史版本 │ │
│ │ • 质量监控:监控检索效果并优化 │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ 4. 性能优化 │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ • 缓存机制:缓存常见查询结果 │ │
│ │ • 预计算:预计算常用查询的 embedding │ │
│ │ • 并行检索:多路并行检索 │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘5.3 高级优化技巧
"""
RAG 高级优化技巧
"""
# 1. 查询改写
def query_rewriting(query: str, llm) -> List[str]:
"""改写查询,生成多个变体"""
prompt = f"""
原始查询:{query}
请生成3个语义相同但表达不同的查询变体:
"""
response = llm(prompt)
return parse_queries(response)
# 2. 重排序
def rerank(query: str, docs: List[RetrievedDocument], reranker) -> List[RetrievedDocument]:
"""使用 Cross-Encoder 重排序"""
scores = reranker.score(
query,
[doc.content for doc in docs]
)
sorted_docs = sorted(zip(docs, scores), key=lambda x: x[1], reverse=True)
return [doc for doc, score in sorted_docs]
# 3. 自适应 Chunk 大小
def adaptive_chunking(text: str) -> List[str]:
"""自适应分块"""
# 根据内容类型选择不同的分块策略
if is_code(text):
return code_aware_split(text)
elif is_table(text):
return table_aware_split(text)
else:
return semantic_split(text)六、面试常见问题
Q1: RAG + Agent 与纯 RAG 有什么区别?
A:
| 对比维度 | 纯 RAG | RAG + Agent |
|---|---|---|
| 执行能力 | 无 | 有(工具调用) |
| 知识来源 | 仅检索 | 检索 + 工具 + 推理 |
| 决策方式 | 直接生成 | 思考后决策 |
| 多步任务 | 不支持 | 支持 |
| 动态调整 | 不支持 | 支持 |
关键差异:RAG + Agent 在检索基础上增加了推理和执行能力,可以完成更复杂的任务。
Q2: 如何选择 RAG 与 Agent 的融合模式?
A:
选择决策树:
任务是否需要知识检索?
├── 是 → 知识是否可以一次性检索完?
│ ├── 是 → 检索优先模式
│ └── 否 → 按需检索或工具化检索
│
└── 否 → 使用纯 Agent场景映射:
| 场景 | 推荐模式 | 原因 |
|---|---|---|
| 知识库问答 | 检索优先 | 一次检索足够 |
| 复杂推理任务 | 工具化检索 | 多次检索 |
| 混合任务 | 按需检索 | 灵活决定 |
Q3: 如何评估 RAG + Agent 系统的效果?
A:
评估维度:
| 维度 | 指标 | 计算方式 |
|---|---|---|
| 检索质量 | 召回率、准确率 | 相关文档 / 检索文档 |
| 生成质量 | 准确性、完整性 | 人工评估或自动评估 |
| 执行成功率 | 工具调用成功率 | 成功调用 / 总调用 |
| 响应效率 | 平均响应时间 | 总时间 / 请求数 |
| 用户满意度 | CSAT/NPS | 用户评分 |
Q4: 如何解决知识库时效性问题?
A:
解决方案:
- 定期更新:设置定时任务更新知识库
- 增量更新:监控数据源变化,增量更新
- 实时检索:对于需要实时数据的场景,使用 API 替代知识库
- 版本管理:保留历史版本,支持回滚
Q5: RAG + Agent 的典型应用场景有哪些?
A:
| 应用场景 | 具体案例 | 核心能力 |
|---|---|---|
| 企业知识库 | HR 政策问答 | 知识检索 + 流程指引 |
| 智能客服 | 产品咨询 | 知识检索 + 工单创建 |
| 技术文档 | API 文档查询 | 检索 + 代码生成 |
| 法律咨询 | 法律条文查询 | 检索 + 分析建议 |
| 医疗助手 | 症状查询 | 检索 + 初步诊断 |
Q6: 如何优化检索召回率?
A:
优化策略:
# 1. 混合检索
def hybrid_search(query, top_k=10):
semantic_results = semantic_search(query, k=top_k)
keyword_results = keyword_search(query, k=top_k)
return reciprocal_rank_fusion(semantic_results, keyword_results)
# 2. 查询扩展
def query_expansion(query, llm):
# 生成同义词、相关词
expanded = llm(f"生成'{query}'的相关查询词")
return [query] + parse_terms(expanded)
# 3. 多跳检索
def multi_hop_search(query, vector_store, hops=2):
context = []
for _ in range(hops):
docs = vector_store.search(query, k=3)
context.extend(docs)
query = generate_next_query(query, docs)
return context七、总结
| 概念 | 一句话总结 | 面试关键词 |
|---|---|---|
| RAG + Agent | 检索增强与执行能力的融合 | 知识增强、智能执行 |
| 检索优先模式 | 先检索再执行 | 适合知识问答 |
| 按需检索模式 | Agent 自主决定检索 | 灵活性高 |
| 工具化检索模式 | 检索作为工具之一 | 复杂任务 |
| 核心优势 | 知识准确 + 可执行 | 企业应用首选 |
| 主要挑战 | 检索质量、上下文管理 | 需要优化策略 |
一句话总结:RAG + Agent 将检索增强生成与智能体执行能力结合,是构建企业级知识密集型应用的核心架构。
最后更新:2026年3月18日