当AI开始学会"使用工具"——从ReAct到MCP,大模型如何获得真正的行动力
大家好,我是摘星,今天我们来聊聊一个正在悄悄改变AI能力边界的话题——大模型的工具调用能力。
你可能已经注意到,最近半年,AI助手们突然变得"能动"了。它们不再只是呆呆地回答问题,而是能帮你查日历、发邮件、写代码并执行、甚至操控浏览器去完成复杂任务。这种变化的背后,是一套被称为"Agent"的技术架构正在快速成熟。从2023年的ReAct范式,到2024年的Function Calling,再到2025年的MCP(Model Context Protocol)协议,大模型获取"行动力"的路径越来越清晰,门槛也越来越低。
这篇文章,我会把这条技术演进脉络拆解清楚,告诉你AI是怎么从"能说"到"能做"的,以及2026年这个领域又出现了什么新东西。不管你是想用AI自动化办公流程,还是在搞智能客服、数字员工,这篇文章都会给你一些实打实的参考。
一、为什么AI需要"工具调用"能力
1.1 大模型的本质局限
大语言模型(LLM)本质是一个超级强大的"文本预测机器"。它能生成连贯、有逻辑的文本,但它无法直接与现实世界交互。你让GPT写一封邮件,它能给你一封完美的邮件文本——但它没办法帮你发出去。你让Claude查一下今天的天气,它能给你一个"天气晴,温度25度"的回答——但它没办法真的去访问气象API获取实时数据。
这种局限来自于模型训练的范式:LLM在训练时只能学习文本数据中的模式,无法直接调用外部系统。模型看到的只是"关于天气"的大量文本,而不是"如何获取天气"的真实数据。
这就是为什么我们需要给AI加上"工具调用"能力——让模型不再只是生成文本,而是能指挥一个执行引擎去真正做事。
1.2 从"嘴炮"到"实操"的跨越
要让AI真正变得有用,需要解决三个核心问题:
第一,感知实时信息。模型训练数据有截止日期,它不知道今天发生了什么,不知道你公司服务器的状态,不知道用户的最新订单。解决方案是让AI能调用搜索API、数据库查询、监控接口。
第二,执行具体操作。AI的输出只是文本,但现实操作需要调用各种系统:发邮件需要调用邮件服务商API,操作数据库需要执行SQL,修改文件需要调用文件系统。解决方案是让AI能调用预定义的函数/工具,并实际执行这些操作。
第三,完成多步骤任务。现实任务往往不是一句Prompt就能搞定的,需要拆解成多个步骤,每一步可能依赖上一步的结果。解决方案是让AI具备"规划-执行-反馈"的循环能力。
工具调用能力,就是为了解决这三个问题而诞生的技术。
二、技术演进:从ReAct到MCP的四代跨越
2.1 第一代:ReAct范式(2023年)
ReAct(Reasoning + Acting)是最早让LLM具备工具调用能力的框架,由Google和普林斯顿的研究者在2023年提出。
核心思想:让模型在"推理"和"行动"之间交替进行。模型先思考"我应该做什么",然后执行一个动作,再根据执行结果继续推理,形成一个"思考→行动→观察→再思考"的循环。
工作流程:
#mermaid-svg-K3Q2KKZDMFyiEyC1{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-K3Q2KKZDMFyiEyC1 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-K3Q2KKZDMFyiEyC1 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-K3Q2KKZDMFyiEyC1 .error-icon{fill:#552222;}#mermaid-svg-K3Q2KKZDMFyiEyC1 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-K3Q2KKZDMFyiEyC1 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-K3Q2KKZDMFyiEyC1 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-K3Q2KKZDMFyiEyC1 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-K3Q2KKZDMFyiEyC1 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-K3Q2KKZDMFyiEyC1 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-K3Q2KKZDMFyiEyC1 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-K3Q2KKZDMFyiEyC1 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-K3Q2KKZDMFyiEyC1 .marker.cross{stroke:#333333;}#mermaid-svg-K3Q2KKZDMFyiEyC1 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-K3Q2KKZDMFyiEyC1 p{margin:0;}#mermaid-svg-K3Q2KKZDMFyiEyC1 .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-K3Q2KKZDMFyiEyC1 .cluster-label text{fill:#333;}#mermaid-svg-K3Q2KKZDMFyiEyC1 .cluster-label span{color:#333;}#mermaid-svg-K3Q2KKZDMFyiEyC1 .cluster-label span p{background-color:transparent;}#mermaid-svg-K3Q2KKZDMFyiEyC1 .label text,#mermaid-svg-K3Q2KKZDMFyiEyC1 span{fill:#333;color:#333;}#mermaid-svg-K3Q2KKZDMFyiEyC1 .node rect,#mermaid-svg-K3Q2KKZDMFyiEyC1 .node circle,#mermaid-svg-K3Q2KKZDMFyiEyC1 .node ellipse,#mermaid-svg-K3Q2KKZDMFyiEyC1 .node polygon,#mermaid-svg-K3Q2KKZDMFyiEyC1 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-K3Q2KKZDMFyiEyC1 .rough-node .label text,#mermaid-svg-K3Q2KKZDMFyiEyC1 .node .label text,#mermaid-svg-K3Q2KKZDMFyiEyC1 .image-shape .label,#mermaid-svg-K3Q2KKZDMFyiEyC1 .icon-shape .label{text-anchor:middle;}#mermaid-svg-K3Q2KKZDMFyiEyC1 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-K3Q2KKZDMFyiEyC1 .rough-node .label,#mermaid-svg-K3Q2KKZDMFyiEyC1 .node .label,#mermaid-svg-K3Q2KKZDMFyiEyC1 .image-shape .label,#mermaid-svg-K3Q2KKZDMFyiEyC1 .icon-shape .label{text-align:center;}#mermaid-svg-K3Q2KKZDMFyiEyC1 .node.clickable{cursor:pointer;}#mermaid-svg-K3Q2KKZDMFyiEyC1 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-K3Q2KKZDMFyiEyC1 .arrowheadPath{fill:#333333;}#mermaid-svg-K3Q2KKZDMFyiEyC1 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-K3Q2KKZDMFyiEyC1 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-K3Q2KKZDMFyiEyC1 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-K3Q2KKZDMFyiEyC1 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-K3Q2KKZDMFyiEyC1 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-K3Q2KKZDMFyiEyC1 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-K3Q2KKZDMFyiEyC1 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-K3Q2KKZDMFyiEyC1 .cluster text{fill:#333;}#mermaid-svg-K3Q2KKZDMFyiEyC1 .cluster span{color:#333;}#mermaid-svg-K3Q2KKZDMFyiEyC1 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-K3Q2KKZDMFyiEyC1 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-K3Q2KKZDMFyiEyC1 rect.text{fill:none;stroke-width:0;}#mermaid-svg-K3Q2KKZDMFyiEyC1 .icon-shape,#mermaid-svg-K3Q2KKZDMFyiEyC1 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-K3Q2KKZDMFyiEyC1 .icon-shape p,#mermaid-svg-K3Q2KKZDMFyiEyC1 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-K3Q2KKZDMFyiEyC1 .icon-shape .label rect,#mermaid-svg-K3Q2KKZDMFyiEyC1 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-K3Q2KKZDMFyiEyC1 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-K3Q2KKZDMFyiEyC1 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-K3Q2KKZDMFyiEyC1 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
是
否
是
否
用户输入任务
模型推理:下一步做什么
是否有工具可用?
选择并调用工具
获取工具返回结果
模型推理:根据结果判断
任务完成?
返回最终结果
直接生成文本响应
ReAct的关键prompt模板:
# ReAct风格的提示词模板
react_prompt = """
你是一个AI助手,需要完成以下任务:{task}
你可以选择以下工具:
– search(query): 搜索互联网信息
– calculator(expression): 计算数学表达式
– get_date(): 获取当前日期
你需要按照以下格式思考和行动:
思考:我需要…(分析当前情况,决定下一步)
行动:调用search("关键词")来获取信息
观察:搜索结果显示…
…(重复直到任务完成)
现在任务开始:
"""
ReAct的局限:
2.2 第二代:Function Calling / Tool Use(2023-2024)
2023年下半年,OpenAI在GPT-4 API中引入了Function Calling功能,随后各大厂商纷纷跟进。这标志着工具调用进入"标准化"时代。
核心改进:
OpenAI Function Calling的调用格式:
# 定义工具(Functions)
functions = [
{
"name": "get_weather",
"description": "获取指定城市的天气信息",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "城市名称,比如'北京'、'上海'"
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"],
"description": "温度单位"
}
},
"required": ["city"]
}
}
]
# 调用示例
response = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "纽约今天热吗?"}],
tools=functions,
tool_choice="auto"
)
# 模型会输出类似这样的结构化调用:
# {"name": "get_weather", "arguments": {"city": "纽约", "unit": "celsius"}}
# 执行工具后,把结果传回模型继续处理
tool_result = get_weather(city="纽约", unit="celsius")
messages.append({"role": "tool", "tool_call_id": "…", "content": str(tool_result)})
# 模型基于工具返回结果生成最终回答
final_response = client.chat.completions.create(
model="gpt-4o",
messages=messages
)
Function Calling的优势:
- 输出格式统一,解析简单
- 工具定义清晰,模型选错工具的概率降低
- 可以强制模型调用指定工具(通过tool_choice参数)
各厂商实现对比:
| OpenAI | GPT-4o, GPT-4-turbo | ✅ 原生支持 | 最早实现,生态成熟 |
| Anthropic | Claude 3.5 | ✅ 通过Tool Use | 支持多轮工具调用 |
| Gemini 1.5 | ✅ 原生支持 | 支持百万token上下文 | |
| 阿里 | Qwen2.5 | ✅ 支持 | 开源模型中做得最好的 |
| Meta | LLaMA 3 | ⚠️ 需微调 | 官方不支持,需第三方实现 |
2.3 第三代:Agent架构的成熟(2024年)
2024年,AI Agent从"单工具调用"进化到"多步骤规划+执行"阶段。标志性事件是多个开源Agent框架的崛起和各大厂商发布的Agent平台。
Agent的核心架构:
#mermaid-svg-A6ytzyOw8iOuIl2J{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-A6ytzyOw8iOuIl2J .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-A6ytzyOw8iOuIl2J .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-A6ytzyOw8iOuIl2J .error-icon{fill:#552222;}#mermaid-svg-A6ytzyOw8iOuIl2J .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-A6ytzyOw8iOuIl2J .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-A6ytzyOw8iOuIl2J .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-A6ytzyOw8iOuIl2J .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-A6ytzyOw8iOuIl2J .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-A6ytzyOw8iOuIl2J .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-A6ytzyOw8iOuIl2J .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-A6ytzyOw8iOuIl2J .marker{fill:#333333;stroke:#333333;}#mermaid-svg-A6ytzyOw8iOuIl2J .marker.cross{stroke:#333333;}#mermaid-svg-A6ytzyOw8iOuIl2J svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-A6ytzyOw8iOuIl2J p{margin:0;}#mermaid-svg-A6ytzyOw8iOuIl2J .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-A6ytzyOw8iOuIl2J .cluster-label text{fill:#333;}#mermaid-svg-A6ytzyOw8iOuIl2J .cluster-label span{color:#333;}#mermaid-svg-A6ytzyOw8iOuIl2J .cluster-label span p{background-color:transparent;}#mermaid-svg-A6ytzyOw8iOuIl2J .label text,#mermaid-svg-A6ytzyOw8iOuIl2J span{fill:#333;color:#333;}#mermaid-svg-A6ytzyOw8iOuIl2J .node rect,#mermaid-svg-A6ytzyOw8iOuIl2J .node circle,#mermaid-svg-A6ytzyOw8iOuIl2J .node ellipse,#mermaid-svg-A6ytzyOw8iOuIl2J .node polygon,#mermaid-svg-A6ytzyOw8iOuIl2J .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-A6ytzyOw8iOuIl2J .rough-node .label text,#mermaid-svg-A6ytzyOw8iOuIl2J .node .label text,#mermaid-svg-A6ytzyOw8iOuIl2J .image-shape .label,#mermaid-svg-A6ytzyOw8iOuIl2J .icon-shape .label{text-anchor:middle;}#mermaid-svg-A6ytzyOw8iOuIl2J .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-A6ytzyOw8iOuIl2J .rough-node .label,#mermaid-svg-A6ytzyOw8iOuIl2J .node .label,#mermaid-svg-A6ytzyOw8iOuIl2J .image-shape .label,#mermaid-svg-A6ytzyOw8iOuIl2J .icon-shape .label{text-align:center;}#mermaid-svg-A6ytzyOw8iOuIl2J .node.clickable{cursor:pointer;}#mermaid-svg-A6ytzyOw8iOuIl2J .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-A6ytzyOw8iOuIl2J .arrowheadPath{fill:#333333;}#mermaid-svg-A6ytzyOw8iOuIl2J .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-A6ytzyOw8iOuIl2J .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-A6ytzyOw8iOuIl2J .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-A6ytzyOw8iOuIl2J .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-A6ytzyOw8iOuIl2J .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-A6ytzyOw8iOuIl2J .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-A6ytzyOw8iOuIl2J .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-A6ytzyOw8iOuIl2J .cluster text{fill:#333;}#mermaid-svg-A6ytzyOw8iOuIl2J .cluster span{color:#333;}#mermaid-svg-A6ytzyOw8iOuIl2J div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-A6ytzyOw8iOuIl2J .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-A6ytzyOw8iOuIl2J rect.text{fill:none;stroke-width:0;}#mermaid-svg-A6ytzyOw8iOuIl2J .icon-shape,#mermaid-svg-A6ytzyOw8iOuIl2J .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-A6ytzyOw8iOuIl2J .icon-shape p,#mermaid-svg-A6ytzyOw8iOuIl2J .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-A6ytzyOw8iOuIl2J .icon-shape .label rect,#mermaid-svg-A6ytzyOw8iOuIl2J .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-A6ytzyOw8iOuIl2J .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-A6ytzyOw8iOuIl2J .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-A6ytzyOw8iOuIl2J :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
外部系统
Agent核心
用户层
用户自然语言指令
规划器 Planner
记忆 Memory
工具箱 Tools
执行器 Executor
搜索API
数据库
文件系统
第三方服务
主流开源Agent框架对比:
| LangChain | LangChain团队 | Python | 生态最全,文档完善 | 50k+ |
| LlamaIndex | LlamaIndex团队 | Python | 数据连接更强 | 30k+ |
| AutoGen | Microsoft | Python | 多Agent协作 | 25k+ |
| CrewAI | CrewAI团队 | Python | 角色扮演Agent | 20k+ |
| Dify | 独立团队 | TypeScript | 可视化编排,开源 | 35k+ |
| Coze | 字节跳动 | 云服务 | 插件市场丰富 | 国内领先 |
一个典型的LangChain Agent实现:
from langchain.agents import AgentExecutor, create_react_agent
from langchain.tools import Tool
from langchain.chat_models import ChatOpenAI
# 定义工具
def search_wiki(query: str) –> str:
"""搜索维基百科"""
# 实现搜索逻辑
return f"关于{query}的信息…"
def calculate(expression: str) –> str:
"""计算数学表达式"""
return str(eval(expression))
tools = [
Tool(name="search", func=search_wiki, description="搜索维基百科获取信息"),
Tool(name="calc", func=calculate, description="计算数学表达式")
]
# 创建Agent
llm = ChatOpenAI(model="gpt-4o", temperature=0)
agent = create_react_agent(llm, tools)
# 执行任务
executor = AgentExecutor.from_agent_and_tools(
agent=agent,
tools=tools,
verbose=True,
max_iterations=10
)
result = executor.invoke({"input": "计算2的10次方是多少?并搜索相关历史"})
2024年的关键进展:
2.4 第四代:MCP协议(2025-2026)
2025年,Anthropic发布了一个可能改变游戏规则的东西——MCP(Model Context Protocol,模型上下文协议)。这是一个专门为AI工具调用设计的开放协议。
MCP要解决什么问题?
在MCP出现之前,每个AI应用要接入外部工具都需要单独开发适配器。如果你的AI助手需要调用Slack、GitHub、数据库、文件系统等10个不同的系统,你就得写10套不同的集成代码。而且这些集成之间无法复用,换一个AI模型可能就要重写一遍。
MCP就是要把这些集成标准化,让AI能"即插即用"各种外部系统。
MCP的核心架构:
外部工具MCP ServerMCP HostAI模型用户外部工具MCP ServerMCP HostAI模型用户#mermaid-svg-38cceVFXIZofLMU4{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-38cceVFXIZofLMU4 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-38cceVFXIZofLMU4 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-38cceVFXIZofLMU4 .error-icon{fill:#552222;}#mermaid-svg-38cceVFXIZofLMU4 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-38cceVFXIZofLMU4 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-38cceVFXIZofLMU4 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-38cceVFXIZofLMU4 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-38cceVFXIZofLMU4 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-38cceVFXIZofLMU4 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-38cceVFXIZofLMU4 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-38cceVFXIZofLMU4 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-38cceVFXIZofLMU4 .marker.cross{stroke:#333333;}#mermaid-svg-38cceVFXIZofLMU4 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-38cceVFXIZofLMU4 p{margin:0;}#mermaid-svg-38cceVFXIZofLMU4 .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-38cceVFXIZofLMU4 text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-38cceVFXIZofLMU4 .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-38cceVFXIZofLMU4 .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-38cceVFXIZofLMU4 .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-38cceVFXIZofLMU4 .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-38cceVFXIZofLMU4 #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-38cceVFXIZofLMU4 .sequenceNumber{fill:white;}#mermaid-svg-38cceVFXIZofLMU4 #sequencenumber{fill:#333;}#mermaid-svg-38cceVFXIZofLMU4 #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-38cceVFXIZofLMU4 .messageText{fill:#333;stroke:none;}#mermaid-svg-38cceVFXIZofLMU4 .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-38cceVFXIZofLMU4 .labelText,#mermaid-svg-38cceVFXIZofLMU4 .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-38cceVFXIZofLMU4 .loopText,#mermaid-svg-38cceVFXIZofLMU4 .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-38cceVFXIZofLMU4 .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-38cceVFXIZofLMU4 .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-38cceVFXIZofLMU4 .noteText,#mermaid-svg-38cceVFXIZofLMU4 .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-38cceVFXIZofLMU4 .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-38cceVFXIZofLMU4 .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-38cceVFXIZofLMU4 .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-38cceVFXIZofLMU4 .actorPopupMenu{position:absolute;}#mermaid-svg-38cceVFXIZofLMU4 .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-38cceVFXIZofLMU4 .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-38cceVFXIZofLMU4 .actor-man circle,#mermaid-svg-38cceVFXIZofLMU4 line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-38cceVFXIZofLMU4 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}发送任务:"帮我查一下今天Slack上的未读消息"请求工具列表发现Slack连接器查询Slack API返回未读消息列表格式化结果提供工具调用建议执行get_slack_messages工具调用Slack工具返回消息数据工具执行结果汇总并展示未读消息
MCP的三层架构:
# MCP协议的核心概念:Resources(资源)、Tools(工具)、Prompts(提示模板)
# 1. Resources – AI可以读取的数据
{
"type": "resource",
"name": "slack_messages",
"uri": "slack://channels/general/messages",
"description": "Slack #general 频道的最新消息"
}
# 2. Tools – AI可以调用的函数
{
"type": "tool",
"name": "send_slack_message",
"description": "向Slack频道发送消息",
"input_schema": {
"type": "object",
"properties": {
"channel": {"type": "string"},
"text": {"type": "string"}
}
}
}
# 3. Prompts – 预定义的提示模板
{
"type": "prompt",
"name": "summarize_channel",
"description": "总结频道今日讨论要点",
"arguments": [{"name": "channel", "type": "string"}]
}
MCP的实战示例:
# 使用Python SDK连接MCP服务器
from mcp import Client
# 连接到文件系统MCP服务器
async with Client("mcp://filesystem") as fs:
# 列出目录
files = await fs.list_resources("file:///projects")
# 读取文件
content = await fs.read("file:///projects/README.md")
# 执行操作
await fs.call_tool("create_file", {
"path": "/projects/test.txt",
"content": "Hello MCP!"
})
# 连接到Slack MCP服务器
async with Client("mcp://slack") as slack:
# 获取未读消息
messages = await slack.call_tool("get_unread_messages", {})
MCP vs Function Calling 对比:
| 适用范围 | 单模型单次调用 | 跨模型跨会话复用 |
| 工具发现 | 每次调用时手动传入 | 自动发现可用工具 |
| 连接管理 | 应用自行管理 | 协议统一管理 |
| 生态 | 厂商私有 | 开放标准 |
| 状态保持 | 无状态 | 有状态(session管理) |
MCP的生态现状(2026年5月):
目前已有超过200个官方的MCP Servers,覆盖:
- 文件系统(本地文件读写)
- 数据库(PostgreSQL、MySQL、MongoDB)
- GitHub(PR、Issue、代码审查)
- Slack/Discord(消息推送)
- 数据库(SQL执行)
- 网页浏览(Playwright驱动)
- S3/云存储
三、实战:用MCP搭建一个多工具AI助手
3.1 项目需求
我们来实战一下:用MCP协议,把搜索、文件系统、Github三个工具接进来,让AI能帮我们完成"搜资料→整理到文件→提交PR"的全流程。
3.2 环境准备
# 安装MCP Python SDK
pip install mcp
# 安装Anthropic Claude API客户端
pip install anthropic
# 或者使用OpenAI
pip install openai
3.3 代码实现
import asyncio
from anthropic import Anthropic
from mcp import Client
from mcp.server.stdio import stdio_server
# 初始化Claude客户端
client = Anthropic()
# 定义MCP服务器配置
MCP_SERVERS = {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]
},
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {"GITHUB_TOKEN": "your_token_here"}
},
"brave-search": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-brave-search"],
"env": {"BRAVE_API_KEY": "your_brave_key"}
}
}
class MCPHost:
"""MCP协议的主机实现"""
def __init__(self):
self.servers = {}
self.tools = []
async def connect_servers(self):
"""连接所有MCP服务器"""
for name, config in MCP_SERVERS.items():
try:
# 启动MCP服务器进程
server = await Client.connect(
command=config["command"],
args=config["args"],
env=config.get("env", {})
)
self.servers[name] = server
# 获取该服务器提供的工具
resources = await server.list_tools()
self.tools.extend(resources)
print(f"✅ 已连接 {name},发现 {len(resources)} 个工具")
except Exception as e:
print(f"❌ 连接 {name} 失败: {e}")
async def execute_tool(self, tool_name: str, arguments: dict):
"""执行指定工具"""
for name, server in self.servers.items():
try:
result = await server.call_tool(tool_name, arguments)
return {"success": True, "result": result}
except:
continue
return {"success": False, "error": f"Tool {tool_name} not found"}
async def cleanup(self):
"""关闭所有服务器连接"""
for server in self.servers.values():
await server.close()
# 主执行逻辑
async def main():
host = MCPHost()
# 连接所有工具
await host.connect_servers()
# 用户任务:搜一下最新的AI Agent框架,选一个写个简单介绍
user_task = """
请帮我完成以下任务:
1. 搜索一下2026年最新的AI Agent开源框架
2. 选择一个框架,写一份500字的介绍
3. 把介绍保存到 /tmp/agent-intro.md 文件
"""
# 构建消息
messages = [
{"role": "user", "content": user_task}
]
# 第一次调用:让模型决定需要哪些工具
response = client.messages.create(
model="claude-sonnet-4-5-20250501",
max_tokens=4096,
messages=messages,
tools=[{"name": t.name, "description": t.description, "input_schema": t.input_schema}
for t in host.tools]
)
# 处理工具调用
while response.stop_reason == "tool_use":
messages.append({"role": "assistant", "content": response.content[0].text})
for block in response.content:
if block.type == "tool_use":
tool_name = block.name
tool_args = block.input
print(f"🔧 调用工具: {tool_name}")
result = await host.execute_tool(tool_name, tool_args)
messages.append({
"role": "user",
"content": [{
"type": "tool_result",
"tool_use_id": block.id,
"content": str(result)
}]
})
# 继续对话,让模型处理结果
response = client.messages.create(
model="claude-sonnet-4-5-20250501",
max_tokens=4096,
messages=messages,
tools=[{"name": t.name, "description": t.description, "input_schema": t.input_schema}
for t in host.tools]
)
# 输出最终结果
print("\\n" + "="*50)
print("AI最终回复:")
print(response.content[0].text)
# 清理
await host.cleanup()
if __name__ == "__main__":
asyncio.run(main())
3.4 运行结果与调试
运行上述代码后,你会看到类似这样的输出:
✅ 已连接 filesystem,发现 5 个工具
✅ 已连接 github,发现 12 个工具
✅ 已连接 brave-search,发现 2 个工具
🔧 调用工具: brave_search
🔧 调用工具: filesystem_write
🔧 调用工具: filesystem_read
==================================================
AI最终回复:
根据我的搜索结果,2026年最值得关注的AI Agent开源框架是 **AutoGPT-Next**…
(完整回复内容)
如果遇到工具调用失败,MCP会返回详细的错误信息。你可以在循环中加入重试逻辑:
async def execute_with_retry(self, tool_name: str, arguments: dict, max_retries=3):
"""带重试的工具执行"""
for attempt in range(max_retries):
try:
result = await self.execute_tool(tool_name, arguments)
if result.get("success"):
return result
except Exception as e:
if attempt == max_retries – 1:
raise
print(f"⚠️ 第 {attempt+1} 次尝试失败,重试中…")
await asyncio.sleep(1)
四、2026年工具调用技术的最新进展
4.1 多模态工具调用成为现实
2026年,大模型不再只能调用文本工具。Claude 3.7、GPT-4o Vision等模型已经能理解图片、PDF、甚至视频内容,并基于这些内容调用工具。
实际应用场景:
- 上传一张截图,AI自动识别界面元素并帮你操作
- 上传一份PDF合同,AI提取关键条款并录入数据库
- 上传一段视频,AI生成描述并存入知识库
# 多模态工具调用示例
response = client.messages.create(
model="claude-sonnet-4-5-20250501",
messages=[{
"role": "user",
"content": [
{"type": "image", "source": {"type": "base64", "data": screenshot_b64}},
{"type": "text", "text": "这个界面报错了,帮我分析一下原因"}
]
}],
tools=[...] # 可以包含截图分析工具
)
4.2 并行工具调用提升效率
传统方式下,模型需要串行调用工具——等一个完成再调用下一个。2025年底开始,支持并行调用的模型开始普及,AI可以一次性决定调用多个独立的工具,大幅提升执行效率。
并行vs串行对比:
| 查天气+搜新闻+发邮件 | 9秒 | 3秒 | 3倍 |
| 读取3个数据库表 | 6秒 | 2秒 | 3倍 |
| 分析5个文件 | 25秒 | 5秒 | 5倍 |
# 并行工具调用示例(Anthropic Claude的新特性)
response = client.messages.create(
model="claude-3-7-sonnet-20251101",
messages=[...],
tools=[...],
tool_choice={"type": "auto"},
# 允许并行调用最多3个工具
max_parallel_tool_calls=3
)
# 返回结果中会包含多个工具调用
for block in response.content:
if block.type == "tool_use":
# 处理每个工具调用
print(f"工具: {block.name}, 参数: {block.input}")
4.3 工具调用的安全性进展
随着AI能做的事情越来越多,安全性变得至关重要。2026年,各厂商都在工具调用安全方面做了大量改进:
主要安全措施:
# 安全配置的示例
tool_config = {
"dangerous_tools": ["delete_file", "format_disk"],
"require_confirmation": True,
"rate_limit": {
"max_calls_per_minute": 60,
"max_calls_per_day": 1000
},
"audit_log": True
}
五、工具调用能力的应用场景
5.1 智能客服与数字员工
这是工具调用最直接的应用场景。AI不再只是回答问题,而是能真正帮你做事:
典型场景:
- 回答用户"我的订单到哪了"→ AI直接查物流系统 → 把状态告诉你
- 用户说"帮我退个货" → AI登录电商后台 → 填写退货单 → 发送确认邮件
实现架构:
#mermaid-svg-phCwrqDQpzF2bKuf{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-phCwrqDQpzF2bKuf .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-phCwrqDQpzF2bKuf .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-phCwrqDQpzF2bKuf .error-icon{fill:#552222;}#mermaid-svg-phCwrqDQpzF2bKuf .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-phCwrqDQpzF2bKuf .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-phCwrqDQpzF2bKuf .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-phCwrqDQpzF2bKuf .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-phCwrqDQpzF2bKuf .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-phCwrqDQpzF2bKuf .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-phCwrqDQpzF2bKuf .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-phCwrqDQpzF2bKuf .marker{fill:#333333;stroke:#333333;}#mermaid-svg-phCwrqDQpzF2bKuf .marker.cross{stroke:#333333;}#mermaid-svg-phCwrqDQpzF2bKuf svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-phCwrqDQpzF2bKuf p{margin:0;}#mermaid-svg-phCwrqDQpzF2bKuf .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-phCwrqDQpzF2bKuf .cluster-label text{fill:#333;}#mermaid-svg-phCwrqDQpzF2bKuf .cluster-label span{color:#333;}#mermaid-svg-phCwrqDQpzF2bKuf .cluster-label span p{background-color:transparent;}#mermaid-svg-phCwrqDQpzF2bKuf .label text,#mermaid-svg-phCwrqDQpzF2bKuf span{fill:#333;color:#333;}#mermaid-svg-phCwrqDQpzF2bKuf .node rect,#mermaid-svg-phCwrqDQpzF2bKuf .node circle,#mermaid-svg-phCwrqDQpzF2bKuf .node ellipse,#mermaid-svg-phCwrqDQpzF2bKuf .node polygon,#mermaid-svg-phCwrqDQpzF2bKuf .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-phCwrqDQpzF2bKuf .rough-node .label text,#mermaid-svg-phCwrqDQpzF2bKuf .node .label text,#mermaid-svg-phCwrqDQpzF2bKuf .image-shape .label,#mermaid-svg-phCwrqDQpzF2bKuf .icon-shape .label{text-anchor:middle;}#mermaid-svg-phCwrqDQpzF2bKuf .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-phCwrqDQpzF2bKuf .rough-node .label,#mermaid-svg-phCwrqDQpzF2bKuf .node .label,#mermaid-svg-phCwrqDQpzF2bKuf .image-shape .label,#mermaid-svg-phCwrqDQpzF2bKuf .icon-shape .label{text-align:center;}#mermaid-svg-phCwrqDQpzF2bKuf .node.clickable{cursor:pointer;}#mermaid-svg-phCwrqDQpzF2bKuf .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-phCwrqDQpzF2bKuf .arrowheadPath{fill:#333333;}#mermaid-svg-phCwrqDQpzF2bKuf .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-phCwrqDQpzF2bKuf .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-phCwrqDQpzF2bKuf .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-phCwrqDQpzF2bKuf .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-phCwrqDQpzF2bKuf .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-phCwrqDQpzF2bKuf .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-phCwrqDQpzF2bKuf .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-phCwrqDQpzF2bKuf .cluster text{fill:#333;}#mermaid-svg-phCwrqDQpzF2bKuf .cluster span{color:#333;}#mermaid-svg-phCwrqDQpzF2bKuf div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-phCwrqDQpzF2bKuf .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-phCwrqDQpzF2bKuf rect.text{fill:none;stroke-width:0;}#mermaid-svg-phCwrqDQpzF2bKuf .icon-shape,#mermaid-svg-phCwrqDQpzF2bKuf .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-phCwrqDQpzF2bKuf .icon-shape p,#mermaid-svg-phCwrqDQpzF2bKuf .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-phCwrqDQpzF2bKuf .icon-shape .label rect,#mermaid-svg-phCwrqDQpzF2bKuf .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-phCwrqDQpzF2bKuf .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-phCwrqDQpzF2bKuf .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-phCwrqDQpzF2bKuf :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
查订单
退货
投诉
用户咨询
NLU理解意图
意图分类
调用订单系统API
调用退换货流程
创建工单系统
组装回复
用户收到回复
5.2 代码审查与自动化
开发者可以利用工具调用能力搭建自动化代码审查流程:
# 自动代码审查Agent
code_review_prompt = """
你是代码审查助手,请完成以下工作:
1. 从GitHub获取最新的PR代码
2. 运行代码质量检查工具
3. 运行安全扫描
4. 检查代码风格
5. 综合以上结果,给出审查意见
"""
# 工具:get_pr_code, run_linter, run_security_scan, post_review_comment
5.3 个人生产力助手
把AI变成真正的私人助手:
- 邮件管理:AI读取邮件内容,决定是否重要,需要回复还是归档
- 日程管理:AI根据你的日历和任务,自动安排会议时间
- 信息收集:AI定期搜索你关注的领域,推送最新进展
六、常见问题与避坑指南
6.1 工具调用失败怎么办
问题:模型选错了工具,或者工具执行报错。
解决方案:
def wrapper_tool(args):
try:
return actual_tool(args)
except Exception as e:
# 返回详细错误,帮助模型纠错
return {
"error": str(e),
"error_type": type(e).__name__,
"hint": "如果是要读取文件,请检查路径是否正确…"
}
6.2 模型总是"过度规划"
问题:模型面对简单任务也要调用多个工具,效率低。
解决:
6.3 工具定义太大,模型处理不过来
问题:定义了20+个工具,模型选择困难。
解决:
总结
从2023年的ReAct到2026年的MCP,大模型的工具调用能力走过了一条从"能用"到"好用"的进化路径:
- ReAct告诉我们AI可以边想边做
- Function Calling让工具调用变得标准化
- Agent架构让AI能处理复杂多步骤任务
- MCP让工具生态真正走向互联互通
2026年,工具调用能力已经成为AI应用的标配。未来,我们期待AI能更自然地融入我们的工作流,成为真正的"数字同事"。
如果你还在用AI做"文字游戏",建议试试给它装上工具调用能力。你可能会惊讶——原来AI可以这么有用。
参考资源:
- Anthropic MCP官方文档:https://modelcontextprotocol.dev
- LangChain Agent指南:https://python.langchain.com/docs/concepts/agents
- OpenAI Function Calling文档:https://platform.openai.com/docs/guides/function-calling
- Microsoft AutoGen:https://github.com/microsoft/autogen






