首页 > 基础资料 博客日记

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

2026-01-23 22:00:02基础资料围观6

本篇文章分享Spring AI学习:工具调用实践(基于和风天气api),对你有帮助的话记得收藏一下,看Java资料网收获更多编程知识

工具调用总体实现:

设计工具类:

@Component
public class WeatherInquiryTools {

    @Autowired
    private WeatherService weatherService;

    @Tool(description = "根据城市名称查询城市LocationID")
    public String getLocationId(@ToolParam(description = "城市名称") String cityName){
        return weatherService.getLocationId(cityName).getLocation().get(0).getId();
    }

    @Tool(description = "根据城市LocationID查询实时温度")
    public String getWeather(@ToolParam(description = "城市LocationID") String locationId){
        return weatherService.getWeather(locationId).getNow().getTemp();
    }
}

将工具交给ai客户端:

屏幕截图 2026-01-23 203014

 对话测试:

屏幕截图 2026-01-23 202500

 具体实现:

实体类:

@NoArgsConstructor
@AllArgsConstructor
@Data
public class WeatherResponse {
    @JsonProperty("code")
    private String code;

    @JsonProperty("updateTime")
    private String updateTime;

    @JsonProperty("fxLink")
    private String fxLink;

    @JsonProperty("now")
    private NowData now;

    @JsonProperty("refer")
    private Refer refer;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class NowData {

    // 观测时间
    @JsonProperty("obsTime")
    private String obsTime;

    // 温度,单位:摄氏度
    @JsonProperty("temp")
    private String temp;

    // 体感温度,单位:摄氏度
    @JsonProperty("feelsLike")
    private String feelsLike;

    // 天气图标代码
    @JsonProperty("icon")
    private String icon;

    // 天气描述
    @JsonProperty("text")
    private String text;

    // 风向360角度
    @JsonProperty("wind360")
    private String wind360;

    // 风向
    @JsonProperty("windDir")
    private String windDir;

    // 风力等级
    @JsonProperty("windScale")
    private String windScale;

    // 风速,单位:公里/小时
    @JsonProperty("windSpeed")
    private String windSpeed;

    // 相对湿度,单位:%
    @JsonProperty("humidity")
    private String humidity;

    // 降水量,单位:毫米
    @JsonProperty("precip")
    private String precip;

    // 大气压强,单位:百帕
    @JsonProperty("pressure")
    private String pressure;

    // 能见度,单位:公里
    @JsonProperty("vis")
    private String vis;

    // 云量,单位:%
    @JsonProperty("cloud")
    private String cloud;

    //露点温度,单位:摄氏度
    @JsonProperty("dew")
    private String dew;
}
@NoArgsConstructor
@AllArgsConstructor
@Data
public class LocationResponse {

    @JsonProperty("code")
    private String code;

    @JsonProperty("location")
    private List<Location> location;

    @JsonProperty("refer")
    private Refer refer;
}
@AllArgsConstructor
@NoArgsConstructor
@Data
public class Location {

    @JsonProperty("name")
    private String name;

    @JsonProperty("id")
    private String id;

    @JsonProperty("lat")
    private String lat;

    @JsonProperty("lon")
    private String lon;

    @JsonProperty("adm2")
    private String adm2;

    @JsonProperty("adm1")
    private String adm1;

    @JsonProperty("country")
    private String country;

    @JsonProperty("tz")
    private String timezone;

    @JsonProperty("utcOffset")
    private String utcOffset;

    @JsonProperty("isDst")
    private String isDst;

    @JsonProperty("type")
    private String type;

    @JsonProperty("rank")
    private String rank;

    @JsonProperty("fxLink")
    private String fxLink;
}
@NoArgsConstructor
@AllArgsConstructor
@Data
public class Refer {

    @JsonProperty("sources")
    private List<String> sources;

    @JsonProperty("license")
    private List<String> license;
}

以上实体类基于 和风天气api 设计。

配置类:

@Component
@Data
@ConfigurationProperties(prefix = "frog.weather")
public class WeatherProperties {

    private String apiKey;

    private String apiHost;
}

以上配置类基于 和风天气api 设计。

序列化与反序列化工具类:

@Component
public class JasonUtils {

    private static final ObjectMapper mapper = new ObjectMapper()
            .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
            .setSerializationInclusion(JsonInclude.Include.NON_NULL)
            .registerModule(new JavaTimeModule());

    public static String toJson(Object obj) {
        try {
            return mapper.writeValueAsString(obj);
        } catch (JsonProcessingException e) {
            throw new RuntimeException("序列化失败", e);
        }
    }

    public static <T> T fromJson(String json, Class<T> clazz) {
        try {
            return mapper.readValue(json, clazz);
        } catch (JsonProcessingException e) {
            throw new RuntimeException("反序列化失败", e);
        }
    }
}

查询功能具体实现:

@Service
@Slf4j
public class WeatherServiceImpl implements WeatherService {

    @Autowired
    private WeatherProperties weatherProperties;

    /**
     * 根据城市LocationID查询实时天气状况
     */
    @Override
    public WeatherResponse getWeather(String locationId) {
        HttpClient client = HttpClient.newHttpClient();
        String apiUrl = weatherProperties.getApiHost() + "/v7/weather/now?location=" + locationId;
        try {
            HttpRequest request = HttpRequest.newBuilder()
                    .uri(URI.create(apiUrl))
                    .header("X-QW-Api-Key", weatherProperties.getApiKey())
                    .GET()
                    .build();
            HttpResponse<byte[]> response = client.send(request, HttpResponse.BodyHandlers.ofByteArray());
            byte[] compressedBody = response.body();
            // 解压缩响应体
            String decompressedBody = GzipDecompressor.decompressToString(compressedBody);
            log.info("查询天气成功, locationId: {}", locationId);
            WeatherResponse weatherResponse = JasonUtils.fromJson(decompressedBody, WeatherResponse.class);
            return weatherResponse;
        } catch (Exception e) {
            log.error("查询天气失败, locationId: {}", locationId, e);
            return null;
        }
    }

    /**
     * 根据城市名称查询城市LocationID
     */
    @Override
    public LocationResponse getLocationId(String cityName) {
        HttpClient client = HttpClient.newHttpClient();
        String apiUrl = weatherProperties.getApiHost() + "/geo/v2/city/lookup?location=" + cityName;
        try {
            HttpRequest request = HttpRequest.newBuilder()
                    .uri(URI.create(apiUrl))
                    .header("X-QW-Api-Key", weatherProperties.getApiKey())
                    .GET()
                    .build();
            HttpResponse<byte[]> response = client.send(request, HttpResponse.BodyHandlers.ofByteArray());
            byte[] compressedBody = response.body();
            // 解压缩响应体
            String decompressedBody = GzipDecompressor.decompressToString(compressedBody);
            log.info("查询城市LocationID成功, cityName: {}", cityName);
            LocationResponse locationResponse = JasonUtils.fromJson(decompressedBody, LocationResponse.class);
            return locationResponse;
        } catch (Exception e) {
            log.error("查询城市LocationID失败, cityName: {}", cityName, e);
            return null;
        }
    }
}

目前实现的tool查询功能局限温度查询,但根据工具需求可拓展(service返回了所有查询所得,tool内对数据重新整理可以产生丰富功能)。


文章来源:https://www.cnblogs.com/syf0824/p/19523990
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:jacktools123@163.com进行投诉反馈,一经查实,立即删除!

标签:

上一篇:Java自学之路1:Hello World
下一篇:没有了

相关文章

本站推荐

标签云