函数回调
Spring AI 中的接口提供了一种标准化的方式来实现大型语言模型 (LLM) 函数调用功能。它允许开发人员注册自定义函数,当在提示中检测到特定条件或意图时,AI 模型可以调用这些函数。FunctionCallback
该接口定义了几个关键方法:FunctionCallback
-
getName()
:返回 AI 模型上下文中的唯一函数名称 -
getDescription()
:提供可帮助模型决定何时调用函数的描述 -
getInputTypeSchema()
:定义函数输入参数的 JSON 架构 -
call(String functionArguments)
:处理实际的函数执行 -
call(String functionArguments, ToolContext toolContext)
:支持其他工具上下文的扩展版本
Builder 模式
Spring AI 提供了一个 Fluent Builder API 用于创建实现。
这对于定义函数回调特别有用,您可以务实地、动态地使用 or model 调用注册这些回调。FunctionCallback
ChatClient
ChatModel
使用该方法创建新的生成器实例,并链接配置方法以设置函数名称、描述、输入类型和其他属性。
这是一个层次结构,具有以下结构:FunctionCallback.builder()
FunctionCallback.Builder
函数调用方法
将任何 、 或 转换为 AI 模型可调用的 a。java.util.function.Function
BiFunction
Supplier
Consumer
FunctionCallback
您可以使用 lambda 表达式或方法引用来定义函数逻辑,但必须使用 .inputType(TYPE) |
函数<I, O>
FunctionCallback callback = FunctionCallback.builder()
.function("processOrder", (Order order) -> processOrderLogic(order))
.description("Process a new order")
.inputType(Order.class)
.build();
BiFunction<I、ToolContext、O>
将 Function 与输入类型 <I> 和其他 ToolContext 参数一起使用:
FunctionCallback callback = FunctionCallback.builder()
.function("processOrder", (Order order, ToolContext context) ->
processOrderWithContext(order, context))
.description("Process a new order with context")
.inputType(Order.class)
.build();
供应商<O>
使用 or 定义不接受任何输入的函数: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();
消费者<I>
使用 or 定义不产生输出的函数: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 架构生成和参数转换。它对于将 Java 方法作为可调用函数集成到 AI 模型交互中特别有用。
调用方法实现接口并提供:FunctionCallback
-
为方法参数自动生成 JSON 架构
-
支持 static 和 instance 方法
-
任意数量的参数(包括 none)和返回值(包括 void)
-
任何参数/返回类型(基元、对象、集合)
-
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 架构(默认)
-
OpenAPI 架构(用于 Vertex AI 兼容性)
FunctionCallback.builder()
.schemaType(SchemaType.OPEN_API_SCHEMA)
// ... other configuration
.build();
最佳实践
工具上下文使用
-
当需要 User 提供的其他状态或上下文,而不是 AI 模型生成的函数输入的一部分时,请使用 ToolContext。
-
用于在函数调用方法中访问 ToolContext,并在方法调用方法中添加参数。
BiFunction<I, ToolContext, O>
ToolContext