使用SpringAI的FuncationCalling示例及介绍
摘要:本文演示了如何通过Spring AI实现大模型与Java代码的交互,以查询实时天气为例。关键步骤包括:1) 定义输入输出数据结构;2) 注册带有@Description注解的Java函数Bean;3) 在ChatClient中启用该函数。当用户询问天气时,系统自动完成意图识别、参数提取、本地执行和结果整合的全流程,将复杂的提示词工程和JSON转换封装为简单的Java方法调用。该方案展示了Sp
模拟一个最经典的场景:查询实时天气。
因为大模型(如 GPT)的数据是预训练的,它不知道此时此刻“北京”的天气如何,所以它必须“回调”我们的 Java 代码来获取真实数据。
示例场景:智能天气助手
我们需要做三件事:
- 定义输入/输出数据结构(Class/Record)。
- 编写具体的 Java 逻辑并注册为 Bean。
- 在 ChatClient 中启用这个函数。
1. 定义输入和输出 (Request & Response)
Spring AI 会利用 Java 的类型系统(Reflection)来读取这些字段,自动生成 JSON Schema 告诉大模型:“这个函数需要一个叫 location 的字符串参数”。
Java
// 1. 请求参数(大模型会尝试提取这个参数)
public record WeatherRequest(String location) {}
// 2. 响应数据(我们将把这个数据返回给大模型)
public record WeatherResponse(String location, String temp, String description) {}
2. 注册函数 Bean (The Magic Part)
这是最关键的一步。我们需要定义一个标准的 java.util.function.Function,并加上 @Description 注解。
@Description的作用: 这段文字会被发送给大模型。大模型通过读这句话来决定 “在什么情况下” 应该调用这个函数。
Java
@Configuration
public class ToolsConfig {
@Bean
@Description("Get the weather in location. 用于查询特定地点的天气状况")
public Function<WeatherRequest, WeatherResponse> weatherFunction() {
return request -> {
// 这里通常会调用第三方API (如高德/OpenWeatherMap)
// 为了演示简单,我们直接模拟数据
System.out.println(">>> 正在调用 Java 方法查询天气: " + request.location());
if (request.location().contains("北京")) {
return new WeatherResponse(request.location(), "25°C", "晴朗");
} else {
return new WeatherResponse(request.location(), "20°C", "多云");
}
};
}
}
3. 实际调用 (ChatClient)
在 Controller 或 Service 中,我们告诉 AI:“你可以使用 weatherFunction 这个工具”。
Java
@RestController
public class ChatController {
private final ChatClient chatClient;
// 构造器注入,Spring AI 自动配置好了 Builder
public ChatController(ChatClient.Builder builder) {
this.chatClient = builder.build();
}
@GetMapping("/ask")
public String askAi(@RequestParam String prompt) {
return chatClient.prompt()
.user(prompt)
// 关键点:启用刚才注册的 Bean 名称
.functions("weatherFunction")
.call()
.content();
}
}
底层原理拆解:刚才发生了什么?
当你访问 /ask?prompt=北京天气怎么样? 时,Spring AI 在底层通过以下步骤完成了“魔法”:
第一步:意图识别与参数提取 (Java -> LLM)
Spring AI 扫描到了 weatherFunction,它将其转换为类似下面的 JSON Schema,附带在发送给 LLM 的请求中:
JSON
// Spring AI 发给 LLM 的 system 提示片段(伪代码)
{
"tools": [
{
"name": "weatherFunction",
"description": "用于查询特定地点的天气状况",
"parameters": {
"type": "object",
"properties": {
"location": { "type": "string", "description": "城市名称" }
},
"required": ["location"]
}
}
],
"messages": [{ "role": "user", "content": "北京天气怎么样?" }]
}
第二步:大模型决策 (LLM -> Java)
LLM 收到请求,分析发现用户问的是天气,且自己手头有一个 weatherFunction 可以用。
它不会直接回答“天气很好”,而是返回一个特殊的指令(Function Call Request):
- LLM 回复: “请帮我调用
weatherFunction,参数是{"location": "北京"}”。
第三步:本地执行与递归 (Java Execution)
- Spring AI 的拦截器捕获到这个“调用请求”。
- 它利用 Java 反射机制,找到
weatherFunctionBean。 - 它将 JSON
{"location": "北京"}反序列化为WeatherRequest对象。 - 执行
weatherFunction.apply()方法(控制台打印>>> 正在调用...)。 - 拿到返回值
WeatherResponse(25°C, 晴朗)。
第四步:最终生成 (Java -> LLM)
Spring AI 拿着 Java 方法的运行结果,再次发起请求给 LLM:
- 发送内容: “函数调用结果是:北京,25°C,晴朗。请根据这个信息回复用户。”
- LLM 最终回复: “目前北京的天气是晴朗的,气温大约 25°C。”
总结
这个过程完全体现了 Spring AI 的核心价值:它把复杂的“提示词工程”和“JSON 序列化/反序列化”封装成了标准的 Java 方法调用。 开发者只需要写业务逻辑(Function),剩下的底层代码由框架自动处理。
火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。
更多推荐
所有评论(0)