Spring AI 2.0实战:Java开发者快速构建大模型应用指南
发布时间:2026/9/7 6:21:14来源:尧图网络
如果你是一名Java开发者最近在关注大模型和AI应用开发但发现Python生态的工具链学习成本高、部署复杂那么Spring AI 2.0可能是你切入这个领域最务实的选择。过去半年我看到不少Java团队在尝试接入大模型能力时陷入两难要么用HTTP客户端硬编码调用API缺乏工程化规范要么被迫学习Python生态的LangChain等框架但团队技术栈不匹配。Spring AI 2.0的出现本质上是在Java生态中复制了Python领域成熟的AI应用开发模式让Java开发者能用熟悉的Spring风格构建AI应用。这篇文章不会简单复述官方文档而是基于实际项目经验重点解决三个关键问题第一Spring AI与传统HTTP调用相比到底在哪些环节提升了开发效率第二从零开发一个可用的Agent需要哪些核心组件第三大模型微调在Java项目中真实的应用场景是什么我将通过完整的代码示例和项目实战带你一周内掌握Spring AI 2.0的核心开发模式。1. Spring AI 2.0解决了Java开发者的哪些真实痛点1.1 传统HTTP调用的工程化困境在没有Spring AI之前Java项目接入大模型通常是这样做的// 传统HTTP调用方式示例 public class BasicOpenAIClient { private static final String API_URL https://api.openai.com/v1/chat/completions; private final String apiKey; public String callChatGPT(String prompt) { // 需要手动构建复杂的请求体 String requestBody {\model\: \gpt-3.5-turbo\, \messages\: [{\role\: \user\, \content\: \ prompt \}]}; // 处理HTTP连接、认证、异常等底层细节 HttpClient client HttpClient.newHttpClient(); HttpRequest request HttpRequest.newBuilder() .uri(URI.create(API_URL)) .header(Authorization, Bearer apiKey) .header(Content-Type, application/json) .POST(HttpRequest.BodyPublishers.ofString(requestBody)) .build(); try { HttpResponseString response client.send(request, HttpResponse.BodyHandlers.ofString()); // 需要手动解析JSON响应 return parseResponse(response.body()); } catch (Exception e) { throw new RuntimeException(API调用失败, e); } } }这种方式的痛点很明显每个项目都要重复实现认证、重试、异常处理等基础逻辑模型切换成本高缺乏统一的对话状态管理。当需要实现复杂功能如流式响应、函数调用时代码会变得极其臃肿。1.2 Spring AI的架构价值Spring AI通过几个核心抽象解决了这些问题统一的ChatClient接口屏蔽不同模型API的差异PromptTemplate机制提供可复用的提示词模板Message抽象层统一处理对话历史和多轮交互函数调用支持将AI能力与业务逻辑无缝集成更重要的是Spring AI继承了Spring生态的配置管理、依赖注入、测试支持等成熟特性让AI应用开发能够遵循熟悉的工程规范。1.3 什么类型的项目最适合使用Spring AI根据实际项目经验Spring AI特别适合以下场景企业级AI应用需要稳定、可维护的代码结构有严格的工程规范要求Java技术栈团队不希望引入Python技术栈降低团队学习成本需要与现有Spring项目集成如微服务架构中的AI能力模块对响应时间和稳定性有要求Spring AI提供了连接池、熔断等企业级特性相反如果是纯粹的研究性质项目或对Python生态有强依赖的场景直接使用Python可能更合适。2. Spring AI 2.0核心概念与架构解析2.1 三层抽象架构Spring AI的架构可以理解为三个层次应用层 (Your Application) ↓ Spring AI抽象层 (ChatClient、PromptTemplate、Message) ↓ 具体模型适配层 (OpenAI、Azure、Ollama等)这种分层设计让业务代码与具体模型解耦。例如在开发环境可以使用本地的Ollama生产环境切换到OpenAI只需修改配置而无需改动业务代码。2.2 核心组件详解ChatClient是最重要的接口定义了几个关键方法public interface ChatClient { // 单次调用 String call(String message); // 支持完整消息历史的调用 ChatResponse call(ChatRequest request); // 流式响应适合实时交互场景 FluxChatResponse stream(ChatRequest request); }PromptTemplate解决了提示词管理的问题// 传统方式字符串拼接容易出错 String prompt 请帮 userName 分析 data 要求格式为 format; // Spring AI方式使用模板 PromptTemplate template new PromptTemplate(请帮{userName}分析{data}要求格式为{format}); Prompt prompt template.create(Map.of( userName, 张三, data, salesData, format, 表格 ));Message体系定义了对话的基本单元// 系统消息 - 设定AI角色 SystemMessage systemMsg new SystemMessage(你是一个专业的Java技术专家); // 用户消息 - 用户输入 UserMessage userMsg new UserMessage(请解释Spring AI的架构设计); // AI消息 - AI的回复 AiMessage aiMsg new AiMessage(Spring AI采用分层架构...); // 组装对话上下文 ListMessage messages Arrays.asList(systemMsg, userMsg, aiMsg);2.3 与Python LangChain的对比很多开发者会问Spring AI是不是Java版的LangChain从设计理念上看确实有相似之处但有几个关键差异特性Spring AILangChain技术栈纯Java/Spring生态Python生态学习曲线对Spring开发者友好需要学习Python企业级特性原生支持Spring安全、配置管理等需要额外集成社区生态相对较新但发展迅速成熟组件丰富部署方式可直接打包为JAR部署简单需要Python环境对于Java团队来说Spring AI降低了技术栈切换的成本但需要接受目前组件相对较少的现状。3. 环境准备与项目搭建3.1 基础环境要求Spring AI 2.0对环境的要求相对宽松Java: 17或更高版本推荐17 LTS构建工具: Maven 3.6 或 Gradle 7.xIDE: IntelliJ IDEA推荐或 Eclipse with Spring Tools模型接入: 需要相应的API密钥或本地模型部署3.2 创建Spring Boot项目最快的方式是使用Spring Initializr# 使用curl创建项目基础结构 curl https://start.spring.io/starter.zip \ -d dependenciesweb,ai \ -d typemaven-project \ -d languagejava \ -d bootVersion3.2.0 \ -d baseDirspring-ai-demo \ -o spring-ai-demo.zip unzip spring-ai-demo.zip cd spring-ai-demo或者手动在pom.xml中添加依赖?xml version1.0 encodingUTF-8? project xmlnshttp://maven.apache.org/POM/4.0.0 modelVersion4.0.0/modelVersion parent groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-parent/artifactId version3.2.0/version relativePath/ /parent groupIdcom.example/groupId artifactIdspring-ai-demo/artifactId version0.0.1-SNAPSHOT/version properties java.version17/java.version spring-ai.version0.8.1/spring-ai.version /properties dependencies dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency !-- Spring AI核心依赖 -- dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-openai-spring-boot-starter/artifactId version${spring-ai.version}/version /dependency dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-test/artifactId scopetest/scope /dependency /dependencies /project3.3 配置模型接入在application.yml中配置OpenAI接入# application.yml spring: ai: openai: api-key: ${OPENAI_API_KEY:your-api-key-here} chat: model: gpt-3.5-turbo options: temperature: 0.7 max-tokens: 1000 # 如果想使用Azure OpenAI服务 # spring: # ai: # azure: # openai: # api-key: ${AZURE_OPENAI_API_KEY} # endpoint: ${AZURE_OPENAI_ENDPOINT} # chat: # model: gpt-35-turbo重要安全提醒永远不要将API密钥硬编码在代码中。使用环境变量或配置中心管理敏感信息。3.4 验证环境配置创建简单的测试Controller验证环境// 文件路径src/main/java/com/example/demo/TestController.java package com.example.demo; import org.springframework.ai.chat.ChatClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; RestController public class TestController { private final ChatClient chatClient; public TestController(ChatClient chatClient) { this.chatClient chatClient; } GetMapping(/chat) public String chat(RequestParam String message) { return chatClient.call(message); } }启动应用并访问http://localhost:8080/chat?messageHello如果返回AI的回复说明环境配置成功。4. 从零开发第一个AI Agent4.1 什么是AI Agent在Spring AI语境中Agent不是神秘的概念而是指能够根据目标自主规划、使用工具、执行任务的AI程序。一个典型的Agent包含三个核心能力规划能力将复杂任务分解为可执行的步骤工具使用调用外部API或函数扩展AI能力记忆机制维护对话历史和任务状态4.2 实现一个天气查询Agent让我们实现一个实用的天气查询Agent它能够理解用户关于天气的询问调用天气API获取真实数据然后生成自然语言的回复。第一步定义工具接口// 文件路径src/main/java/com/example/demo/weather/WeatherService.java package com.example.demo.weather; import org.springframework.stereotype.Service; import org.springframework.web.client.RestTemplate; Service public class WeatherService { private final RestTemplate restTemplate new RestTemplate(); public WeatherData getWeather(String city) { // 这里使用模拟数据实际项目可以接入真实天气API // 例如和风天气、OpenWeatherMap等 String apiUrl https://api.example.com/weather?city city; // 模拟返回数据 return new WeatherData(city, 25, 晴, 60, 1013); } public static class WeatherData { private String city; private int temperature; private String condition; private int humidity; private int pressure; // 构造方法、getter、setter省略 public WeatherData(String city, int temperature, String condition, int humidity, int pressure) { this.city city; this.temperature temperature; this.condition condition; this.humidity humidity; this.pressure pressure; } // getter方法 public String getCity() { return city; } public int getTemperature() { return temperature; } public String getCondition() { return condition; } public int getHumidity() { return humidity; } public int getPressure() { return pressure; } } }第二步创建Agent类// 文件路径src/main/java/com/example/demo/agent/WeatherAgent.java package com.example.demo.agent; import org.springframework.ai.chat.ChatClient; import org.springframework.ai.chat.prompt.Prompt; import org.springframework.ai.chat.prompt.PromptTemplate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import com.example.demo.weather.WeatherService; import java.util.Map; Component public class WeatherAgent { private final ChatClient chatClient; private final WeatherService weatherService; Autowired public WeatherAgent(ChatClient chatClient, WeatherService weatherService) { this.chatClient chatClient; this.weatherService weatherService; } public String handleWeatherQuery(String userMessage) { // 第一步识别用户意图和城市信息 String city extractCityFromMessage(userMessage); if (city null) { return 请告诉我您想查询哪个城市的天气; } // 第二步调用天气服务获取数据 WeatherService.WeatherData weatherData weatherService.getWeather(city); // 第三步使用AI生成自然语言回复 PromptTemplate template new PromptTemplate( 用户询问{city}的天气情况。实际天气数据如下 - 温度{temperature}°C - 天气状况{condition} - 湿度{humidity}% - 气压{pressure}hPa 请用友好、自然的语言向用户回复天气情况并适当添加穿衣建议或出行提示。 ); Prompt prompt template.create(Map.of( city, city, temperature, weatherData.getTemperature(), condition, weatherData.getCondition(), humidity, weatherData.getHumidity(), pressure, weatherData.getPressure() )); return chatClient.call(prompt).getResult().getOutput().getContent(); } private String extractCityFromMessage(String message) { // 简单的城市提取逻辑实际项目可以使用更复杂的NLP技术 if (message.contains(北京)) return 北京; if (message.contains(上海)) return 上海; if (message.contains(广州)) return 广州; if (message.contains(深圳)) return 深圳; return null; } }第三步创建Controller暴露API// 文件路径src/main/java/com/example/demo/agent/WeatherAgentController.java package com.example.demo.agent; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; RestController RequestMapping(/api/agent) public class WeatherAgentController { Autowired private WeatherAgent weatherAgent; PostMapping(/weather) public String queryWeather(RequestBody WeatherQueryRequest request) { return weatherAgent.handleWeatherQuery(request.getMessage()); } public static class WeatherQueryRequest { private String message; // getter和setter public String getMessage() { return message; } public void setMessage(String message) { this.message message; } } }4.3 测试Agent功能使用curl测试Agentcurl -X POST http://localhost:8080/api/agent/weather \ -H Content-Type: application/json \ -d {message: 今天北京的天气怎么样}预期会得到类似这样的回复北京今天天气晴朗温度25°C湿度60%是个出门的好天气建议穿轻薄衣物。这个简单的Agent展示了Spring AI开发的核心模式识别用户意图 → 调用工具获取数据 → 使用AI生成自然语言回复。5. 高级特性函数调用与流式响应5.1 实现真正的函数调用前面的WeatherAgent虽然能工作但城市提取逻辑比较简陋。Spring AI支持真正的函数调用让AI自主决定何时调用工具。第一步定义函数工具// 文件路径src/main/java/com/example/demo/agent/WeatherFunction.java package com.example.demo.agent; import org.springframework.ai.chat.model.ChatResponse; import org.springframework.ai.chat.prompt.Prompt; import org.springframework.ai.model.function.FunctionCallback; import org.springframework.ai.model.function.FunctionCallbackContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Description; import java.util.function.Function; Configuration public class WeatherFunction { Bean Description(根据城市名称获取天气信息) // 这个描述很重要AI靠它理解函数用途 public FunctionWeatherRequest, WeatherResponse getWeather() { return request - { // 模拟天气数据实际项目调用真实API return new WeatherResponse(request.city(), 25, 晴朗, 60); }; } public record WeatherRequest(String city) {} public record WeatherResponse(String city, int temperature, String condition, int humidity) {} }第二步配置函数回调// 文件路径src/main/java/com/example/demo/config/FunctionConfig.java package com.example.demo.config; import org.springframework.ai.chat.client.ChatClient; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; Configuration public class FunctionConfig { Bean public ChatClient customChatClient(ChatClient.Builder chatClientBuilder) { return chatClientBuilder .build() .defaultFunctions(getWeather); // 注册函数 } }第三步使用函数调用// 增强的Agent实现 public String handleWeatherQueryWithFunction(String userMessage) { String systemPrompt 你是一个天气助手当用户询问天气时调用getWeather函数获取数据。 如果用户没有指定城市请询问具体城市。 ; Prompt prompt new Prompt(userMessage, new SystemMessage(systemPrompt)); ChatResponse response chatClient.call(prompt); return response.getResult().getOutput().getContent(); }5.2 实现流式响应对于需要实时反馈的场景流式响应能显著提升用户体验// 文件路径src/main/java/com/example/demo/agent/StreamingAgentController.java package com.example.demo.agent; import org.springframework.ai.chat.ChatClient; import org.springframework.ai.chat.ChatResponse; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; import reactor.core.publisher.Flux; RestController public class StreamingAgentController { private final ChatClient chatClient; public StreamingAgentController(ChatClient chatClient) { this.chatClient chatClient; } PostMapping(value /api/chat/stream, produces MediaType.TEXT_EVENT_STREAM_VALUE) public FluxString streamChat(RequestBody ChatRequest request) { return chatClient.stream(request.getMessage()) .map(ChatResponse::getResult) .map(result - result.getOutput().getContent()); } public static class ChatRequest { private String message; // getter/setter } }前端可以通过SSEServer-Sent Events接收流式响应// 前端示例代码 const eventSource new EventSource(/api/chat/stream?message你好); eventSource.onmessage function(event) { console.log(收到数据:, event.data); // 实时更新UI };6. 大模型微调在Java项目中的实战应用6.1 为什么需要在Java项目中做微调很多开发者认为微调是Python的专属领域但实际上Java项目在以下场景需要微调能力领域知识适配让通用大模型掌握行业特定术语和知识风格一致性确保AI生成内容符合企业文案风格任务特定优化针对特定任务类型如分类、提取优化模型表现6.2 基于Spring AI的微调方案Spring AI本身不提供微调功能但可以集成外部微调服务。这里以OpenAI微调API为例第一步准备训练数据// 文件路径src/main/java/com/example/demo/fine-tuning/TrainingDataPreparer.java package com.example.demo.fine-tuning; import org.springframework.stereotype.Component; import com.fasterxml.jackson.databind.ObjectMapper; import java.util.List; import java.util.Map; Component public class TrainingDataPreparer { private final ObjectMapper objectMapper new ObjectMapper(); public String prepareTrainingData(ListTrainingExample examples) { // 将训练数据转换为OpenAI要求的JSONL格式 StringBuilder jsonlBuilder new StringBuilder(); for (TrainingExample example : examples) { try { MapString, Object trainingRecord Map.of( messages, List.of( Map.of(role, system, content, example.getSystemPrompt()), Map.of(role, user, content, example.getUserInput()), Map.of(role, assistant, content, example.getAssistantOutput()) ) ); jsonlBuilder.append(objectMapper.writeValueAsString(trainingRecord)) .append(\n); } catch (Exception e) { throw new RuntimeException(训练数据格式转换失败, e); } } return jsonlBuilder.toString(); } public static class TrainingExample { private String systemPrompt; private String userInput; private String assistantOutput; // 构造方法、getter/setter } }第二步微调任务管理// 文件路径src/main/java/com/example/demo/fine-tuning/FineTuningService.java package com.example.demo.fine-tuning; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.*; import org.springframework.stereotype.Service; import org.springframework.web.client.RestTemplate; Service public class FineTuningService { Value(${spring.ai.openai.api-key}) private String apiKey; private final RestTemplate restTemplate new RestTemplate(); public String createFineTuningJob(String trainingFileId) { String url https://api.openai.com/v1/fine_tuning/jobs; // 构建微调请求 String requestBody String.format( { training_file: %s, model: gpt-3.5-turbo, hyperparameters: { n_epochs: 3 } } , trainingFileId); HttpHeaders headers new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); headers.setBearerAuth(apiKey); HttpEntityString entity new HttpEntity(requestBody, headers); ResponseEntityString response restTemplate.exchange( url, HttpMethod.POST, entity, String.class); return response.getBody(); } }第三步使用微调后的模型// 在application.yml中配置使用微调模型 spring: ai: openai: chat: model: ft:gpt-3.5-turbo:my-org:custom-model-name:1.06.3 实际项目中的微调策略根据项目经验微调需要遵循几个原则数据质量优于数量1000条高质量数据比10000条噪声数据更有效渐进式微调先在小数据集上验证效果再扩大规模持续评估建立评估体系监控微调效果版本管理对微调模型进行版本控制便于回滚7. 项目实战构建智能客服Agent系统7.1 系统架构设计让我们构建一个完整的智能客服系统展示Spring AI在真实项目中的应用用户界面 (Web/Mobile) ↓ Spring Boot Controller层 ↓ Agent调度器 (根据意图路由到不同Agent) ↓ 专业Agent集群 (产品咨询、技术支持、投诉处理) ↓ 工具层 (知识库查询、工单系统、用户信息)7.2 核心代码实现第一步定义基础Agent接口// 文件路径src/main/java/com/example/demo/customer/agent/SupportAgent.java package com.example.demo.customer.agent; public interface SupportAgent { String getName(); // Agent名称 boolean canHandle(String userMessage); // 判断是否能处理该消息 String handleMessage(String userMessage, String sessionId); // 处理消息 }第二步实现产品咨询Agent// 文件路径src/main/java/com/example/demo/customer/agent/ProductAgent.java package com.example.demo.customer.agent; import org.springframework.ai.chat.ChatClient; import org.springframework.ai.chat.prompt.Prompt; import org.springframework.ai.chat.prompt.SystemMessage; import org.springframework.stereotype.Component; Component public class ProductAgent implements SupportAgent { private final ChatClient chatClient; private final ProductService productService; public ProductAgent(ChatClient chatClient, ProductService productService) { this.chatClient chatClient; this.productService productService; } Override public String getName() { return 产品咨询Agent; } Override public boolean canHandle(String userMessage) { return userMessage.contains(产品) || userMessage.contains(购买) || userMessage.contains(价格) || userMessage.contains(功能); } Override public String handleMessage(String userMessage, String sessionId) { SystemMessage systemMsg new SystemMessage( 你是专业的产品咨询顾问负责回答用户关于产品的相关问题。 公司主要产品包括A系列面向企业、B系列面向个人。 回答时要专业、友好能够准确介绍产品特性和优势。 ); Prompt prompt new Prompt(userMessage, systemMsg); return chatClient.call(prompt).getResult().getOutput().getContent(); } }第三步实现Agent调度器// 文件路径src/main/java/com/example/demo/customer/AgentDispatcher.java package com.example.demo.customer; import org.springframework.stereotype.Component; import com.example.demo.customer.agent.SupportAgent; import java.util.List; Component public class AgentDispatcher { private final ListSupportAgent agents; public AgentDispatcher(ListSupportAgent agents) { this.agents agents; } public SupportAgent dispatch(String userMessage) { return agents.stream() .filter(agent - agent.canHandle(userMessage)) .findFirst() .orElseThrow(() - new RuntimeException(没有合适的Agent处理该消息)); } }第四步实现会话管理// 文件路径src/main/java/com/example/demo/customer/SessionManager.java package com.example.demo.customer; import org.springframework.stereotype.Component; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; Component public class SessionManager { private final MapString, ChatSession sessions new ConcurrentHashMap(); public ChatSession getOrCreateSession(String sessionId) { return sessions.computeIfAbsent(sessionId, id - new ChatSession(id)); } public static class ChatSession { private final String sessionId; private final StringBuilder history new StringBuilder(); public ChatSession(String sessionId) { this.sessionId sessionId; } public void addMessage(String role, String content) { history.append(role).append(: ).append(content).append(\n); } public String getHistory() { return history.toString(); } } }7.3 系统集成与测试创建完整的客服端点// 文件路径src/main/java/com/example/demo/customer/CustomerSupportController.java package com.example.demo.customer; import org.springframework.web.bind.annotation.*; RestController RequestMapping(/api/support) public class CustomerSupportController { private final AgentDispatcher dispatcher; private final SessionManager sessionManager; public CustomerSupportController(AgentDispatcher dispatcher, SessionManager sessionManager) { this.dispatcher dispatcher; this.sessionManager sessionManager; } PostMapping(/chat) public ChatResponse handleCustomerQuery(RequestBody ChatRequest request) { // 获取或创建会话 SessionManager.ChatSession session sessionManager.getOrCreateSession(request.getSessionId()); // 记录用户消息 session.addMessage(用户, request.getMessage()); // 分派到合适的Agent SupportAgent agent dispatcher.dispatch(request.getMessage()); String response agent.handleMessage(request.getMessage(), request.getSessionId()); // 记录AI回复 session.addMessage(客服, response); return new ChatResponse(response, agent.getName()); } public static class ChatRequest { private String sessionId; private String message; // getter/setter } public static class ChatResponse { private String response; private String handledBy; // 构造方法、getter/setter } }8. 性能优化与生产环境部署8.1 连接池与超时配置在生产环境中合理的HTTP客户端配置至关重要# application-prod.yml spring: ai: openai: chat: options: connect-timeout: 10s read-timeout: 30s # 自定义RestTemplate配置 Bean public RestTemplate restTemplate() { return new RestTemplateBuilder() .setConnectTimeout(Duration.ofSeconds(10)) .setReadTimeout(Duration.ofSeconds(30)) .build(); }8.2 缓存策略对于频繁查询的内容实现缓存机制// 文件路径src/main/java/com/example/demo/cache/ResponseCache.java package com.example.demo.cache; import org.springframework.stereotype.Component; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; Component public class ResponseCache { private final ConcurrentHashMapString, CacheEntry cache new ConcurrentHashMap(); public void put(String key, String value, long ttlMinutes) { cache.put(key, new CacheEntry(value, System.currentTimeMillis() TimeUnit.MINUTES.toMillis(ttlMinutes))); } public String get(String key) { CacheEntry entry cache.get(key); if (entry ! null entry.isValid()) { return entry.getValue(); } cache.remove(key); // 清理过期条目 return null; } private static class CacheEntry { private final String value; private final long expiryTime; public CacheEntry(String value, long expiryTime) { this.value value; this.expiryTime expiryTime; } public String getValue() { return value; } public boolean isValid() { return System.currentTimeMillis() expiryTime; } } }8.3 监控与日志添加详细的日志记录和监控指标// 文件路径src/main/java/com/example/demo/monitoring/AiMetrics.java package com.example.demo.monitoring; import org.springframework.stereotype.Component; import io.micrometer.core.instrument.Counter; import io.micrometer.core.instrument.MeterRegistry; Component public class AiMetrics { private final Counter apiCallCounter; private final Counter errorCounter; public AiMetrics(MeterRegistry registry) { this.apiCallCounter Counter.builder(ai.api.calls) .description(AI API调用次数) .register(registry); this.errorCounter Counter.builder(ai.api.errors) .description(AI API调用错误次数) .register(registry); } public void recordApiCall() { apiCallCounter.increment(); } public void recordError() { errorCounter.increment(); } }9. 常见问题与解决方案9.1 依赖冲突问题Spring AI可能与其他Spring组件产生依赖冲突解决方案!-- 在pom.xml中排除冲突依赖 -- dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-openai-spring-boot-starter/artifactId version${spring-ai.version}/version exclusions exclusion groupIdorg.springframework/groupId artifactIdspring-core/artifactId /exclusion /exclusions /dependency9.2 API限流处理实现简单的限流和重试机制// 文件路径src/main/java/com/example/demo/retry/RetryableChatClient.java package com.example.demo.retry; import org.springframework.ai.chat.ChatClient; import org.springframework.ai.chat.ChatResponse; import org.springframework.ai.chat.ChatRequest; import org.springframework.retry.annotation.Backoff; import org.springframework.retry.annotation.Retryable; import org.springframework.stereotype.Component; Component public class RetryableChatClient { private final ChatClient chatClient; public RetryableChatClient(ChatClient chatClient) { this.chatClient chatClient; } Retryable( value {Exception.class}, maxAttempts 3, backoff Backoff(delay 1000, multiplier 2) ) public String callWithRetry(String message) { return chatClient.call(message); } }9.3 内存优化处理大模型响应时的内存管理// 使用流式处理避免大内存占用 public void processLargeResponse(String sessionId) { chatClient.stream(生成大量内容) .window(100) // 每100个字符处理一次 .subscribe(chunk - { // 增量处理避免内存峰值 saveToDatabase(sessionId, chunk); }); }10. 最佳实践总结经过多个项目的实践验证以下Spring AI开发经验值得分享工程规范方面严格遵循配置外部化原则敏感信息通过环境变量管理为不同的Agent建立清晰的职责边界和接口规范实现完整的日志记录和监控体系性能优化方面合理使用缓存减少API调用次数实现连接池和超时控制对耗时操作采用异步处理用户体验方面重要交互场景使用流式响应实现会话状态管理保证连续性提供fallback机制确保服务可用性团队协作方面建立提示词模板库避免重复工作制定Agent开发规范保证代码一致性创建共享的工具函数库Spring AI 2.0为Java开发者提供了进入AI应用开发的高效路径关键在于理解其设计哲学而非简单调用API。真正的价值在于将AI能力有机融入现有技术栈在保持工程规范的同时提升智能水平。建议从简单的Agent开始实践逐步掌握函数调用、流式响应等高级特性最终构建出真正解决业务问题的智能系统。随着Spring AI生态的成熟Java开发者在大模型时代的技术竞争力将得到显著提升。
网站建设高端定制企业官网