Spring AI 的工具调用功能支持通过声明式(@Tool 注解)、编程式(MethodToolCallback/FunctionToolCallback)及动态(@Bean 注解)三种方式定义工具,工具类型涵盖信息检索和执行操作两类核心场景,可通过ChatClient或ChatModel配置工具(含默认工具与运行时工具),由ToolCallingManager管理工具执行生命周期(框架控制或用户控制模式),并提供 JSON Schema 自动生成、结果转换、ToolContext 上下文传递、异常处理及动态工具解析等能力,模型仅负责请求工具调用,实际执行由应用程序完成,保障安全性与灵活性。
一、工具调用基础概念
- 定义与核心价值:工具调用(函数调用)是AI应用通过与API交互扩展模型能力的模式,模型仅负责请求调用并提供参数,应用程序执行工具并返回结果,模型无法直接访问工具API(关键安全原则)。
- 两大核心场景:
- 信息检索:从外部源(数据库、网络、文件等)获取实时/特定信息(如天气、新闻),支持检索增强生成(RAG)。
- 执行操作:自动化人工任务(如发送邮件、创建数据库记录、设置闹钟)。
- 依赖组件:需支持工具调用的AI模型(参考“聊天模型对比指南”),且需从已弃用的FunctionCallback迁移至ToolCallback API。
二、工具定义的三种方式
定义方式 | 核心实现 | 配置关键 | 适用场景 |
声明式(@Tool注解) | 方法添加@Tool注解,自动生成ToolCallback | 可配置name、description、returnDirect、resultConverter;参数用 | 快速定义工具,无需手动构建回调 |
编程式 | MethodToolCallback(方法转工具)、FunctionToolCallback(函数转工具) | 需手动构建ToolDefinition、ToolMetadata,指定工具名称/描述/输入类型 | 需自定义工具执行逻辑场景 |
动态式(@Bean注解) | 函数类型(Function/Supplier等)Spring Bean,由SpringBeanToolCallbackResolver动态解析 | Bean名称为工具名,@Description提供描述 | 需动态注册、跨请求共享的通用工具 |
- 工具参数与JSON Schema:
- 自动生成:Spring AI通过JsonSchemaGenerator为工具输入参数生成JSON Schema,供模型理解调用方式。
- 自定义支持:可通过
@ToolParam、Swagger@Schema、Jackson注解配置参数描述、必需性(默认所有参数必需,@Nullable可设为可选)。
三、工具的配置与使用
- 配置载体:
- ChatClient:通过
tools()(运行时工具)或defaultTools()(默认工具,跨实例共享)传入工具实例/名称。 - ChatModel:通过ToolCallingChatOptions的
toolCallbacks()(运行时工具)或defaultOptions()(默认工具,跨请求共享)配置。 - 优先级:运行时工具完全覆盖默认工具。
- ChatClient:通过
- 快速入门示例:
- 信息检索工具:DateTimeTools类的getCurrentDateTime方法(获取用户时区当前时间),通过ChatClient.tools()传入,模型可回答“明天是哪天”。
- 执行操作工具:DateTimeTools类的setAlarm方法(ISO-8601格式时间参数),结合当前时间工具可实现“10分钟后设置闹钟”。
四、核心组件与关键机制
- 核心接口:
- ToolCallback:工具定义与执行核心接口,含getToolDefinition(工具名称/描述/输入Schema)、getToolMetadata、call(执行逻辑)方法。
- ToolCallingManager:管理工具执行完整生命周期,负责解析工具定义、执行工具调用,默认实现为DefaultToolCallingManager。
- ToolDefinition:定义工具名称、描述、输入Schema,支持从方法/函数自动生成或手动构建。
- 关键能力扩展:
- 结果转换:通过ToolCallResultConverter将工具结果序列化为字符串(默认Jackson转JSON),支持自定义实现。
- ToolContext:传递额外上下文数据(如tenantId),不发送给模型,仅工具执行时使用。
- 直接返回(returnDirect):工具结果可直接返回调用方(true)或传回模型(false,默认),多工具调用需全部设为true才生效。
五、工具执行与异常处理
- 两种执行模式:
- 框架控制执行(默认):ChatModel通过ToolCallingManager自动拦截工具调用请求,执行后返回结果给模型,全程透明。
- 用户控制执行:设置ToolCallingChatOptions的
internalToolExecutionEnabled=false,需手动检查ChatResponse中的工具调用,通过ToolCallingManager执行并维护会话历史。
- 异常处理:
- 异常类型:工具调用失败抛出ToolExecutionException。
- 处理机制:ToolExecutionExceptionProcessor将异常转为模型可处理的字符串(默认)或抛出给调用方,可通过
spring.ai.tools.throw-exception-on-error配置(默认false)。
六、约束与可观测性
- 不支持的类型:
- 方法工具:Optional、异步类型(CompletableFuture)、响应式类型(Mono/Flux)、函数式类型。
- 函数工具:基本类型、Optional、集合类型、异步/响应式类型。
- 可观测性:
- 日志:org.springframework.ai包DEBUG级别日志记录工具调用关键操作。
- 追踪:通过
spring.ai.tool观测项记录执行时间、传播追踪信息;工具参数/结果可导出为span属性(默认禁用)。
七、工具解析
- 核心接口:ToolCallbackResolver,负责运行时将工具名称解析为ToolCallback实例。
- 默认实现:DelegatingToolCallbackResolver,委托SpringBeanToolCallbackResolver(解析函数Bean)和StaticToolCallbackResolver(解析静态ToolCallback Bean)。