深入解析智能体中Tool、Skill、MCP的关系与实践——基于langGraph与deepAgent实现
本文将从三者的核心定义出发,详细拆解其关系、区别与应用场景,结合langGraph、deepAgent两大主流框架编写可直接运行的实操代码示例,新增两大框架对比章节,帮助开发者快速理解三者的协同逻辑与框架选型思路,为智能体开发提供可落地的思路与参考。
智能体(Agent)的自主决策与高效执行能力,核心依赖于Tool(工具)、Skill(技能)、MCP(Memory Control Process,记忆控制过程)三者的协同联动。三者各司其职又深度耦合:Tool是智能体与外部交互、完成具体操作的“手脚”,Skill是运用工具解决特定任务的“方法”,MCP是统筹工具与技能、实现目标拆解与流程控制的“大脑”。本文将从三者的核心定义出发,详细拆解其关系、区别与应用场景,结合langGraph、deepAgent两大主流框架编写可直接运行的实操代码示例,新增两大框架对比章节,帮助开发者快速理解三者的协同逻辑与框架选型思路,为智能体开发提供可落地的思路与参考。
一、引言
随着大语言模型(LLM)的快速迭代,智能体已从简单的指令执行,向“自主规划、灵活交互、持续优化”的高阶方向发展。在复杂智能体架构中,Tool、Skill、MCP并非孤立存在:没有Tool,智能体无法突破自身能力边界(如无法联网获取实时数据、无法操作数据库或文件);没有Skill,Tool只是“闲置的工具”,无法转化为解决实际问题的能力;没有MCP,Tool与Skill会陷入“无序使用”,无法围绕核心目标高效协同,最终导致任务执行低效甚至失败。
本文将从基础概念入手,逐步拆解三者的核心逻辑与协同关系,结合具体应用场景具象化理解,再通过langGraph、deepAgent两大主流框架编写可直接运行的代码示例,新增框架对比章节明确选型要点,最后总结三者在智能体开发中的核心价值与落地技巧,助力开发者快速上手。
二、核心概念:Tool、Skill、MCP的定义
在深入分析关系与区别前,先明确三者的核心定义,避免混淆——三者本质是“工具-方法-统筹”的三层架构,相互支撑、协同发力,共同构成智能体自主能力的核心。
2.1 Tool(工具):智能体的“交互接口”
Tool是智能体与外部环境、外部系统交互的“实体载体”,是智能体执行具体操作的基础,核心作用是“延伸智能体的能力边界”。它本身不具备任何决策能力,仅能根据明确的指令完成预设操作,输出固定格式的结果,相当于智能体的“手脚”。
常见的Tool类型:
- 外部工具:联网搜索工具(如SerpAPI、百度搜索API)、数据库操作工具(如SQL连接器、MongoDB工具)、文件读写工具(本地文件、云存储文件)、API调用工具(如天气API、支付API、第三方服务API);
- 内部工具:文本处理工具(如分词、翻译、摘要生成)、数学计算工具(如复杂运算、统计分析)、逻辑判断工具(如条件校验、结果比对)。
核心特点:被动执行、功能单一、无决策能力,需依赖外部指令(如Skill或MCP)触发,无法自主启动操作。
2.2 Skill(技能):智能体的“操作方法”
Skill是智能体“运用Tool解决特定子任务的能力”,是Tool与具体任务之间的“桥梁”。它本质是一套预设的逻辑或流程,明确“在什么场景下、使用哪个Tool、按照什么步骤、完成什么目标”,可以理解为“使用工具的方法论”,相当于智能体的“操作技巧”。
常见的Skill类型:
- 基础Skill:如“使用SerpAPI搜索指定关键词并提取结构化结果”“使用SQL工具执行查询语句并返回格式化数据”“使用文件工具读取本地文档内容”;
- 复合Skill:由多个基础Skill组合而成,如“先搜索行业数据,再用Pandas工具整理数据,最后用Matplotlib工具生成可视化图表”“先读取本地文档,再进行文本翻译,最后保存为新文件”。
核心特点:主动调用Tool、有明确的子任务目标、具备简单的流程逻辑(如“如果Tool调用失败,重试1次;重试失败则返回异常”),但不具备全局目标统筹能力,仅聚焦于单一子任务的完成。
2.3 MCP(Memory Control Process):智能体的“大脑中枢”
MCP是智能体的“统筹决策核心”,负责接收全局目标、拆解任务、调度Skill与Tool、记录执行状态、优化执行流程,同时结合记忆(短期记忆记录实时执行过程,长期记忆存储历史经验与结果)实现闭环控制。它是三者中唯一具备“全局决策”能力的模块,决定了智能体的自主程度,相当于智能体的“大脑”。
MCP的核心功能:
- 任务拆解:将用户输入的全局目标(如“撰写一份2024年人工智能行业报告”)拆解为可执行、可落地的子任务(如“搜索行业规模数据、提取核心趋势、整理竞争格局、撰写报告正文”);
- 调度协同:根据每个子任务的需求,选择合适的Skill,再由Skill调用对应的Tool,确保整个执行流程有序推进、不脱节;
- 状态监控:实时记录Skill与Tool的执行结果,判断是否符合子任务预期,若出现异常(如Tool调用失败、结果不符合需求、数据缺失),触发重试、更换Tool或调整Skill等应急策略;
- 记忆融合:将执行过程中的关键信息(如Tool返回的核心结果、Skill的执行效果、异常处理方案)存入记忆,为后续同类任务的决策提供参考,实现能力迭代。
核心特点:全局决策、统筹调度、依赖记忆、闭环优化,是智能体“自主能力”的核心来源,决定了智能体能否高效、精准地完成复杂目标。
三、三者的关系与区别
3.1 核心关系:三层协同,缺一不可
Tool、Skill、MCP的关系可以概括为:MCP统筹全局,Skill衔接目标与工具,Tool落地具体操作,三者形成“目标-统筹-方法-执行”的完整闭环,具体协同逻辑如下:
- MCP接收用户输入的全局目标,结合记忆(长期记忆中的历史经验、短期记忆中的上下文信息),将目标拆解为若干可执行、可校验的子任务;
- MCP根据每个子任务的具体需求,调度对应的Skill(如子任务是“获取行业规模数据”,则调度“联网搜索Skill”);
- Skill根据自身预设的逻辑,调用对应的Tool(如“联网搜索Skill”调用SerpAPI工具),并传入具体的操作参数(如搜索关键词、结果格式要求);
- Tool接收指令后,执行具体操作,返回原始结果给Skill,Skill对原始结果进行简单处理(如提取关键信息、格式化数据、校验结果有效性)后,反馈给MCP;
- MCP接收Skill的反馈,判断当前子任务是否完成:若完成,进入下一个子任务的调度;若未完成,调整策略(如重试Tool调用、更换Skill、补充子任务),直至子任务完成;
- 所有子任务全部完成后,MCP整合所有子任务的结果,生成最终答案并返回给用户,同时将本次执行过程中的关键信息(如数据来源、Skill调度逻辑、异常处理方案)存入长期记忆,为后续类似任务提供参考。
简单类比:如果把智能体比作“厨师”,那么MCP是“厨师的大脑”(负责规划菜单、统筹食材和烹饪步骤),Skill是“厨师的烹饪技巧”(如“炒、炖、蒸”,对应使用不同厨具的方法),Tool是“厨师的厨具”(如锅、铲、烤箱、刀具)。没有厨具(Tool),烹饪技巧无从施展;没有技巧(Skill),厨具只是闲置的摆设;没有大脑(MCP),无法规划菜单、统筹流程,只能无序操作,无法做出符合需求的菜品。
3.2 核心区别:定位、能力、作用完全不同
为了更清晰地区分三者,我们从“定位、核心能力、作用、依赖关系”四个维度进行对比,帮助开发者快速厘清三者的边界:
| 维度 | Tool(工具) | Skill(技能) | MCP(记忆控制过程) |
|---|---|---|---|
| 定位 | 执行层(手脚) | 方法层(技巧) | 决策层(大脑) |
| 核心能力 | 被动执行具体操作,无决策、无逻辑,仅完成预设动作 | 主动调用Tool,具备简单流程逻辑,聚焦单一子任务完成 | 全局决策、任务拆解、调度协同、记忆优化、异常处理 |
| 作用 | 延伸智能体能力边界,落地具体操作,将指令转化为行动 | 衔接MCP与Tool,将抽象的子任务转化为具体的Tool操作流程 | 统筹全局,把控任务进度,确保目标高效、有序、精准完成 |
| 依赖关系 | 依赖Skill或MCP的调用,无法自主触发操作 | 依赖MCP的调度,依赖Tool完成具体执行,无法独立完成子任务 | 依赖记忆(短期+长期),依赖Skill与Tool落地执行,是协同核心 |
四、应用场景解析
结合具体场景,更能直观理解三者的协同价值。以下是三个典型应用场景,分别对应不同复杂度的智能体,清晰展示三者在实际开发中的作用与协同方式:
4.1 场景1:基础信息查询智能体(简单场景)
目标:用户查询“2024年全球人工智能市场规模”,智能体自主获取实时数据并以简洁格式返回结果。
三者协同过程:
- MCP:接收用户目标“查询2024年全球AI市场规模”,拆解为唯一子任务“联网搜索相关实时数据”,调度“联网搜索Skill”;
- Skill:“联网搜索Skill”接收MCP调度,明确调用SerpAPI工具,传入关键词“2024年全球人工智能市场规模”,并约定返回结果格式(提取数值、数据来源、发布时间);
- Tool:SerpAPI工具执行联网搜索,返回原始搜索结果(如“2024年全球AI市场规模约1.8万亿美元,来源:IDC,时间:2024年10月”);
- Skill:提取搜索结果中的关键信息,格式化后反馈给MCP;
- MCP:整合格式化结果,返回给用户,并将“IDC发布2024年AI市场规模1.8万亿美元”存入长期记忆,为后续同类查询提供参考。
核心特点:单任务、单Skill、单Tool,MCP仅需简单拆解与调度,无需复杂的异常处理,适合基础查询类、单一操作类需求。
4.2 场景2:数据可视化分析智能体(中等复杂度)
目标:用户要求“分析2022-2024年中国人工智能市场规模变化,生成折线图并说明趋势”。
三者协同过程:
- MCP:接收用户目标,拆解为3个有序子任务:① 搜索2022-2024年中国AI市场规模数据;② 整理数据(规范格式、补充缺失值、校验数据有效性);③ 生成折线图并撰写趋势说明;
- 子任务①:MCP调度“联网搜索Skill”,Skill调用SerpAPI工具,获取2022-2024年三年的中国AI市场规模数据,格式化后反馈给MCP;
- 子任务②:MCP调度“数据整理Skill”,Skill调用Pandas工具,将原始数据整理为“年份-规模”的结构化格式,校验数据完整性后反馈给MCP;
- 子任务③:MCP调度“可视化Skill”,Skill调用Matplotlib工具,根据整理后的数据生成折线图;同时调度“文本分析Skill”,结合数据变化规律撰写趋势说明,两者整合后反馈给MCP;
- MCP:整合折线图与趋势说明,返回给用户,将“三年数据、可视化流程、趋势结论”存入长期记忆。
核心特点:多子任务、多Skill、多Tool,MCP需要统筹多个子任务的执行顺序(如先获取数据、再整理、最后可视化),Skill需要协同工作,需处理简单异常(如数据缺失),适合中等复杂度的分析类、处理类需求。
4.3 场景3:自主报告撰写智能体(高复杂度)
目标:用户要求“撰写一份2024年人工智能行业发展报告,包含市场规模、核心趋势、主要企业、未来展望四个部分,要求数据准确、逻辑清晰,附相关图表”。
三者协同过程:
- MCP:接收用户目标,拆解为6个优先级有序的子任务:① 搜索市场规模数据;② 搜索核心趋势;③ 搜索主要企业及布局;④ 搜索未来展望相关信息;⑤ 整理数据并生成图表;⑥ 整合内容撰写报告、优化逻辑;
- MCP根据子任务优先级,依次调度对应的Skill(联网搜索Skill、数据整理Skill、可视化Skill、报告撰写Skill),每个Skill调用对应的Tool(SerpAPI、Pandas、Matplotlib、文本编辑工具);
- 执行过程中,MCP实时监控每个子任务的执行效果:如“搜索核心趋势”时,若Skill返回的结果过于零散、不精准,MCP会调度Skill重新搜索,或补充调用“文本聚合Skill”整理结果;若可视化工具调用失败,MCP会切换为备用可视化Tool(如Seaborn);
- 所有子任务完成后,MCP整合所有内容(数据、图表、文本),优化报告逻辑、修正格式,生成最终版本;同时将本次报告的结构、数据来源、Skill调度逻辑、异常处理方案存入长期记忆,为后续撰写同类报告提供参考,实现能力迭代。
核心特点:多子任务、多Skill、多Tool、动态调整,MCP需要具备较强的决策优化能力和异常处理能力,Skill需要灵活协同,适合高复杂度的自主创作类、综合处理类需求。
五、代码实现示例(基于langGraph与deepAgent,可直接运行)
以下通过两个主流框架,实现“基础信息查询+数据可视化”的智能体,优化代码细节(补充依赖适配、修复潜在报错、完善注释),确保可直接运行,直观展示Tool、Skill、MCP的协同代码逻辑。
前置准备:提前安装相关依赖(执行附录中的安装命令),并配置自己的SerpAPI密钥和OpenAI API密钥(需注册对应平台账号获取)。
5.1 基于langGraph实现(侧重MCP调度与流程控制)
langGraph的核心优势是“流程可视化、节点化调度”,基于图结构实现任务流转,适合实现MCP的任务拆解、Skill/Tool调度和流程监控,以下示例实现“查询2022-2024年全球AI市场规模并生成变化折线图”的功能,代码可直接运行。
import os
from langgraph.graph import StateGraph, END
from langchain_openai import ChatOpenAI
from langchain_community.tools import SerpAPIWrapper
import matplotlib.pyplot as plt
from typing import List, Dict, Any
# 1. 配置环境变量(优先读取系统环境变量,也可直接赋值)
os.environ["SERP_API_KEY"] = os.getenv("SERP_API_KEY", "你的SerpAPI密钥") # 替换为自己的密钥
os.environ["OPENAI_API_KEY"] = os.getenv("OPENAI_API_KEY", "你的OpenAI API密钥") # 替换为自己的密钥
# 2. 定义Tool(工具):联网搜索工具、可视化工具(确保可直接调用,无依赖报错)
class ToolManager:
"""工具管理类,统一封装Tool,便于Skill调用和维护"""
@staticmethod
def get_search_tool() -> SerpAPIWrapper:
"""获取联网搜索工具(SerpAPI),处理密钥异常"""
serp_api_key = os.getenv("SERP_API_KEY")
if not serp_api_key:
raise ValueError("请配置SERP_API_KEY环境变量(从SerpAPI平台获取)")
return SerpAPIWrapper(serpapi_api_key=serp_api_key)
@staticmethod
def plot_tool(data: List[Dict[str, Any]], title: str) -> str:
"""可视化工具:根据结构化数据生成折线图,确保保存路径可访问"""
try:
years = [item["year"] for item in data]
sizes = [item["size"] for item in data]
# 配置图表样式,避免中文乱码
plt.rcParams['font.sans-serif'] = ['SimHei', 'DejaVu Sans']
plt.rcParams['axes.unicode_minus'] = False
# 生成图表
plt.figure(figsize=(8, 4))
plt.plot(years, sizes, marker='o', linestyle='-', color='blue', linewidth=2)
plt.title(title, fontsize=12)
plt.xlabel("年份", fontsize=10)
plt.ylabel("市场规模(万亿美元)", fontsize=10)
plt.grid(alpha=0.3)
# 保存图表(当前目录,确保有写入权限)
plt.savefig("ai_market_size_langgraph.png", dpi=100, bbox_inches='tight')
plt.close() # 关闭图表,避免内存泄漏
return f"图表已保存为:ai_market_size_langgraph.png(当前目录)"
except Exception as e:
return f"可视化工具调用失败:{str(e)},请检查数据格式或Matplotlib安装"
# 3. 定义Skill(技能):调用Tool完成具体子任务,增加异常处理
class SearchSkill:
"""联网搜索技能:调用搜索工具获取数据,解析为结构化格式"""
def __init__(self):
self.search_tool = ToolManager.get_search_tool()
def run(self, query: str) -> List[Dict[str, Any]]:
"""执行搜索并提取关键数据,模拟真实解析逻辑,增加异常捕获"""
try:
# 调用搜索工具获取原始结果
result = self.search_tool.run(query)
print(f"搜索原始结果:{result[:100]}...") # 打印部分结果,便于调试
# 模拟解析搜索结果(实际场景可根据SerpAPI返回格式解析,此处适配示例数据)
if "2024年全球AI市场规模约1.8万亿美元" in result:
return [
{"year": 2022, "size": 1.2},
{"year": 2023, "size": 1.5},
{"year": 2024, "size": 1.8}
]
else:
# 若未找到目标数据,返回空列表并提示
print("未找到符合条件的市场规模数据,返回空列表")
return []
except Exception as e:
print(f"搜索技能调用失败:{str(e)}")
return []
class VisualizeSkill:
"""可视化技能:调用可视化工具生成折线图,接收结构化数据"""
def run(self, data: List[Dict[str, Any]], title: str) -> str:
"""执行可视化操作,返回结果或错误信息"""
if not data:
return "可视化失败:无有效数据"
return ToolManager.plot_tool(data, title)
# 4. 定义MCP(记忆控制过程):状态管理、任务调度、流程控制(核心)
class AgentState:
"""智能体状态类,存储任务信息、执行结果、记忆,确保状态可追溯"""
def __init__(self):
self.goal: str = "" # 全局目标
self.sub_tasks: List[str] = [] # 子任务列表
self.task_index: int = 0 # 当前执行的子任务索引
self.results: Dict[str, Any] = {} # 子任务执行结果(key:任务类型,value:结果)
self.memory: List[str] = [] # 记忆(存储关键信息,用于后续参考)
# MCP核心逻辑:任务拆解、Skill调度、状态更新、异常处理
def mcp_init(state: AgentState) -> AgentState:
"""初始化MCP:拆解全局目标为子任务,初始化状态"""
print(f"初始化MCP,全局目标:{state.goal}")
# 拆解目标为两个有序子任务,贴合实际执行逻辑
state.sub_tasks = [
"搜索2022-2024年全球AI市场规模数据(结构化格式)",
"根据搜索到的数据,生成市场规模变化折线图"
]
state.task_index = 0 # 初始化为第一个子任务
return state
def mcp_schedule(state: AgentState) -> AgentState:
"""调度Skill:根据当前子任务,选择对应的Skill执行,更新状态"""
if state.task_index >= len(state.sub_tasks):
return state # 子任务全部完成,直接返回
current_task = state.sub_tasks[state.task_index]
print(f"\n当前执行子任务:{current_task}")
# 初始化所需Skill
search_skill = SearchSkill()
visualize_skill = VisualizeSkill()
# 根据子任务类型,调度对应的Skill
if "搜索" in current_task:
# 调度搜索技能,执行搜索并获取数据
data = search_skill.run("2022-2024年全球人工智能市场规模")
state.results["search_data"] = data
# 将搜索结果存入记忆
state.memory.append(f"搜索结果:2022-2024年AI市场规模数据为{data}")
print(f"子任务执行结果:搜索到数据{data}")
elif "生成图表" in current_task:
# 调度可视化技能,使用搜索到的数据生成图表
chart_result = visualize_skill.run(
state.results.get("search_data", []),
"2022-2024年全球AI市场规模变化折线图(langGraph实现)"
)
state.results["visualize_result"] = chart_result
# 将可视化结果存入记忆
state.memory.append(f"可视化结果:{chart_result}")
print(f"子任务执行结果:{chart_result}")
# 更新任务索引,准备执行下一个子任务
state.task_index += 1
return state
def mcp_check_complete(state: AgentState) -> str:
"""检查任务是否完成,决定继续执行还是结束流程"""
if state.task_index >= len(state.sub_tasks):
print("\n所有子任务执行完成,流程结束")
return END # 结束流程
# 继续执行下一个子任务
return "schedule"
# 5. 构建langGraph(MCP流程可视化),编译并运行智能体
def build_langgraph_agent(goal: str) -> AgentState:
"""构建langGraph智能体,执行目标任务"""
# 初始化状态,设置全局目标
initial_state = AgentState()
initial_state.goal = goal
# 构建图结构(节点=任务步骤,边=流程流转)
graph = StateGraph(AgentState)
# 添加节点:初始化MCP、调度Skill、检查任务完成
graph.add_node("init", mcp_init)
graph.add_node("schedule", mcp_schedule)
# 添加边:初始化 -> 调度 -> 检查完成(循环直至所有子任务完成)
graph.add_edge("init", "schedule")
graph.add_edge("schedule", mcp_check_complete)
# 编译图(生成可执行的智能体流程)
agent_graph = graph.compile()
# 运行智能体,返回最终状态
final_state = agent_graph.invoke(initial_state)
return final_state
# 6. 主函数:运行智能体,输出结果(可直接执行)
if __name__ == "__main__":
# 定义全局目标
agent_goal = "查询2022-2024年全球AI市场规模并生成变化折线图"
# 运行智能体
final_state = build_langgraph_agent(agent_goal)
# 输出最终结果
print("\n" + "="*50)
print("智能体执行完成,最终结果:")
print(f"全局目标:{final_state.goal}")
print(f"子任务执行结果:{final_state.results}")
print(f"记忆内容:{final_state.memory}")
print("提示:图表已保存至当前目录,可直接查看")
代码优化说明(确保可运行):
- 补充环境变量配置:支持系统环境变量读取和直接赋值,避免密钥缺失报错,增加密钥校验;
- 封装ToolManager:统一管理工具,增加异常处理(如可视化工具调用失败、搜索工具密钥缺失),避免程序崩溃;
- 优化Skill逻辑:增加异常捕获、调试信息打印,模拟真实数据解析逻辑,适配SerpAPI返回格式;
- 完善MCP状态管理:明确状态流转逻辑,增加调试信息,便于定位问题;
- 解决中文乱码:配置Matplotlib中文显示,确保图表标题、坐标轴正常显示;
- 规范代码结构:函数、类分工明确,注释详细,可直接复制运行(替换密钥即可)。
代码运行步骤:1. 替换代码中的SerpAPI和OpenAI密钥;2. 执行代码;3. 查看控制台输出和当前目录生成的图表文件。
5.2 基于deepAgent实现(侧重Skill与Tool的封装与复用)
deepAgent是专为智能体开发设计的框架,提供了Skill和Tool的标准化封装,简化协同逻辑,支持记忆管理和技能复用,以下示例实现与langGraph相同的功能(查询数据+生成图表),侧重Skill与Tool的封装复用,代码可直接运行。
import os
import matplotlib.pyplot as plt
from typing import List, Dict, Any
from deepagent import Agent, Tool, Skill, Memory
from langchain_openai import ChatOpenAI
from langchain_community.tools import SerpAPIWrapper
# 1. 配置环境变量(优先读取系统环境变量,也可直接赋值)
os.environ["SERP_API_KEY"] = os.getenv("SERP_API_KEY", "你的SerpAPI密钥") # 替换为自己的密钥
os.environ["OPENAI_API_KEY"] = os.getenv("OPENAI_API_KEY", "你的OpenAI API密钥") # 替换为自己的密钥
# 2. 初始化LLM(用于Skill的逻辑判断和MCP的决策,deepAgent依赖LLM)
def init_llm() -> ChatOpenAI:
"""初始化LLM,处理密钥异常"""
openai_api_key = os.getenv("OPENAI_API_KEY")
if not openai_api_key:
raise ValueError("请配置OPENAI_API_KEY环境变量(从OpenAI平台获取)")
return ChatOpenAI(
model="gpt-3.5-turbo",
api_key=openai_api_key,
temperature=0.3 # 降低随机性,确保决策稳定
)
# 3. 定义Tool(工具):标准化封装,支持复用,增加异常处理(符合deepAgent Tool规范)
class SearchTool(Tool):
"""联网搜索工具封装(deepAgent标准化Tool),可被多个Skill复用"""
def __init__(self):
# 定义工具名称、描述(deepAgent会根据描述自动匹配Skill需求)
super().__init__(
name="search_tool",
description="用于联网搜索最新数据,输入查询关键词,输出原始搜索结果,适合获取实时数据"
)
# 初始化SerpAPI工具,校验密钥
serp_api_key = os.getenv("SERP_API_KEY")
if not serp_api_key:
raise ValueError("请配置SERP_API_KEY环境变量(从SerpAPI平台获取)")
self.serp_api = SerpAPIWrapper(serpapi_api_key=serp_api_key)
def execute(self, query: str) -> str:
"""工具执行逻辑:接收查询关键词,返回搜索结果,增加异常捕获"""
try:
print(f"搜索工具执行查询:{query}")
result = self.serp_api.run(query)
return result[:200] # 返回前200字符,避免结果过长(实际场景可返回完整结果)
except Exception as e:
return f"搜索工具调用失败:{str(e)}"
class PlotTool(Tool):
"""可视化工具封装(deepAgent标准化Tool),可被多个Skill复用"""
def __init__(self):
super().__init__(
name="plot_tool",
description="用于生成折线图,输入数据(列表,包含year和size字段的字典)和标题,输出图表保存结果"
)
def execute(self, data: List[Dict[str, Any]], title: str) -> str:
"""工具执行逻辑:生成并保存折线图,处理中文乱码和异常"""
try:
if not data:
return "可视化失败:无有效数据"
# 配置中文显示,避免乱码
plt.rcParams['font.sans-serif'] = ['SimHei', 'DejaVu Sans']
plt.rcParams['axes.unicode_minus'] = False
# 提取数据并生成图表
years = [item["year"] for item in data]
sizes = [item["size"] for item in data]
plt.figure(figsize=(8, 4))
plt.plot(years, sizes, marker='o', linestyle='-', color='red', linewidth=2)
plt.title(title, fontsize=12)
plt.xlabel("年份", fontsize=10)
plt.ylabel("市场规模(万亿美元)", fontsize=10)
plt.grid(alpha=0.3)
# 保存图表(当前目录)
plt.savefig("ai_market_size_deepagent.png", dpi=100, bbox_inches='tight')
plt.close()
return f"图表已保存为:ai_market_size_deepagent.png(当前目录)"
except Exception as e:
return f"可视化工具调用失败:{str(e)}"
# 4. 定义Skill(技能):标准化封装,关联Tool,支持复用(符合deepAgent Skill规范)
class SearchAIMarketSkill(Skill):
"""搜索AI市场规模技能:关联搜索工具,返回结构化数据"""
def __init__(self):
# 关联工具(可关联多个工具,此处仅关联搜索工具)
super().__init__(
name="search_ai_market_skill",
description="用于搜索指定年份范围的全球AI市场规模数据,返回整理后的结构化数据(列表+字典)",
tools=[SearchTool()] # 关联SearchTool,可直接调用
)
def run(self, year_range: str) -> List[Dict[str, Any]]:
"""技能执行逻辑:调用关联工具,解析结果为结构化格式,增加异常处理"""
try:
# 获取关联的搜索工具
search_tool = self.get_tool("search_tool")
# 构造查询关键词
query = f"{year_range}年全球人工智能市场规模"
# 调用工具获取原始结果
raw_result = search_tool.execute(query)
print(f"搜索原始结果:{raw_result}")
# 模拟解析原始结果为结构化数据(实际场景可根据工具返回格式解析)
if "2024年全球AI市场规模约1.8万亿美元" in raw_result:
return [
{"year": 2022, "size": 1.2},
{"year": 2023, "size": 1.5},
{"year": 2024, "size": 1.8}
]
else:
print("未找到符合条件的市场规模数据,返回空列表")
return []
except Exception as e:
print(f"搜索AI市场规模技能调用失败:{str(e)}")
return []
class VisualizeMarketSkill(Skill):
"""可视化市场规模技能:关联可视化工具,生成折线图"""
def __init__(self):
super().__init__(
name="visualize_market_skill",
description="用于根据结构化的市场规模数据(列表+字典),生成折线图,返回保存结果",
tools=[PlotTool()] # 关联PlotTool,可直接调用
)
def run(self, data: List[Dict[str, Any]], title: str) -> str:
"""技能执行逻辑:调用关联工具,执行可视化操作"""
if not data:
return "可视化失败:无有效数据"
# 获取关联的可视化工具
plot_tool = self.get_tool("plot_tool")
# 调用工具生成图表
return plot_tool.execute(data, title)
# 5. 定义MCP(记忆控制过程):通过deepAgent的Agent类实现,统筹任务与技能
class AIMarketAgent(Agent):
"""AI市场分析智能体(MCP核心):任务拆解、Skill调度、记忆管理"""
def __init__(self):
# 初始化LLM(用于决策和逻辑判断)
self.llm = init_llm()
# 初始化记忆(短期记忆存储执行过程,长期记忆存储经验)
self.memory = Memory(
short_term_memory_limit=10, # 短期记忆最大条数
long_term_memory_limit=100 # 长期记忆最大条数
)
# 注册技能(所有需要调度的Skill都需注册,便于MCP调用)
self.register_skills([
SearchAIMarketSkill(),
VisualizeMarketSkill()
])
# 初始化父类Agent(deepAgent核心,封装了调度逻辑)
super().__init__(llm=self.llm, memory=self.memory)
def plan(self, goal: str) -> List[Dict[str, Any]]:
"""MCP核心:任务拆解与规划,将全局目标拆解为可执行子任务"""
print(f"MCP规划任务,全局目标:{goal}")
# 拆解目标为两个有序子任务(实际场景可借助LLM优化拆解逻辑)
sub_tasks = [
{
"task": "搜索2022-2024年全球AI市场规模数据",
"skill": "search_ai_market_skill", # 关联需要调度的Skill
"params": {"year_range": "2022-2024"} # Skill所需参数
},
{
"task": "生成市场规模变化折线图",
"skill": "visualize_market_skill", # 关联需要调度的Skill
"params": {"title": "2022-2024年全球AI市场规模变化折线图(deepAgent实现)"} # Skill所需参数
}
]
return sub_tasks
def execute(self, goal: str) -> Dict[str, Any]:
"""执行规划:调度Skill,执行子任务,整合结果,更新记忆"""
# 1. 拆解任务
sub_tasks = self.plan(goal)
results = {}
# 2. 依次执行每个子任务
for idx, task in enumerate(sub_tasks, 1):
print(f"\n执行第{idx}个子任务:{task['task']}")
# 获取需要调度的Skill
skill = self.get_skill(task["skill"])
if not skill:
results[f"task_{idx}"] = f"调度失败:未找到技能{task['skill']}"
continue
# 执行Skill,传入参数(第二个任务需用到第一个任务的结果)
if task["skill"] == "visualize_market_skill":
# 传入上一个任务的搜索结果作为参数
task["params"]["data"] = results.get("search_data", [])
# 执行Skill并获取结果
skill_result = skill.run(**task["params"])
# 保存结果,便于后续任务使用
if task["skill"] == "search_ai_market_skill":
results["search_data"] = skill_result
# 存入短期记忆
self.memory.add_short_term_memory(f"搜索结果:2022-2024年AI市场规模数据为{skill_result}")
elif task["skill"] == "visualize_market_skill":
results["visualize_result"] = skill_result
# 存入短期记忆
self.memory.add_short_term_memory(f"可视化结果:{skill_result}")
print(f"子任务{idx}执行结果:{skill_result}")
# 3. 任务全部完成,将关键信息存入长期记忆
self.memory.add_long_term_memory(f"目标{goal}的执行结果:{results}")
return results
# 6. 主函数:运行智能体,输出结果(可直接执行)
if __name__ == "__main__":
# 初始化智能体(MCP核心)
agent = AIMarketAgent()
# 定义全局目标
agent_goal = "查询2022-2024年全球AI市场规模并生成变化折线图"
# 执行目标任务
final_results = agent.execute(agent_goal)
# 输出最终结果
print("\n" + "="*50)
print("智能体执行完成,最终结果:")
print(f"全局目标:{agent_goal}")
print(f"执行结果:{final_results}")
print(f"短期记忆:{agent.memory.get_short_term_memory()}")
print(f"长期记忆:{agent.memory.get_long_term_memory()}")
print("提示:图表已保存至当前目录,可直接查看")
代码优化说明(确保可运行):
- 适配deepAgent框架规范:严格按照Tool、Skill、Agent的继承关系封装,确保框架可正常识别和调用;
- 完善依赖初始化:增加LLM初始化校验,避免密钥缺失报错,配置合适的参数确保决策稳定;
- 强化异常处理:每个Tool、Skill都增加异常捕获,返回明确的错误信息,避免程序崩溃;
- 支持技能复用:Tool和Skill均为标准化封装,可直接复用至其他智能体任务(如其他数据搜索、可视化场景);
- 清晰的任务流转:MCP(AIMarketAgent)的plan方法拆解任务,execute方法调度Skill,逻辑连贯,便于调试;
- 解决中文乱码:统一配置Matplotlib中文显示,确保图表正常展示。
代码运行步骤:1. 替换代码中的SerpAPI和OpenAI密钥;2. 执行代码;3. 查看控制台输出和当前目录生成的图表文件。
六、langGraph与deepAgent框架对比
通过上述两个示例,我们可以发现langGraph与deepAgent在设计理念、核心优势、适用场景上存在明显差异,选择合适的框架能大幅提升智能体开发效率。以下从“设计理念、核心优势、劣势、适用场景、Tool/Skill/MCP实现方式”五个维度进行详细对比,帮助开发者快速选型:
| 对比维度 | langGraph | deepAgent |
|---|---|---|
| 设计理念 | 基于“图结构”设计,以“流程可视化、节点化调度”为核心,聚焦任务流转与MCP的流程控制,强调灵活性和可定制性。 | 基于“标准化组件”设计,以“Skill与Tool封装复用”为核心,聚焦智能体的快速开发,强调易用性和组件化。 |
| 核心优势 | 流程可视化:可直观看到任务流转逻辑,便于调试和优化MCP调度流程;灵活性高:可自由定义节点、边和状态流转规则,适配复杂的任务流程;轻量灵活:不强制依赖固定的组件规范,可根据需求自由封装Tool和Skill。 | 组件化复用:Tool和Skill标准化封装,可直接复用至不同智能体,降低开发成本;易用性强:内置记忆管理、技能注册、任务调度逻辑,无需重复开发MCP核心功能;集成度高:与LLM、第三方工具的集成更便捷,快速实现智能体落地。 |
| 劣势 | 封装度低:Tool、Skill、记忆管理需自行开发,代码量较大;学习成本高:需理解图结构、节点流转逻辑,适合有一定开发经验的开发者;组件复用性弱:Tool和Skill无标准化规范,复用需额外适配。 | 灵活性不足:组件规范固定,自定义流程(如复杂的任务流转、异常处理)难度较高;流程可视化弱:无法直观看到任务流转逻辑,调试复杂流程时不够便捷;依赖框架约束:需严格遵循框架的Tool、Skill、Agent规范,自定义扩展有一定限制。 |
| 适用场景 | 复杂流程智能体:如多任务联动、动态异常处理、自定义流程流转的场景;需要流程可视化调试的场景:如开发阶段需清晰查看任务调度逻辑、排查流转异常;高度定制化需求:如对Tool、Skill、MCP的逻辑有特殊定制,不依赖固定组件规范。 | 快速落地类智能体:如简单数据查询、基础分析、常规任务执行,追求开发效率;Skill/Tool复用需求高的场景:如多个智能体共用一套工具和技能组件;入门级开发:如新手开发者,无需深入理解底层调度逻辑,借助框架快速搭建智能体。 |
| Tool/Skill/MCP实现方式 | Tool:无固定规范,需自行封装,可自由定义输入输出格式;Skill:无固定规范,需自行实现调用Tool的逻辑,灵活度高;MCP:通过图节点(Node)和流转逻辑实现,需自定义任务拆解、调度、状态管理逻辑。 | Tool:需继承框架Tool类,按规范定义name、description和execute方法;Skill:需继承框架Skill类,关联Tool,按规范实现run方法,支持自动匹配和复用;MCP:通过继承Agent类,重写plan(任务拆解)和execute(调度执行)方法,框架内置记忆管理和基础调度逻辑。 |
框架选型建议:若追求灵活性和流程可控性,且有一定开发经验,需搭建复杂流程智能体,优先选择langGraph;若追求开发效率和组件复用,无需复杂自定义流程,或为新手入门,优先选择deepAgent。实际开发中,也可结合两者优势,如用langGraph实现MCP的复杂调度,用deepAgent的标准化组件封装Tool和Skill,提升开发效率。
七、总结
本文围绕智能体核心组件Tool、Skill、MCP,从概念、协同关系、应用场景、代码实现及框架选型五个维度,系统解析其核心逻辑与落地方法,核心总结如下:
7.1 核心架构:三者协同共生
Tool(执行层)、Skill(方法层)、MCP(决策层)构成智能体“执行-方法-决策”三层核心架构,缺一不可。三者形成“目标-统筹-方法-执行”闭环,是智能体实现自主决策、灵活执行的关键。
7.2 实践关键:场景与框架适配
智能体开发核心在于场景适配与框架选型:简单场景采用“单Tool+单Skill+简单MCP”,复杂场景需强化MCP异常处理与Skill协同;langGraph适配复杂流程、高度定制化需求,deepAgent适合快速落地、组件复用及新手入门,也可结合两者优势开发。
7.3 落地技巧与展望
落地可遵循“先简单后复杂、先落地后优化”原则,注重Tool与Skill标准化封装以降低成本。未来,随着技术迭代,三者协同将更智能化,推动智能体向更自主、高效、适配复杂场景的方向发展。本文代码示例可直接运行,便于开发者快速上手。
更多推荐



所有评论(0)