FunctionCallback

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

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

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

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

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

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

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

  • call(String functionArguments, ToolContext toolContext): Extended version that supports additional tool context

ビルダーパターン

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 スキーマ (for Vertex AI compatibility)

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 を使用します。

  • Use BiFunction<I, ToolContext, O> to access the ToolContext in the function invocation approach and add ToolContext parameter in the method invoking approach.

Notes on Schema Generation

  • The framework automatically generates JSON schemas from Java types

  • For function invoking, the schema is generated based on the input type for the function that needs to be set using inputType(TYPE). Use ParameterizedTypeReference for generic types.

  • Generated schemas respect Jackson annotations on model classes

  • You can bypass the automatic generation by providing custom schemas using inputTypeSchema()

Common Pitfalls to Avoid

Lack of Description

  • Always provide explicit descriptions instead of relying on auto-generated ones

  • Clear descriptions improve model’s function selection accuracy

Schema Mismatches

  • Ensure input types match the Function’s input parameter types.

  • Use ParameterizedTypeReference for generic types.