找回密码
 立即注册
首页 业界区 业界 Spring AI学习:工具调用实践(基于和风天气api) ...

Spring AI学习:工具调用实践(基于和风天气api)

贡醮 2026-2-4 14:00:11
工具调用总体实现:

设计工具类:

  1. @Component
  2. public class WeatherInquiryTools {
  3.     @Autowired
  4.     private WeatherService weatherService;
  5.     @Tool(description = "根据城市名称查询城市LocationID")
  6.     public String getLocationId(@ToolParam(description = "城市名称") String cityName){
  7.         return weatherService.getLocationId(cityName).getLocation().get(0).getId();
  8.     }
  9.     @Tool(description = "根据城市LocationID查询实时温度")
  10.     public String getWeather(@ToolParam(description = "城市LocationID") String locationId){
  11.         return weatherService.getWeather(locationId).getNow().getTemp();
  12.     }
  13. }
复制代码
将工具交给ai客户端:

1.png

 对话测试:

2.png

 具体实现:

实体类:

  1. @NoArgsConstructor
  2. @AllArgsConstructor
  3. @Data
  4. public class WeatherResponse {
  5.     @JsonProperty("code")
  6.     private String code;
  7.     @JsonProperty("updateTime")
  8.     private String updateTime;
  9.     @JsonProperty("fxLink")
  10.     private String fxLink;
  11.     @JsonProperty("now")
  12.     private NowData now;
  13.     @JsonProperty("refer")
  14.     private Refer refer;
  15. }
复制代码
  1. @Data
  2. @AllArgsConstructor
  3. @NoArgsConstructor
  4. public class NowData {
  5.     // 观测时间
  6.     @JsonProperty("obsTime")
  7.     private String obsTime;
  8.     // 温度,单位:摄氏度
  9.     @JsonProperty("temp")
  10.     private String temp;
  11.     // 体感温度,单位:摄氏度
  12.     @JsonProperty("feelsLike")
  13.     private String feelsLike;
  14.     // 天气图标代码
  15.     @JsonProperty("icon")
  16.     private String icon;
  17.     // 天气描述
  18.     @JsonProperty("text")
  19.     private String text;
  20.     // 风向360角度
  21.     @JsonProperty("wind360")
  22.     private String wind360;
  23.     // 风向
  24.     @JsonProperty("windDir")
  25.     private String windDir;
  26.     // 风力等级
  27.     @JsonProperty("windScale")
  28.     private String windScale;
  29.     // 风速,单位:公里/小时
  30.     @JsonProperty("windSpeed")
  31.     private String windSpeed;
  32.     // 相对湿度,单位:%
  33.     @JsonProperty("humidity")
  34.     private String humidity;
  35.     // 降水量,单位:毫米
  36.     @JsonProperty("precip")
  37.     private String precip;
  38.     // 大气压强,单位:百帕
  39.     @JsonProperty("pressure")
  40.     private String pressure;
  41.     // 能见度,单位:公里
  42.     @JsonProperty("vis")
  43.     private String vis;
  44.     // 云量,单位:%
  45.     @JsonProperty("cloud")
  46.     private String cloud;
  47.     //露点温度,单位:摄氏度
  48.     @JsonProperty("dew")
  49.     private String dew;
  50. }
复制代码
  1. @NoArgsConstructor
  2. @AllArgsConstructor
  3. @Data
  4. public class LocationResponse {
  5.     @JsonProperty("code")
  6.     private String code;
  7.     @JsonProperty("location")
  8.     private List<Location> location;
  9.     @JsonProperty("refer")
  10.     private Refer refer;
  11. }
复制代码
  1. @AllArgsConstructor
  2. @NoArgsConstructor
  3. @Data
  4. public class Location {
  5.     @JsonProperty("name")
  6.     private String name;
  7.     @JsonProperty("id")
  8.     private String id;
  9.     @JsonProperty("lat")
  10.     private String lat;
  11.     @JsonProperty("lon")
  12.     private String lon;
  13.     @JsonProperty("adm2")
  14.     private String adm2;
  15.     @JsonProperty("adm1")
  16.     private String adm1;
  17.     @JsonProperty("country")
  18.     private String country;
  19.     @JsonProperty("tz")
  20.     private String timezone;
  21.     @JsonProperty("utcOffset")
  22.     private String utcOffset;
  23.     @JsonProperty("isDst")
  24.     private String isDst;
  25.     @JsonProperty("type")
  26.     private String type;
  27.     @JsonProperty("rank")
  28.     private String rank;
  29.     @JsonProperty("fxLink")
  30.     private String fxLink;
  31. }
复制代码
  1. @NoArgsConstructor
  2. @AllArgsConstructor
  3. @Data
  4. public class Refer {
  5.     @JsonProperty("sources")
  6.     private List<String> sources;
  7.     @JsonProperty("license")
  8.     private List<String> license;
  9. }
复制代码
以上实体类基于 和风天气api 设计。
配置类:

  1. @Component
  2. @Data
  3. @ConfigurationProperties(prefix = "frog.weather")
  4. public class WeatherProperties {
  5.     private String apiKey;
  6.     private String apiHost;
  7. }<br>
复制代码
以上配置类基于 和风天气api 设计。
序列化与反序列化工具类:

  1. @Component
  2. public class JasonUtils {
  3.     private static final ObjectMapper mapper = new ObjectMapper()
  4.             .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
  5.             .setSerializationInclusion(JsonInclude.Include.NON_NULL)
  6.             .registerModule(new JavaTimeModule());
  7.     public static String toJson(Object obj) {
  8.         try {
  9.             return mapper.writeValueAsString(obj);
  10.         } catch (JsonProcessingException e) {
  11.             throw new RuntimeException("序列化失败", e);
  12.         }
  13.     }
  14.     public static <T> T fromJson(String json, Class<T> clazz) {
  15.         try {
  16.             return mapper.readValue(json, clazz);
  17.         } catch (JsonProcessingException e) {
  18.             throw new RuntimeException("反序列化失败", e);
  19.         }
  20.     }
  21. }
复制代码
查询功能具体实现:

  1. @Service
  2. @Slf4j
  3. public class WeatherServiceImpl implements WeatherService {
  4.     @Autowired
  5.     private WeatherProperties weatherProperties;
  6.     /**
  7.      * 根据城市LocationID查询实时天气状况
  8.      */
  9.     @Override
  10.     public WeatherResponse getWeather(String locationId) {
  11.         HttpClient client = HttpClient.newHttpClient();
  12.         String apiUrl = weatherProperties.getApiHost() + "/v7/weather/now?location=" + locationId;
  13.         try {
  14.             HttpRequest request = HttpRequest.newBuilder()
  15.                     .uri(URI.create(apiUrl))
  16.                     .header("X-QW-Api-Key", weatherProperties.getApiKey())
  17.                     .GET()
  18.                     .build();
  19.             HttpResponse<byte[]> response = client.send(request, HttpResponse.BodyHandlers.ofByteArray());
  20.             byte[] compressedBody = response.body();
  21.             // 解压缩响应体
  22.             String decompressedBody = GzipDecompressor.decompressToString(compressedBody);
  23.             log.info("查询天气成功, locationId: {}", locationId);
  24.             WeatherResponse weatherResponse = JasonUtils.fromJson(decompressedBody, WeatherResponse.class);
  25.             return weatherResponse;
  26.         } catch (Exception e) {
  27.             log.error("查询天气失败, locationId: {}", locationId, e);
  28.             return null;
  29.         }
  30.     }
  31.     /**
  32.      * 根据城市名称查询城市LocationID
  33.      */
  34.     @Override
  35.     public LocationResponse getLocationId(String cityName) {
  36.         HttpClient client = HttpClient.newHttpClient();
  37.         String apiUrl = weatherProperties.getApiHost() + "/geo/v2/city/lookup?location=" + cityName;
  38.         try {
  39.             HttpRequest request = HttpRequest.newBuilder()
  40.                     .uri(URI.create(apiUrl))
  41.                     .header("X-QW-Api-Key", weatherProperties.getApiKey())
  42.                     .GET()
  43.                     .build();
  44.             HttpResponse<byte[]> response = client.send(request, HttpResponse.BodyHandlers.ofByteArray());
  45.             byte[] compressedBody = response.body();
  46.             // 解压缩响应体
  47.             String decompressedBody = GzipDecompressor.decompressToString(compressedBody);
  48.             log.info("查询城市LocationID成功, cityName: {}", cityName);
  49.             LocationResponse locationResponse = JasonUtils.fromJson(decompressedBody, LocationResponse.class);
  50.             return locationResponse;
  51.         } catch (Exception e) {
  52.             log.error("查询城市LocationID失败, cityName: {}", cityName, e);
  53.             return null;
  54.         }
  55.     }
  56. }
复制代码
目前实现的tool查询功能局限温度查询,但根据工具需求可拓展(service返回了所有查询所得,tool内对数据重新整理可以产生丰富功能)。

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

2026-2-4 19:09:34

举报

2026-2-9 06:46:40

举报

2026-2-11 22:54:10

举报

您需要登录后才可以回帖 登录 | 立即注册