当前位置: 首页 > news >正文

完整教程:SpringAi-MCP技术

1.定义

  1. 定义一个工具
  2. 把工具注册进去

MCP ,全称是 Model Context Protocol (模型上下⽂协议),是⼀种标准化协议,使 AI 模型能 够以结构化的⽅式与外部⼯具和资源进⾏交互。该协议⽀持多种传输机制,以在不同环境中提供灵活 性。可以把它想象成⼀个让 AI 模型更顺畅⼯作的桥梁和助⼿。

2.快速入门(获取当前时间)

2.1导包

    org.springframework.bootspring-boot-starter-weborg.springframework.aispring-ai-starter-model-openai

2.2配置yml文件

server:port: 8007
spring:application:name: ai-siliconflow-mcp-glmai:openai:base-url: https://api.siliconflow.cnapi-key: sk-rlpneielwjrtbzwghvmtnkrfzsqoorkclubnimumojlptvqzchat:options:model: "zai-org/GLM-4.6"temperature: 0.7

2.3写config类

@Configuration
public class ChatClientConfig {@Resourceprivate OpenAiChatModel openAiChatModel;@Bean("openAiChatClient")public ChatClient openAiChatClient(WeatherJiaService weatherJiaService, AmapSrvice amapSrvice){return ChatClient.builder(openAiChatModel).build();}
}

2.4写工具类service

package com.jiazhong.mingxing.ai.siliconflow.mcp.glm.service;
import org.springframework.stereotype.Service;
@Service
public interface NowDateToolService {String getNowDate();
}

2.5写工具类的具体实现类

@Slf4j
@Service
public class NowDateToolServiceImpl implements NowDateToolService {//@Tool(description = "获取到系统的当前时间")public String getNowDate() {log.info("开始调用获取当前时间的工具......");SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");return simpleDateFormat.format(new Date());}
}

2.6在config类中注册tool工具

@Configuration
public class ChatClientConfig {@Resourceprivate OpenAiChatModel openAiChatModel;@Resourceprivate NowDateToolService nowDateToolService;@Bean("openAiChatClient")public ChatClient openAiChatClient(WeatherJiaService weatherJiaService, AmapSrvice amapSrvice){return ChatClient.builder(openAiChatModel).defaultTools(nowDateToolService).build();}
}

2.7写ccontroller类

@GetMapping(value = "/stream",produces = "text/html;charset=utf-8")public Flux stream(@RequestParam("question") String question){return openAiChatClient.prompt().user(question).stream().content();}

2.8配置启动类

并在浏览器中问关于时间的问题,会给出系统时间

3.采取行动

在前⾯的示例中,我们使⽤了⼀个⼯具来确定当前⽇期和时间。在这个例⼦中,我们将定义第⼆个⼯ 具,⽤于在特定时间设置警报。⽬标是从现在开始设置10分钟的警报,因此我们需要为模型提供这两 种⼯具来完成这项任务。 我们将把新⼯具添加到与以前相同的 DateTimeToolsService 类中。新⼯具将采⽤⼀个参数,即 ISO-8601 格式的时间。然后,该⼯具将向控制台打印⼀条消息,指示已在给定时间内设置报警。与 之前⼀样,该⼯具被定义为⼀个⽤ @tool 注释的⽅法,我们还使⽤它来提供详细的描述,以帮助模 型理解何时以及如何使⽤该⼯具。

@Tool(description = "设置一个时间报警器")public void setAlarm(@ToolParam(description = "当前系统时间") String time){log.info("时间是:{}",time);LocalDateTime localDateTime=LocalDateTime.parse(time);log.info("转换后的时间:{}",localDateTime);}

4.方法即工具

4.1声明式

您可以通过使⽤ @tool 对⽅法进⾏注释,将其转化为⼯具。

如上述入门案例所示。

@Tool 注释允许您提供有关⼯具的关键信息:

  • name :工具具的名称。如果没有提供,将使⽤⽅法名称。 AI 模型在调⽤⼯具时使⽤此名称来 标识⼯具。因此,不允许在同⼀类中有两个同名⼯具。对于特定的聊天请求,该名称在模型可 ⽤的所有⼯具中必须是唯⼀的。(可以不写)
  • description :⼯具的描述,模型可以使⽤它来了解何时以及如何调⽤⼯具。如果没有提 供,⽅法名称将⽤作⼯具描述。然⽽,强烈建议提供详细的描述,因为这对于模型理解⼯具的 ⽬的以及如何使⽤它⾄关重要。如果不能提供⼀个好的描述,可能会导致模型在应该使⽤的时 候不使⽤⼯具,或者使⽤不当。(要写)
  • returnDirect :⼯具结果是应该直接返回给客户端还是传递回模型。
  • resultConverter : ToolCallResultConverter 实现,⽤于将⼯具调⽤的结果转换为 String 对象,以发送回 AI 模型。

SpringAI 将⾃动为 @Tool 注释⽅法的输⼊参数⽣成 JSON 模式。模型使⽤模式来了解如何调⽤⼯ 具和准备⼯具请求。 @ToolParam 注释可⽤于提供有关输⼊参数的其他信息,例如描述参数是必需的 还是可选的。默认情况下,所有输⼊参数都被认为是必需的。

4.2编程式

4.2.1在controller中

 @GetMapping(value = "/stream2",produces = "text/html;charset=utf-8")public Flux stream2(@RequestParam("question") String question){//获取到了指定的方法Method method = ReflectionUtils.findMethod(NowDateToolService.class,"getNowDate");//开始创建工具ToolDefinition toolDefinition = ToolDefinitions.builder(method).description("获取⽤户时区中的当前时间").name("getCurrentDateTime2").build();//开始注册工具MethodToolCallback methodToolCallback = MethodToolCallback.builder().toolDefinition(toolDefinition).toolMethod(method).toolObject(nowDateToolService) // 必须是DateTimeToolsService类的实例.build();return openAiChatClient.prompt().toolCallbacks(methodToolCallback).user(question).stream().content();}

删掉serviceImp中的@Tool注解即可实现。

5.函数即工具

SpringAI 提供了从函数中指定⼯具的内置⽀持,可以使⽤ FunctionToolCallback 实现进⾏编 程,也可以在运⾏时动态解析 @Bean 。

5.1函数工具的回调

案例--查看城市天气(假的)

5.1.1bean包下写Weather类

定义两个实体类

package com.jiazhong.mingxing.ai.siliconflow.mcp.glm.bean;
public class Weather {//城市public record WeatherRequest(String city){}//气温public record WeatherResponse(double weather){}
}

5.1.2service包

package com.jiazhong.mingxing.ai.siliconflow.mcp.glm.service;
import com.jiazhong.mingxing.ai.siliconflow.mcp.glm.bean.Weather;
import org.springframework.stereotype.Service;
import java.util.function.Function;
@Service
public interface WeatherJiaService extends Function {
}

5.1.3impl类

package com.jiazhong.mingxing.ai.siliconflow.mcp.glm.service.impl;
import com.jiazhong.mingxing.ai.siliconflow.mcp.glm.bean.Weather;
import com.jiazhong.mingxing.ai.siliconflow.mcp.glm.service.WeatherJiaService;
import org.springframework.stereotype.Service;
@Service
public class WeatherJiaServiceImpl implements WeatherJiaService {@Override//因为WeatherRequest是内部类,在Weather类中,所以要使用Weather.WeatherRequestpublic Weather.WeatherResponse apply(Weather.WeatherRequest weatherRequest) {if ("西安".equals(weatherRequest.city())){return new Weather.WeatherResponse(30.1);}else if ("宝鸡".equals(weatherRequest.city())){return new Weather.WeatherResponse(25.4);}else if ("漠河".equals(weatherRequest.city())){return new Weather.WeatherResponse(-27.9);}return new Weather.WeatherResponse(15);}
}

5.1.4controller类(局部写法)

@GetMapping(value = "stream3",produces = "text/html;charset=utf-8")public Flux stream3(@RequestParam("question") String question){FunctionToolCallback toolCallback=FunctionToolCallback.builder("weatherJiaServiceImpl",weatherJiaService).description("获取到指定位置的天气").inputType(Weather.WeatherRequest.class).build();return openAiChatClient.prompt().toolCallbacks(toolCallback).user(question).stream().content();}

5.1.5config类(全局写法)

@Bean("openAiChatClient")public ChatClient openAiChatClient(WeatherJiaService weatherJiaService, AmapSrvice amapSrvice){FunctionToolCallback toolCallback=FunctionToolCallback.builder("weatherJiaServiceImpl",weatherJiaService).description("获取到执行位置的天气").inputType(Weather.WeatherRequest.class).build();return ChatClient.builder(openAiChatModel).defaultTools(weatherJiaService)/*.defaultToolNames("currentWeather","currentDressing")*/.defaultTools(toolCallback).build();}

5.2@Bean 动态规范

5.2.1新建ToolConfig类

package com.jiazhong.mingxing.ai.siliconflow.mcp.glm.config;
import com.jiazhong.mingxing.ai.siliconflow.mcp.glm.bean.Weather;
import com.jiazhong.mingxing.ai.siliconflow.mcp.glm.service.DressingService;
import com.jiazhong.mingxing.ai.siliconflow.mcp.glm.service.WeatherJiaService;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.function.Function;
@Configuration
public class ToolConfig {@Resourceprivate WeatherJiaService weatherJiaService;@Resourceprivate DressingService dressingService;@Bean("currentWeather")public Function weather(){return weatherJiaService;}@Bean("currentDressing")public Function dressing(){return dressingService;}
}

5.2.2写ChatClientController

 @Bean("openAiChatClient")public ChatClient openAiChatClient(WeatherJiaService weatherJiaService, AmapSrvice amapSrvice){/*FunctionToolCallback toolCallback=FunctionToolCallback.builder("weatherJiaServiceImpl",weatherJiaService).description("获取到执行位置的天气").inputType(Weather.WeatherRequest.class).build();*/return ChatClient.builder(openAiChatModel)/*.defaultTools(currentWeather)*/.defaultToolNames("currentWeather")/* .defaultTools(amapSrvice)*/.build();}

http://www.jsqmd.com/news/392621/

相关文章:

  • 大数据GDPR合规与性能平衡:5个优化技巧让系统不卡顿
  • 冥想第一千七百九十八天(1798)
  • [兰溪民间故事]高辛王封畲氏
  • 兰溪民间故事《吕洞宾为啥肩背宝剑》
  • [兰溪民间故事]老牛神和天蚕:从被骗下凡到人间耕织的上古密码
  • 差分隐私在知识图谱中的应用与创新
  • AI驱动元宇宙广告的混合云架构:私有云与公有云的协同设计
  • 探寻2026好氧活性污泥:这些源头厂家口碑佳,知名的好氧活性污泥技术实力与市场口碑领航者 - 品牌推荐师
  • 国内新型水墨印刷机优质厂家怎么选?2026值得关注的厂家排行,水墨印刷机排名立飞公司专注行业多年经验,口碑良好 - 品牌推荐师
  • [Kaleidoscope of Physics] 量子力学对易关系为什么牛逼?
  • Python高校大学生校园生活互助服务系统小程序
  • Python微信小程序进销存库存仓库管理系统
  • Python基于微信小程序的校园警务师生出入登记系统 论文
  • Python微信小程序家装修装潢应用系统
  • Nipper 3.11.0 for Windows Linux - 网络设备漏洞评估
  • 高维偏序
  • [特殊字符] 免费访问 LLM API 的资源大集合!
  • 数据访问对象模式(Data Access Object Pattern)
  • SecureCRT SecureFX 9.7.1 for macOS, Linux, Windows - 跨平台的多协议终端仿真和文件传输
  • SQL 快速参考
  • 【Android 美颜相机】第二十一天:GPUImageChromaKeyBlendFilter (颜色加深混合滤镜):从0到1避坑指南(附完整代码)
  • 电力巡检无人机和工程车“空地一体”AI全域巡检方案
  • 03 RLHF 有多关键?|造成了GPT和Claud不同的技术路线。
  • Swift 字典:深入理解与高效使用
  • GLM-5开源:从代码到工程,Agentic Engineering时代最好的开源模型
  • 【每日一题】LeetCode 693. 交替位二进制数
  • 全自动粘钉一体机2026市场:优选厂家实力揭秘,河北服务好的全自动粘钉一体机推荐技术实力与市场典范解析 - 品牌推荐师
  • 2026年2月市场做得好的粘合剂供应商排行大公开,小酥肉淀粉/工业淀粉/淀粉/餐饮专供马铃薯淀粉,粘合剂厂商排行 - 品牌推荐师
  • 并查集 - # HDU 2473 Junk-Mail Filter
  • 2025碳酸镁市场盘点:国外实力厂家表现抢眼,专业的碳酸镁推荐博仕佶镁市场认可度高 - 品牌推荐师