最近在开发一个需要大语言模型能力的项目,选择了DeepSeek的API作为技术方案。这个项目基于Spring Boot框架实现,主要目标是构建一个稳定可靠的API调用系统。在实际开发过程中,我发现虽然DeepSeek官方文档提供了基础调用示例,但在企业级应用中还需要考虑很多额外因素。
DeepSeek API提供了强大的自然语言处理能力,特别适合需要中文场景的应用。相比其他方案,它有以下几个优势:
选择Spring Boot作为基础框架主要基于以下考虑:
我设计了一个三层封装结构来调用DeepSeek API:
java复制public class DeepSeekService {
private final RestTemplate restTemplate;
public CompletionResponse generateText(CompletionRequest request) {
// 1. 参数校验
validateRequest(request);
// 2. 设置请求头
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.set("Authorization", "Bearer " + apiKey);
// 3. 构建请求体
HttpEntity<CompletionRequest> entity = new HttpEntity<>(request, headers);
// 4. 发送请求
ResponseEntity<CompletionResponse> response = restTemplate.postForEntity(
API_ENDPOINT, entity, CompletionResponse.class);
// 5. 处理响应
return processResponse(response);
}
}
针对API调用可能出现的各种异常,我实现了完善的错误处理:
java复制@ControllerAdvice
public class ApiExceptionHandler {
@ExceptionHandler(HttpClientErrorException.class)
public ResponseEntity<ErrorResponse> handleApiError(HttpClientErrorException ex) {
if(ex.getStatusCode() == HttpStatus.TOO_MANY_REQUESTS) {
return new ResponseEntity<>(
new ErrorResponse("API调用频率超限,请稍后再试"),
HttpStatus.TOO_MANY_REQUESTS);
}
// 其他错误处理...
}
}
为了提升API调用效率,我优化了RestTemplate的连接池配置:
yaml复制# application.yml
http:
pool:
max-total: 100
default-max-per-route: 20
validate-after-inactivity: 5000
针对重复性请求,实现了两级缓存:
采用Vault进行密钥管理,避免硬编码:
java复制@Configuration
public class ApiConfig {
@Value("${vault.path.deepseek-api-key}")
private String vaultPath;
@Bean
public String deepseekApiKey(VaultTemplate vaultTemplate) {
return vaultTemplate.read(vaultPath)
.getData()
.get("value")
.toString();
}
}
使用Guava RateLimiter实现客户端限流:
java复制public class RateLimitedDeepSeekService {
private final RateLimiter rateLimiter;
public RateLimitedDeepSeekService(int permitsPerSecond) {
this.rateLimiter = RateLimiter.create(permitsPerSecond);
}
public CompletionResponse generateText(CompletionRequest request) {
if(!rateLimiter.tryAcquire()) {
throw new RateLimitExceededException();
}
return delegate.generateText(request);
}
}
集成Micrometer监控API调用指标:
java复制@Bean
public MeterBinder deepSeekMetrics(DeepSeekService service) {
return registry -> {
Gauge.builder("deepseek.api.latency", service::getAverageLatency)
.register(registry);
Counter.builder("deepseek.api.errors")
.register(registry);
};
}
使用Logback实现结构化日志:
xml复制<appender name="JSON" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="net.logstash.logback.encoder.LogstashEncoder">
<fieldNames>
<timestamp>time</timestamp>
<message>msg</message>
<logger>logger</logger>
<level>level</level>
<thread>thread</thread>
</fieldNames>
</encoder>
</appender>
使用Mockito模拟API响应:
java复制@Test
public void testGenerateText() {
// 准备模拟响应
CompletionResponse mockResponse = new CompletionResponse();
mockResponse.setChoices(List.of(new Choice("测试响应")));
// 设置Mock
when(restTemplate.postForEntity(anyString(), any(), any()))
.thenReturn(ResponseEntity.ok(mockResponse));
// 执行测试
CompletionResponse response = service.generateText(new CompletionRequest());
// 验证结果
assertEquals("测试响应", response.getChoices().get(0).getText());
}
使用Testcontainers进行真实API测试:
java复制@Testcontainers
@SpringBootTest
public class DeepSeekIntegrationTest {
@Autowired
private DeepSeekService service;
@Test
void testRealApiCall() {
CompletionRequest request = new CompletionRequest();
request.setPrompt("你好");
request.setMaxTokens(50);
CompletionResponse response = service.generateText(request);
assertNotNull(response);
assertFalse(response.getChoices().isEmpty());
}
}
使用Spring Profile管理不同环境配置:
yaml复制# application-prod.yml
deepseek:
api:
endpoint: https://api.deepseek.com/v1
timeout: 5000
# application-dev.yml
deepseek:
api:
endpoint: https://sandbox.deepseek.com/v1
timeout: 10000
实现自定义健康检查指标:
java复制@Component
public class DeepSeekHealthIndicator implements HealthIndicator {
@Override
public Health health() {
try {
// 简单ping测试
restTemplate.getForObject(API_ENDPOINT + "/ping", String.class);
return Health.up().build();
} catch (Exception e) {
return Health.down(e).build();
}
}
}
在项目开发过程中,我积累了一些宝贵经验:
超时设置:API调用超时建议设置在3-5秒,太短会导致频繁超时,太长会影响用户体验
重试策略:对于可重试的错误(如429、502等),建议使用指数退避算法重试2-3次
输入验证:特别注意prompt长度限制,超过限制会导致API返回错误
流式处理:对于长文本生成,使用流式API可以显著提升用户体验
成本控制:监控token使用量,避免意外的高额账单
这个基础实现还可以进一步扩展:
这个项目让我深刻体会到,一个好的API集成不仅仅是简单的HTTP调用,还需要考虑性能、安全、监控等各个方面。Spring Boot的丰富生态让这些工作变得简单高效。