Tools、MCP 和 Function Calling

Tools、MCP 和 Function Calling 详细对比文档

基于 Lynxe 项目的实际实现分析

地址:https://github.com/spring-ai-alibaba/Lynxe

概述

在 AI Agent 开发中,ToolsMCPFunction Calling 是三种不同的工具调用机制,它们各有特点和应用场景。本文档是基于 Lynxe 项目的实际实现,详细说明三者的区别、关系和使用方式。

核心概念速览

特性 Tools (Spring AI) MCP Function Calling
定位 框架层面的工具抽象 协议标准 模型层面的能力
实现层级 应用框架层 协议层 模型 API 层
标准化程度 Spring AI 框架标准 行业协议标准 模型厂商标准
集成方式 直接集成 通过协议集成 通过 API 集成
扩展性 框架内扩展 跨平台扩展 模型能力限制

Tools (Spring AI Tools)

定义

Tools 是 Spring AI 框架提供的统一工具调用机制,它是框架层面的抽象,用于将各种功能封装成可被 LLM 调用的工具。

核心特点

  1. 框架级抽象:不依赖特定模型,是 Spring AI 框架的统一接口
  2. 类型安全:使用 Java 泛型,提供类型安全的工具定义
  3. 统一管理 :通过 ToolCallingManager 统一管理所有工具
  4. 灵活扩展:可以轻松添加自定义工具

在 Lynxe 中的实现

1. 工具定义接口

所有工具都实现 ToolCallBiFunctionDef 接口:

java 复制代码
// ToolCallBiFunctionDef.java
public interface ToolCallBiFunctionDef<I> 
    extends BiFunction<I, ToolContext, ToolExecuteResult> {
    
    String getServiceGroup();      // 工具分组
    String getName();               // 工具名称
    String getDescription();       // 工具描述
    String getParameters();        // 参数定义(JSON Schema)
    Class<I> getInputType();       // 输入类型
    boolean isReturnDirect();      // 是否直接返回结果
    boolean isSelectable();        // 是否可选
}
2. 工具注册流程

PlanningFactory.toolCallbackMap() 方法中:

java 复制代码
// 1. 创建工具定义列表
List<ToolCallBiFunctionDef<?>> toolDefinitions = new ArrayList<>();

// 2. 添加内置工具(例如:浏览器工具、数据库工具等)
toolDefinitions.add(BrowserUseTool.getInstance(...));
toolDefinitions.add(DatabaseReadTool.getInstance(...));
toolDefinitions.add(new Bash(...));
// ... 更多工具

// 3. 将工具定义包装成 FunctionToolCallback
for (ToolCallBiFunctionDef<?> toolDefinition : toolDefinitions) {
    FunctionToolCallback<?, ToolExecuteResult> functionToolCallback = 
        FunctionToolCallback
            .builder(qualifiedKey, toolDefinition)
            .description(toolDefinition.getDescriptionWithServiceGroup())
            .inputSchema(toolDefinition.getParameters())
            .inputType(toolDefinition.getInputType())
            .toolMetadata(ToolMetadata.builder()
                .returnDirect(toolDefinition.isReturnDirect())
                .build())
            .build();
    
    // 4. 注册到工具回调映射
    toolCallbackMap.put(qualifiedKey, functionToolCallback);
}
3. 工具调用流程

DynamicAgent 中调用 LLM:

java 复制代码
// 1. 获取工具回调列表
List<ToolCallback> callbacks = getToolCallList();

// 2. 通过 ChatClient 调用,传递工具
Flux<ChatResponse> responseFlux = chatClient.prompt(userPrompt)
    .toolCallbacks(callbacks)  // 关键:传递工具列表
    .stream()
    .chatResponse();

// 3. LLM 返回工具调用请求
List<ToolCall> toolCalls = streamResult.getEffectiveToolCalls();

// 4. 通过 ToolCallingManager 执行工具
ToolExecutionResult result = toolCallingManager.executeToolCalls(
    userPrompt, response);

典型工具示例

浏览器工具 (BrowserUseTool)
java 复制代码
public class BrowserUseTool extends AbstractBaseTool<BrowserInput> {
    @Override
    public ToolExecuteResult run(BrowserInput input) {
        // 执行浏览器操作
        // 返回结果
    }
}
数据库工具 (DatabaseReadTool)
java 复制代码
public class DatabaseReadTool extends AbstractBaseTool<DatabaseQueryInput> {
    @Override
    public ToolExecuteResult run(DatabaseQueryInput input) {
        // 执行数据库查询
        // 返回查询结果
    }
}

Tools 的优势

统一接口 :所有工具使用相同的接口,易于管理

类型安全 :编译时类型检查,减少运行时错误

框架集成 :与 Spring AI 深度集成,开箱即用

易于扩展 :实现接口即可添加新工具

统一管理:通过 ToolCallingManager 统一管理执行流程

Tools 的局限性

框架绑定 :依赖 Spring AI 框架

平台限制:主要在 Java/Spring 生态中使用


MCP (Model Context Protocol)

定义

MCP (Model Context Protocol) 是由 Anthropic 提出的一个开放协议标准,用于在 AI 应用和外部服务之间建立标准化的通信协议。它允许 AI 应用通过标准化的方式访问外部工具、资源和上下文。

核心特点

  1. 协议标准:跨平台、跨语言的协议标准
  2. 标准化通信:定义标准的消息格式和通信流程
  3. 外部服务集成:可以集成任何支持 MCP 的外部服务
  4. 资源访问:不仅支持工具调用,还支持资源访问和提示词模板

MCP 协议架构

复制代码
┌─────────────┐         MCP Protocol         ┌─────────────┐
│  AI Client  │ ◄─────────────────────────► │  MCP Server  │
│  (Lynxe)    │      (JSON-RPC over         │  (External)  │
│             │       stdio/HTTP/SSE)       │              │
└─────────────┘                             └─────────────┘

AI 客户端如: Lynxe 可以通过 MCP 协议(JSON-RPC)和外部 MCP 服务器通信,通信方式可以是标准输入输出、HTTP 请求或者 SSE 推送。

在 Lynxe 中的实现

1. MCP 服务管理

McpService 负责管理 MCP 服务器连接:

java 复制代码
@Component
public class McpService {
    // 获取 MCP 服务器的工具回调
    public List<McpServiceEntity> getFunctionCallbacks(String planId) {
        // 1. 从数据库加载 MCP 配置
        // 2. 建立 MCP 连接
        // 3. 获取工具列表
        // 4. 返回工具实体
    }
}
2. MCP 工具包装

MCP 工具通过 McpTool 包装成 Spring AI Tools:

java 复制代码
public class McpTool extends AbstractBaseTool<Map<String, Object>> {
    private final ToolCallback toolCallback;  // MCP 协议返回的 ToolCallback
    
    @Override
    public ToolExecuteResult run(Map<String, Object> inputMap) {
        // 1. 将输入转换为 JSON
        String jsonInput = objectMapper.writeValueAsString(inputMap);
        
        // 2. 通过 MCP 协议调用外部服务
        String result = toolCallback.call(jsonInput, null);
        
        // 3. 处理结果并返回
        return new ToolExecuteResult(result);
    }
}
3. MCP 工具注册

PlanningFactory 中,MCP 工具被统一注册:

java 复制代码
// 获取 MCP 服务的工具回调
List<McpServiceEntity> functionCallbacks = mcpService.getFunctionCallbacks(planId);

for (McpServiceEntity toolCallback : functionCallbacks) {
    String serviceGroup = toolCallback.getServiceGroup();
    ToolCallback[] tCallbacks = toolCallback.getAsyncMcpToolCallbackProvider()
        .getToolCallbacks();
    
    for (ToolCallback tCallback : tCallbacks) {
        // 将 MCP ToolCallback 包装成 McpTool
        toolDefinitions.add(new McpTool(
            tCallback, 
            serviceGroup, 
            planId, 
            innerStorageService, 
            objectMapper
        ));
    }
}

// 最终,MCP 工具也会被包装成 FunctionToolCallback
// 与内置工具一起注册到 toolCallbackMap

MCP 工具示例

假设有一个外部的文件系统 MCP 服务器:

json 复制代码
{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/allowed/files"]
    }
  }
}

这个 MCP 服务器提供的工具会被自动注册到 Lynxe 中,就像内置工具一样使用。

MCP 的优势

标准化 :遵循行业标准协议,易于集成

跨平台 :不依赖特定框架或语言

外部服务 :可以集成任何支持 MCP 的外部服务

资源访问 :不仅支持工具,还支持资源和提示词

解耦:AI 应用与外部服务解耦,通过协议通信

MCP 的局限性

协议开销 :需要额外的协议转换层

外部依赖 :依赖外部 MCP 服务器的可用性

配置复杂:需要配置 MCP 服务器连接


Function Calling

定义

Function Calling 是 LLM 模型原生支持的能力,允许模型在生成响应时,输出特定格式的函数调用请求。这些请求通常以 JSON 格式表示,包含函数名称和参数。

核心特点

  1. 模型原生能力:是 LLM 模型(如 GPT-4、Claude 等)的内置功能
  2. 标准化格式:模型输出标准化的函数调用 JSON
  3. 直接调用:应用层直接解析和执行函数调用
  4. 模型依赖:依赖模型是否支持 Function Calling

Function Calling 流程

LLM Function Calling 流程步骤

第 1 步:接收函数定义
  • 应用程序将可调用函数列表发送给 LLM API
  • 包含函数名、描述、参数定义(JSON Schema)
  • LLM 了解可用的外部能力
第 2 步:生成函数调用(JSON)
  • LLM 根据用户输入和函数定义,决定调用哪个函数
  • 生成 JSON 格式的函数调用请求
  • 包含函数名和参数值
第 3 步:解析调用
  • 应用程序接收 LLM 返回的函数调用 JSON
  • 解析函数名和参数
  • 准备执行对应函数
第 4 步:执行函数
  • 应用程序执行被调用的函数
  • 使用解析出的参数
  • 完成实际业务逻辑(如查询数据库、调用 API 等)
第 5 步:接收结果
  • 应用程序将函数执行结果返回给 LLM API
  • LLM 接收结果后继续生成响应
  • 可能基于结果进行后续处理或生成最终回答

Function Calling 示例

OpenAI Function Calling 格式

1. 定义函数

json 复制代码
{
  "functions": [
    {
      "name": "get_weather",
      "description": "Get the current weather in a given location",
      "parameters": {
        "type": "object",
        "properties": {
          "location": {
            "type": "string",
            "description": "The city and state, e.g. San Francisco, CA"
          },
          "unit": {
            "type": "string",
            "enum": ["celsius", "fahrenheit"]
          }
        },
        "required": ["location"]
      }
    }
  ]
}

2. 模型返回函数调用

json 复制代码
{
  "role": "assistant",
  "content": null,
  "function_call": {
    "name": "get_weather",
    "arguments": "{\"location\": \"San Francisco, CA\", \"unit\": \"celsius\"}"
  }
}

3. 应用执行函数并返回结果

json 复制代码
{
  "role": "function",
  "name": "get_weather",
  "content": "{\"temperature\": 22, \"unit\": \"celsius\", \"description\": \"Sunny\"}"
}

在 Lynxe 中的处理

虽然 Lynxe 使用 Spring AI Tools 机制,但底层模型(如 OpenAI)仍然使用 Function Calling。Spring AI 框架会自动处理转换:

java 复制代码
// Spring AI 内部处理流程:
// 1. Tools → Function Calling 格式转换
// 2. 调用模型 API(使用 Function Calling)
// 3. 解析模型返回的函数调用
// 4. 执行对应的工具
// 5. 将结果转换回 Tools 格式

Function Calling 的优势

模型原生 :模型直接支持,无需额外框架

标准化 :遵循模型厂商的标准格式

直接通信 :与模型 API 直接通信,延迟低

广泛支持:主流模型都支持 Function Calling

Function Calling 的局限性

模型依赖 :依赖模型是否支持

格式固定 :需要遵循模型厂商的格式

平台绑定 :不同模型的格式可能不同

功能有限:主要是函数调用,不支持资源访问等


三者关系与区别

关系图

第一层:框架抽象层(Framework Abstraction Layer)

核心组件:Spring AI Tools

  • 作用:提供统一的工具接口,屏蔽底层差异

  • 特点:

  • 内置工具(Built-in Tools):框架内定义的工具,如数据库工具、文件工具等

  • MCP 工具包装(MCP Tools):将外部 MCP 服务包装成统一格式

为什么需要这一层?

  • 统一管理:所有工具使用相同接口

  • 类型安全:Java 强类型,编译时检查

  • 易于扩展:实现接口即可添加新工具


第二层:标准化协议层(Standardization Protocol)

核心组件:MCP Protocol

  • 作用:跨平台、跨语言的标准化通信协议

  • 特点:

  • 外部服务 1、外部服务 2:支持多个 MCP 服务器

  • 标准化通信:定义统一的消息格式和通信流程

为什么需要这一层?

  • 解耦:应用与外部服务通过协议通信

  • 标准化:遵循行业标准,易于集成

  • 跨平台:不依赖特定框架或语言


第三层:模型原生能力层(Model Native Capability)

核心组件:Function Calling

  • 作用:LLM 模型原生支持的函数调用能力

  • 特点:

  • OpenAI API:支持 Function Calling

  • Claude API:支持 Function Calling

  • 模型原生:模型直接支持,无需额外框架

详细对比表

维度 Tools (Spring AI) MCP Function Calling
定位层级 应用框架层 协议层 模型 API 层
标准化 Spring AI 框架标准 行业协议标准 模型厂商标准
实现方式 Java 接口实现 协议通信 API 调用
工具来源 框架内定义 外部 MCP 服务器 应用层定义
集成方式 直接集成 通过协议集成 通过 API 集成
类型安全 ✅ 强类型(Java) ⚠️ 弱类型(JSON) ⚠️ 弱类型(JSON)
跨平台 ❌ Java/Spring 生态 ✅ 跨平台 ⚠️ 模型依赖
扩展性 ✅ 框架内扩展 ✅ 外部服务扩展 ⚠️ 模型能力限制
资源访问 ✅ 支持 ✅ 支持 ❌ 仅函数调用
配置复杂度
性能开销 中(协议转换)
学习曲线 中(需了解框架) 中(需了解协议) 低(直接 API)

核心区别总结

1. 抽象层级不同
  • Tools:应用框架层的抽象,提供统一的工具接口
  • MCP:协议层的抽象,定义标准化的通信协议
  • Function Calling:模型 API 层的抽象,模型原生能力
2. 实现方式不同
  • Tools:通过 Java 接口实现,编译时类型检查
  • MCP:通过 JSON-RPC 协议通信,运行时动态调用
  • Function Calling:通过模型 API 调用,返回 JSON 格式
3. 工具来源不同
  • Tools:框架内定义的工具(如 BrowserUseTool、DatabaseReadTool)
  • MCP:外部 MCP 服务器提供的工具
  • Function Calling:应用层定义的函数
4. 集成方式不同
  • Tools:直接实现接口,框架自动管理
  • MCP:配置 MCP 服务器,通过协议获取工具
  • Function Calling:定义函数列表,模型返回调用请求

在 Lynxe 项目中的实现

关键代码位置

1. 工具注册:PlanningFactory.toolCallbackMap()

文件src/main/java/com/alibaba/cloud/ai/lynxe/planning/PlanningFactory.java

关键代码

java 复制代码
// 内置工具
toolDefinitions.add(BrowserUseTool.getInstance(...));
toolDefinitions.add(DatabaseReadTool.getInstance(...));

// MCP 工具
List<McpServiceEntity> functionCallbacks = mcpService.getFunctionCallbacks(planId);
for (McpServiceEntity toolCallback : functionCallbacks) {
    toolDefinitions.add(new McpTool(...));
}

// 统一包装
FunctionToolCallback<?, ToolExecuteResult> functionToolCallback = 
    FunctionToolCallback.builder(...).build();
2. 工具调用:DynamicAgent.think()

文件src/main/java/com/alibaba/cloud/ai/lynxe/agent/DynamicAgent.java

关键代码

java 复制代码
List<ToolCallback> callbacks = getToolCallList();
Flux<ChatResponse> responseFlux = chatClient.prompt(userPrompt)
    .toolCallbacks(callbacks)
    .stream()
    .chatResponse();
3. MCP 工具包装:McpTool

文件src/main/java/com/alibaba/cloud/ai/lynxe/mcp/model/vo/McpTool.java

关键代码

java 复制代码
public class McpTool extends AbstractBaseTool<Map<String, Object>> {
    private final ToolCallback toolCallback;  // MCP 协议返回
    
    @Override
    public ToolExecuteResult run(Map<String, Object> inputMap) {
        String result = toolCallback.call(jsonInput, null);
        return new ToolExecuteResult(result);
    }
}

数据流转示例

场景:调用 MCP 文件系统工具
复制代码
1. 用户请求:读取文件 /path/to/file.txt

2. PlanningFactory.toolCallbackMap()
   ├─ 获取 MCP 工具列表
   ├─ 创建 McpTool 实例
   └─ 包装成 FunctionToolCallback
      └─ 注册到 toolCallbackMap

3. DynamicAgent.think()
   ├─ 获取工具列表(包含 MCP 工具)
   ├─ 调用 ChatClient
   │  └─ Spring AI 转换为 Function Calling 格式
   │     └─ 发送到模型 API

4. 模型返回函数调用
   └─ {"name": "filesystem_read_file", "arguments": {...}}

5. ToolCallingManager.executeToolCalls()
   ├─ 查找对应的工具(McpTool)
   ├─ 调用 McpTool.run()
   │  └─ 通过 MCP 协议调用外部服务
   │     └─ 返回文件内容
   └─ 返回结果给模型

6. 模型生成最终响应
   └─ 包含文件内容

使用场景建议

何时使用 Tools (Spring AI Tools)

适用场景

  • 开发框架内的核心功能工具
  • 需要类型安全和编译时检查
  • 工具逻辑与业务紧密相关
  • 需要高性能和低延迟

示例

  • 数据库操作工具
  • 文件系统操作工具
  • 浏览器自动化工具
  • 业务逻辑工具

何时使用 MCP

适用场景

  • 集成外部标准化服务
  • 需要跨平台、跨语言集成
  • 工具由第三方提供
  • 需要动态加载工具

示例

  • 集成 GitHub MCP 服务器
  • 集成文件系统 MCP 服务器
  • 集成数据库 MCP 服务器
  • 集成第三方 API 服务

何时使用 Function Calling

适用场景

  • 直接调用模型 API,不使用框架
  • 简单的函数调用场景
  • 不需要复杂的工具管理
  • 快速原型开发

示例

  • 简单的天气查询
  • 简单的计算函数
  • 简单的数据转换

混合使用策略

在 Lynxe 项目中,推荐使用 Tools + MCP 的组合:

  1. 核心功能使用 Tools:框架内定义,类型安全,性能好
  2. 外部服务使用 MCP:标准化集成,易于扩展
  3. 统一管理:通过 Spring AI Tools 机制统一管理

总结

核心要点

  1. Tools (Spring AI) 是应用框架层的抽象,提供统一的工具接口和管理机制
  2. MCP 是协议层的标准,用于集成外部服务,最终也会被包装成 Tools
  3. Function Calling 是模型 API 层的能力,Spring AI 会自动处理转换

在 Lynxe 中的实际应用

  • 主要使用 Tools 机制:所有工具(包括 MCP 工具)都通过 Tools 机制统一管理
  • MCP 作为扩展 :MCP 工具通过 McpTool 包装,无缝集成到 Tools 机制中
  • Function Calling 透明:Spring AI 框架自动处理 Tools 与 Function Calling 的转换

选择建议

场景 推荐方案 原因
开发核心业务工具 Tools 类型安全、性能好、易维护
集成外部标准化服务 MCP 标准化、易扩展、解耦
简单快速原型 Function Calling 直接、简单、快速
企业级应用 Tools + MCP 兼顾性能和扩展性
相关推荐
小小Fred2 小时前
FreeRTOS函数prvInitialiseNewTask解析
java·开发语言
rgb2gray2 小时前
城市韧性与交通基础设施系统耦合协调度的时空演变及影响因素
网络·人工智能·python·ai·写作·耦合·耦合协调
初级炼丹师(爱说实话版)2 小时前
大模型部署-数据并行/模型并行
人工智能·python
小杜的生信筆記2 小时前
基于R语言绘制网络图,新人选手上手
开发语言·r语言·生物信息学·组学
listhi5202 小时前
机械系统运动学与动力学在MATLAB及SimMechanics中的实现方案
人工智能·算法·matlab
AI大模型学徒2 小时前
大模型应用开发(十五)_知识库1
人工智能·chatgpt·大模型·llm·知识库·deepseek
小码哥0682 小时前
家政服务管理-家政服务管理平台-家政服务管理平台源码-家政服务管理平台java代码-基于springboot的家政服务管理平台
java·开发语言·spring boot·家政服务·家政服务平台·家政服务系统·家政服务管理平台源码
爪洼守门员2 小时前
前端性能优化
开发语言·前端·javascript·笔记·性能优化
音视频牛哥2 小时前
从“十五五”到数字化转型:音视频技术在未来产业中的关键作用
人工智能·深度学习·计算机视觉·音视频·十五五规划音视频低延迟方案·十五五规划低空经济低延迟方案·rtsp rtmp播放器