Spring AI如何调用Function Calling

news/2025/2/22 18:15:06/

在 AI 智能体开发的过程中,RAG(Retrieval-Augmented Generation) 和 功能调用(Function Calling) 已经成为两种至关重要的模式。RAG 通过结合检索技术和生成模型的强大能力,使智能体能够实时从外部数据源获取信息,并在生成过程中增强其知识深度和推理能力。Function Calling模式为智能体提供了调用外部工具的能力,极大地扩展了其应用范围。智能体可以通过调用外部工具(如数据库操作、业务规则执行、算法工具调用等),完成更为复杂的任务和操作。这种灵活性使得智能体在各种实际场景中都能表现得更为高效和精确。本文将介绍使用Spring AI 开源框架,验证AI大模型如何调用外部函数。

1、什么是Function Calling

功能调用(Function Calling)允许大型语言模型(LLM)在必要时调用一个或多个可用的工具,这些工具通常由开发者定义。工具可以是任何东西:网页搜索、对外部 API 的调用,或特定代码的执行等。

功能调用是AI应用与模型交互中一个非常典型的范式,它可以辅助模型更好的回答用户问题。我们在给模型输入的过程中,附带上可用的函数列表(包含函数名、函数描述等),模型在收到问题和函数列表后,根据对问题的推理在必要的时候发起对函数的调用。

SpringAI 帮我们规范了函数定义、注册等过程,并在发起模型请求之前自动将函数注入到 Prompt 中,而当模型决策在合适的时候去调用某个函数时,Spring AI 完成函数调用动作,最终将函数执行结果与原始问题再一并发送给模型,模型根据新的输入决策下一步动作。这其中涉及与大模型的多次交互过程,一次函数调用就是一次完成的交互过程。

2、开发示例前提条件

  • JDK为17以上版本,本人使用的jdk21版本;
  • SpringBoot版本为3.x以上,本项目使用的是SpringBoot 3.3.3版本;
  • 本文采用了阿里巴巴的Qwen大模型进行实验与验证。若选用阿里巴巴的AI服务,则需首先在阿里云平台上开通相应的大型模型服务,并获取所需的API密钥,以便在后续代码中调用。具体的开通与配置步骤,请参阅阿里云大模型服务平台“百炼”的相关文档和指南如何获取API Key_大模型服务平台百炼(Model Studio)-阿里云帮助中心。这样可以确保您能够顺利地集成和使用这些先进的AI资源。

3、添加maven依赖

创建springboot工程后,在pom.xml文件里引入ai相关sdk包,本示例使用了spring-ai-alibaba框架和Qwen模型,而spring-ai-alibaba又是基于spring-ai开发的,所以引入spring-ai-alibaba即可。

Pom.xml完整内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.yuncheng</groupId><artifactId>spring-ai-demo</artifactId><version>1.0-SNAPSHOT</version><properties><maven.compiler.source>21</maven.compiler.source><maven.compiler.target>21</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><spring-ai.version>1.0.0-M5</spring-ai.version><spring-ai-alibaba.version>1.0.0-M5.1</spring-ai-alibaba.version></properties><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.3.3</version><relativePath/></parent><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>com.alibaba.cloud.ai</groupId><artifactId>spring-ai-alibaba-starter</artifactId><version>${spring-ai-alibaba.version}</version></dependency></dependencies><repositories><repository><id>spring-milestones</id><name>Spring Milestones</name><url>https://repo.spring.io/milestone</url><snapshots><enabled>false</enabled></snapshots></repository><repository><id>spring-snapshots</id><name>Spring Snapshots</name><url>https://repo.spring.io/snapshot</url><releases><enabled>false</enabled></releases></repository><repository><id>aliyun</id><name>aliyun Repository</name><url>http://maven.aliyun.com/nexus/content/groups/public/</url><snapshots><enabled>false</enabled></snapshots></repository></repositories></project>

3、配置yml文件

#配置访问阿里巴巴AI服务的api-key,并指定了使用qwen-plus模型

server:port: 8080spring:application:name: spring-ai-demoai:dashscope:api-key: sk-b90ad31bb3eb4a158524928354x39dc5chat:options:model: qwen-plus

4、创建自定义的FunctionTools

自定义函数需要提供一个 name、description 和 function call signature,以便模型知道函数能做什么、期望的输入参数。Spring AI 使这一过程变得简单,只需定义一个返回 java.util.Function 的 @Bean 定义,并在调用 ChatModel 时将 bean 名称作为选项进行注册。在底层,Spring 会用适当的适配器代码包装你的 POJO(即函数),以便与 AI 模型进行交互,免去了编写繁琐的样板代码。FunctionCallback.java 接口和配套的 FunctionCallbackWrapper.java 工具类包含了底层实现代码,它们是简化 Java 回调函数的实现和注册的关键。
以下是自定义了模拟算术运算的函数,可以执行加法和乘法运算,在实际的业务中,你可以在自定义函数中执行数据库操作、调用HTTP服务、执行业务逻辑等。

import java.util.function.Function;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Description;@Configuration
public class FunctionTools {private static final Logger logger = LoggerFactory.getLogger(FunctionTools.class);public record AddOperationRequest(int d1, int d2) {}public record MulOperationRequest(int d1, int d2) {}@Bean@Description("加法运算")public Function<AddOperationRequest, Integer>  addOperation() {return request -> {logger.info("加法运算函数被调用了:" + request.d1 + "," + request.d2 );return request.d1 + request.d2;};}@Bean@Description("乘法运算")public Function<MulOperationRequest, Integer>  mulOperation() {return request -> {logger.info("乘法运算函数被调用了:" + request.d1 + "," + request.d2 );return request.d1 * request.d2;};}}

如何定义&注册函数:

您可以在应用程序上下文中定义 @Beans,就像定义任何其他 Spring 管理对象一样。

在内部,Spring AI ChatModel 将创建一个 FunctionCallbackWrapper 包装器的实例,该包装器添加通过 AI 模型调用它的逻辑。@Bean 的名称作为 ChatOption 传递。

@Description 注释是可选的,它提供了函数描述,可帮助模型了解何时调用该函数。这是一个重要的属性,可帮助 AI 模型确定要调用哪个客户端函数。

5、创建ChatClient并启用自定义函数

以下代码创建一个简单的Controller类来测试验证。


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/ai")
public class FunctionCallController {private static final Logger log = LoggerFactory.getLogger(FunctionCallController.class);@Autowiredprivate ChatModel chatModel;@GetMapping(value = "/chat", produces = MediaType.APPLICATION_STREAM_JSON_VALUE)public String ragJsonText(@RequestParam(value = "userMessage") String userMessage){return ChatClient.builder(chatModel).build().prompt().system("""您是算术计算器的代理。您能够支持加法运算、乘法运算等操作,其余功能将在后续版本中添加,如果用户问的问题不支持请告知详情。在提供加法运算、乘法运算等操作之前,您必须从用户处获取如下信息:两个数字,运算类型。请调用自定义函数执行加法运算、乘法运算。请讲中文。""").user(userMessage).functions("addOperation", "mulOperation").call().content();}
}

为了让模型知道并调用您的自定义函数,您需要在 Prompt 请求中启用它,如上述代码,在functions("addOperation", "mulOperation")中告知ChatClient要使用这两个自定义函数。

另外指定了System Prompt:要求AI 模型被设定为一个算术计算器代理,能够执行加法和乘法运算,并且要求用户提供两个数字和运算类型。这个提示词内容很关键,如何让AI按照自己的意图去执行,要不断测试提示词内容。

6、测试验证Function Calling

以下测试通过4次提问进行验证AI大模型如何调用自定义函数Function

第1次提问:打招呼

http://localhost:8080/ai/chat?userMessage=你好

返回信息如下:

你好!我是一个算术计算器的代理,目前我可以帮助你进行加法运算和乘法运算。请提供两个数字以及你想要进行的运算类型。

通过返回信息说明了,给ChatClient设置的system提示词生效了,按照默认角色输出了打招呼内容。

第2次提问:算加法

http://localhost:8080/ai/chat?userMessage=3加5等于几

返回信息如下:

3加5等于8。

此时查看后台日志输出,springai.functioncall.FunctionTools  : 加法运算函数被调用了:3,5

通过返回信息说明了,证明确实调用了自定义加法函数

第3次提问:算乘法

http://localhost:8080/ai/chat?userMessage=2乘9等于多少

返回信息如下:

2乘9等于18。如果您还有其他数学问题,欢迎继续提问。

此时查看后台日志输出,springai.functioncall.FunctionTools  : 乘法运算函数被调用了:2,9

通过返回信息说明了,证明确实调用了自定义乘法函数

第4次提问:算减法

http://localhost:8080/ai/chat?userMessage=5减3等于多少

返回信息如下:

目前我只能协助进行加法和乘法运算。减法功能将在后续版本中添加,敬请期待。如果您有其他运算需求,欢迎告诉我。

由于该示例中没有自定义减法运算函数,所以AI大模型还是按照提示词理解输出的,没有调用其它工具进行输出。

7、验证DeepSeek是否支持Function Calling

修改yml配置文件中的model值,改成deepseek-v3或deepseek-r1,重启springboot后再次测试。

spring:

  ai:

    dashscope:

      api-key: sk-b90ad31bb3eb4a158524928354x39dc5

      chat:

        options:

          model: deepseek-v3

再次请求http://localhost:8080/ai/chat?userMessage=3加5等于几

后台报错:

InternalError.Algo.InvalidParameter: The tool call is not supported

说明deepseek-v3和deepseek-r1目前不支持function calling功能。


http://www.ppmy.cn/news/1574220.html

相关文章

从CNN到Transformer:遥感影像目标检测的技术演进(矿产勘探、精准农业、城市规划、林业测量、军事目标识别和灾害评估等)

在遥感影像分析领域&#xff0c;目标检测一直是研究热点之一。随着高分辨率对地观测系统的不断发展&#xff0c;遥感影像的分辨率和数据量呈爆发式增长&#xff0c;如何高效、准确地从海量数据中提取有用信息&#xff0c;成为了一个亟待解决的问题。近年来&#xff0c;深度学习…

游戏引擎学习第111天

仓库:https://gitee.com/mrxiao_com/2d_game_2 将调试相机稍微拉远一点 今天的任务是查看地面块的相关内容。首先&#xff0c;在开始之前&#xff0c;决定将调试摄像头稍微拉远一些&#xff0c;因为希望能够看到粉色区域的整体情况。 在渲染组中&#xff0c;昨天介绍了一个概…

游戏引擎学习第107天

仓库:https://gitee.com/mrxiao_com/2d_game_2 回顾我们之前停留的位置 在这段内容中&#xff0c;讨论了如何处理游戏中的三维效果&#xff0c;特别是如何处理额外的“Z层”。由于游戏中的艺术资源是位图而不是3D模型&#xff0c;因此实现三维效果变得非常具有挑战性。虽然可…

一款社交媒体中查用户名的工具

简介 追踪 400 多个社交网络中的用户名社交媒体账户以查找账户 安装 # python环境 pip安装 pip install sherlock-project # Mac环境 brew安装 brew install sherlock # docker安装 docker pull sherlock/sherlock 使用方式 ->$ sherlock -h usage: sherlock [-h] [-…

23种设计模式 - 观察者模式

模式定义 观察者模式&#xff08;Observer Pattern&#xff09;是一种行为型设计模式&#xff0c;定义了一对多的依赖关系&#xff1a;当一个对象&#xff08;称为主题&#xff09;状态变化时&#xff0c;所有依赖它的对象&#xff08;称为观察者&#xff09;会自动收到通知并…

Android自带的省电模式主要做什么呢?

Android自带的省电模式主要做什么呢&#xff1f; 省电模式支持的策略 LOCATION 灭屏后开启GPS待机省电模式 VIBRATION 关闭触摸震动和来电震动 ANIMATION 关闭动画 FULL_BACKUP 全备份 KEYVALUE_BACKUP 键值备份 NETWORK_FIREWALL 网络防火墙&#xff0c;限制 Doze …

在 Flutter 中实现文件读写

在下面的代码中&#xff0c;分别声明了三个函数&#xff0c;即创建文件目录函数、写文件函数与读文件函数。 //创建文件目录 Future<File> get _localFile async { final directory await getApplicationDocumentsDirectory(); final path directory.path; return File…

MATLAB在数据分析和绘图中的应用:从基础到实践

引言 股票数据分析是金融领域中的重要研究方向&#xff0c;通过对历史价格、成交量等数据的分析&#xff0c;可以帮助投资者更好地理解市场趋势和做出决策。MATLAB作为一种强大的科学计算工具&#xff0c;提供了丰富的数据处理和可视化功能&#xff0c;非常适合用于股票数据的…