AI 概念小扫盲:MCP 与 Function Calling 是什么关系?

160 阅读3分钟

什么是Function Calling?

Function Calling是一种让大语言模型(LLM)能够与外部工具和系统交互的机制。它允许模型在需要时识别并调用适当的工具来获取信息或执行作。

工作原理

  • 工具定义: 首先,开发者需要定义模型可以使用的工具列表,每个工具包括:
    • 名称(name)
    • 描述(description)
    • 参数信息(parameters),通常使用JSON Schema格式
  • 模型决策: 当用户提出问题时,模型会:
    • 分析问题是否需要外部工具
    • 如果需要,决定调用哪个工具
    • 生成符合要求的参数
  • 结构化输出: 模型会输出一个结构化的响应,通常是类似这样的JSON格式:
{
 "name": "get_weather",
 "arguments": {
   "location": "北京"
 }
}
  • 后端执行: 应用程序的后端会执行如下操作。
    • 解析模型的输出
    • 根据工具名称找到对应的函数
    • 使用提供的参数执行该函数
    • 获取执行结果
  • 结果反馈: 执行结果会作为新的上下文提供给模型,模型基于这些信息生成最终的自然语言响应。

为什么 Function Calling 不够用,要有 MCP?

Function Calling 有哪些问题?

  1. 格式依赖和脆弱性问题
    • 模型可能输出不规范的JSON
    • 可能缺少必要字段或参数
    • 格式错误导致整个工具调用失败
    • 需要复杂的Prompt工程来约束输出格式
  2. 缺乏标准化
    • 工具难以在不同平台间移植
    • 需要为每个平台重新实现工具集成
    • 增加了开发和维护成本
  3. 工具发现机制不足
    • 工具列表通常在会话开始时静态定义
    • 难以动态添加或移除工具
    • 工具元数据描述能力有限
  4. 错误处理不统一
    • 每个实现都有自己的一套错误处理机制
    • 难以建立统一的错误恢复策略
    • 错误信息传递不规范

MCP 如何解决?

1. 标准化的通信协议

MCP基于JSON-RPC 2.0标准:

// 标准的MCP工具调用请求
{
  "jsonrpc": "2.0",
  "id": "1",
  "method": "tools/call",
  "params": {
    "name": "get_weather",
    "arguments": {
      "location": "北京"
    }
  }
}

// 标准的响应格式
{
  "jsonrpc": "2.0",
  "id": "1",
  "result": {
    "temperature": "25°C",
    "condition": "晴天"
  }
}

// 标准的错误格式
{
  "jsonrpc": "2.0",
  "id": "1",
  "error": {
    "code": -32601,
    "message": "Method not found"
  }
}
2. 动态工具发现
// 工具发现请求
{
  "jsonrpc": "2.0",
  "id": "2",
  "method": "tools/list",
  "params": {}
}

// 工具列表响应
{
  "jsonrpc": "2.0",
  "id": "2",
  "result": [
    {
      "name": "get_weather",
      "description": "获取指定地点的天气信息",
      "inputSchema": {
        "type": "object",
        "properties": {
          "location": {
            "type": "string",
            "description": "地点名称"
          }
        }
      }
    }
  ]
}
3. 标准化的初始化和能力协商
// 初始化请求
{
  "jsonrpc": "2.0",
  "id": "init-1",
  "method": "initialize",
  "params": {
    "protocolVersion": "2024-11-05",
    "capabilities": {
      "tools": {},
      "resources": {}
    },
    "clientInfo": {
      "name": "MyAIApp",
      "version": "1.0.0"
    }
  }
}

场景对比

  • Function Calling场景

    1. 开发者需要为每个LLM平台编写不同的工具集成代码
    2. 工具调用容易因模型输出格式问题而失败
    3. 工具管理复杂,难以动态扩展
  • MCP场景

    1. 一次编写,到处使用(Write Once, Run Everywhere)
    2. 标准化协议确保工具调用的可靠性
    3. 动态工具发现和注册机制便于扩展