建议大家先看前三章内容:
Spring AI Alibaba 入门开发1-环境搭建、ollama部署、Chat和ChatModel、流式输出-CSDN博客
Spring AI Alibaba 入门开发2-提示词功能、提示词模板、格式化输出-CSDN博客
Spring AI Alibaba 入门开发3-持久化记忆、向量数据库、RAG-CSDN博客
目录
[一、Tool Calling 工具调用](#一、Tool Calling 工具调用)
[1.1 介绍](#1.1 介绍)
[1.2 开发](#1.2 开发)
[1.2.1 不使用工具时](#1.2.1 不使用工具时)
[1.2.2 用工具时------分别使用ChatModel、ChatClient实现](#1.2.2 用工具时——分别使用ChatModel、ChatClient实现)
[2.1 MCP介绍](#2.1 MCP介绍)
[2.2 Spring AI MCP](#2.2 Spring AI MCP)
[2.3 开发](#2.3 开发)
[2.3.1 本地MCP开发](#2.3.1 本地MCP开发)
[2.3.2 远程MCP增强案例-对接互联网通用MCP服务(百度地图)](#2.3.2 远程MCP增强案例-对接互联网通用MCP服务(百度地图))
一、Tool Calling 工具调用
1.1 介绍
"工具调用(Tool Calling)"或"函数调用"允许大型语言模型(LLM)在必要时调用一个或多个可用的工具,这些工具通常由开发者定义。工具可以是任何东西:网页搜索、对外部 API 的调用,或特定代码的执行等。LLM 本身不能实际调用工具;相反,它们会在响应中表达调用特定工具的意图(而不是以纯文本回应)。然后,应用程序应该执行这个工具,并报告工具执行的结果给模型。当 LLM 可以访问工具时,它可以在合适的情况下决定调用其中一个工具,这是一个非常强大的功能。
许多 AI 应用程序通过自然语言与用户交互。然而,某些业务场景需要模型使用结构化输入直接与外部系统(如 API、数据库或文件系统)进行交互。
Tools 是 agents 调用来执行操作的组件。它们通过定义良好的输入和输出让模型与外部世界交互,从而扩展模型的能力。Tools 封装了一个可调用的函数及其输入模式。我们可以把工具定义传递给兼容的 models,允许模型决定是否调用工具以及使用什么参数。在这些场景中,工具调用使模型能够生成符合指定输入模式的请求。
注意:服务器端工具使用
某些聊天模型(例如 OpenAI、Anthropic 和 Gemini)具有在服务器端执行的内置工具,如 Web 搜索和代码解释器。请参阅提供商概述以了解如何使用特定聊天模型访问这些工具。
ool calling (也称为 function calling )是 AI 应用程序中的常见模式,允许 model 与一组 API 或 tools 交互,增强其能力。
Tools 主要用于:
- 信息检索。此类别中的 tools 可用于从外部源检索信息,例如数据库、Web 服务、文件系统或 Web 搜索引擎。目标是增强 model 的知识,使其能够回答原本无法回答的问题。因此,它们可以在 Retrieval Augmented Generation (RAG) 场景中使用。例如,可以使用 tool 检索给定位置的当前天气、检索最新新闻文章或查询数据库中的特定记录。
- 执行操作。此类别中的 tools 可用于在软件系统中执行操作,例如发送电子邮件、在数据库中创建新记录、提交表单或触发工作流。目标是自动化原本需要人工干预或显式编程的任务。例如,可以使用 tool 为与聊天机器人交互的客户预订航班、填写网页上的表单,或在代码生成场景中基于自动化测试(TDD)实现 Java 类。
尽管我们通常将 tool calling 称为 model 能力,但实际上由客户端应用程序提供 tool calling 逻辑。Model 只能请求 tool call 并提供输入参数,而应用程序负责从输入参数执行 tool call 并返回结果。Model 永远无法访问作为 tools 提供的任何 API,这是一个关键的安全考虑。
Spring AI 提供了便捷的 API 来定义 tools、解析来自 model 的 tool call 请求并执行 tool calls。
Tool Calling(工具调用,也称为 Function Calling)是 AI 应用中的常见模式,允许模型与一组 API 或工具进行交互,增强模型的能力。
工具主要用于:
- 信息检索:从外部数据源检索信息,如数据库、Web 服务、文件系统或 Web 搜索引擎。例如,获取当前天气、检索最新新闻、查询数据库等。
- 执行操作:在软件系统中执行特定操作,如发送电子邮件、在数据库中创建新记录、提交表单或触发工作流。例如,预订航班、填写表单、生成代码等。
Spring AI Alibaba 扩展了 Spring AI 的 Tool Calling 功能,提供了多种预构建的工具实现,包括:
- 搜索引擎(百度搜索、Google Scholar、Tavily Search 等)
- 翻译服务(阿里翻译、百度翻译、Google 翻译等)
- 地图服务(高德地图、百度地图、腾讯地图等)
- 数据服务(天气、快递、新闻等)
- 开发工具(GitHub、JSON 处理、正则表达式等)
- 其他工具(时间、Python 执行、敏感词过滤等)
工作流程如下:

1.2 开发
需求:询问大模型当前时间
项目基础结构:

pom.xml、配置文件如下:
XML
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--spring-ai-alibaba dashscope-->
<dependency>
<groupId>com.alibaba.cloud.ai</groupId>
<artifactId>spring-ai-alibaba-starter-dashscope</artifactId>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.38</version>
</dependency>
<!--hutool-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.22</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<compilerArgs>
<arg>-parameters</arg>
</compilerArgs>
<source>21</source>
<target>21</target>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
server.port=8888 #解决中文乱码 server.servlet.encoding.charset=UTF-8 server.servlet.encoding.enabled=true server.servlet.encoding.force=true spring.application.name=ssa-13-ToolCalling #Sprig AI Alibaba 相关配置 spring.ai.dashscope.api-key=${qianwen-api}
1.2.1 不使用工具时
新建controller
java
@RestController
public class NoToolCallingController {
@Resource
private ChatModel chatModel;
@GetMapping("/v1/chat")
public Flux<String> getChatModel(@RequestParam(name = "msg",defaultValue = "你是谁,现在几点了?")String msg) {
return chatModel.stream(msg);
}
}
运行如下:

1.2.2 用工具时------分别使用ChatModel、ChatClient实现
新建功能工具类
java
public class DateTimeTools {
/*
1、定义function call
2、returnDirect
true:工具直接返回,不经过大模型
false:大模型获取工具返回的结果,由大模型回复
*/
@Tool(description = "获取当前时间",returnDirect = false)
public String getCurrentTime(){
return LocalDateTime.now().toString();
}
}
新建配置类
java
@Configuration
public class LLMConfig {
@Bean
public ChatClient chatClient(ChatModel chatModel){
return ChatClient.builder(chatModel).build();
}
}
新建controller
java
@RestController
public class ToolCallingController {
@Resource
private ChatModel chatModel;
@Resource
private ChatClient chatClient;
@GetMapping("/v2/chat")
public String chat2 (@RequestParam(name = "msg",defaultValue = "你是谁,现在几点了?")String msg){
//1、工具注册到工具集合里
ToolCallback[] tools = ToolCallbacks.from(new DateTimeTools());
//2、把工具配置到ChatOptions对象
ToolCallingChatOptions options = ToolCallingChatOptions.builder().toolCallbacks(tools).build();
//3、构建提示词
Prompt prompt = new Prompt(msg, options);
return chatModel.call(prompt).getResult().getOutput().getText();
}
@GetMapping("/v3/chat")
public Flux<String> chat3(@RequestParam(name = "msg",defaultValue = "你是谁,现在几点了?")String msg){
return chatClient.prompt(msg)
.tools(new DateTimeTools())
.stream().content();
}
}
运行结果如下:

二、MCP上下文协议
2.1 MCP介绍
MCP(模型上下文协议)是一种用于将人工智能应用程序连接到外部系统的开源标准。使用 MCP,Claude 或 ChatGPT 等人工智能应用程序可以连接到数据源(例如本地文件、数据库)、工具(例如搜索引擎、计算器)和工作流程(例如专门提示),使它们能够访问关键信息并执行任务。将 MCP 想象成用于 AI 应用的 USB-C 端口。正如 USB-C 提供了一种连接电子设备的标准化方式一样,MCP 也提供了一种将 AI 应用程序连接到外部系统的标准化方式。

是一个开放协议,它规范了应用程序如何向大型语言模型(LLM)提供上下文。MCP 提供了一种统一的方式将 AI 模型连接到不同的数据源和工具,它定义了统一的集成方式。在开发智能体(Agent)的过程中,我们经常需要将将智能体与数据和工具集成,MCP 以标准的方式规范了智能体与数据及工具的集成方式,可以帮助您在 LLM 之上构建智能体(Agent)和复杂的工作流。目前已经有大量的服务接入并提供了 MCP server 实现,当前这个生态正在以非常快的速度不断的丰富中。
在MCP通信协议中,一般有两种模式:
1、STDIO(标准输入/输出):支持标准输入和输出流进行通信,主要用于本地集成、命令行工具等场景。
2、SSE (Server-Sent Events):支持使用 HTTP POST 请求进行服务器到客户端流式处理,以实现客户端到服务器的通信。

两者对比如下:

2.2 Spring AI MCP
Spring AI MCP 为模型上下文协议提供 Java 和 Spring 框架集成。它使 Spring AI 应用程序能够通过标准化的接口与不同的数据源和工具进行交互,支持同步和异步通信模式。

Spring AI MCP 采用模块化架构,包括以下组件:
- Spring AI 应用程序:使用 Spring AI 框架构建想要通过 MCP 访问数据的生成式 AI 应用程序
- Spring MCP 客户端:MCP 协议的 Spring AI 实现,与服务器保持 1:1 连接
- MCP 服务器:轻量级程序,每个程序都通过标准化的模型上下文协议公开特定的功能
- 本地数据源:MCP 服务器可以安全访问的计算机文件、数据库和服务
- 远程服务:MCP 服务器可以通过互联网(例如,通过 API)连接到的外部系统
2.3 开发
2.3.1 本地MCP开发
MCP-Server服务端实现
新建子模块:修改pom.xml、新增配置文件、新增启动类。
XML
<dependencies>
<!--注意事项(重要)
spring-ai-starter-mcp-server-webflux不能和<artifactId>spring-boot-starter-web</artifactId>依赖并存,
否则会使用tomcat启动,而不是netty启动,从而导致mcpserver启动失败,但程序运行是正常的,mcp客户端连接不上。
-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!--mcp-server-webflux-->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-mcp-server-webflux</artifactId>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.38</version>
</dependency>
<!--hutool-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.22</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<compilerArgs>
<arg>-parameters</arg>
</compilerArgs>
<source>21</source>
<target>21</target>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
server.port=8014 #解决中文乱码 server.servlet.encoding.charset=UTF-8 server.servlet.encoding.enabled=true server.servlet.encoding.force=true spring.application.name=ssa-13-ToolCalling #Sprig AI Alibaba 相关配置 #spring.ai.dashscope.api-key=${qianwen-api} # ====mcp-server Config============= spring.ai.mcp.server.type=async spring.ai.mcp.server.name=customer-define-mcp-server spring.ai.mcp.server.version=1.0.0
java
@SpringBootApplication
public class SSA_14_LocalMCPServerApplication {
public static void main(String[] args) {
SpringApplication.run(SSA_14_LocalMCPServerApplication.class, args);
}
}
新增service,模拟本地调用
java
@Service
public class WeatherService
{
@Tool(description = "根据城市名称获取天气预报")
public String getWeatherByCity(String city)
{
Map<String, String> map = Map.of(
"北京", "11111降雨频繁,其中今天和后天雨势较强,部分地区有暴雨并伴强对流天气,需注意",
"上海", "22222多云,15℃~27℃,南风3级,当前温度27℃。",
"深圳", "333333多云40天,阴16天,雨30天,晴3天"
);
return map.getOrDefault(city, "抱歉:未查询到对应城市!");
}
}
新增接口配置类
java
//将工具方法暴露给外部 mcp client 调用
@Configuration
public class McpServerConfig {
@Bean
public ToolCallbackProvider weatherTools(WeatherService weatherService) {
return MethodToolCallbackProvider
.builder()
.toolObjects(weatherService)
.build();
}
}
本地启动后,如下

MCP-Client客户端实现
新建子模块:修改pom.xml、新增配置文件、新增启动类
XML
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--spring-ai-alibaba dashscope-->
<dependency>
<groupId>com.alibaba.cloud.ai</groupId>
<artifactId>spring-ai-alibaba-starter-dashscope</artifactId>
</dependency>
<!-- 2.mcp-clent 依赖 -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-mcp-client</artifactId>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.38</version>
</dependency>
<!--hutool-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.22</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<compilerArgs>
<arg>-parameters</arg>
</compilerArgs>
<source>21</source>
<target>21</target>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
server.port=8015 #解决中文乱码 server.servlet.encoding.charset=UTF-8 server.servlet.encoding.enabled=true server.servlet.encoding.force=true spring.application.name=ssa-13-ToolCalling #Sprig AI Alibaba 相关配置 spring.ai.dashscope.api-key=${qianwen-api} # ====mcp-client Config============= spring.ai.mcp.client.type=async spring.ai.mcp.client.request-timeout=60s spring.ai.mcp.client.toolcallback.enabled=true spring.ai.mcp.client.sse.connections.mcp-server1.url=http://localhost:8014
java
@SpringBootApplication
public class SSA_15_LocalMCPClientApplication {
public static void main(String[] args) {
SpringApplication.run(SSA_15_LocalMCPClientApplication.class, args);
}
}
新建配置类;
java
@Configuration
public class LLMConfig {
@Bean
public ChatClient ChatClient(ChatModel chatModel, ToolCallbackProvider callbackProvider) {
return ChatClient.builder(chatModel)
.defaultToolCallbacks(callbackProvider.getToolCallbacks())
.build();
}
}
新增controller类
java
@RestController
public class McpClientController {
//使用mcp
@Resource
private ChatClient chatClient;
//没有纳入tool,普通调用
@Resource
private ChatModel chatModel;
@GetMapping("/v1/test")
public Flux<String> chat1(@RequestParam(name = "msg",defaultValue = "北京") String msg) {
System.out.println("使用了MCP协议");
return chatClient.prompt(msg).stream().content();
}
@GetMapping("/v2/test")
public Flux<String> chat2(@RequestParam(name = "msg",defaultValue = "北京") String msg) {
System.out.println("未使用MCP协议");
return chatModel.stream(msg);
}
}
客户端调用截图:

2.3.2 远程MCP增强案例-对接互联网通用MCP服务(百度地图)
MCP应用市场:https://mcp.so/zh/server/baidu-map/baidu-maps
提前申请百度地图api-key。
下载node.js,用于nodejs配置编码-Typescript接入。
新建子模块:修改pom.xml、新增配置文件、新增nodejs配置编码-Typescript接入、启动类
XML
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--spring-ai-alibaba dashscope-->
<dependency>
<groupId>com.alibaba.cloud.ai</groupId>
<artifactId>spring-ai-alibaba-starter-dashscope</artifactId>
</dependency>
<!-- 2.mcp-clent 依赖 -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-mcp-client</artifactId>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.38</version>
</dependency>
<!--hutool-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.22</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<compilerArgs>
<arg>-parameters</arg>
</compilerArgs>
<source>21</source>
<target>21</target>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
server.port=6016 #解决中文乱码 server.servlet.encoding.charset=UTF-8 server.servlet.encoding.enabled=true server.servlet.encoding.force=true spring.application.name=ssa-16-MCPClient-baiduMap #Sprig AI Alibaba 相关配置 spring.ai.dashscope.api-key=${qianwen-api} spring.ai.dashscope.base-url=https://ws-6tq01jo6mtthlhoq.cn-beijing.maas.aliyuncs.com/compatible-mode/v1 spring.ai.dashscope.chat.options.model=qwen-max spring.ai.mcp.client.toolcallback.enabled=true spring.ai.mcp.client.stdio.servers-configuration=classpath:/mcp-server.json
mcp-server.json
{ "mcpServers": { "baidu-map": { "command": "cmd", "args": ["/c", "npx", "-y", "@baidumap/mcp-server-baidu-map"], "env": { "BAIDU_MAP_API_KEY": "BfOSYFsYLqhwXEmNRT532Ib0w1GqWoO3", "NPM_CONFIG_CACHE": "E:/CodingTools/npm-cache" } } } }
新增配置类
java
@Configuration
public class LLMConfig {
@Bean
public ChatClient chatClient(ChatModel chatModel, ToolCallbackProvider toolCallbackProvider) {
return ChatClient.builder(chatModel)
.defaultToolCallbacks(toolCallbackProvider.getToolCallbacks())
.build();
}
}
java
@RestController
public class MCPClientController {
@Resource
private ChatClient chatClient;//添加了MCP调用能力
@Resource
private ChatModel chatModel;//未添加MCP调用能力
@GetMapping("/v1/chat")
public Flux<String> chat1(String msg){
return chatClient.prompt(msg)
.stream().content();
}
@GetMapping("/v2/chat")
public Flux<String> chat2(String msg){
return chatModel.stream(msg);
}
}
java
@SpringBootApplication
public class MCPClientApplication {
public static void main(String[] args) {
SpringApplication.run(MCPClientApplication.class, args);
}
}
运行如下:
