在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智能体开发中灵活应对不同场景——无论是基于闭源模型快速落地项目,还是基于开源模型搭建定制化智能体,都能游刃有余。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐