Appearance
Q3 · Spring AI 工具调用与工具管理
难度 P1 高频 · 岗位 应用 · 预计阅读 11 min 关键词 tool-use · framework
用户问“北京今天天气怎么样?”模型本身没有你业务系统里的实时天气数据。用 Spring AI 开发 Java 应用时,可以把查询天气的方法注册成工具,让模型提出调用请求;应用执行方法后,再把查询结果交给模型形成答复。
先认清文中的词和代码
| 词或代码 | 含义 | 天气例子里的作用 |
|---|---|---|
| Spring AI | Java 应用使用模型、提示词和工具等能力的框架 | 组织模型调用与天气工具执行 |
@Tool | 标注可作为工具的方法,并描述它能做什么 | 标记 getWeather 方法 |
@ToolParam | 描述工具参数的用途和要求 | 说明 city 是城市名 |
| Schema | 工具名称、参数类型和必填项等约定 | 告诉模型查询天气需要城市 |
ChatClient | Spring AI 发起模型调用的客户端接口 | 提交问题、注册工具并取得答复 |
tool_calls | 模型返回的结构化工具调用请求 | 请求查询北京天气 |
模型提出请求,Java 应用执行查询。 框架可以处理通用的工具调用往返;工具能否访问某个城市、是否允许执行写操作等业务限制,仍要由应用代码明确控制。
一个 Java 方法如何接入工具调用
用注解描述天气工具
下面是说明调用关系的示例代码片段;weatherApi 代表应用自己的天气服务,需在真实项目中实现和注入。city 是用户要查的城市,unit 是可选的温度单位,返回值是天气服务提供的查询结果。
java
@Service
public class WeatherService {
@Tool(description = "获取指定城市的实时天气信息,包括气温、天气状况、风速")
public String getWeather(
@ToolParam(description = "城市名称,如北京、上海,不要带省份") String city,
@ToolParam(description = "温度单位,celsius或fahrenheit", required = false) String unit
) {
// 你的业务逻辑:调天气 API、查数据库...
return weatherApi.query(city, unit);
}
}注意这里有几个关键设计:
@Tool加在方法上:description解释工具能做什么,帮助模型判断是否使用它。@ToolParam加在参数上:说明每个参数的含义和是否必填;框架据此生成供模型使用的工具说明。返回值也需要设计:示例返回
String,真实应用最好包含来源、时间和错误状态,方便判断数据是否可用。
完整调用流程
ChatClient 是调用模型的入口。下面的配置注册 WeatherService,并展示一次收到 userMessage 后的调用;这是结构示意,省略了异常处理、鉴权和实际天气服务的实现。
java
@Configuration
public class AgentConfig {
@Bean
public ChatClient chatClient(ChatModel chatModel, WeatherService weatherService) {
return ChatClient.builder(chatModel)
.defaultTools(weatherService) // 注册工具,可以注册多个
.defaultSystem("你是一个有用的助手,可以使用工具帮助用户")
.build();
}
}
@RestController
public class ChatController {
@Autowired
private ChatClient chatClient;
@PostMapping("/chat")
public String chat(@RequestBody String userMessage) {
return chatClient.prompt()
.user(userMessage)
.call() // 这里 Spring AI 自动处理:LLM 决策 → 调工具 → 结果返回 → 生成最终答案
.content();
}
}用户发「北京今天天气怎么样?」,整个流程是这样的:

Spring AI 把
WeatherService里的方法转成 JSON schema,和 prompt 一起发给 LLMLLM 返回 tool_calls,说要调
getWeather,参数{"city": "北京"}Spring AI 自动解析,找到
WeatherService.getWeather方法,反射调用拿到结果「晴天 25°C」,塞进对话历史作为 tool 消息
再次调用 LLM,LLM 生成最终自然语言回答
框架负责通用的调用往返,但应用仍要处理工具失败、超时、参数校验和权限。若天气服务不可用,不能把模型猜出的天气当成实时查询结果。
工具管理:数量多了怎么办
实际项目里工具可能很多,几十个甚至上百个。全塞给 LLM 会有两个问题:一是 prompt 太长浪费 token,二是工具太多 LLM 决策容易出错。
示意代码按场景选择工具集:
java
@Bean
public List<Object> coreTools() {
// 通用工具:搜索、计算、日历等
return List.of(new SearchTool(), new CalculatorTool(), new CalendarTool());
}
@Bean
public List<Object> domainTools() {
// 业务工具:数据库查询、报表生成等
return List.of(new DatabaseQueryTool(), new ReportGeneratorTool());
}
// 不同场景用不同工具集
chatClient.prompt()
.tools(coreTools()) // 只用核心工具
.user(question)
.call();面试中如何回答
面试时说 Spring AI 工具调用,要抓住这几个点:
注解驱动 :
@Tool+@ToolParam注解让工具定义变得极其简单,不需要手写 JSON schema调用往返:框架帮助处理工具说明、模型请求、Java 方法执行与结果回传;应用负责业务安全和失败处理。
工具管理 :工具多了要分组管理或动态选择,避免一次性塞太多工具给 LLM
直接使用模型 API 时,应用需要自行组织更多工具调用细节;使用框架能减少通用代码,但业务权限、结果校验和可观测性仍须自己设计。