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.

相关推荐
顾漂亮2 分钟前
Spring AOP 实战案例+避坑指南
java·后端·spring
间彧13 分钟前
Redis Stream相比阻塞列表和发布订阅有哪些优势?适合什么场景?
后端
机器之心17 分钟前
Meta用40万个GPU小时做了一个实验,只为弄清强化学习Scaling Law
人工智能·openai
间彧19 分钟前
Redis阻塞弹出和发布订阅模式有什么区别?各自适合什么场景?
后端
苏三说技术26 分钟前
统计接口耗时的6种常见方法
后端
SimonKing32 分钟前
Mybatis-Plus的竞争对手来了,试试 MyBatis-Flex
java·后端·程序员
光军oi38 分钟前
JAVA全栈JVM篇————初识JVM
java·开发语言·jvm
我命由我1234543 分钟前
PDFBox - PDFBox 加载 PDF 异常清单(数据为 null、数据为空、数据异常、文件为 null、文件不存在、文件异常)
java·服务器·后端·java-ee·pdf·intellij-idea·intellij idea
渣哥1 小时前
当容器里有多个 Bean,@Qualifier 如何精准定位?
javascript·后端·面试
7哥♡ۣۖᝰꫛꫀꪝۣℋ1 小时前
Spring Boot
java·spring boot·后端