This guide helps you migrate from the deprecated FunctionCallback API to the new ToolCallback API in Spring AI.
The Spring AI project is moving from "functions" to "tools" terminology to better align with industry standards. This involves several API changes while maintaining backward compatibility through deprecated methods.
FunctionCallback
→ToolCallback
FunctionCallback.builder().functions()
→FunctionToolCallback.builder()
FunctionCallback.builder().method()
→MethodToolCallback.builder()
FunctionCallingOptions
→ToolCallingChatOptions
- Method names from
functions()
→tools()
Before:
FunctionCallback.builder()
.function("getCurrentWeather", new MockWeatherService())
.description("Get the weather in location")
.inputType(MockWeatherService.Request.class)
.build()
After:
FunctionToolCallback.builder("getCurrentWeather", new MockWeatherService())
.description("Get the weather in location")
.inputType(MockWeatherService.Request.class)
.build()
Before:
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();
After:
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();
Before:
FunctionCallback.builder()
.method("getWeatherInLocation", String.class, Unit.class)
.description("Get the weather in location")
.targetClass(TestFunctionClass.class)
.build()
After:
var toolMethod = ReflectionUtils.findMethod(
TestFunctionClass.class, "getWeatherInLocation", String.class, Unit.class);
MethodToolCallback.builder()
.toolDefinition(ToolDefinition.builder(toolMethod)
.description("Get the weather in location")
.build())
.toolMethod(toolMethod)
.build()
And you can use the same ChatClient#tools()
API to register method-based tool callbackes:
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();
Before:
FunctionCallingOptions.builder()
.model(modelName)
.function("weatherFunction")
.build()
After:
ToolCallingChatOptions.builder()
.model(modelName)
.tools("weatherFunction")
.build()
Before:
ChatClient.builder(chatModel)
.defaultFunctions(FunctionCallback.builder()
.function("getCurrentWeather", new MockWeatherService())
.description("Get the weather in location")
.inputType(MockWeatherService.Request.class)
.build())
.build()
After:
ChatClient.builder(chatModel)
.defaultTools(FunctionToolCallback.builder("getCurrentWeather", new MockWeatherService())
.description("Get the weather in location")
.inputType(MockWeatherService.Request.class)
.build())
.build()
Before:
@Bean
public FunctionCallback weatherFunctionInfo() {
return FunctionCallback.builder()
.function("WeatherInfo", new MockWeatherService())
.description("Get the current weather")
.inputType(MockWeatherService.Request.class)
.build();
}
After:
@Bean
public ToolCallback weatherFunctionInfo() {
return FunctionToolCallback.builder("WeatherInfo", new MockWeatherService())
.description("Get the current weather")
.inputType(MockWeatherService.Request.class)
.build();
}
-
The
method()
configuration in function callbacks has been replaced with a more explicit method tool configuration usingToolDefinition
andMethodToolCallback
. -
When using method-based callbacks, you now need to explicitly find the method using
ReflectionUtils
and provide it to the builder. -
For non-static methods, you must now provide both the method and the target object:
MethodToolCallback.builder()
.toolDefinition(ToolDefinition.builder(toolMethod)
.description("Description")
.build())
.toolMethod(toolMethod)
.toolObject(targetObject)
.build()
The following methods are deprecated and will be removed in a future release:
ChatClient.Builder.defaultFunctions(String...)
ChatClient.Builder.defaultFunctions(FunctionCallback...)
ChatClient.RequestSpec.functions()
Use their tools
counterparts instead.
Now you can use the method-level annothation (@Tool
) to register tools with Spring AI
public class Home {
@Tool(description = "Turn light On or Off in a room.")
public void turnLight(String roomName, boolean on) {
// ...
logger.info("Turn light in room: {} to: {}", roomName, on);
}
}
Home homeAutomation = new HomeAutomation();
String response = ChatClient.create(this.chatModel).prompt()
.user("Turn the light in the living room On.")
.tools(homeAutomation)
.call()
.content();
- The new API provides better separation between tool definition and implementation.
- Tool definitions can be reused across different implementations.
- The builder pattern has been simplified for common use cases.
- Better support for method-based tools with improved error handling.
The deprecated methods will be maintained for backward compatibility in the current major version but will be removed in the next major release. It's recommended to migrate to the new API as soon as possible.