ToolService 实战:天气与时间
约 527 字大约 2 分钟
布欧-Lewyon
2026-06-08
首页 › Agent Spring Boot › Function Calling
get_weather:模拟数据
agent-function-calling 用 Map 模拟六城天气,演示 Tool 返回结构:
public Map<String, Object> getWeather(String city) {
Map<String, String> mock = Map.of(
"北京", "晴 25°C",
"上海", "多云 22°C",
"深圳", "阵雨 28°C"
// ...
);
if (mock.containsKey(city)) {
return Map.of("city", city, "weather", mock.get(city), "source", "mock");
}
// 模糊匹配 contains
return Map.of("city", city, "weather", "未知", "tip", "请指定北上广深杭成");
}换真实 API 时只改 ToolService,AgentService 循环不变:
public String getWeather(String city) {
return restClient.get()
.uri("/weather?city={c}", city)
.retrieve()
.body(String.class);
}get_current_time:真实逻辑
public String getCurrentTime(String timezone) {
ZoneId zone;
try {
zone = ZoneId.of(timezone != null ? timezone : "Asia/Shanghai");
} catch (Exception e) {
zone = ZoneId.of("Asia/Shanghai");
}
return ZonedDateTime.now(zone)
.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss z"));
}Tool 内处理非法时区,别把异常抛给模型。
参数解析注意
模型传来的 arguments 是 JSON 字符串,不是对象:
"{\"city\":\"北京\"}"必须用 ObjectMapper.readValue 解析后再取值。
返回类型选择
| 类型 | 适用 |
|---|---|
String | 简单文本,模型最好消化 |
Map / POJO | 结构化数据,Jackson 序列化后回传 |
| 异常 | 应捕获,返回「服务不可用:...」 |
联调示例
# 单工具
curl "http://localhost:8080/api/agent/chat?message=深圳天气怎么样"
# 多工具
curl "http://localhost:8080/api/agent/chat?message=北京几点了,天气如何"观察日志里两轮 callLLM 与 Mono.zip 并行 tool 执行。
扩展到数据库 Tool(agent-rag / 业务系统)
模式相同,在 agent-memory / agent-rag 里会加:
save_memory/search_memory→ Redissearch_articles→ MySQL 向量检索
case "search_articles":
result = articleService.search((String) args.get("query")).block();
break;阻塞 JPA 放在 Schedulers.boundedElastic() 或 block() 于 tool 层,不要阻塞 Netty 事件线程。
学习点
- Tool 实现保持「窄接口 + 容错返回」。
- 模拟数据适合 Demo;上线替换 HTTP/JDBC 实现。
- 参数从 JSON 字符串解析,注意默认值。
小结
get_weather演示结构化 Map 返回;get_current_time演示真实 Java 逻辑。- 换真 API 只动 ToolService;Agent 协议层不动。
- 下一阶段
agent-memory在 Tool 列表中加入记忆相关函数。
上一节:Tool 定义与循环
下一节:多工具并行与安全
