从 FunctionCallback 迁移到 ToolCallback API
本指南帮助你将已弃用的 FunctionCallback API 迁移到 Spring AI 中新的 ToolCallback API。有关新 API 的更多信息,请参考工具调用(Tools Calling)文档。
本指南帮助你将已弃用的 FunctionCallback API 迁移到 Spring AI 中新的 ToolCallback API。有关新 API 的更多信息,请参考工具调用(Tools Calling)文档。
更改概览
这些更改是 Spring AI 提升和扩展工具调用功能的更广泛工作的一部分。新 API 将术语从 “functions” 转为 “tools”,以更好地符合行业惯例。这涉及若干 API 更改,同时通过已弃用的方法保持向后兼容性。
主要更改
FunctionCallback→ToolCallbackFunctionCallback.builder().function()→FunctionToolCallback.builder()FunctionCallback.builder().method()→MethodToolCallback.builder()FunctionCallingOptions→ToolCallingChatOptionsChatClient.builder().defaultFunctions()→ChatClient.builder().defaultTools()ChatClient.functions()→ChatClient.tools()FunctionCallingOptions.builder().functions()→ToolCallingChatOptions.builder().toolNames()FunctionCallingOptions.builder().functionCallbacks()→ToolCallingChatOptions.builder().toolCallbacks()
迁移示例
1. 基本函数回调
迁移前:
FunctionCallback.builder()
.function("getCurrentWeather", new MockWeatherService())
.description("获取指定位置的天气")
.inputType(MockWeatherService.Request.class)
.build();
迁移后:
FunctionToolCallback.builder("getCurrentWeather", new MockWeatherService())
.description("获取指定位置的天气")
.inputType(MockWeatherService.Request.class)
.build();
2. ChatClient 使用
迁移前:
String response = ChatClient.create(chatModel)
.prompt()
.user("旧金山的天气怎么样?")
.functions(FunctionCallback.builder()
.function("getCurrentWeather", new MockWeatherService())
.description("获取指定位置的天气")
.inputType(MockWeatherService.Request.class)
.build())
.call()
.content();
迁移后:
String response = ChatClient.create(chatModel)
.prompt()
.user("旧金山的天气怎么样?")
.tools(FunctionToolCallback.builder("getCurrentWeather", new MockWeatherService())
.description("获取指定位置的天气")
.inputType(MockWeatherService.Request.class)
.build())
.call()
.content();
3. 基于方法的函数回调
迁移前:
FunctionCallback.builder()
.method("getWeatherInLocation", String.class, Unit.class)
.description("获取指定位置的天气")
.targetClass(TestFunctionClass.class)
.build();
迁移后:
var toolMethod = ReflectionUtils.findMethod(TestFunctionClass.class, "getWeatherInLocation");
MethodToolCallback.builder()
.toolDefinition(ToolDefinition.builder(toolMethod)
.description("获取指定位置的天气")
.build())
.toolMethod(toolMethod)
.build();
或者使用声明式方法:
class WeatherTools {
@Tool(description = "获取指定位置的天气")
public void getWeatherInLocation(String location, Unit unit) {
// ...
}
}
你可以使用相同的 ChatClient#tools() API 注册基于方法的工具回调:
String response = ChatClient.create(chatModel)
.prompt()
.user("旧金山的天气怎么样?")
.tools(MethodToolCallback.builder()
.toolDefinition(ToolDefinition.builder(toolMethod)
.description("获取指定位置的天气")
.build())
.toolMethod(toolMethod)
.build())
.call()
.content();
或者使用声明式方法:
String response = ChatClient.create(chatModel)
.prompt()
.user("旧金山的天气怎么样?")
.tools(new WeatherTools())
.call()
.content();
4. 选项配置
迁移前:
FunctionCallingOptions.builder()
.model(modelName)
.function("weatherFunction")
.build();
迁移后:
ToolCallingChatOptions.builder()
.model(modelName)
.toolNames("weatherFunction")
.build();
5. ChatClient Builder 中的默认函数
迁移前:
ChatClient.builder(chatModel)
.defaultFunctions(FunctionCallback.builder()
.function("getCurrentWeather", new MockWeatherService())
.description("获取指定位置的天气")
.inputType(MockWeatherService.Request.class)
.build())
.build();
迁移后:
ChatClient.builder(chatModel)
.defaultTools(FunctionToolCallback.builder("getCurrentWeather", new MockWeatherService())
.description("获取指定位置的天气")
.inputType(MockWeatherService.Request.class)
.build())
.build();
6. Spring Bean 配置
迁移前:
@Bean
public FunctionCallback weatherFunctionInfo() {
return FunctionCallback.builder()
.function("WeatherInfo", new MockWeatherService())
.description("获取当前天气")
.inputType(MockWeatherService.Request.class)
.build();
}
迁移后:
@Bean
public ToolCallback weatherFunctionInfo() {
return FunctionToolCallback.builder("WeatherInfo", new MockWeatherService())
.description("获取当前天气")
.inputType(MockWeatherService.Request.class)
.build();
}
重大更改
- 在函数回调中,原来的
method()配置已被更明确的基于方法的工具配置所取代,使用ToolDefinition和MethodToolCallback。 - 在使用基于方法的回调时,现在需要显式地使用
ReflectionUtils查找方法,并将其提供给构建器。或者,你可以使用带有@Tool注解的声明式方法。 - 对于非静态方法,现在必须同时提供方法和目标对象:
MethodToolCallback.builder()
.toolDefinition(ToolDefinition.builder(toolMethod)
.description("描述")
.build())
.toolMethod(toolMethod)
.toolObject(targetObject)
.build();
已弃用方法
以下方法已被弃用,并将在未来版本中移除:
ChatClient.Builder.defaultFunctions(String…)ChatClient.Builder.defaultFunctions(FunctionCallback…)ChatClient.RequestSpec.functions()
请改用对应的工具(tools)方法。
使用 @Tool 的声明式规范
现在你可以使用方法级注解(@Tool)在 Spring AI 中注册工具:
class Home {
@Tool(description = "控制房间内的灯开关")
void turnLight(String roomName, boolean on) {
// ...
logger.info("将房间 {} 的灯设置为: {}", roomName, on);
}
}
String response = ChatClient.create(this.chatModel).prompt()
.user("把客厅的灯打开。")
.tools(new Home())
.call()
.content();
附加说明
- 新 API 提供了工具定义与实现之间的更好分离。
- 工具定义可以在不同的实现中复用。
- 对于常见用例,构建器模式已被简化。
- 对基于方法的工具提供了更好的支持,并改进了错误处理。
时间表
已弃用的方法将在当前里程碑版本中保持向后兼容,但将在下一个里程碑版本中移除。建议尽快迁移到新 API。