
1. Spring AI实战构建智能对话系统的完整指南在当今企业级应用开发中整合AI能力已成为提升产品竞争力的关键。Spring AI作为Spring生态中的AI集成框架为Java开发者提供了便捷的大模型接入方案。本文将深入探讨如何基于Spring AI构建具备对话交互、提示词优化、API调用和文件处理能力的智能系统。2. 环境准备与基础配置2.1 项目初始化首先创建一个标准的Spring Boot项目推荐使用Spring Initializrhttps://start.spring.io生成项目骨架。关键依赖包括dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-core/artifactId version0.8.1/version /dependency dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-openai-spring-boot-starter/artifactId version0.8.1/version /dependency2.2 配置API密钥在application.yml中配置大模型服务凭证spring: ai: openai: api-key: ${OPENAI_API_KEY} base-url: https://api.openai.com/v1提示实际项目中建议使用Vault或配置中心管理敏感信息不要将密钥硬编码在配置文件中3. 核心功能实现3.1 基础对话服务创建ChatService实现基础对话功能Service public class ChatService { private final ChatClient chatClient; public ChatService(ChatClient chatClient) { this.chatClient chatClient; } public String generate(String message) { Prompt prompt new Prompt(new UserMessage(message)); return chatClient.call(prompt).getResult().getOutput().getContent(); } }3.2 提示词工程实践Spring AI提供了强大的提示词模板功能Bean public PromptTemplate customerServicePrompt() { return new PromptTemplate( 你是一名专业的客服代表请用{language}回答关于{product}的问题。 用户问题{question} 回答时要遵守以下规则 1. 保持友好和专业 2. 不超过100字 3. 包含至少一个使用场景示例 ); }使用方式MapString, Object params new HashMap(); params.put(language, 中文); params.put(product, 智能手表); params.put(question, 如何设置心率监测); String response customerServicePrompt().render(params); String result chatClient.call(new Prompt(response)).getResult().getOutput().getContent();4. 高级功能实现4.1 文件内容处理Spring AI支持多种文档格式的解析Service public class DocumentService { private final VectorStore vectorStore; private final EmbeddingClient embeddingClient; public DocumentService(VectorStore vectorStore, EmbeddingClient embeddingClient) { this.vectorStore vectorStore; this.embeddingClient embeddingClient; } public void processDocument(Resource document) { // 文档解析和向量化 DocumentReader reader new PdfDocumentReader(document); ListDocument documents reader.get(); // 存储向量化结果 vectorStore.add(documents.stream() .map(doc - new Embedding(doc.getContent(), embeddingClient.embed(doc.getContent()))) .collect(Collectors.toList())); } public ListString searchDocument(String query) { // 语义搜索 return vectorStore.similaritySearch(query).stream() .map(Embedding::getContent) .collect(Collectors.toList()); } }4.2 自定义API调用对于需要直接调用大模型API的场景RestController RequestMapping(/api/ai) public class AIController { PostMapping(/complete) public ResponseEntityString completeText(RequestBody CompletionRequest request) { OpenAiApi openAiApi new OpenAiApi(https://api.openai.com/v1); CompletionRequest apiRequest new CompletionRequest.Builder() .withModel(request.getModel()) .withPrompt(request.getPrompt()) .withMaxTokens(request.getMaxTokens()) .build(); CompletionResult result openAiApi.createCompletion(apiRequest).block(); return ResponseEntity.ok(result.getChoices().get(0).getText()); } }5. 性能优化与最佳实践5.1 对话历史管理实现有记忆的对话系统Service Scope(value WebApplicationContext.SCOPE_SESSION, proxyMode ScopedProxyMode.TARGET_CLASS) public class SessionChatService { private final ListMessage history new ArrayList(); public String chat(String message) { history.add(new UserMessage(message)); Prompt prompt new Prompt(history); ChatResponse response chatClient.call(prompt); history.add(response.getResult().getOutput()); return response.getResult().getOutput().getContent(); } }5.2 流式响应处理对于长文本生成场景使用流式响应提升用户体验GetMapping(/stream) public SseEmitter streamCompletion(RequestParam String prompt) { SseEmitter emitter new SseEmitter(); FluxChatResponse flux chatClient.stream(new Prompt(prompt)); flux.subscribe( response - { try { emitter.send(response.getResult().getOutput().getContent()); } catch (IOException e) { emitter.completeWithError(e); } }, emitter::completeWithError, emitter::complete ); return emitter; }6. 常见问题排查6.1 性能问题诊断当遇到响应延迟时可按照以下步骤排查检查网络延迟记录API调用往返时间分析提示词复杂度过长的提示词会增加处理时间监控Token使用量大模型通常按Token计费和处理检查模型选择较大模型虽然能力强但响应慢6.2 错误处理策略实现全局异常处理器ControllerAdvice public class AIExceptionHandler { ExceptionHandler(ApiException.class) public ResponseEntityErrorResponse handleApiException(ApiException ex) { return ResponseEntity.status(ex.getStatusCode()) .body(new ErrorResponse(ex.getMessage())); } ExceptionHandler(RateLimitException.class) public ResponseEntityErrorResponse handleRateLimit(RateLimitException ex) { return ResponseEntity.status(429) .header(Retry-After, String.valueOf(ex.getRetryAfter())) .body(new ErrorResponse(请求过于频繁请稍后再试)); } }7. 部署与扩展7.1 容器化部署创建Dockerfile实现容器化FROM eclipse-temurin:17-jdk-jammy WORKDIR /app COPY target/spring-ai-demo.jar app.jar ENTRYPOINT [java, -jar, app.jar]7.2 水平扩展策略当需要处理高并发请求时使用Redis实现对话状态共享配置API网关的限流规则考虑使用消息队列异步处理非实时请求对大模型响应实现本地缓存8. 安全注意事项输入验证所有用户输入都应进行严格的验证和清理输出过滤对模型生成内容进行适当过滤权限控制敏感操作需要身份验证日志审计记录所有AI交互的关键信息在实际项目中我发现Spring AI的PromptTemplate对中文支持需要特别注意标点符号的处理。建议在复杂提示词中使用多行字符串语法可以避免很多格式问题。另外对于文件处理功能PDF解析对中文文档的兼容性最好而Word文档需要注意不同版本间的格式差异。