别再搞混了!MCP真的需要Function Calling吗?Cline源码揭秘

在快速发展的AI编程助手领域,有两个概念经常被一起提及,甚至被一些开发者和技术文章所混淆:Function CallingModel Context Protocol (MCP)。是不是一定要LLM具备Function Calling能力,才能有效利用MCP与外部工具交互呢?答案可能和你想象的不一样。今天,我们就来澄清这个常见的误解,并深入流行的VSCode插件——Cline的源码,看看它是如何巧妙解决这个问题的。

Function Calling vs. MCP:先厘清概念

  • Function Calling (函数调用): 这通常指的是大语言模型(LLM)本身的一种能力。当用户用自然语言提出请求时,具备Function Calling能力的LLM能够理解这个请求,并自主判断是否需要、以及需要调用哪些预定义的外部工具(函数/API)来完成任务。它还能生成符合特定格式(通常是JSON)的调用参数。简单说,Function Calling是LLM决定“用哪个工具”和“怎么用”的智能决策过程。
  • Model Context Protocol (MCP,模型上下文协议): MCP则是一个标准化的交互协议。它定义了LLM Agent应用(如Cline这样的编程助手)与外部系统(MCP Server,提供各种工具或数据源)之间应该如何通信。它规范了请求和响应的格式,确保双方能够顺畅地“对话”。MCP关心的是“如何传递工具调用指令和结果”,而不是LLM如何做出调用决策。

看到这里,你可能已经有点明白了:MCP负责的是“通信管道”的标准,而Function Calling是某些LLM拥有的“智能大脑”的一部分。理论上,只要LLM应用能按照MCP规定的格式发出请求,MCP就能工作,并不强制要求LLM本身具备原生的Function Calling能力。

普遍的误解:为什么会认为MCP依赖Function Calling?

误解的产生往往源于一个看似合理的逻辑链:

  1. MCP需要执行外部工具(tools)。
  2. 调用哪个工具、传入什么参数,这个“决策”需要LLM来做。
  3. LLM做出这种结构化决策并输出调用指令,这不就是Function Calling吗?

这个逻辑没错,但它忽略了一点:LLM产生“调用哪个工具以及如何调用”的结构化输出,不一定非要依赖其内置的Function Calling能力

Cline的解决方案:强大的System Prompt

VSCode上广受欢迎的Cline插件就是一个很好的例子。它支持通过OpenRouter这样的平台接入上百种不同的LLM。显然,这些LLM中只有少数具备原生的Function Calling能力,但这并不妨碍用户在Cline中使用各种MCP Server提供的强大功能。

Cline是如何做到的呢?答案就藏在它的开源代码里,具体来说是src/core/prompts/system.ts文件中的SYSTEM_PROMPT函数。这个函数构建了一个极其详尽、长达近千行的系统提示词(System Prompt)

这个System Prompt就像一份详细的说明书,告诉LLM:

  1. “你有权使用工具”: 明确告知LLM它可以使用一系列工具来完成任务。
  2. “工具调用的标准格式是这样的”: Cline定义了一种基于XML的工具调用格式,并清晰地展示给LLM。
<tool_name>
  <parameter1_name>value1</parameter1_name>
  <parameter2_name>value2</parameter2_name>
  ...
</tool_name>

<!-- 示例 -->
<read_file>
  <path>src/main.js</path>
</read_file>

LLM被要求严格遵守这种XML格式来发起工具调用。

  1. “这是你可以用的内置工具”: System Prompt预定义了一些Cline的基础工具,如执行命令行(execute_command)、读文件(read_file)、写文件(write_to_file)等,并详细说明了它们的用途、参数和使用格式。 (有趣的是,根据源码注释,Cline的这几个基础工具调用是通过VSCode API实现的,并未走MCP通道)。
<!-- 执行命令示例 -->
<execute_command>
  <command>npm install react</command>
  <requires_approval>true</requires_approval> <!-- 某些操作需要用户确认 -->
</execute_command>

<!-- 写文件示例 -->
<write_to_file>
  <path>src/App.js</path>
  <content>
    // 完整的JS代码内容...
  </content>
</write_to_file>
  1. “如果你启用了MCP,还可以这样调用外部工具”: 当用户在Cline中配置并启用了MCP Server时,System Prompt会动态地加入两个关键的MCP工具调用指令:use_mcp_tool(使用MCP服务器提供的工具)和access_mcp_resource(访问MCP服务器提供的资源)。
<!-- 调用MCP工具示例 -->
<use_mcp_tool>
  <server_name>example-weather-server</server_name>
  <tool_name>get_forecast</tool_name>
  <arguments>
    {
      "city": "北京",
      "days": 3
    }
  </arguments>
</use_mcp_tool>

<!-- 访问MCP资源示例 -->
<access_mcp_resource>
  <server_name>example-weather-server</server_name>
  <uri>weather://San Francisco/current</uri>
</access_mcp_resource>
  1. “这是已连接的MCP Server提供的具体能力”: 最关键的一步!如果用户连接了MCP Server,Cline会读取这些Server提供的工具(Tools)和资源(Resources)的描述、输入/输出模式(Schema)等信息,并将这些信息动态地插入到System Prompt中

例如,如果连接了一个天气查询的MCP Server,System Prompt里就会包含类似这样的描述:

## example-weather-server (`node /path/to/weather-server/build/index.js`)

### Available Tools
- get_forecast: Get weather forecast for a city
    Input Schema:
    {
      "type": "object",
      "properties": { ... }, // 详细的参数定义
      "required": ["city"]
    }

### Resource Templates
- weather://{city}/current (Current weather for a given city): ...

### Direct Resources
- weather://San Francisco/current (Current weather in San Francisco): ...

通过这种方式,即使LLM本身没有Function Calling能力,它也能通过阅读这份极其详尽的System Prompt,“学习”到当前可用的所有工具(包括来自MCP Server的)以及如何按照规定的XML格式来请求调用它们。Cline的后端代码再解析这个XML输出,转换成真正的MCP请求发送出去。

System Prompt 方式的利弊

Cline的这种做法非常聪明,它以兼容性换取了一些潜在的代价

  • 优点:
    • 极高的兼容性: 几乎可以适配任何能理解并遵循指令的LLM,无论其是否具备原生Function Calling能力。这使得用户可以通过OpenRouter等平台自由选择模型。
  • 缺点:
    • 巨大的Token消耗: 近千行的System Prompt本身就占用了大量的上下文窗口(Context Window)。随着连接的MCP Server增多,这个Prompt还会进一步膨胀(可能达到60KB甚至更多)。对于那些Token限制较低的模型,留给用户输入和对话历史的空间就非常有限了。
    • 潜在的效率和准确性问题? 有人可能会担心,强制LLM通过阅读长Prompt来模拟Function Calling,会不会比原生能力效率低、更容易出错?

System Prompt 效果如何?意外的发现

关于上述缺点的第二点,一个有趣的参考来自 Berkeley Function-Calling Leaderboard。这个排行榜评估了各种LLM在Function Calling任务上的表现。值得注意的是,排行榜也将“使用System Prompt引导LLM进行工具调用”的方式纳入了比较。

结果有些出人意料:对于像OpenAI的GPT-4o和o1这样的顶尖模型,使用System Prompt的方式在某些测试维度上,表现甚至优于或显著优于它们自身的原生Function Calling能力!

GPT-4o: Function Calling (FC) vs. System Prompt (Prompt)
在这里插入图片描述

当然,对于大多数其他LLM来说,原生Function Calling的表现通常还是更好一些,但差距并没有想象中那么大。这表明,只要System Prompt设计得足够好、足够清晰,通过Prompt引导的方式完全可以达到非常理想的工具调用效果。 Cline的做法在平衡通用性和准确性上是相当成功的。

(注:Cline团队未来或许可以考虑优化,比如先检测LLM是否支持原生Function Calling,如果支持则优先使用,以节省Token。)

总结

所以,回到最初的问题:MCP必须依赖Function Calling吗?答案是否定的。

MCP只是一个通信协议。虽然实现MCP交互需要LLM能够生成结构化的工具调用指令,但这并不一定需要LLM具备原生的Function Calling能力。通过像Cline那样精心设计、内容详尽的System Prompt,完全可以引导几乎任何LLM“学会”如何按照MCP的要求与外部世界互动。

理解了这一点,能帮助我们更清晰地认识当前LLM Agent架构,也更能体会到像Cline这样优秀工具在设计上的巧思。下一次当你使用或开发类似的AI应用时,就能更深刻地理解其背后的运作机制了。

想探索AI前沿?来 ChatTools (https://chat.chattools.cn)!聚合GPT-4o(支持图片编辑)、Claude 3.7 Sonnet、DeepSeek-R1、Gemini等顶尖模型。亮点:Midjourney免费无限生图!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值