FunctionCallback から ToolCallback API への移行

This guide helps you migrate from the deprecated FunctionCallback API to the new ToolCallback API in Spring AI. For more information about the new API, check out the ツール呼び出し documentation.

変更の概要

These changes are part of a broader effort to improve and extend the tool calling capabilities in Spring AI. Among the other things, the new API moves from "functions" to "tools" terminology to better align with industry conventions. This involves several API changes while maintaining backward compatibility through deprecated methods.

主な変更点

  1. FunctionCallback → ToolCallback

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

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

  4. FunctionCallingOptions → ToolCallingChatOptions

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

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

  7. FunctionCallingOptions.builder().functionCallbacks() → ToolCallingChatOptions.builder().toolCallbacks()

移行例

1. 基本関数コールバック

次の前で改ページ:

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

次の後で改ページ:

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

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();

次の後で改ページ:

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();

3. メソッドベースの関数コールバック

次の前で改ページ:

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

次の後で改ページ:

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

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

あるいは宣言的なアプローチでは次のようになります。

class WeatherTools {

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

}

また、同じ 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();

あるいは宣言的なアプローチでは次のようになります。

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

4. オプション設定

次の前で改ページ:

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

次の後で改ページ:

ToolCallingChatOptions.builder()
    .model(modelName)
    .toolCallbacks(weatherFunctionCallback)
    .build()

5. ChatClient ビルダーのデフォルト機能

次の前で改ページ:

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

次の後で改ページ:

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

6. Spring Bean の構成

次の前で改ページ:

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

次の後で改ページ:

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

重大な変更

  1. 関数コールバックの method() 構成は、ToolDefinition と MethodToolCallback を使用したより明示的なメソッドツール構成に置き換えられました。

  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 による宣言的仕様

Now you can use the method-level annotation (@Tool) to register tools with 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();

追加メモ

  1. 新しい API により、ツールの定義と実装がより適切に分離されます。

  2. ツール定義は、さまざまな実装間で再利用できます。

  3. ビルダーパターンは、一般的なユースケースに合わせて簡素化されています。

  4. エラー処理が改善され、メソッドベースのツールのサポートが向上しました。

タイムライン

非推奨のメソッドは、現在のマイルストーンバージョンでは下位互換性のために維持されますが、次のマイルストーンリリースでは削除されます。できるだけ早く新しい API に移行することをお勧めします。