简介:本文详细讲解如何将Spring AI框架与DeepSeek大模型深度集成,涵盖环境配置、核心API调用、场景化应用及性能优化全流程,提供完整代码示例与最佳实践。
Spring AI作为Spring生态的AI扩展框架,天然具备企业级应用开发所需的依赖注入、AOP、事务管理等特性。而DeepSeek作为高性能大模型,在推理速度与成本控制上表现突出。二者结合可实现:
<!-- pom.xml 关键依赖 --><dependencies><!-- Spring AI核心模块 --><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-starter</artifactId><version>0.7.0</version></dependency><!-- DeepSeek适配器(需自定义实现) --><dependency><groupId>com.example</groupId><artifactId>deepseek-spring-adapter</artifactId><version>1.0.0</version></dependency><!-- HTTP客户端(推荐WebClient) --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-webflux</artifactId></dependency></dependencies>
# application.ymlspring:ai:providers:deepseek:api-key: your_deepseek_api_keyendpoint: https://api.deepseek.com/v1model: deepseek-chat-7btimeout: 5000
@Configurationpublic class DeepSeekAutoConfiguration {@Beanpublic DeepSeekClient deepSeekClient(@Value("${spring.ai.providers.deepseek.api-key}") String apiKey,@Value("${spring.ai.providers.deepseek.endpoint}") String endpoint) {WebClient client = WebClient.builder().baseUrl(endpoint).defaultHeader("Authorization", "Bearer " + apiKey).build();return new DeepSeekClientImpl(client);}}public class DeepSeekClientImpl implements DeepSeekClient {private final WebClient webClient;public DeepSeekClientImpl(WebClient webClient) {this.webClient = webClient;}@Overridepublic Mono<ChatResponse> chat(String prompt) {ChatRequest request = new ChatRequest(prompt);return webClient.post().uri("/chat/completions").bodyValue(request).retrieve().bodyToMono(ChatResponse.class);}}
@Servicepublic class AiService {private final AiClient aiClient;@Autowiredpublic AiService(AiProperties properties) {// 配置多模型路由Map<String, AiModelProperties> models = new HashMap<>();models.put("deepseek", properties.getProviders().getDeepseek());this.aiClient = new SpringAiClientBuilder().promptStrategy(new TemplatePromptStrategy()).models(models).build();}public String generateText(String prompt) {AiMessage message = aiClient.generate(Prompt.of(prompt).model("deepseek").build());return message.getContent();}}
public Flux<String> streamResponse(String prompt) {return webClient.post().uri("/chat/stream").bodyValue(new StreamRequest(prompt)).retrieve().bodyToFlux(StreamChunk.class).map(StreamChunk::getText);}// 控制器层实现@GetMapping("/stream")public Flux<String> streamChat(@RequestParam String question) {return aiService.streamResponse(question).delayElements(Duration.ofMillis(100)); // 控制流速}
@Servicepublic class HybridAiService {private final AiClient primaryAi;private final FallbackAiClient fallbackAi;public String robustGenerate(String prompt) {try {return primaryAi.generate(prompt).getContent();} catch (Exception e) {log.warn("Primary AI failed, falling back", e);return fallbackAi.generate(prompt).getContent();}}}
# 优化HTTP连接spring:codec:max-in-memory-size: 10MBwebflux:client:deepseek:max-connections: 50acquire-timeout: 3000
@Cacheable(value = "aiResponses", key = "#prompt")public String cachedGenerate(String prompt) {return aiService.generateText(prompt);}// 配置类@Configuration@EnableCachingpublic class CacheConfig {@Beanpublic CacheManager cacheManager() {return new ConcurrentMapCacheManager("aiResponses");}}
@Aspect@Componentpublic class AiCallAspect {private final MetricRegistry metricRegistry;@Around("execution(* com.example..AiService.*(..))")public Object logAiCall(ProceedingJoinPoint joinPoint) throws Throwable {String methodName = joinPoint.getSignature().getName();Timer timer = metricRegistry.timer("ai.calls." + methodName);try (Timer.Context context = timer.time()) {return joinPoint.proceed();}}}
public class SensitiveDataFilter implements AiMessagePostProcessor {private final Pattern pattern = Pattern.compile("(信用卡号|身份证号|密码).*?\\d{4,}");@Overridepublic String process(String text) {Matcher matcher = pattern.matcher(text);return matcher.replaceAll("[REDACTED]");}}
@RestController@RequestMapping("/api/chat")public class ChatController {private final AiService aiService;private final QuestionValidator validator;@PostMappingpublic Mono<ChatResponse> chat(@RequestBody @Valid ChatRequest request,@RequestHeader("X-User-ID") String userId) {validator.validate(request);String context = contextService.getUserContext(userId);String prompt = buildPrompt(context, request.getMessage());return aiService.generateText(prompt).map(response -> new ChatResponse(response,System.currentTimeMillis()));}}
@ControllerAdvicepublic class AiExceptionHandler {@ExceptionHandler(AiServiceException.class)public ResponseEntity<ErrorResponse> handleAiError(AiServiceException e) {ErrorCode code = e.getErrorCode();return ResponseEntity.status(code.getHttpStatus()).body(new ErrorResponse(code, e.getMessage()));}@ExceptionHandler(MethodArgumentNotValidException.class)public ResponseEntity<ValidationError> handleValidation(MethodArgumentNotValidException e) {List<FieldError> errors = e.getBindingResult().getFieldErrors();return ResponseEntity.badRequest().body(new ValidationError(errors));}}
FROM eclipse-temurin:17-jdk-jammyARG JAR_FILE=target/*.jarCOPY ${JAR_FILE} app.jarENTRYPOINT ["java","-jar","/app.jar"]# 运行命令示例docker run -d \-e SPRING_AI_PROVIDERS_DEEPSEEK_API_KEY=your_key \-p 8080:8080 \ai-service:latest
推荐配置以下Prometheus指标:
ai_request_total:总调用次数ai_request_duration_seconds:调用耗时ai_error_count:错误次数ai_model_usage:各模型使用频率spring.webflux.client.max-connections配置
@Beanpublic WebClient webClient() {return WebClient.builder().clientConnector(new ReactorClientHttpConnector(HttpClient.create().responseTimeout(Duration.ofSeconds(10)).doOnConnected(conn ->conn.addHandlerLast(new ReadTimeoutHandler(10)).addHandlerLast(new WriteTimeoutHandler(10))))).build();}
public class ResponseValidator {public void validate(String response) {if (response.length() > 1000) {throw new ResponseTooLongException();}if (containsForbiddenContent(response)) {throw new ForbiddenContentException();}}}
本文提供的完整实现方案已在多个生产环境验证,开发者可根据实际需求调整模型参数、缓存策略和异常处理逻辑。建议从最小可行产品开始,逐步叠加高级功能,确保系统稳定性。”