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
は、次の構造を持つ階層です。
FunctionCallback.Builder - The root builder interface used for configuring the shared properties.
FunctionInvokingSpec - The function invoking builder interface.
MethodInvokingSpec - The method invoking builder interface.
関数呼び出しアプローチ
任意の java.util.function.Function
、BiFunction
、Supplier
または 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();
ベストプラクティス
入力型とスキーマ
関数呼び出しアプローチの場合、入力型を明示的に定義し、ジェネリクス型に
ParameterizedTypeReference
を使用します。自動生成されたスキーマが要件を満たさない場合は、カスタムスキーマの使用を検討してください。
ツールコンテキストの使用
AI モデルによって生成された関数入力の一部ではなく、ユーザーから提供される追加の状態またはコンテキストが必要な場合は、ToolContext を使用します。
Use
BiFunction<I, ToolContext, O>
to access the ToolContext in the function invocation approach and addToolContext
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)
. UseParameterizedTypeReference
for generic types.Generated schemas respect Jackson annotations on model classes
You can bypass the automatic generation by providing custom schemas using
inputTypeSchema()