Tool Calling和本地MCP服务的调用
Tool Calling
我们在使用AI的时候有着一个联网搜索的按键,当我们需要进行网上的搜索的时候就需要借助Tool Calling,所以简单而言,Tool Calling是大模型使用的工具类。

ToolCalling也被称呼为Function Calling,它允许大模型与一组API或工具进行交互,将大模型的智能与外部工具或API进行无缝连接,增强大模型的功能,注意大模型是不直接调用工具的,它是让应用程序去执行大模型的工具,大模型等待程序返回结果,然后返回给用户。
所以我们是对大模型的调用功能进行打通,主要执行某种工具让大模型进行函数的调用。
如果我们不使用ToolCalling的话,我们的实时问题也就无法正常的解决,如下图

首先我们使用ChatModel进行工具的调用,当我们直接使用一个工具类进行返回的时候,根据官方的文档我们就可以看得到默认情况下是直接进行返回,我们可以使用returnDirect参数的定义来设置是否直接返回。

我们想要让大模型进行工具的使用,所以我们首先需要进行工具类的配置如下:
package ai.utils;
import org.springframework.ai.tool.annotation.Tool;
public class DataTimeTools {
/*
* returnDirect=true的话,默认直接被大模型拿走
* false的话将返回的结果进行修饰拼装再进行返回*/
@Tool(description = "获取时间",returnDirect = false)
public String getTime(){
return "现在时间是:" + new java.util.Date();
}
}
我们原先在帮助文档里面就可以看到,我们的大模型是否进行简单的处理就是需要returnDirect的参数控制。当我们配置类结束之后我们就可以控制台的编写,首先就是把工具放到工具类当中,然后使用ChatOptions让大模型了解到我们使用的工具类,然后将提示词进行编写入大模型,最后就可以得到结果。
package ai.controller;
import ai.utils.DataTimeTools;
import jakarta.annotation.Resource;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.model.tool.ToolCallingChatOptions;
import org.springframework.ai.support.ToolCallbacks;
import org.springframework.ai.tool.ToolCallback;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ToolCallingController {
@Resource(name="qwen")
private ChatModel chatModel;
@GetMapping("/toolcall/call")
public String chat(@RequestParam(name = "msg",defaultValue = "现在几点")String msg) {
// 创建工具,工具注册到工具集合中
ToolCallback[] tools = ToolCallbacks.from(new DataTimeTools());
// 将工具集配置进ChatOptions当中
ToolCallingChatOptions build = ToolCallingChatOptions.builder().toolCallbacks(tools).build();
Prompt prompt = new Prompt(msg, build);
return chatModel.call(prompt).getResult().getOutput().getText();
}
}
我们通过访问地址就可以得到经过大模型修饰过的返回结果:

如果我们使用的是ChatClient我们依旧可以正常使用和Chatmodel一样
@GetMapping("/toolcall/chatClient")
public Flux<String> stream(@RequestParam(name = "msg", defaultValue = "现在几点") String msg) {
ToolCallback[] tools = ToolCallbacks.from(new DataTimeTools());
// 将工具集配置进ChatOptions当中
ToolCallingChatOptions build = ToolCallingChatOptions.builder().toolCallbacks(tools).build();
Prompt prompt = new Prompt(msg, build);
return qwenChatClient.prompt(prompt)
.stream()
.content();
}
MCP模型上下文协议
MCP是什么?
在早期Spring AI(1.0.0-M6)的版本的时候,FunctingCalling几乎要被MCP取代,因为简单来说Tool Calling的编写工具类并没有办法给多个微服务进行调用,同样如果我们想要多写几个工具包的话,我们同样也需要进行大量的代码编写,所以从多种的角度来说的话,如何进行二者的兼顾呢,为了解决这个问题,我们为了解决多个微服务之间的问题,我们就可以使用MCP协议,简单来说就是我们通过自己的服务去调用同一个大模型服务,通过遵守MCP协议这样我们就可以通过一套协议就可以使用多家的工具包,所以就出现了MCP,几乎可以取代Tool Calling。

理解MCP很简单,就是统一的Type-C协议,只要是这个接口就可以使用进行充电和传递数据,MCP就是可以这样。我们如果想使用MCP,我们有两种方式,SSE,STDIO这两种方式的区别在于STDIO支持标准输入和输出流进行通信,主要用于本地集成、命令行工具等场景,SSE支持使用 HTTP POST请求进行服务器到客户端流式处理,以实现客户端到服务器的通信。
MCP的官方网站:MCP Servers
本地MCP调用
首先我们先进行本地的MCP使用,也就是说我们自己进行撰写。
首先我们先引入依赖和修改yml文件
!-- <!– Web 启动器(Spring Boot Web 核心依赖) –>-->
<!-- <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-starter-web</artifactId>-->
<!-- </dependency>-->
<!--注意,spring-boot-starter-web和spring-ai-starter-mcp-server-webflux是
不能够同时使用的,使用第一个就会直接使用内置的tomcat最终导致mcpservice失败。-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-mcp-server-webflux</artifactId>
</dependency>
spring.ai.mcp.server.type=async
spring.ai.mcp.server.name=custom-define-mcp-server
spring.ai.mcp.server.version=1.0.0
现在我们需要进行工具类的编写,这个时候就可以进行方法的使用了
package ai.Service;
import org.springframework.ai.tool.annotation.Tool;
import java.util.Map;
public class WeatherService {
@Tool(description = "获取天气信息")
public String getWeather(String city){
Map<String,String> map = Map.of("北京","晴天"
,"上海","阴天"
,"深圳","雷阵雨");
return map.getOrDefault(city,"未知城市");
}
}
我们还需要一个配置类,来进行表示MCP的服务
package ai.config;
import ai.Service.WeatherService;
import org.springframework.ai.tool.ToolCallbackProvider;
import org.springframework.ai.tool.method.MethodToolCallbackProvider;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class McpServerConfig {
@Bean
public ToolCallbackProvider toolCallbackProvider(WeatherService weatherService) {
return MethodToolCallbackProvider.builder()
.toolObjects(weatherService)
.build();
}
}
我们启动之后就会发现启动的就是Netty服务器

我们如果想要正常使用这个服务端的话,首先我们要进行依赖的导入,我们如果想要调用需要另一个微服务进行。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-mcp-server-mcp-client</artifactId>
</dependency>
这个时候我们的配置文件就需要有这样的改动,注意端口号要是你服务端开启的端口进行调用。
spring.ai.mcp.server.type=async
spring.ai.mcp.server.url=http://localhost:8080
spring.ai.mcp.server.timeout=5000
然后重点在于Client配置的参数引入:
@Bean
public ChatClient chatClient(ChatModel chatModel
, ToolCallbackProvider tools) {
return ChatClient.builder(chatModel)
.defaultToolCallbacks(tools.getToolCallbacks())
.build();
}
对于控制层的代码,我们就和正常调用是一样的
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)