跳到主要内容

从 FunctionCallback 迁移到 ToolCallback API

DeepSeek V3 中英对照 Migrating to ToolCallback API Migrating from FunctionCallback to ToolCallback API

本指南帮助您从已弃用的 FunctionCallback API 迁移到 Spring AI 中的新 ToolCallback API。有关新 API 的更多信息,请查看 工具调用 文档。

变更概述

这些变化是改进和扩展 Spring AI 中工具调用能力的广泛努力的一部分。除此之外,新的 API 从“函数”术语转向“工具”术语,以更好地与行业惯例保持一致。这涉及多个 API 更改,同时通过弃用方法保持向后兼容性。

主要变更

  1. FunctionCallbackToolCallback

  2. FunctionCallback.builder().function()FunctionToolCallback.builder()

  3. FunctionCallback.builder().method()MethodToolCallback.builder()

  4. FunctionCallingOptionsToolCallingChatOptions

  5. ChatClient.builder().defaultFunctions()ChatClient.builder().defaultTools()

  6. ChatClient.functions()ChatClient.tools()

  7. FunctionCallingOptions.builder().functions()ToolCallingChatOptions.builder().toolNames()

  8. FunctionCallingOptions.builder().functionCallbacks()ToolCallingChatOptions.builder().toolCallbacks()

迁移示例

1. 基本函数回调

之前:

FunctionCallback.builder()
.function("getCurrentWeather", new MockWeatherService())
.description("Get the weather in location")
.inputType(MockWeatherService.Request.class)
.build()
java

之后:

FunctionToolCallback.builder("getCurrentWeather", new MockWeatherService())
.description("Get the weather in location")
.inputType(MockWeatherService.Request.class)
.build()
java

2. ChatClient 使用指南

之前:

String response = ChatClient.create(chatModel)
.prompt()
.user("What's the weather like in San Francisco?")
.functions(FunctionCallback.builder()
.function("getCurrentWeather", new MockWeatherService())
.description("Get the weather in location")
.inputType(MockWeatherService.Request.class)
.build())
.call()
.content();
java

之后:

String response = ChatClient.create(chatModel)
.prompt()
.user("What's the weather like in San Francisco?")
.tools(FunctionToolCallback.builder("getCurrentWeather", new MockWeatherService())
.description("Get the weather in location")
.inputType(MockWeatherService.Request.class)
.build())
.call()
.content();
java

3. 基于方法的函数回调

之前:

FunctionCallback.builder()
.method("getWeatherInLocation", String.class, Unit.class)
.description("Get the weather in location")
.targetClass(TestFunctionClass.class)
.build()
java

之后:

var toolMethod = ReflectionUtils.findMethod(TestFunctionClass.class, "getWeatherInLocation");

MethodToolCallback.builder()
.toolDefinition(ToolDefinition.builder(toolMethod)
.description("Get the weather in location")
.build())
.toolMethod(toolMethod)
.build()
java

或者使用声明式方法:

class WeatherTools {

@Tool(description = "Get the weather in location")
public void getWeatherInLocation(String location, Unit unit) {
// ...
}

}
java

你可以使用相同的 ChatClient#tools() API 来注册基于方法的工具回调:

String response = ChatClient.create(chatModel)
.prompt()
.user("What's the weather like in San Francisco?")
.tools(MethodToolCallback.builder()
.toolDefinition(ToolDefinition.builder(toolMethod)
.description("Get the weather in location")
.build())
.toolMethod(toolMethod)
.build())
.call()
.content();
java

或者使用声明式方法:

String response = ChatClient.create(chatModel)
.prompt()
.user("What's the weather like in San Francisco?")
.tools(new WeatherTools())
.call()
.content();
java

4. 选项配置

之前:

FunctionCallingOptions.builder()
.model(modelName)
.function("weatherFunction")
.build()
java

之后:

ToolCallingChatOptions.builder()
.model(modelName)
.toolNames("weatherFunction")
.build()
java

5. ChatClient Builder 中的默认函数

之前:

ChatClient.builder(chatModel)
.defaultFunctions(FunctionCallback.builder()
.function("getCurrentWeather", new MockWeatherService())
.description("Get the weather in location")
.inputType(MockWeatherService.Request.class)
.build())
.build()
java

之后:

ChatClient.builder(chatModel)
.defaultTools(FunctionToolCallback.builder("getCurrentWeather", new MockWeatherService())
.description("Get the weather in location")
.inputType(MockWeatherService.Request.class)
.build())
.build()
java

6. Spring Bean 配置

之前:

@Bean
public FunctionCallback weatherFunctionInfo() {
return FunctionCallback.builder()
.function("WeatherInfo", new MockWeatherService())
.description("Get the current weather")
.inputType(MockWeatherService.Request.class)
.build();
}
java

之后:

@Bean
public ToolCallback weatherFunctionInfo() {
return FunctionToolCallback.builder("WeatherInfo", new MockWeatherService())
.description("Get the current weather")
.inputType(MockWeatherService.Request.class)
.build();
}
java

重大变更

  1. 函数回调中的 method() 配置已被替换为更显式的方法工具配置,使用 ToolDefinitionMethodToolCallback

  2. 当使用基于方法的回调时,你现在需要显式地使用 ReflectionUtils 查找方法并将其提供给构建器。或者,你可以使用带有 @Tool 注解的声明式方法。

  3. 对于非静态方法,你现在必须同时提供方法和目标对象:

MethodToolCallback.builder()
.toolDefinition(ToolDefinition.builder(toolMethod)
.description("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 = "Turn light On or Off in a room.")
void turnLight(String roomName, boolean on) {
// ...
logger.info("Turn light in room: {} to: {}", roomName, on);
}
}

String response = ChatClient.create(this.chatModel).prompt()
.user("Turn the light in the living room On.")
.tools(new Home())
.call()
.content();
java

附加说明

  1. 新的 API 提供了工具定义和实现之间更好的分离。

  2. 工具定义可以在不同的实现中重复使用。

  3. 构建器模式已针对常见用例进行了简化。

  4. 改进了对基于方法的工具的支持,并增强了错误处理。

时间线

已弃用的方法将在当前里程碑版本中继续保留以保持向后兼容性,但将在下一个里程碑版本中移除。建议尽快迁移至新的 API。