AI项目博客
记录 AI 工程实践与大模型应用

Spring AI Alibaba 12|Tools 工具 · Tool 规范

在 Spring AI 中,tools 通过 ToolCallback 接口建模。在前面的部分中,我们已经看到了如何使用 Spring AI 提供的内置支持从方法和函数定义 tools。本节将更深入地介绍 tool 规范以及如何自定义和扩展它以支持更多用例。

Tool Callback

ToolCallback 接口提供了一种定义可由 AI model 调用的 tool 的方法,包括定义和执行逻辑。当您想从头开始定义 tool 时,这是要实现的主要接口。

接口提供以下方法:

public interface ToolCallback {

  /**
   * Definition used by the AI model to determine when and how to call the tool.
   */
  ToolDefinition getToolDefinition();

  /**
   * Metadata providing additional information on how to handle the tool.
   */
  ToolMetadata getToolMetadata();

  /**
   * Execute tool with the given input and return the result to send back to the AI model.
   */
  String call(String toolInput);

  /**
   * Execute tool with the given input and context, and return the result to send back to the AI model.
   */
  String call(String toolInput, ToolContext toolContext);

}

Spring AI 为 tool 方法(MethodToolCallback)和 tool 函数(FunctionToolCallback)提供内置实现。

Tool Definition

ToolDefinition 接口提供 AI model 了解 tool 可用性所需的信息,包括 tool 名称、描述和输入 schema。每个 ToolCallback 实现必须提供 ToolDefinition 实例来定义 tool。

接口提供以下方法:

public interface ToolDefinition {

  /**
   * The tool name. Unique within the tool set provided to a model.
   */
  String name();

  /**
   * The tool description, used by the AI model to determine what the tool does.
   */
  String description();

  /**
   * The schema of the parameters used to call the tool.
   */
  String inputSchema();

}

ToolDefinition.Builder 允许您使用默认实现(DefaultToolDefinition)构建 ToolDefinition 实例。

ToolDefinition toolDefinition = ToolDefinition.builder()
  .name("currentWeather")
  .description("Get the weather in location")
  .inputSchema("""
      {
          "type": "object",
          "properties": {
              "location": {
                  "type": "string"
              },
              "unit": {
                  "type": "string",
                  "enum": ["C", "F"]
              }
          },
          "required": ["location", "unit"]
      }
  """)
  .build();

JSON Schema

向 AI model 提供 tool 时,model 需要知道调用 tool 的输入类型的 schema。Schema 用于理解如何调用 tool 并准备 tool 请求。Spring AI 通过 JsonSchemaGenerator 类为生成 tool 输入类型的 JSON Schema 提供内置支持。Schema 作为 ToolDefinition 的一部分提供。

JsonSchemaGenerator 类在底层用于为方法或函数的输入参数生成 JSON schema。JSON schema 生成逻辑支持一系列注解,您可以在方法和函数的输入参数上使用这些注解来自定义生成的 schema。

本节描述在生成 tool 输入参数的 JSON schema 时可以自定义的两个主要选项:描述和必需状态。

描述

除了为 tool 本身提供描述外,您还可以为 tool 的输入参数提供描述。描述可用于提供有关输入参数的关键信息,例如参数应该是什么格式、允许什么值等。这对于帮助 model 理解输入 schema 以及如何使用它很有用。Spring AI 使用以下注解之一为输入参数生成描述提供内置支持:

  • Spring AI 的 @ToolParam(description = “…”)
  • Jackson 的 @JsonClassDescription(description = “…”)
  • Jackson 的 @JsonPropertyDescription(description = “…”)
  • Swagger 的 @Schema(description = “…”)

此方法适用于方法和函数,并且可以递归地用于嵌套类型。

必需/可选

默认情况下,每个输入参数都被视为必需,这强制 AI model 在调用 tool 时为其提供值。但是,您可以使用以下注解之一使输入参数可选,按此优先级顺序:

  • Spring AI 的 @ToolParam(required = false)
  • Jackson 的 @JsonProperty(required = false)
  • Swagger 的 @Schema(required = false)
  • Spring Framework 的 @Nullable

此方法适用于方法和函数,并且可以递归地用于嵌套类型。

class CustomerTools {

  @Tool(description = "Update customer information")
  void updateCustomerInfo(Long id, String name, @ToolParam(required = false) String email) {
      System.out.println("Updated info for customer with id: " + id);
  }

}

WARNING: 为输入参数定义正确的必需状态对于减轻幻觉风险并确保 model 在调用 tool 时提供正确的输入至关重要。在前面的示例中,email 参数是可选的,这意味着 model 可以在不为其提供值的情况下调用 tool。如果参数是必需的,model 在调用 tool 时必须为其提供值。如果不存在值,model 可能会编造一个,导致幻觉。

结果转换

Tool call 的结果使用 ToolCallResultConverter 序列化,然后发送回 AI model。ToolCallResultConverter 接口提供了一种将 tool call 的结果转换为 String 对象的方法。

@FunctionalInterface
public interface ToolCallResultConverter {

  /**
   * Given an Object returned by a tool, convert it to a String compatible with the
   * given class type.
   */
  String convert(@Nullable Object result, @Nullable Type returnType);

}

结果必须是可序列化类型。默认情况下,结果使用 Jackson(DefaultToolCallResultConverter)序列化为 JSON,但您可以通过提供自己的 ToolCallResultConverter 实现来自定义序列化过程。

Spring AI 在方法和函数 tools 中都依赖 ToolCallResultConverter。

方法 Tool Call 结果转换

使用声明式方法从方法构建 tools 时,您可以通过设置 @Tool 注解的 resultConverter() 属性来为 tool 提供自定义 ToolCallResultConverter。

class CustomerTools {

  @Tool(description = "Retrieve customer information", resultConverter = CustomToolCallResultConverter.class)
  Customer getCustomerInfo(Long id) {
      return customerRepository.findById(id);
  }

}

如果使用编程式方法,您可以通过设置 MethodToolCallback.Builder 的 resultConverter() 属性来为 tool 提供自定义 ToolCallResultConverter。

函数 Tool Call 结果转换

使用编程式方法从函数构建 tools 时,您可以通过设置 FunctionToolCallback.Builder 的 resultConverter() 属性来为 tool 提供自定义 ToolCallResultConverter。

返回直接

默认情况下,tool call 的结果作为响应发送回 model。然后,model 可以使用结果继续对话。

在某些情况下,您可能希望将结果直接返回给调用者,而不是将其发送回 model。例如,如果您构建一个依赖 RAG tool 的 agent,您可能希望将结果直接返回给调用者,而不是将其发送回 model 进行不必要的后处理。或者,您可能有某些 tools 应该结束 agent 的推理循环。

每个 ToolCallback 实现可以定义 tool call 的结果是否应直接返回给调用者或发送回 model。默认情况下,结果发送回 model。但您可以按 tool 更改此行为。

负责管理 tool 执行生命周期的 ToolCallingManager 负责处理与 tool 关联的 returnDirect 属性。如果属性设置为 true,tool call 的结果将直接返回给调用者。否则,结果将发送回 model。

NOTE: 如果同时请求多个 tool calls,所有 tools 的 returnDirect 属性必须设置为 true 才能将结果直接返回给调用者。否则,结果将发送回 model。

方法返回直接

使用声明式方法从方法构建 tools 时,您可以通过将 @Tool 注解的 returnDirect 属性设置为 true 来标记 tool 将结果直接返回给调用者。

class CustomerTools {

  @Tool(description = "Retrieve customer information", returnDirect = true)
  Customer getCustomerInfo(Long id) {
      return customerRepository.findById(id);
  }

}

如果使用编程式方法,您可以通过 ToolMetadata 接口设置 returnDirect 属性,并将其传递给 MethodToolCallback.Builder。

ToolMetadata toolMetadata = ToolMetadata.builder()
  .returnDirect(true)
  .build();

函数返回直接

使用编程式方法从函数构建 tools 时,您可以通过 ToolMetadata 接口设置 returnDirect 属性,并将其传递给 FunctionToolCallback.Builder。

本文整理自 Spring AI Alibaba 官方文档《Tools 工具》:https://java2ai.com/docs/frameworks/agent-framework/tutorials/tools

赞(0)
未经允许不得转载:AI项目博客 » Spring AI Alibaba 12|Tools 工具 · Tool 规范

评论 抢沙发

AI项目博客

专注 AI 工程化落地 —— 覆盖智能体、大模型、Java AI 与 Python 的学习笔记,以及 AI 平台的项目实战记录。

关于本站文章归档

登录

找回密码

注册