SpringAI——完成 Function Calling

前言

在上一篇文章中,我们知道了如何使用 SpringAI 接入 DeepSeek,而这种接入实际上和网页上的没什么区别,甚至网页上的还免费。所以,这篇文章中,我们讲讲如何进行工具调用,让自己接入的 DeepSeek 可以更智能。

上一篇文章:SpringAI ------ 接入DeepSeek

工具是什么

官网的那些概念,我也讲不来,这里说下自己的理解。
工具调用 实际上就是 AI 在发现自己可能处理不了这个问题的时候,尝试着从外界获取信息的过程,而这个提供外界信息的东西,就是我们现在在讲的 工具。

工具是为了弥补 AI 在问题解决上出现的不足 而拓展出来的模块,它支持AI在需要的情况下,进行自动的调用

配置

先说明一下 大致的流程 吧:

SpringAI 在请求的时候 如果AI发现自己处理不了,它就会去找 已经注册了的 工具中有没有可以解决这个问题的工具,通过调用工具,将工具的返回值纳入自己的参考结果中,然后再进行一些分析,最后返回。

所以我们需要注意的就是 要让 AI 找到并知晓我们这些工具的作用分别是什么,应该怎么进行调用。
基于此,给出实现思路

  • 要让AI找到,我们就需要将工具注册到 构建的AI请求中
  • 要让AI理解我们工具的作用,就需要给出一些AI可以理解的文字信息来进行说明。
  • 要让AI知道如何调用我们的工具,我们需要对调用工具之前需要的内容进行一个声明与解释。

Maven依赖

如果在上一篇文章的整合中没有出现问题的话,这里就可以跳过了。
并不需要添加额外的依赖项

相关代码

这一步骤中,我们需要完成 修改配置添加工具类注册工具 等流程

配置类修改

如果在上一篇文章的整合中没有出现问题的话,这里就可以跳过了。
并不需要添加额外的配置

工具类添加

复制代码
 示例的工具代码如下:
java 复制代码
@Description("天气查询工具")
public class GetWeatherTool {

  @Tool(description ="获取特定地区今天的天气信息")
  public String getWeatherInfo(@ToolParam(description = "特定的地区",required = true) String location) {
      return "the weather of " + location + "is sunny ,but it may be raining afternoon  ! ";
  }

  @Tool(description = "获取特定地区明天的天气信息")
  public String getWeatherInfoTomorrow(@ToolParam(description = "特定的地区",required = true) String location) {
      return "the weather of " + location + "is sunny tomorrow ! ";
  }

  @Tool(description = "获取特定地区后天的天气信息")
  public String getWeatherInfoAfterTomorrow(@ToolParam(description = "特定的地区",required = true) String location) {
      return "the weather of " + location + "is sunny after tomorrow ! ";
  }
}

上面的代码中,我们

  • 通过 给方法添加 @Tool 注解,说明了这是一个工具。
  • 通过 description 属性,说明了这个工具的作用
  • 通过对工具中参数 使用 @ToolParam 来说明需要添加参数,
  • 通过 description 属性,说明了这个参数应该传入什么内容。

注册工具

在构建SpringAI 的请求的时候 参考以下内容

java 复制代码
String content = chatClient.prompt()
      .user(message)
      .tools(new GetWeatherTool())
      .call()
      .content();

上述代码中,我们在之前的基础上 添加了 tools(new GetWeatherTool()) 对工具进行了注册。

注意事项

  1. 在工具类中,尽量避免出现 AI 自己可以解决的问题,不然即使注册了,AI也不会优先对工具进行调用。

测试

Controller

将上述内容完成后,我们可以通过 Controller 对功能进行测试,示例代码如下:

less 复制代码
@RestController
@RequestMapping("/tool")
public class ToolController {

@Autowired
private ChatClient chatClient;

@GetMapping("/weather-push")
public String toolWeatherPush(@RequestParam("message") String message) {
  System.out.println("chatClient = " + chatClient);

  String content = chatClient.prompt()
          .user(message)
          .tools(new GetWeatherTool()) // add tools
          .call()
          .content();

  return content;
}
}

运行后,在 APIFOX 中查看结果,如下:

由于我们的问题是 天气内容,而 AI并不能直接去查询天气,然后由于我们的工具类中给出的信息是 上午是晴天,下午可能会下雨。 AI在调用了我们的工具后 获得了天气信息, 最后经过一系列的整合 返回了结果。
测试完毕.

补充

配置的注入

在上一篇文章中,我们注入 API_KEY 的方式是在控制台的环境变量中进行插入,但是太麻烦了。
我们其实可以考虑使用 SpringBoot 自带的 配置读取机制来解决这个问题.

  • 新建一个用来存放配置的文件(.env)
  • 修改 SpringBoot 的配置文件:
yaml 复制代码
spring:
 config:
   import: optional:classpath:.env[.properties]

我这里采用的是 classPath,即 .env 的位置是在 resources目录 下。
如果需要采用绝对路径,可以考虑修改成 file .

总结

这篇文章中 讲述了 如何在 SpringAI 中实现 Function Calling.

相关推荐
专注代码七年14 分钟前
IDEA JVM优化配置idea64.vmoptions - 保守兼容版本 兼容IDEA 2023.3.6版本【亲测可用】
java·jvm·intellij-idea
疯癫的老码农28 分钟前
【word解析】Java文件解析问题排查:无法找到OMML2MML.xsl的IO异常解析
java·开发语言·spring boot·spring·maven
songx_991 小时前
leetcode(填充每个节点的下一个右侧节点指针 II)
java·数据结构·算法·leetcode
chenyuhao20241 小时前
vector深度求索(上)实用篇
开发语言·数据结构·c++·后端·算法·类和对象
程序新视界2 小时前
MySQL中的数据去重,该用DISTINCT还是GROUP BY?
数据库·后端·mysql
花心蝴蝶.2 小时前
JVM 内存结构
java·开发语言·jvm
lichong9512 小时前
【大前端++】Android studio Log日志高对比度配色方案
android·java·前端·json·android studio·大前端·大前端++
豌豆花下猫2 小时前
Python 潮流周刊#121:工程师如何做出高效决策?
后端·python·ai
97zz2 小时前
实战排查:Java 解析 Excel 大型 导致内存溢出问题的完整解决过程
java·开发语言·spring boot·excel
没头脑的男大2 小时前
如何把pdf转换的excell多个表格合并
java·前端·pdf