Spring AI学习:工具调用实践(基于和风天气api)
工具调用总体实现:设计工具类:
@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客户端:
对话测试:
具体实现:
实体类:
@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;
}<br>以上配置类基于 和风天气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内对数据重新整理可以产生丰富功能)。
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! 喜欢鼓捣这些软件,现在用得少,谢谢分享! 过来提前占个楼 yyds。多谢分享 东西不错很实用谢谢分享 鼓励转贴优秀软件安全工具和文档! 用心讨论,共获提升! 前排留名,哈哈哈 收藏一下 不知道什么时候能用到 热心回复! 这个有用。 感谢发布原创作品,程序园因你更精彩 前排留名,哈哈哈 感谢分享,学习下。 东西不错很实用谢谢分享 这个好,看起来很实用 很好很强大我过来先占个楼 待编辑 这个好,看起来很实用 这个有用。 感谢分享,学习下。
页:
[1]
2