Spring AI 2.0实战:构建天气预报Agent智能体的完整指南 Spring AI 2.0 为 Java 开发者提供了直接集成大语言模型的能力让传统后端程序员不再需要额外学习 Python 生态就能构建智能应用。实际项目中从零搭建一个可用的 Agent 智能体需要解决环境配置、模型选择、API 封装、流程控制和异常处理等多个环节而不仅仅是调用一个对话接口那么简单。本文将基于 Spring AI 2.0 最新稳定版本带您完成一个完整的天气预报查询 Agent 实战项目。这个案例涵盖了模型接入、工具调用、记忆管理和流式响应等核心概念学完后您将掌握如何将大模型能力嵌入到现有 Java 系统中并理解生产环境中需要关注的配置细节和排查方法。1. 理解 Spring AI 的核心架构与关键概念Spring AI 通过抽象层将大模型的能力标准化让开发者可以用统一的接口调用不同厂商的模型服务。这种设计类似于 Spring Data 对数据库操作的封装您只需要关注业务逻辑而不需要为每个模型适配不同的 SDK。1.1 核心组件的作用域划分AI Model是 Spring AI 的基础抽象代表一个大语言模型的实例。常见的实现包括 OpenAI 的 GPT 系列、Anthropic 的 Claude 系列以及阿里云、百度等国内厂商的模型。在代码中您通过AiModel接口与模型交互发送提示词并接收响应。Prompt Template负责管理提示词的构建过程。实际项目中直接拼接字符串的方式难以维护且容易出错。Prompt 模板支持变量替换、条件逻辑和外部文件加载让复杂的提示词工程变得可控。// 示例使用 PromptTemplate 构建动态提示词 PromptTemplate template new PromptTemplate(请为{city}生成一份天气预报要求包含温度、湿度和风速); Prompt prompt template.create(Map.of(city, 北京));Chat Client在 AI Model 基础上提供了更便捷的对话式接口。它自动维护对话历史支持多轮交互适合构建聊天机器人或需要上下文记忆的场景。AI Function允许大模型调用您定义的 Java 方法这是构建 Agent 智能体的关键技术。模型根据用户请求决定何时调用哪个函数并将函数执行结果整合到响应中。1.2 Agent 智能体的工作流程一个完整的 Agent 包含三个核心部分感知理解用户输入、决策选择执行路径、执行调用工具或生成响应。Spring AI 通过 Function Calling 机制实现这一流程用户输入被发送到大模型进行分析模型判断是否需要调用外部工具获取信息如果需要模型返回函数调用请求Spring AI 执行对应的 Java 方法执行结果被送回模型进行整合最终生成面向用户的自然语言响应这种架构让大模型成为智能决策中心而具体的业务逻辑仍由您的 Java 代码处理。2. 环境准备与项目初始化开始编码前需要确保开发环境就绪。Spring AI 2.0 需要 Java 17 或更高版本推荐使用 JDK 21 以获得更好的性能。2.1 开发环境检查清单在命令行中执行以下命令验证环境# 检查 Java 版本 java -version # 检查 Maven 版本 mvn -version # 检查 Spring Boot 兼容性需要 3.2.0 以上 mvn spring-boot:version如果使用 IDE建议 IntelliJ IDEA 2023.3 或更高版本它提供了对 Spring AI 的专门支持。2.2 创建 Spring Boot 项目使用 Spring Initializr 快速生成项目骨架curl https://start.spring.io/starter.zip \ -d dependenciesweb,ai \ -d javaVersion21 \ -d artifactIdweather-agent \ -d baseDirweather-agent \ -o weather-agent.zip解压后检查pom.xml确保包含 Spring AI 依赖dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-bom/artifactId version2.0.0/version typepom/type scopeimport/scope /dependency dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-openai-spring-boot-starter/artifactId /dependency2.3 配置模型接入参数在application.yml中配置 OpenAI 兼容的接口以阿里云灵积为例spring: ai: openai: base-url: https://dashscope.aliyuncs.com/compatible-mode/v1 api-key: ${ALI_API_KEY:your-key-here} chat: options: model: qwen-plus temperature: 0.7 max-tokens: 2000关键参数说明参数含义推荐值配置不当的影响base-url模型服务地址根据厂商文档填写连接失败或超时api-key认证密钥从控制台获取401 未授权错误model模型名称qwen-plus/gpt-4等404 模型不存在temperature创造性程度0.1-0.9过高则回答随机过低则刻板max-tokens响应最大长度500-4000过长浪费资源过短回答截断注意api-key 等敏感信息不要直接写在配置文件中应该使用环境变量或配置中心管理。本地开发时可以在~/.bashrc或~/.zshrc中设置export ALI_API_KEYyour-actual-key。3. 实现天气预报查询 Agent我们将构建一个能理解用户位置查询意图并调用真实天气 API 返回结构化信息的智能体。这个案例演示了如何将大模型的自然语言理解能力与外部数据源结合。3.1 定义天气查询工具函数首先创建WeatherService类封装对外部天气 API 的调用Service public class WeatherService { private final RestTemplate restTemplate; public WeatherService(RestTemplate.Builder restTemplateBuilder) { this.restTemplate restTemplateBuilder.build(); } Bean public FunctionCallbackWeatherService.WeatherRequest, WeatherService.WeatherResponse weatherFunction() { return FunctionCallback.builder( getWeather, 根据城市名称获取实时天气信息, new TypeReferenceWeatherRequest() {}, new TypeReferenceWeatherResponse() {} ) .function(this::getRealTimeWeather) .build(); } public WeatherResponse getRealTimeWeather(WeatherRequest request) { // 模拟调用真实天气 API String city request.city(); // 实际项目中这里会调用和风天气、OpenWeatherMap 等第三方服务 // 为演示简化返回模拟数据 return new WeatherResponse( city, 晴, 25.0, 60.0, 东南风 3级, System.currentTimeMillis() ); } public record WeatherRequest(String city) {} public record WeatherResponse( String city, String condition, Double temperature, Double humidity, String wind, Long timestamp ) {} }这个函数将被注册到 Spring AI 的函数调用系统中大模型在需要天气信息时会自动调用它。3.2 配置 Agent 并启用函数调用创建配置类来定义 Agent 的行为特性Configuration public class AgentConfig { Bean public ChatClient chatClient( ChatModel chatModel, ListFunctionCallback toolFunctionCallbacks ) { return ChatClient.builder(chatModel) .defaultFunctions(toolFunctionCallbacks) .defaultSystemPrompt( 你是一个专业的天气预报助手专门帮助用户查询各地天气情况。 当用户询问天气时你应该主动调用天气查询功能获取最新信息。 回答要简洁专业包含温度、天气状况和舒适度建议。 ) .build(); } Bean public PromptTemplate weatherPromptTemplate() { return new PromptTemplate( 用户问{userInput} 请根据以上问题判断是否需要查询天气信息。 如果需要调用合适的工具函数并生成友好回复。 ); } }系统提示词System Prompt在这里起到关键作用它设定了 Agent 的角色和行为边界让模型知道在什么情况下应该调用天气查询功能。3.3 实现控制器处理用户请求创建 REST 接口接收用户查询并返回 Agent 响应RestController public class WeatherAgentController { private final ChatClient chatClient; private final PromptTemplate promptTemplate; public WeatherAgentController(ChatClient chatClient, PromptTemplate promptTemplate) { this.chatClient chatClient; this.promptTemplate promptTemplate; } PostMapping(/chat) public FluxString chat(RequestBody ChatRequest request) { Prompt prompt promptTemplate.create( Map.of(userInput, request.message()) ); return chatClient.prompt(prompt) .stream() .content(); } public record ChatRequest(String message) {} }这里使用FluxString返回流式响应让用户能够实时看到生成过程提升交互体验。3.4 测试 Agent 完整流程启动应用后使用 curl 或 Postman 进行测试curl -X POST http://localhost:8080/chat \ -H Content-Type: application/json \ -d {message: 北京今天天气怎么样}正常响应应该显示模型识别了天气查询意图调用工具函数并返回整合后的信息北京今天天气晴温度25度湿度60%东南风3级适合户外活动。如果看到工具调用的日志说明 Function Calling 机制工作正常。4. 关键配置详解与参数调优实际项目中默认配置往往无法满足生产要求。下面分析几个关键配置项的影响和调优建议。4.1 模型参数对响应质量的影响temperature 参数控制生成的随机性不同场景需要不同的设置场景类型推荐 temperature理由不当设置的后果数据查询类0.1-0.3需要准确一致的回答过高会导致每次回答不同创意生成类0.7-0.9鼓励多样性创新过低会显得刻板无趣代码生成类0.2-0.4需要确定性输出过高可能产生语法错误对话交互类0.5-0.7平衡准确性和自然度极端值影响用户体验在application.yml中针对不同接口设置不同的参数spring: ai: openai: chat: options: temperature: 0.3 top-p: 0.9 presence-penalty: 0.1 frequency-penalty: 0.1top-p 控制生成时的词汇选择范围与 temperature 配合使用效果更好。4.2 超时与重试配置生产环境必须配置合理的超时和重试策略spring: ai: openai: client: connect-timeout: 10s read-timeout: 30s max-attempts: 3 backoff: initial-interval: 1s multiplier: 2.0 max-interval: 10s超时配置需要根据模型响应速度调整通常简单查询 10-15 秒足够复杂推理可能需要 30 秒以上。4.3 令牌使用统计与成本控制大模型按令牌数计费需要监控使用量避免意外开销Component public class TokenUsageMonitor { private final MeterRegistry meterRegistry; public TokenUsageMonitor(MeterRegistry meterRegistry) { this.meterRegistry meterRegistry; } EventListener public void handleTokenUsage(AiTokenUsageEvent event) { meterRegistry.counter(ai.tokens.prompt, model, event.getModelName()) .increment(event.getPromptTokens()); meterRegistry.counter(ai.tokens.completion, model, event.getModelName()) .increment(event.getCompletionTokens()); } }结合 Micrometer 将令牌使用情况发送到监控系统可以设置告警阈值。5. 常见问题排查与解决方案在实际开发和部署过程中会遇到各种问题。下面列出典型问题及其解决方法。5.1 连接与认证问题问题现象应用启动时报连接拒绝或认证失败。排查步骤检查 base-url 是否正确特别是 https 和路径是否完整验证 api-key 是否有权限访问目标模型确认网络环境能否访问外部 API 服务查看完整错误堆栈关注根因异常解决方案# 测试网络连通性 telnet dashscope.aliyuncs.com 443 # 验证 API Key 有效性 curl -H Authorization: Bearer YOUR_API_KEY \ https://dashscope.aliyuncs.com/api/v1/models5.2 函数调用不触发问题现象期望模型调用工具函数但实际直接生成了回答。可能原因函数描述不够清晰模型无法理解使用场景系统提示词没有明确指示使用工具用户输入意图识别失败函数注册到 Spring 上下文失败检查清单确认 FunctionCallback 被正确声明为 Bean检查函数描述是否准确说明功能和适用场景验证系统提示词包含使用工具的指导在日志中搜索函数调用相关的调试信息5.3 流式响应中断或超时问题现象前端收到部分数据后连接断开。排查方向网络代理或负载均衡器的超时设置过短模型响应时间超过客户端等待时间服务器内存不足导致进程被杀配置调整server: servlet: async: request-timeout: 60s tomcat: threads: max: 200 max-connections: 10000同时确保前端配置合理的读取超时时间。5.4 内存溢出与性能问题Spring AI 处理大模型响应时可能占用较多内存特别是处理长文本或高并发场景。监控指标JVM 堆内存使用率垃圾回收频率和耗时线程池队列长度模型响应时间 P95/P99优化建议// 对于大文件处理使用分块流式处理 FluxDataBuffer streamContent chatClient.prompt(prompt) .stream() .map(chatResponse - { // 逐块处理避免内存积累 return bufferFactory.wrap(chatResponse.getContent().getBytes()); });6. 生产环境最佳实践将 Spring AI 应用部署到生产环境时需要考虑可用性、安全性和可维护性。6.1 多模型故障转移配置不要依赖单一模型服务配置多个备选方案spring: ai: openai: base-url: https://primary-model.com/v1 api-key: ${PRIMARY_KEY} azure: openai: endpoint: https://backup-model.openai.azure.com/ api-key: ${BACKUP_KEY} chat: options: deployment-name: gpt-4在代码中实现智能路由Primary Bean public ChatModel chatModel( Qualifier(openAiChatModel) ChatModel primary, Qualifier(azureOpenAiChatModel) ChatModel backup ) { return new FallbackChatModel(primary, backup); }6.2 敏感信息与提示词安全提示词中可能包含业务逻辑需要防止泄露Component public class PromptSecurer { public String securePrompt(String originalPrompt) { // 移除可能的敏感信息 return originalPrompt .replaceAll((?i)password[:][^\\s], password***) .replaceAll(api[_-]?key[:][^\\s], api_key***); } }日志中的提示词和响应内容应该脱敏处理。6.3 性能监控与告警建立完整的监控体系management: endpoints: web: exposure: include: health,metrics,prometheus metrics: export: prometheus: enabled: true endpoint: metrics: enabled: true health: enabled: true关键监控指标请求成功率与错误率平均响应时间与令牌消耗函数调用成功率系统资源使用率6.4 测试策略AI 应用需要特殊的测试方法SpringBootTest class WeatherAgentTest { Test void testWeatherFunctionCall() { // 测试函数调用逻辑不依赖真实模型 WeatherService service new WeatherService(); var response service.getRealTimeWeather( new WeatherRequest(北京) ); assertThat(response.temperature()).isBetween(-50.0, 50.0); assertThat(response.city()).isEqualTo(北京); } Test void testPromptConstruction() { // 测试提示词构建是否正确 PromptTemplate template new PromptTemplate(查询{city}天气); Prompt prompt template.create(Map.of(city, 上海)); assertThat(prompt.getContents()).contains(上海); } }单元测试应该聚焦业务逻辑集成测试验证端到端流程。通过这个完整的天气预报 Agent 案例您已经掌握了 Spring AI 2.0 的核心用法。实际项目中可以根据业务需求扩展更多工具函数设计更复杂的 Agent 工作流。关键是要理解大模型在系统中的定位它不是万能的解决方案而是需要与传统业务逻辑紧密配合的智能组件。