SpringAI工具调用实战:手把手教你用ChatClient集成天气查询API(附完整代码)
SpringAI工具调用实战手把手教你用ChatClient集成天气查询API最近在开发一个智能聊天机器人时遇到了一个常见需求让机器人能够回答用户关于天气的实时查询。经过一番探索我发现SpringAI的ChatClient配合工具调用功能可以优雅地实现这个需求。下面就把我的实战经验分享给大家从工具定义到结果处理一步步教你如何完成这个功能闭环。1. 环境准备与基础配置在开始之前确保你的项目已经正确配置了SpringAI依赖。如果你使用Maven可以在pom.xml中添加以下依赖dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-openai-spring-boot-starter/artifactId version0.8.0/version /dependency对于天气API我选择了OpenWeatherMap的服务它提供了免费的开发者套餐。你需要先注册获取API Key。在application.properties中配置必要的参数spring.ai.openai.api-key你的OpenAI密钥 weather.api.key你的OpenWeatherMap密钥 weather.api.urlhttps://api.openweathermap.org/data/2.5/weather提示建议将敏感信息如API Key存储在环境变量或配置中心而不是直接写在配置文件中。2. 定义天气查询工具工具调用的核心是定义一个FunctionCallback实现。这里我们创建一个WeatherService类来处理天气查询逻辑Service public class WeatherService implements FunctionCallback { Value(${weather.api.key}) private String apiKey; Value(${weather.api.url}) private String apiUrl; Override public String getName() { return getCurrentWeather; } Override public String call(String arguments, MapString, Object context) { try { JSONObject params new JSONObject(arguments); String location params.getString(location); RestTemplate restTemplate new RestTemplate(); String url String.format(%s?q%sappid%sunitsmetric, apiUrl, location, apiKey); String response restTemplate.getForObject(url, String.class); return parseWeatherResponse(response); } catch (Exception e) { return 无法获取天气信息 e.getMessage(); } } private String parseWeatherResponse(String jsonResponse) { JSONObject response new JSONObject(jsonResponse); JSONObject main response.getJSONObject(main); JSONArray weather response.getJSONArray(weather); return String.format(当前温度: %.1f°C, 体感温度: %.1f°C, 天气状况: %s, main.getDouble(temp), main.getDouble(feels_like), weather.getJSONObject(0).getString(description)); } }这个实现有几个关键点需要注意getName()方法定义了工具名称ChatClient将通过这个名称来匹配工具调用call()方法是实际执行逻辑的地方接收JSON格式的参数我们使用Spring的RestTemplate来调用外部天气API返回结果会被ChatClient自动传递给AI模型进行后续处理3. 注册工具并配置ChatClient有了工具实现后我们需要将其注册到ChatClient中。这里我创建了一个配置类来集中管理Configuration public class ChatConfig { Bean public ChatClient chatClient(ChatModel chatModel, WeatherService weatherService) { return ChatClient.builder(chatModel) .tools(weatherService) .defaultSystem( 你是一个智能助手可以帮助用户查询天气信息。 当用户询问天气时你会自动调用getCurrentWeather工具。 回答时请保持友好、简洁的风格。 ) .build(); } }这里有几个值得注意的配置项tools()方法注册了我们之前定义的WeatherServicedefaultSystem()设置了系统提示词指导AI模型的行为ChatClient会自动处理工具调用的完整生命周期注意如果你的项目中有多个工具需要注册可以使用tools()方法传入多个FunctionCallback实例。4. 处理工具调用与用户交互现在我们可以创建一个简单的控制器来测试整个流程RestController public class WeatherBotController { private final ChatClient chatClient; public WeatherBotController(ChatClient chatClient) { this.chatClient chatClient; } GetMapping(/ask) public String ask(RequestParam String question) { return chatClient.prompt() .user(question) .call() .content(); } }测试时你可以发送类似北京现在的天气怎么样的查询。ChatClient会自动完成以下步骤将用户问题发送给AI模型模型识别需要调用天气查询工具ChatClient找到匹配的WeatherService并执行将天气API的结果返回给模型模型生成最终回复返回给用户5. 常见问题与调试技巧在实际开发中你可能会遇到一些典型问题。以下是我遇到的一些坑和解决方案问题1工具调用未被触发可能原因系统提示词中没有明确指导模型使用工具工具名称与模型期望的不匹配参数格式不符合模型预期解决方案// 调整系统提示词明确指导工具使用 .defaultSystem( 你是一个天气助手当用户询问天气时你必须调用getCurrentWeather工具。 工具参数需要包含location字段值为城市名称。 )问题2参数解析失败可能原因参数不是有效的JSON格式缺少必填字段解决方案// 在工具实现中添加更健壮的参数处理 public String call(String arguments, MapString, Object context) { try { JSONObject params new JSONObject(arguments); if (!params.has(location)) { return 需要提供location参数; } // 其余逻辑... } catch (JSONException e) { return 参数格式错误需要是JSON格式; } }问题3API调用失败可能原因网络问题API密钥无效城市名称不支持解决方案// 添加重试机制和更友好的错误提示 private String callWeatherApi(String location) { int retries 3; while (retries 0) { try { // API调用逻辑... } catch (HttpClientErrorException e) { if (e.getStatusCode() HttpStatus.NOT_FOUND) { return 找不到该城市的天气信息; } retries--; if (retries 0) { return 天气服务暂时不可用; } } } return 天气查询失败; }6. 进阶优化与扩展完成基础功能后我们可以考虑一些优化措施缓存天气数据Cacheable(value weather, key #location) public String getWeatherWithCache(String location) { // 原有天气查询逻辑 }支持更多参数// 工具描述中可以定义更丰富的参数 FunctionDescription( name getCurrentWeather, description 获取指定城市的当前天气信息, parameters { Parameter( name location, description 城市名称如北京或New York, required true ), Parameter( name unit, description 温度单位celsius或fahrenheit, required false ) } )多工具组合使用// 注册多个工具 .tools(weatherService, stockService, translationService)异步工具调用public CompletableFutureString callAsync(String arguments) { return CompletableFuture.supplyAsync(() - { // 工具调用逻辑 }); }在实际项目中我发现这种工具调用模式非常灵活不仅可以用于天气查询还能扩展到各种外部服务集成。通过合理设计工具描述和参数可以让AI模型更准确地决定何时以及如何使用这些工具。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2497651.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!