Spring AI使用FunctionCallback示例
目录
在 AI 智能体开发的过程中,RAG(Retrieval-Augmented Generation) 和 功能调用(Function Calling) 已经成为两种至关重要的模式。RAG 通过结合检索技术和生成模型的强大能力,使智能体能够实时从外部数据源获取信息,并在生成过程中增强其知识深度和推理能力。Function Calling模式为智能体提供了调用外部工具的能力,极大地扩展了其应用范围。智能体可以通过调用外部工具(如数据库操作、业务规则执行、算法工具调用等),完成更为复杂的任务和操作。这种灵活性使得智能体在各种实际场景中都能表现得更为高效和精确。本文将介绍使用Spring AI 开源框架,验证AI大模型如何调用外部函数。
欢迎关注我的公众号
1、什么是Function Calling
功能调用(Function Calling)允许大型语言模型(LLM)在必要时调用一个或多个可用的工具,这些工具通常由开发者定义。工具可以是任何东西:网页搜索、对外部 API 的调用,或特定代码的执行等。
功能调用是AI应用与模型交互中一个非常典型的范式,它可以辅助模型更好的回答用户问题。我们在给模型输入的过程中,附带上可用的函数列表(包含函数名、函数描述等),模型在收到问题和函数列表后,根据对问题的推理在必要的时候发起对函数的调用。
2、Spring Boot集成Spring AI框架
如何基于Springboot集成Spring AI框架,并调用阿里云AI服务,请参考文章Spring AI Alibaba入门示例,这里不再重复说明。
3、创建自定义FunctionTools
自定义模拟算术运算的函数,可以执行加法和乘法运算,在实际的业务中,你可以在自定义函数中执行数据库操作、调用HTTP服务、执行业务逻辑等。
package com.wcy.ai.config;
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;
import java.util.function.Function;
/**
* @desc
* @date: 2025/3/11
* @version: 1.0
*/
@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;
};
}
}
4、创建FunctionCallController
为了让模型知道并调用您的自定义函数,您需要在 Prompt 请求中启用它,如上述代码,在functions("addOperation", "mulOperation")中告知ChatClient要使用这两个自定义函数。
另外指定了System Prompt:要求AI 模型被设定为一个算术计算器代理,能够执行加法和乘法运算,并且要求用户提供两个数字和运算类型。这个提示词内容很关键,如何让AI按照自己的意图去执行,要不断测试提示词内容。
package com.wcy.ai.controller;
import lombok.extern.slf4j.Slf4j;
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;
import reactor.core.publisher.Flux;
/**
* @desc 功能函数调用
* @date: 2025/3/11
* @version: 1.0
*/
@RestController
@RequestMapping("/ai")
public class FunctionCallController {
@Autowired
private ChatModel chatModel;
@GetMapping(value = "/call", produces = MediaType.APPLICATION_STREAM_JSON_VALUE)
public String call(@RequestParam(value = "input") String input){
return ChatClient.builder(chatModel)
.build()
.prompt()
.system("""
您是算术计算器的代理。
您能够支持加法运算、乘法运算等操作,其余功能将在后续版本中添加,如果用户问的问题不支持请告知详情。
在提供加法运算、乘法运算等操作之前,您必须从用户处获取如下信息:两个数字,运算类型。
请调用自定义函数执行加法运算、乘法运算。
请讲中文。
""")
.user(input)
.functions("addOperation", "mulOperation")
.call()
.content();
}
@GetMapping(value = "/callStream", produces = MediaType.APPLICATION_STREAM_JSON_VALUE)
public Flux<String> callStream(@RequestParam(value = "input") String input){
return ChatClient.builder(chatModel)
.build()
.prompt()
.system("""
您是算术计算器的代理。
您能够支持加法运算、乘法运算等操作,其余功能将在后续版本中添加,如果用户问的问题不支持请告知详情。
在提供加法运算、乘法运算等操作之前,您必须从用户处获取如下信息:两个数字,运算类型。
请调用自定义函数执行加法运算、乘法运算。
请讲中文。
""")
.user(input)
.functions("addOperation", "mulOperation")
.stream()
.content();
}
}
5、启动Springboot工程并测试
第1次提问:打招呼
http://localhost:8080/ai/chat?input=你好
返回信息如下:
你好!我是一个算术计算器的代理,目前我可以帮助你进行加法运算和乘法运算。请提供两个数字以及你想要进行的运算类型。
通过返回信息说明了,给ChatClient设置的system提示词生效了,按照默认角色输出了打招呼内容。
第2次提问:算加法
http://localhost:8080/ai/chat?input=5加5等于几
返回信息如下:
5加5等于10
第3次提问:算乘法
http://localhost:8080/ai/chat?input=5乘5等于多少
返回信息如下:
5乘5等于25
第4次提问:算减法
http://localhost:8080/ai/chat?input=5减5等于多少
返回信息如下:
目前我只能协助进行加法和乘法运算。减法功能将在后续版本中添加,敬请期待。如果您有其他运算需求,欢迎告诉我。