详解大模型工具调用双核心:MCP与Function Calling
在AI智能体(Agent)开发中,“工具调用”是连接大模型与外部世界的关键桥梁——让模型从“只能生成文本”升级为“能执行实际操作”,比如查天气、查数据库、调用API、执行代码等。而MCP(Multi-Context Prompting,多上下文提示)与Function Calling(函数调用),正是工具调用的两大核心方式,二者各有侧重、适配不同场景,掌握这两种方式,能大幅提升智能体的开发效率与落地能力。
本文将详细拆解MCP与Function Calling的核心功能、适用场景,搭配可直接运行的实操示例,帮你快速理解并上手,无论是面试讲解还是实际开发,都能直接复用。
一、先搞懂核心定位:MCP vs Function Calling
在深入讲解前,先明确二者的核心区别,避免混淆:
• Function Calling(函数调用):大模型原生支持的结构化工具调用能力,模型直接输出标准化的“函数名+参数”,无需复杂提示词约束,稳定性高、适配工业级落地。
• MCP(多上下文提示):一种提示词工程范式,不依赖模型原生能力,通过将工具描述、调用格式、示例、上下文等信息整合到提示词中,引导模型按规则调用工具,灵活适配各类模型(尤其是不支持原生Function Calling的开源模型)。
简单来说:Function Calling是“模型自带的工具调用技能”,MCP是“靠提示词教模型学会工具调用”,二者可单独使用,也可结合互补。
二、Function Calling:大模型原生的工具调用“标准答案”
2.1 核心功能解析
Function Calling是目前主流大模型(OpenAI GPT系列、Claude、文心一言、通义千问等)均支持的原生能力,其核心价值是“让模型输出结构化的工具调用指令”,而非杂乱的自然语言,开发者可直接解析指令、调用对应工具,再将工具返回结果回填给模型,生成最终回答,形成“提问→调用工具→获取结果→生成回答”的闭环。
核心功能亮点:
-
标准化输出:模型严格按照约定的格式(通常是JSON)输出函数名、参数,解析成本极低,不易出现格式错乱。
-
智能判断:模型会自主判断“是否需要调用工具”——如果问题可直接回答(如“1+1等于几”),则不调用工具;如果需要外部信息(如“今天北京天气”),则自动调用对应工具。
-
多工具兼容:支持同时定义多个工具,模型可根据问题自主选择适配的工具,甚至支持多工具并行调用。
-
可监控可追溯:工具调用的每一步(调用哪个工具、传入什么参数、返回什么结果)都可日志记录,便于调试和问题排查,适合工业级落地。
2.2 适用场景
Function Calling因其稳定性和标准化,是大多数企业级智能体的首选工具调用方式,核心适用场景包括:
-
外部数据查询:调用天气API、股票API、物流API等,获取实时数据(如“查询上海明天的气温”“查询某订单的物流状态”)。
-
结构化数据查询:结合NL2SQL,调用数据库工具,将自然语言转换为SQL语句,查询业务数据(如“查询2025年1月销售额超100万的门店”)。
-
工具执行类任务:调用计算器、代码解释器、邮件发送工具等,执行具体操作(如“计算(3.14×5)²的值”“生成一段Python代码实现数据可视化”)。
-
多步骤工具串联:配合智能体推理框架(ReAct、Planning),实现多工具按顺序调用(如“先查销量→再算增长率→最后生成报表”)。
2.3 实操示例(基于OpenAI GPT-3.5/4,可直接运行)
本次示例实现“天气查询”功能,步骤:定义天气查询工具→调用大模型→解析函数调用结果→执行工具→回填结果生成回答。
前提:安装依赖包 pip install openai python-dotenv,并配置OpenAI API Key。
from openai import OpenAI
from dotenv import load_dotenv
import os
# 1. 加载环境变量(存储API Key)
load_dotenv()
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
# 2. 定义工具(天气查询函数,模拟真实API调用)
def get_weather(city: str, date: str) -> str:
"""
功能:查询指定城市指定日期的天气情况
参数:
city: 城市名称(如“北京”“上海”)
date: 日期(格式:YYYY-MM-DD,如“2025-03-15”)
返回:天气描述字符串
"""
# 模拟API返回结果(实际开发中替换为真实API调用)
weather_data = {
"北京-2025-03-15": "晴,-5℃~5℃,微风,空气质量良",
"上海-2025-03-15": "阴转小雨,8℃~12℃,东风3级,空气质量优"
}
key = f"{city}-{date}"
return weather_data.get(key, f"未查询到{city}{date}的天气信息")
# 3. 定义工具列表(告诉模型有哪些可用工具)
tools = [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "查询指定城市指定日期的天气情况",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "城市名称,如北京、上海",
},
"date": {
"type": "string",
"description": "日期,格式为YYYY-MM-DD,如2025-03-15",
}
},
"required": ["city", "date"], # 必须传入的参数
}
}
}
]
# 4. 向模型提问,触发工具调用
user_question = "查询北京2025年03月15日的天气"
response = client.chat.completions.create(
model="gpt-3.5-turbo",
messages=[{"role": "user", "content": user_question}],
tools=tools,
tool_choice="auto" # 让模型自主判断是否调用工具
)
# 5. 解析模型响应,执行工具调用
response_message = response.choices[0].message
if response_message.tool_calls:
# 提取工具调用信息
tool_call = response_message.tool_calls[0]
function_name = tool_call.function.name
function_args = eval(tool_call.function.arguments) # 解析参数(实际开发可用json.loads)
# 执行对应的工具函数
if function_name == "get_weather":
weather_result = get_weather(** function_args)
print(f"工具调用结果:{weather_result}")
# 6. 将工具结果回填给模型,生成最终回答
final_response = client.chat.completions.create(
model="gpt-3.5-turbo",
messages=[
{"role": "user", "content": user_question},
response_message, # 模型之前的工具调用响应
{
"role": "tool",
"name": function_name,
"content": weather_result
}
]
)
print(f"最终回答:{final_response.choices[0].message.content}")
else:
# 无需调用工具,直接输出回答
print(f"最终回答:{response_message.content}")
运行结果:
工具调用结果:晴,-5℃~5℃,微风,空气质量良
最终回答:北京2025年03月15日的天气情况为:晴,气温-5℃~5℃,微风,空气质量良。
示例说明:模型自主判断需要调用get_weather工具,输出标准化的参数(city=北京,date=2025-03-15),我们解析后执行工具,再将结果回填给模型,最终生成自然语言回答,整个流程闭环且可控。
三、MCP(Multi-Context Prompting):无模型依赖的工具调用“万能方案”
3.1 核心功能解析
MCP并非大模型原生能力,而是一种工程化的提示词设计范式——核心思想是“把所有与工具调用相关的信息,一次性整合到提示词中”,让模型即使不支持原生Function Calling,也能按照约定的格式调用工具。
MCP的核心是“上下文完整性”,提示词需包含以下关键要素:
-
角色定义:明确智能体的身份(如“工具调用助手”)。
-
工具列表:详细说明可用工具的名称、功能、参数格式、必填项。
-
调用规则:明确“什么时候调用工具”“调用格式要求”(如必须输出指定JSON格式)。
-
示例引导:提供正确/错误的调用示例,让模型快速学习。
-
上下文历史:保留多轮对话历史,确保工具调用的连贯性。
核心功能亮点:
-
无模型依赖:适配所有大模型,包括不支持原生Function Calling的开源模型(如Llama3、Qwen、GLM等)。
-
高度灵活:可根据业务需求,自定义工具调用格式、规则,无需受模型原生能力限制。
-
低成本落地:无需依赖模型的特殊接口,仅通过提示词优化,就能实现工具调用。
3.2 适用场景
MCP的灵活性使其适合多种场景,尤其是开源模型开发、快速原型验证等场景,核心适用场景包括:
-
开源模型工具调用:使用Llama3、Qwen等开源模型开发智能体,因模型不支持原生Function Calling,用MCP实现工具调用。
-
多工具定制化调用:需要自定义工具调用格式(如非JSON格式),或对工具调用逻辑有特殊要求(如多轮校验)。
-
快速原型验证:无需搭建复杂的工具调用解析逻辑,通过提示词快速验证工具调用的可行性。
-
低资源场景:模型算力有限,无法支持复杂的原生Function Calling,用MCP简化调用逻辑。
3.3 实操示例(适配所有大模型,以Qwen-7B为例)
本次示例同样实现“天气查询”功能,通过MCP提示词引导模型输出指定格式的工具调用指令,再解析执行。
前提:安装依赖包 pip install transformers accelerate qwen,加载Qwen-7B模型(可使用量化版本,降低算力要求)。
from transformers import AutoModelForCausalLM, AutoTokenizer
# 1. 加载Qwen-7B模型(量化版本,适配普通电脑)
model_name = "Qwen/Qwen-7B-Chat-Int4"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(
model_name,
device_map="auto",
trust_remote_code=True
)
# 2. 定义MCP提示词(核心:整合所有工具调用相关信息)
mcp_prompt = """
你是一个工具调用助手,必须严格按照以下规则调用工具,不能直接回答问题。
### 可用工具列表
1. 工具名称:get_weather
功能:查询指定城市指定日期的天气情况
参数:
city:字符串,必填,城市名称(如“北京”“上海”)
date:字符串,必填,日期格式为YYYY-MM-DD(如“2025-03-15”)
### 调用规则
1. 只有当用户问题需要查询天气时,才调用get_weather工具;
2. 调用工具必须输出以下JSON格式,不能添加任何多余文本:
{"tool": "get_weather", "params": {"city": "城市名", "date": "日期"}}
3. 若参数缺失(如未说明日期),无需追问,直接输出格式错误提示:{"error": "参数缺失,需提供城市和日期"}
### 正确示例
用户:查询上海2025年03月15日的天气
输出:{"tool": "get_weather", "params": {"city": "上海", "date": "2025-03-15"}}
### 错误示例
用户:查询上海天气
输出:{"error": "参数缺失,需提供城市和日期"}
### 上下文历史
无
### 用户问题
查询北京2025年03月15日的天气
"""
# 3. 调用模型,获取响应
inputs = tokenizer(mcp_prompt, return_tensors="pt").to(model.device)
outputs = model.generate(** inputs, max_new_tokens=100, temperature=0.1)
response = tokenizer.decode(outputs[0], skip_special_tokens=True)
# 4. 提取模型输出,解析工具调用指令
# 截取模型输出中的JSON部分(实际开发可用正则优化解析)
import json
try:
# 提取{}包裹的JSON内容
json_start = response.find("{")
json_end = response.rfind("}") + 1
tool_call = json.loads(response[json_start:json_end])
# 5. 执行工具调用(复用之前的get_weather函数)
if tool_call.get("tool") == "get_weather":
weather_result = get_weather(** tool_call["params"])
print(f"工具调用结果:{weather_result}")
# 生成最终回答(可再次调用模型,将结果回填)
final_prompt = f"用户问的是'查询北京2025年03月15日的天气',工具调用结果是:{weather_result},请用自然语言总结回答。"
final_inputs = tokenizer(final_prompt, return_tensors="pt").to(model.device)
final_outputs = model.generate(** final_inputs, max_new_tokens=100, temperature=0.1)
final_answer = tokenizer.decode(final_outputs[0], skip_special_tokens=True)
print(f"最终回答:{final_answer}")
elif tool_call.get("error"):
print(f"模型提示:{tool_call['error']}")
except:
print(f"模型输出格式错误,输出内容:{response}")
运行结果:
工具调用结果:晴,-5℃~5℃,微风,空气质量良
最终回答:北京2025年03月15日的天气为晴,气温在-5℃到5℃之间,微风,空气质量良。
示例说明:通过MCP提示词,我们明确了工具调用的格式、规则和示例,即使Qwen-7B不支持原生Function Calling,也能输出标准化的工具调用指令。解析指令后执行工具,再将结果回填给模型,完成整个工具调用流程。
四、MCP与Function Calling 深度对比及选型建议
4.1 核心对比表
|
对比维度 |
Function Calling |
MCP |
|---|---|---|
|
核心依赖 |
大模型原生支持 |
提示词工程,无模型依赖 |
|
输出格式 |
标准化JSON,稳定可控 |
依赖提示词约束,易出现格式错乱 |
|
开发成本 |
低(无需复杂提示词,解析简单) |
高(需设计完善的提示词,优化解析逻辑) |
|
适配模型 |
主流闭源模型(GPT、Claude等)+ 部分开源模型 |
所有大模型(闭源+开源) |
|
稳定性 |
高,工业级可用 |
中等,取决于提示词质量 |
|
调试难度 |
低,可日志监控每一步调用 |
高,需优化提示词、调整解析逻辑 |
4.2 选型建议
-
优先选Function Calling:如果使用闭源模型(GPT、文心一言等),且追求稳定性、工业级落地,优先使用Function Calling,开发效率高、调试简单。
-
选MCP的情况:使用开源模型(Llama3、Qwen等),或需要自定义工具调用格式、规则,无法使用原生Function Calling时,选择MCP。
-
混合使用:实际开发中,可结合二者优势——用Function Calling实现核心工具调用,用MCP适配特殊场景(如开源模型 fallback),提升系统的兼容性和稳定性。
五、总结
MCP与Function Calling,是大模型工具调用的两大核心方式,二者并非对立,而是互补共生:Function Calling胜在“稳定、标准、高效”,适合工业级落地;MCP胜在“灵活、无依赖、低成本”,适合开源模型和定制化场景。
掌握这两种工具调用方式,能让你在AI智能体开发中灵活应对不同场景——无论是基于闭源模型快速落地项目,还是基于开源模型搭建定制化智能体,都能游刃有余。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐

所有评论(0)