深入浅出 Spring AI 工具调用:工具调用高级知识

0 阅读6分钟

Spring AI 不仅简化了 AI 模型的接入,更通过优雅的工具调用机制让 AI 与现实世界交互。本文将深入剖析 Spring AI 工具调用的底层数据结构、上下文传递、立即返回机制以及执行原理。

在构建 AI 应用时,模型的知识是静态的。为了让 AI 能够查询实时天气、操作数据库或调用企业内部服务,我们需要用到 Function Calling(工具调用) 。Spring AI 对这一机制做了高度抽象和封装,本文将带你揭开 Spring AI 工具调用的神秘面纱。

一、工具调用的底层数据结构:AI 是如何“看懂”工具的?

AI 模型本身无法直接运行 Java 代码。Spring AI 通过一套精妙的底层结构,将 Java 方法“翻译”成 AI 能理解的描述。核心在于 ToolCallback 接口。

1.1 ToolCallback 接口解析

ToolCallback 是所有工具实现的基础,它定义了工具与 AI 交互的契约:

  • getToolDefinition() :提供工具的 元数据定义(名称、描述、参数 Schema)。这部分信息会被序列化并发送给 AI 模型,AI 依靠它来判断“什么时候该用这个工具”。
  • getToolMetadata() :提供附加信息,例如是否 returnDirect(直接返回,下文详解)。
  • call() :工具的实际执行逻辑入口。

1.2 注解背后的魔法:为什么 @Tool 注解就能生效?

当我们使用 @Tool(description = "获取用户订单") 标注一个方法时,Spring AI 在背后做了大量的转换工作:

  1. JsonSchemaGenerator:自动解析方法签名和注解参数,生成符合 JSON Schema 规范的参数定义,填入 ToolDefinition
  2. ToolCallResultConverter:将方法返回的各种复杂类型(Object、List 等)统一转换为 String 格式,以便交还给 AI 模型处理。
  3. MethodToolCallback:这是一个核心适配器,它实现了 ToolCallback 接口,内部封装了对注解方法的反射调用。

一句话总结:Spring AI 在运行时构建了一个包含方法描述、参数结构和执行入口的“工具包装盒”,AI 拿到的只是包装盒上的“说明书”,执行时再通过包装盒里的“机关”触发真正的代码。

二、工具上下文:安全的“幕后数据通道”

在实际开发中,工具执行往往依赖于当前请求的上下文,例如 当前登录用户的 ID。如果让 AI 模型提供用户 ID,既不安全(可能被伪造),也不符合用户体验。

Spring AI 提供了 ToolContext 机制来解决这个问题。

2.1 核心特性

  • 对 AI 不可见ToolContext 中携带的数据 不会 作为 Prompt 的一部分发送给 AI 模型。
  • 应用内部使用:仅在 call() 方法执行时,由框架注入使用。

2.2 场景与流程图解

场景示例:用户自助退款。
用户说“我要退款”,AI 不需要询问“你是谁?”,而是直接调用退款工具,工具内部从 ToolContext 获取当前会话的 userId

image.png 工具上下文流程:AI 决定调用工具,但具体的上下文参数(如 userId)由后端安全注入,不暴露给 AI。

2.3 实战逻辑模拟

  1. 用户请求:“我要退款。”
  2. Spring AI 处理:系统将用户输入转换为 Prompt,并附加工具定义 [用户退款工具](该工具定义中不包含 userId 参数,AI 认为该工具无需输入)。
  3. AI 决策toolCalls: { toolName: "用户退款工具", "params": {} }
  4. 框架执行:Spring AI 找到该工具对应的 ToolCallback,在 call 方法内,开发者可以从 ToolContext 读取当前线程绑定的 userId 进行退款操作。
  5. 结果返回:工具执行返回“退款成功”。

三、立即返回:绕过 AI 的直接响应

在大多数对话场景中,工具执行的结果需要 AI 再次润色(例如:“正在查询天气...北京今天晴天”)。但在某些场景下,工具的结果就是最终答案,无需 AI 画蛇添足(例如:直接生成一个 PDF 文件流)。

3.1 默认流程 vs 立即返回流程

Spring AI 通过 returnDirect 属性改变了调用链条。

默认流程AI决策 -> 执行工具 -> 将工具结果发回AI总结 -> 返回用户

立即返回流程
在立即返回模式中,工具执行结果直接返回给调用者,不再回传 AI 模型进行二次处理。

image.png

3.2 适用场景与代码示例

这种模式非常适合:

  • 返回二进制数据(图片、文件)。
  • 返回大量结构化数据,不需要 AI 总结。
  • 产生确定性结果的强操作(如数据库删除成功)。

使用方法:

public class FileTool {

    @Tool(description = "根据查询条件生成销售报表PDF文件", returnDirect = true)
    public byte[] generateSalesReport(ReportRequest request) {
        // 1. 业务逻辑生成 PDF
        // 2. 返回 PDF 字节流,Spring AI 会直接将 byte[] 作为 HTTP Response Body 返回
        return pdfBytes;
    }
}

四、工具底层执行原理:框架控制 vs 用户控制

Spring AI 提供了两种工具执行模式,默认情况下使用框架控制的工具执行

4.1 核心组件:ToolCallingManager

ToolCallingManager 是管理 AI 工具调用全过程的“大脑”,负责两大核心职责:

  1. 解析定义resolveToolDefinitions() - 根据请求匹配要发送给模型的工具列表。
  2. 执行调用executeToolCalls() - 根据 AI 返回的指令执行具体的 Java 方法。

4.2 默认模式:框架控制的自动执行

这是最简单的模式,开发者只需配置好 ChatClient,Spring AI 会自动处理工具调用的循环逻辑。

完整执行链路图:

image.png

步骤拆解:

  1. 发起请求:用户提问。
  2. 定义传递ToolCallingManager 通过 ChatModelAPI 将 ToolDefinition 发送给 AI 模型。
  3. AI 响应:模型返回 Chat Response,其中可能包含 toolCalls 指令。
  4. 分发与执行ToolCallingManager 接收到指令,自动 Dispatch Tool,在本地 JVM 执行对应代码。
  5. 循环(如需要) :如果 returnDirect=false,执行结果会作为新的消息再次发送给 AI,AI 可能继续调用工具或生成最终回答。
  6. 最终返回:框架将最终答案返回给用户。

4.3 进阶模式:用户控制的工具执行

在某些极端定制化的场景下,如果开发者不希望框架自动循环,也可以手动处理工具执行。这通常涉及实现 ToolCallback 或直接使用底层的 ChatModel API 处理 ToolCall 消息,给予开发者最大的控制权,但也意味着需要自行管理对话状态和循环逻辑。


通过本文的梳理,相信你已经掌握了 Spring AI 工具调用的骨架与脉络。利用好 ToolContext 保障安全,活用 returnDirect 优化响应效率,将让你的 AI 应用更加健壮和强大。