FunctionCallback

このページでは、関数呼び出し API の以前のバージョンについて説明します。このバージョンは非推奨となり、次のリリースで削除される予定です。現在のバージョンはツール呼び出しで入手できます。詳細については、移行ガイドを参照してください。

Spring AI の FunctionCallback インターフェースは、大規模言語モデル (LLM) 関数呼び出し機能を実装するための標準化された方法を提供します。これにより、開発者は、プロンプトで特定の条件またはインテントが検出された場合に AI モデルによって呼び出されるカスタム関数を登録できます。

FunctionCallback インターフェースはいくつかの重要なメソッドを定義します。

  • getName(): AI モデルのコンテキスト内で一意の関数名を返します

  • getDescription(): モデルが関数を呼び出すタイミングを決定するのに役立つ説明を提供します

  • getInputTypeSchema(): 関数の入力パラメーターの JSON スキーマを定義します

  • call(String functionArguments): 実際の関数実行を処理する

  • call(String functionArguments, ToolContext toolContext): 追加のツールコンテキストをサポートする拡張バージョン

ビルダーパターン

Spring AI は、FunctionCallback 実装を作成するための流れるようなビルダー API を提供します。これは、ChatClient または ChatModel モデル呼び出しで実用的にオンザフライで登録できる関数コールバックを定義する場合に特に便利です。

FunctionCallback.builder() メソッドを使用して新しいビルダーインスタンスを作成し、構成メソッドチェーンを使用して関数名、説明、入力型、その他のプロパティを設定します。FunctionCallback.Builder は、次の構造を持つ階層です。

関数呼び出しアプローチ

任意の java.util.function.FunctionBiFunctionSupplier または Consumer を、AI モデルから呼び出すことができる FunctionCallback に変換します。

ラムダ式またはメソッド参照を使用して関数ロジックを定義できますが、inputType(TYPE) を使用して関数の入力型を指定する必要があります。

Function<I, O>

FunctionCallback callback = FunctionCallback.builder()
    .function("processOrder", (Order order) -> processOrderLogic(order))
    .description("Process a new order")
    .inputType(Order.class)
    .build();

バイファンクション <I, ToolContext, O>

入力型 <I> と追加の ToolContext パラメーターを持つ関数の使用: </i>

FunctionCallback callback = FunctionCallback.builder()
    .function("processOrder", (Order order, ToolContext context) ->
        processOrderWithContext(order, context))
    .description("Process a new order with context")
    .inputType(Order.class)
    .build();

Supplier<O>

入力を受け取らない関数を定義するには、java.util.Supplier<O> または java.util.function.Function<Void, O> を使用します。

FunctionCallback.builder()
	.function("turnsLight", () -> state.put("Light", "ON"))
    .description("Turns light on in the living room")
    .inputType(Void.class)
	.build();

Consumer<I>

出力を生成しない関数を定義するには、java.util.Consumer<I> または java.util.function.Function<I, Void> を使用します。

record LightInfo(String roomName, boolean isOn) {}

FunctionCallback.builder()
	.function("turnsLight", (LightInfo lightInfo) -> {
				logger.info("Turning light to [" + lightInfo.isOn + "] in " + lightInfo.roomName());
			})
    .description("Turns light on/off in a selected room")
    .inputType(LightInfo.class)
	.build();

ジェネリクス入力型

ParameterizedTypeReference を使用して、汎用入力型の関数を定義します。

record TrainSearchRequest<T>(T data) {}

record TrainSearchSchedule(String from, String to, String date) {}

record TrainSearchScheduleResponse(String from, String to, String date, String trainNumber) {}

FunctionCallback.builder()
	.function("trainSchedule", (TrainSearchRequest<TrainSearchSchedule> request) -> {
        logger.info("Schedule: " + request.data().from() + " to " + request.data().to());
        return new TrainSearchScheduleResponse(request.data().from(), request.  data().to(), "", "123");
    })
    .description("Schedule a train reservation")
    .inputType(new ParameterizedTypeReference<TrainSearchRequest<TrainSearchSchedule>>() {})
	.build();

メソッド呼び出しアプローチ

JSON スキーマの生成とパラメーター変換を自動的に処理しながら、リフレクションによるメソッド呼び出しを有効にします。これは、AI モデルのインタラクション内で呼び出し可能な関数として Java メソッドを統合する場合に特に便利です。

呼び出しメソッドは FunctionCallback インターフェースを実装し、以下を提供します。

  • メソッドパラメーターの JSON スキーマの自動生成

  • 静的メソッドとインスタンスメソッドの両方をサポート

  • 任意の数のパラメーター(なしも含む)と戻り値 (無効を含む)

  • 任意のパラメーター / 戻り値の型 (プリミティブ、オブジェクト、コレクション)

  • ToolContext パラメーターの特別な処理

静的メソッド呼び出し

メソッド名、パラメーターの型、ターゲットクラスを指定することで、クラス内の静的メソッドを参照できます。

public class WeatherService {
    public static String getWeather(String city, TemperatureUnit unit) {
        return "Temperature in " + city + ": 20" + unit;
    }
}

FunctionCallback callback = FunctionCallback.builder()
    .method("getWeather", String.class, TemperatureUnit.class)
    .description("Get weather information for a city")
    .targetClass(WeatherService.class)
    .build();

オブジェクトインスタンスメソッド呼び出し

メソッド名、パラメーターの型、ターゲットオブジェクトインスタンスを指定することで、クラス内のインスタンスメソッドを参照できます。

public class DeviceController {
    public void setDeviceState(String deviceId, boolean state, ToolContext context) {
        Map<String, Object> contextData = context.getContext();
        // Implementation using context data
    }
}

DeviceController controller = new DeviceController();

String response = ChatClient.create(chatModel).prompt()
    .user("Turn on the living room lights")
    .functions(FunctionCallback.builder()
        .method("setDeviceState", String.class,boolean.class,ToolContext.class)
        .description("Control device state")
        .targetObject(controller)
        .build())
    .toolContext(Map.of("location", "home"))
    .call()
    .content();
オプションで、.name() を使用して、メソッド名とは異なるカスタム関数名を設定できます。

共通構成

関数コールバックをカスタマイズするために使用できる一般的な構成がいくつかあります。

スキーマの種類

フレームワークは、入力パラメーターのスキーマを生成するためにさまざまなスキーマ型をサポートしています。

  • JSON スキーマ (default)

  • OpenAPI スキーマ (Vertex AI 互換性のため)

FunctionCallback.builder()
    .schemaType(SchemaType.OPEN_API_SCHEMA)
    // ... other configuration
    .build();

カスタムレスポンス処理

関数レスポンスを AI モデルに返す前にフォーマットするためのカスタムレスポンスコンバーターを提供できます。ほとんどの AI モデルはテキストレスポンスを期待しているため、関数レスポンスをテキスト形式に変換するのはユーザーの責任です。デフォルトでは、レスポンスは文字列に変換されます。

多くのモデルは JSON レスポンスに適切に対応しているため、JSON 文字列を返すことができます。
FunctionCallback.builder()
    .responseConverter(response ->
        customResponseFormatter.format(response))
    // ... other configuration
    .build();

カスタムオブジェクトマッピング

Spring AI は、JSON の直列化とデ直列化に ObjectMapper を使用します。カスタムオブジェクトマッピングを処理するために、カスタム ObjectMapper を提供できます。

FunctionCallback.builder()
    .objectMapper(customObjectMapper)
    // ... other configuration
    .build();

ベストプラクティス

わかりやすい名前と説明

  • 一意の関数名を提供する

  • モデルが関数を呼び出すタイミングを理解できるように、包括的な説明を記述します。

入力型とスキーマ

  • 関数呼び出しアプローチの場合、入力型を明示的に定義し、ジェネリクス型に ParameterizedTypeReference を使用します。

  • 自動生成されたスキーマが要件を満たさない場合は、カスタムスキーマの使用を検討してください。

エラー処理

  • 関数実装で適切なエラー処理を実装し、レスポンスでエラーメッセージを返す

  • 必要に応じて ToolContext を使用して追加のエラーコンテキストを提供することができます

ツールコンテキストの使用

  • AI モデルによって生成された関数入力の一部ではなく、ユーザーから提供される追加の状態またはコンテキストが必要な場合は、ToolContext を使用します。

  • 関数呼び出しアプローチでは BiFunction<I, ToolContext, O> を使用して ToolContext にアクセスし、メソッド呼び出しアプローチでは ToolContext パラメーターを追加します。

スキーマ生成に関する注意事項

  • フレームワークは Java 型から JSON スキーマを自動的に生成します

  • 関数呼び出しの場合、スキーマは、inputType(TYPE) を使用して設定する必要がある関数の入力型に基づいて生成されます。ジェネリクス型には ParameterizedTypeReference を使用します。

  • 生成されたスキーマはモデルクラスの Jackson アノテーションを考慮します

  • inputTypeSchema() を使用してカスタムスキーマを提供することで、自動生成をバイパスできます。

避けるべきよくある落とし穴

説明不足

  • 自動生成された説明に頼るのではなく、常に明確な説明を提供する

  • 明確な説明によりモデルの機能選択の精度が向上する

スキーマの不一致

  • 入力型が関数の入力パラメーター型と一致していることを確認します。

  • ジェネリクス型には ParameterizedTypeReference を使用します。