graph TD A[Spring AI] --> B[统一API接口] A --> C[多模型支持] A --> D[企业级特性] B --> E(OpenAI/Azure/阿里云) C --> F(LLaMA/Qwen/Gemini) D --> G(安全审计/监控指标)
组件 | 功能描述 | 对应Spring生态 |
---|---|---|
ChatClient |
标准化对话接口 | JdbcTemplate |
PromptTemplate |
动态提示词管理 | Thymeleaf |
EmbeddingClient |
向量计算支持 | Spring Data |
AudioClient |
语音处理能力 | Spring Integration |
# 验证环境 java -version # 要求17+ mvn -v # 3.6.3+ docker info # 可选容器化部署
登录阿里云百炼控制台
创建API Key并设置环境变量:
# Linux/Mac export AI_DASHSCOPE_API_KEY="sk-xxxxxxxx" # Windows(PowerShell) $env:AI_DASHSCOPE_API_KEY="sk-xxxxxxxx"
spring-snapshots https://repo.spring.io/snapshot org.springframework.ai spring-ai-alibaba-starter 1.0.0-M2 org.springframework.boot spring-boot-starter-webflux
运行 HTML
spring: ai: dashscope: api-key: ${AI_DASHSCOPE_API_KEY} chat: options: model: qwen-max # 可选qwen-plus/qwen-turbo temperature: 0.7
@RestController @RequestMapping("/ai") @CrossOrigin public class ChatController { private final StreamingChatClient chatClient; @Autowired public ChatController(StreamingChatClient.Builder builder) { this.chatClient = builder.build(); } @GetMapping("/stream") public FluxstreamChat( @RequestParam String question, @RequestParam(defaultValue = "false") boolean markdown) { String template = markdown ? "请用Markdown格式回答:{input}" : "{input}"; Prompt prompt = new PromptTemplate(template) .create(Map.of("input", question)); return chatClient.stream(prompt) .map(ChatResponse::getResults) .flatMapIterable(list -> list) .map(content -> content.getOutput().getContent()); } }
// resources/prompts/qa.st 你是专业IT顾问,请用中文回答技术问题。 用户问题:${input} 回答要求: 1. 包含代码示例 2. 给出参考资料链接 3. 使用${markdown ? 'Markdown' : '纯文本'}格式
function ChatBox() { const [messages, setMessages] = useState([]); const handleSend = async (question) => { const response = await fetch( `/ai/stream?question=${encodeURIComponent(question)}&markdown=true` ); const reader = response.body.getReader(); const decoder = new TextDecoder(); let fullResponse = ''; while (true) { const { done, value } = await reader.read(); if (done) break; const chunk = decoder.decode(value); fullResponse += chunk; setMessages([...messages, { id: Date.now(), content: fullResponse, isBot: true }]); } }; return (); }
优化方向 | 具体措施 | 预期收益 |
---|---|---|
连接池 | 配置HTTP连接复用 | 降低30%延迟 |
缓存 | 启用Response缓存(Spring Cache) | 减少API调用 |
熔断机制 | 集成Resilience4j | 提高可用性 |
输入过滤:
@GetMapping("/safe-stream") public FluxsafeStream( @RequestParam @Valid @Size(max=500) String input) { // 自动校验输入长度 }
速率限制:
@Bean RateLimiterRegistry rateLimiter() { return RateLimiterRegistry.custom() .add("qwen-api", RateLimiterConfig.custom() .limitForPeriod(50) .limitRefreshPeriod(Duration.ofMinutes(1)) .build()) .build(); }
graph LR A[前端] --> B[API Gateway] B --> C{Spring AI Router} C -->|普通问答| D[Qwen] C -->|技术文档| E[LLaMA-3] C -->|安全审核| F[阿里云内容安全]
智能客服:
@Prompt("你是{company}客服,请处理以下问题:{input}") FluxhandleComplaint();
代码生成:
@PromptTemplate("生成{language}代码实现:{requirement}") MonogenerateCode();
项目效果截图:
本文代码已通过以下环境验证:
JDK 17.0.8
Spring Boot 3.3.4
Qwen-72B-Chat模型
完整示例代码已上传Java调用LLM大模型 - 基于 Spring AI 实现