AI Agent详解:RAG与MCP的区别与联合实现智能体
特性RAGMCP知识检索✅❌工具调用❌✅静态知识✅❌动态操作❌✅信息生成✅❌系统集成❌✅/*** 工具名称*//*** 工具描述*//*** 执行工具*/输入:用户问题↓1. 任务分析(LLM)↓2. 工具选择(LLM + 工具描述)↓3. 工具执行├─→ RAG工具:检索知识库└─→ MCP工具:调用外部系统↓4. 结果整合(LLM)↓输出:最终回答 + 使用的工具 + 中间结果RAG。
·
AI Agent详解:RAG与MCP的区别与联合实现智能体
一、什么是AI Agent?
AI Agent(智能体)是一个能够感知环境、做出决策并执行行动的自主系统。在AI领域,Agent通常指能够:
- 感知:理解用户输入和环境状态
- 推理:分析问题并制定解决方案
- 行动:调用工具和服务执行任务
- 学习:从交互中改进性能
AI Agent的核心组件
- LLM(大语言模型):提供推理和决策能力
- 工具集(Tools):可执行的操作集合
- 记忆系统(Memory):存储对话历史和知识
- 规划器(Planner):制定执行计划
- 执行器(Executor):执行具体操作
二、RAG与MCP的区别
1. RAG(检索增强生成)
核心功能:
- 从知识库中检索相关信息
- 将检索到的信息作为上下文增强生成
- 主要用于知识问答和信息检索
特点:
- ✅ 静态知识库查询
- ✅ 基于文档的问答
- ✅ 可追溯的信息来源
- ❌ 无法执行操作
- ❌ 无法调用外部服务
适用场景:
- 文档问答系统
- 知识库查询
- 内容生成(基于已有文档)
2. MCP(模型上下文协议)
核心功能:
- 提供标准化的工具调用接口
- 连接外部系统和数据源
- 执行具体的操作和任务
特点:
- ✅ 动态工具调用
- ✅ 外部系统集成
- ✅ 实时数据获取
- ✅ 可执行操作
- ❌ 不提供知识检索
适用场景:
- 数据库操作
- API调用
- 文件系统操作
- 业务系统集成
3. 对比总结
| 特性 | RAG | MCP |
|---|---|---|
| 知识检索 | ✅ | ❌ |
| 工具调用 | ❌ | ✅ |
| 静态知识 | ✅ | ❌ |
| 动态操作 | ❌ | ✅ |
| 信息生成 | ✅ | ❌ |
| 系统集成 | ❌ | ✅ |
三、为什么需要联合使用?
RAG和MCP各有优势,联合使用可以构建更强大的AI Agent:
- 知识 + 行动:RAG提供知识,MCP执行操作
- 静态 + 动态:RAG处理历史知识,MCP处理实时数据
- 查询 + 执行:RAG回答"是什么",MCP执行"做什么"
四、联合实现AI Agent
1. 架构设计
用户输入
↓
Agent控制器
↓
┌─────────────────┐
│ 规划器(Planner) │ ← 使用LLM分析任务
└─────────────────┘
↓
┌─────────────────┐
│ 工具选择器 │
└─────────────────┘
↓
├──→ RAG工具(知识检索)
│ ↓
│ 向量数据库
│
└──→ MCP工具(操作执行)
↓
外部系统
↓
结果整合
↓
用户输出
2. 添加依赖
<dependencies>
<!-- Spring AI Core -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-core</artifactId>
<version>1.0.0</version>
</dependency>
<!-- Spring AI OpenAI -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-openai-spring-boot-starter</artifactId>
<version>1.0.0</version>
</dependency>
<!-- Spring AI MCP -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-mcp</artifactId>
<version>1.0.0</version>
</dependency>
<!-- Spring AI Vector Store -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-pgvector-store</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
3. 定义工具接口
package com.example.agent.tools;
import org.springframework.ai.chat.model.ToolCall;
public interface AgentTool {
/**
* 工具名称
*/
String getName();
/**
* 工具描述
*/
String getDescription();
/**
* 执行工具
*/
String execute(ToolCall toolCall);
}
4. 实现RAG工具
package com.example.agent.tools;
import org.springframework.ai.chat.model.ToolCall;
import org.springframework.ai.document.Document;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.stream.Collectors;
@Component
public class RAGTool implements AgentTool {
@Autowired
private VectorStore vectorStore;
@Override
public String getName() {
return "rag_search";
}
@Override
public String getDescription() {
return "从知识库中检索相关信息。输入:查询问题。输出:相关文档内容。";
}
@Override
public String execute(ToolCall toolCall) {
String query = toolCall.getArguments().get("query").toString();
int topK = Integer.parseInt(toolCall.getArguments().getOrDefault("top_k", "5").toString());
// 检索相关文档
List<Document> docs = vectorStore.similaritySearch(query, topK);
if (docs.isEmpty()) {
return "未找到相关信息";
}
// 格式化返回结果
return docs.stream()
.map(doc -> String.format(
"来源:%s\n内容:%s",
doc.getMetadata().get("source"),
doc.getContent()
))
.collect(Collectors.joining("\n\n---\n\n"));
}
}
5. 实现MCP工具
package com.example.agent.tools;
import org.springframework.ai.chat.model.ToolCall;
import org.springframework.ai.mcp.McpClient;
import org.springframework.ai.mcp.McpRequest;
import org.springframework.ai.mcp.McpResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class DatabaseMcpTool implements AgentTool {
@Autowired
private McpClient mcpClient;
@Override
public String getName() {
return "database_query";
}
@Override
public String getDescription() {
return "查询数据库信息。输入:SQL查询语句或自然语言查询。输出:查询结果。";
}
@Override
public String execute(ToolCall toolCall) {
String query = toolCall.getArguments().get("query").toString();
McpRequest request = McpRequest.builder()
.tool("query_database")
.parameter("query", query)
.build();
McpResponse response = mcpClient.send(request);
return response.getContent();
}
}
6. 实现Agent核心服务
package com.example.agent.service;
import com.example.agent.tools.AgentTool;
import org.springframework.ai.chat.ChatClient;
import org.springframework.ai.chat.messages.AssistantMessage;
import org.springframework.ai.chat.messages.SystemMessage;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.model.ToolCall;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
@Service
public class AgentService {
@Autowired
private ChatClient chatClient;
@Autowired
private List<AgentTool> tools;
/**
* Agent主处理流程
*/
public AgentResponse process(AgentRequest request) {
String userInput = request.getInput();
List<String> conversationHistory = request.getHistory();
// 1. 构建系统提示
String systemPrompt = buildSystemPrompt();
// 2. 构建对话历史
List<Object> messages = new ArrayList<>();
messages.add(new SystemMessage(systemPrompt));
// 添加历史对话
for (int i = 0; i < conversationHistory.size(); i += 2) {
if (i + 1 < conversationHistory.size()) {
messages.add(new UserMessage(conversationHistory.get(i)));
messages.add(new AssistantMessage(conversationHistory.get(i + 1)));
}
}
// 添加当前用户输入
messages.add(new UserMessage(userInput));
// 3. 调用LLM(支持工具调用)
Prompt prompt = new Prompt(messages);
AssistantMessage response = chatClient.call(prompt).getResult().getOutput();
// 4. 处理工具调用
List<ToolCall> toolCalls = response.getToolCalls();
if (toolCalls != null && !toolCalls.isEmpty()) {
return handleToolCalls(toolCalls, userInput, conversationHistory);
}
// 5. 返回最终结果
return AgentResponse.builder()
.output(response.getContent())
.toolsUsed(Collections.emptyList())
.build();
}
/**
* 构建系统提示
*/
private String buildSystemPrompt() {
StringBuilder prompt = new StringBuilder();
prompt.append("你是一个智能助手,可以使用以下工具:\n\n");
for (AgentTool tool : tools) {
prompt.append(String.format(
"- %s: %s\n",
tool.getName(),
tool.getDescription()
));
}
prompt.append("\n根据用户的问题,选择合适的工具来获取信息或执行操作。");
prompt.append("如果需要查询知识库,使用rag_search工具。");
prompt.append("如果需要查询数据库,使用database_query工具。");
prompt.append("可以组合使用多个工具来完成任务。");
return prompt.toString();
}
/**
* 处理工具调用
*/
private AgentResponse handleToolCalls(List<ToolCall> toolCalls,
String userInput,
List<String> history) {
List<String> toolsUsed = new ArrayList<>();
List<String> toolResults = new ArrayList<>();
// 执行所有工具调用
for (ToolCall toolCall : toolCalls) {
String toolName = toolCall.getName();
AgentTool tool = findTool(toolName);
if (tool != null) {
toolsUsed.add(toolName);
String result = tool.execute(toolCall);
toolResults.add(String.format("%s的结果:%s", toolName, result));
}
}
// 将工具结果整合到提示中,再次调用LLM生成最终回答
String combinedResults = String.join("\n\n", toolResults);
String finalPrompt = String.format(
"用户问题:%s\n\n工具执行结果:\n%s\n\n请基于工具执行结果回答用户问题。",
userInput,
combinedResults
);
Prompt prompt = new Prompt(new UserMessage(finalPrompt));
AssistantMessage finalResponse = chatClient.call(prompt).getResult().getOutput();
return AgentResponse.builder()
.output(finalResponse.getContent())
.toolsUsed(toolsUsed)
.intermediateResults(toolResults)
.build();
}
private AgentTool findTool(String name) {
return tools.stream()
.filter(tool -> tool.getName().equals(name))
.findFirst()
.orElse(null);
}
}
7. 创建控制器
package com.example.agent.controller;
import com.example.agent.service.AgentService;
import com.example.agent.model.AgentRequest;
import com.example.agent.model.AgentResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
@RestController
@RequestMapping("/api/agent")
public class AgentController {
@Autowired
private AgentService agentService;
@PostMapping("/chat")
public AgentResponse chat(@RequestBody AgentRequest request) {
return agentService.process(request);
}
}
8. 数据模型
package com.example.agent.model;
import lombok.Builder;
import lombok.Data;
import java.util.List;
@Data
@Builder
public class AgentRequest {
private String input;
private List<String> history;
}
@Data
@Builder
public class AgentResponse {
private String output;
private List<String> toolsUsed;
private List<String> intermediateResults;
}
五、智能体实现示例
示例场景:智能客服助手
输入:
{
"input": "用户ID为123的用户最近有什么订单?订单总金额是多少?",
"history": []
}
处理流程:
-
规划阶段:
- LLM分析:需要查询用户订单信息
- 决定使用工具:
database_query
-
执行阶段:
- 调用
database_query工具 - 执行SQL:
SELECT * FROM orders WHERE user_id = 123 ORDER BY create_time DESC - 获取订单数据
- 调用
-
整合阶段:
- LLM基于查询结果生成回答
- 格式化输出
输出:
{
"output": "用户ID为123的用户最近有以下订单:\n1. 订单号:ORD-2024-001,金额:¥1,299.00,状态:已完成\n2. 订单号:ORD-2024-002,金额:¥599.00,状态:待发货\n订单总金额:¥1,898.00",
"toolsUsed": ["database_query"],
"intermediateResults": [
"database_query的结果:订单列表数据..."
]
}
更复杂的示例:知识查询 + 数据操作
输入:
{
"input": "根据公司政策文档,新用户的优惠额度是多少?然后帮我查询用户ID为456的账户余额。",
"history": []
}
处理流程:
-
规划阶段:
- 需要查询政策文档(使用RAG)
- 需要查询用户账户(使用MCP)
-
执行阶段:
- 调用
rag_search工具:查询"新用户优惠额度" - 调用
database_query工具:查询用户账户余额
- 调用
-
整合阶段:
- LLM整合两个工具的结果
- 生成完整回答
输出:
{
"output": "根据公司政策文档,新用户的优惠额度是¥100。\n\n用户ID为456的账户当前余额为¥1,250.00。",
"toolsUsed": ["rag_search", "database_query"],
"intermediateResults": [
"rag_search的结果:政策文档相关内容...",
"database_query的结果:账户余额数据..."
]
}
六、Agent工作流程总结
输入:用户问题
↓
1. 任务分析(LLM)
↓
2. 工具选择(LLM + 工具描述)
↓
3. 工具执行
├─→ RAG工具:检索知识库
└─→ MCP工具:调用外部系统
↓
4. 结果整合(LLM)
↓
输出:最终回答 + 使用的工具 + 中间结果
七、最佳实践
1. 工具设计
- 单一职责:每个工具只做一件事
- 清晰描述:工具描述要准确,帮助LLM正确选择
- 错误处理:工具执行要有完善的错误处理
2. 提示工程
- 明确指令:清楚说明何时使用哪个工具
- 格式规范:统一工具输入输出格式
- 上下文管理:合理管理对话历史
3. 性能优化
- 并行执行:多个独立工具可以并行执行
- 缓存机制:对频繁查询的结果进行缓存
- 超时控制:设置工具执行超时时间
八、总结
通过联合使用RAG和MCP,我们可以构建强大的AI Agent:
- RAG:提供知识检索能力,回答"是什么"
- MCP:提供工具调用能力,执行"做什么"
- Agent:整合两者,实现智能决策和执行
这种架构使得AI系统既能理解知识,又能执行操作,真正实现了智能体的自主能力。
参考资料
更多推荐



所有评论(0)