Spring AI集成OpenAI:实现语音与文字的双向转换

Spring AI接入OpenAI实现文字转语音、语音转文字功能

一、技术背景与需求分析

在智能化应用场景中,语音与文字的双向转换已成为核心需求。例如,智能客服需要实时将用户语音转为文字并生成语音回复,教育平台需支持课程内容的语音合成与交互。OpenAI提供的Whisper(ASR)和TTS(Text-to-Speech)API为开发者提供了高精度的解决方案,而Spring AI作为轻量级Java框架,可简化API调用流程,提升开发效率。

1.1 OpenAI API的核心能力

  • Whisper模型:支持100+种语言的语音识别,具备抗噪声能力,适用于会议记录、语音指令等场景。
  • TTS模型:生成自然流畅的语音,支持多种音色和语速调节,可定制化输出格式(如MP3、WAV)。

1.2 Spring AI的集成优势

  • 简化配置:通过依赖注入管理API密钥、请求参数等配置。
  • 统一接口:抽象OpenAI API的调用细节,提供类型安全的Java方法。
  • 扩展性:支持自定义拦截器处理响应数据或错误。

二、开发环境准备

2.1 依赖配置

在Maven项目的pom.xml中添加Spring AI和OpenAI客户端依赖:

  1. <dependencies>
  2. <!-- Spring AI核心库 -->
  3. <dependency>
  4. <groupId>org.springframework.ai</groupId>
  5. <artifactId>spring-ai-core</artifactId>
  6. <version>0.7.0</version>
  7. </dependency>
  8. <!-- OpenAI Java客户端 -->
  9. <dependency>
  10. <groupId>com.theokanning.openai-api</groupId>
  11. <artifactId>openai-client</artifactId>
  12. <version>0.11.0</version>
  13. </dependency>
  14. </dependencies>

2.2 配置OpenAI API密钥

application.properties中设置密钥(建议通过环境变量注入):

  1. openai.api-key=${OPENAI_API_KEY}
  2. openai.organization-id=${OPENAI_ORG_ID}

三、文字转语音(TTS)实现

3.1 核心代码实现

通过Spring AI调用OpenAI TTS API的步骤如下:

3.1.1 创建TTS服务类

  1. import com.theokanning.openai.service.OpenAiService;
  2. import com.theokanning.openai.speech.CreateSpeechRequest;
  3. import com.theokanning.openai.speech.SpeechResponse;
  4. import org.springframework.beans.factory.annotation.Value;
  5. import org.springframework.stereotype.Service;
  6. @Service
  7. public class TtsService {
  8. private final OpenAiService openAiService;
  9. public TtsService(@Value("${openai.api-key}") String apiKey) {
  10. this.openAiService = new OpenAiService(apiKey);
  11. }
  12. public byte[] textToSpeech(String text, String voice, String format) {
  13. CreateSpeechRequest request = CreateSpeechRequest.builder()
  14. .model("tts-1") // 或 tts-1-hd(高清版)
  15. .input(text)
  16. .voice(voice) // 例如 "alloy"、"echo"、"fable"
  17. .responseFormat(format) // "mp3", "opus", "aac", "flac"
  18. .build();
  19. SpeechResponse response = openAiService.createSpeech(request);
  20. return response.getAudio();
  21. }
  22. }

3.1.2 控制器层调用

  1. import org.springframework.web.bind.annotation.*;
  2. import org.springframework.http.ResponseEntity;
  3. import org.springframework.http.MediaType;
  4. @RestController
  5. @RequestMapping("/api/tts")
  6. public class TtsController {
  7. private final TtsService ttsService;
  8. public TtsController(TtsService ttsService) {
  9. this.ttsService = ttsService;
  10. }
  11. @GetMapping(value = "/generate", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
  12. public ResponseEntity<byte[]> generateSpeech(
  13. @RequestParam String text,
  14. @RequestParam(defaultValue = "alloy") String voice,
  15. @RequestParam(defaultValue = "mp3") String format) {
  16. byte[] audio = ttsService.textToSpeech(text, voice, format);
  17. return ResponseEntity.ok()
  18. .header("Content-Type", "audio/" + format)
  19. .body(audio);
  20. }
  21. }

3.2 关键参数说明

  • 模型选择tts-1(标准版)与tts-1-hd(高清版)的音质差异。
  • 音色库:OpenAI提供6种预设音色,可通过voice参数指定。
  • 响应格式:推荐使用MP3以兼容多数设备。

四、语音转文字(ASR)实现

4.1 核心代码实现

4.1.1 创建ASR服务类

  1. import com.theokanning.openai.service.OpenAiService;
  2. import com.theokanning.openai.audio.CreateTranscriptionRequest;
  3. import com.theokanning.openai.audio.TranscriptionResponse;
  4. import org.springframework.stereotype.Service;
  5. @Service
  6. public class AsrService {
  7. private final OpenAiService openAiService;
  8. public AsrService(@Value("${openai.api-key}") String apiKey) {
  9. this.openAiService = new OpenAiService(apiKey);
  10. }
  11. public String speechToText(byte[] audioData, String language, String model) {
  12. CreateTranscriptionRequest request = CreateTranscriptionRequest.builder()
  13. .file(audioData)
  14. .model(model) // 推荐 "whisper-1"
  15. .language(language) // 可选,如 "zh"、"en"
  16. .prompt("请识别以下内容") // 可选提示词
  17. .temperature(0.0f) // 确定性输出
  18. .build();
  19. TranscriptionResponse response = openAiService.createTranscription(request);
  20. return response.getText();
  21. }
  22. }

4.1.2 控制器层调用

  1. import org.springframework.web.bind.annotation.*;
  2. import org.springframework.web.multipart.MultipartFile;
  3. @RestController
  4. @RequestMapping("/api/asr")
  5. public class AsrController {
  6. private final AsrService asrService;
  7. public AsrController(AsrService asrService) {
  8. this.asrService = asrService;
  9. }
  10. @PostMapping("/transcribe")
  11. public String transcribeAudio(
  12. @RequestParam("file") MultipartFile file,
  13. @RequestParam(defaultValue = "zh") String language) {
  14. try {
  15. byte[] audioBytes = file.getBytes();
  16. return asrService.speechToText(audioBytes, language, "whisper-1");
  17. } catch (Exception e) {
  18. throw new RuntimeException("音频处理失败", e);
  19. }
  20. }
  21. }

4.2 优化建议

  • 文件格式支持:Whisper支持MP3、WAV、FLAC等格式,需在前端校验文件类型。
  • 长音频处理:对于超过25MB的音频,建议分段处理或使用流式API(需OpenAI高级权限)。
  • 语言检测:若未指定language参数,Whisper会自动检测语种。

五、最佳实践与性能优化

5.1 错误处理机制

  • 重试策略:对网络超时或API限流错误实现指数退避重试。
  • 日志记录:记录API调用耗时、错误码等指标,便于问题排查。

5.2 缓存策略

  • TTS缓存:对常用文本(如固定提示语)缓存生成的音频文件。
  • ASR缓存:对重复音频片段存储识别结果。

5.3 安全性考虑

  • API密钥保护:通过Vault或KMS管理密钥,避免硬编码。
  • 输入验证:校验文本长度、音频大小等参数,防止恶意请求。

六、完整示例:智能客服场景

6.1 业务流程

  1. 用户上传语音问题 → ASR识别为文字。
  2. 系统生成文字回复 → TTS转为语音。
  3. 返回语音响应至用户。

6.2 代码实现

  1. @RestController
  2. @RequestMapping("/api/chat")
  3. public class ChatController {
  4. private final AsrService asrService;
  5. private final TtsService ttsService;
  6. private final ChatService chatService; // 假设的对话逻辑服务
  7. public ChatController(AsrService asrService, TtsService ttsService, ChatService chatService) {
  8. this.asrService = asrService;
  9. this.ttsService = ttsService;
  10. this.chatService = chatService;
  11. }
  12. @PostMapping(value = "/voice-chat", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
  13. public ResponseEntity<byte[]> voiceChat(
  14. @RequestParam("file") MultipartFile audioFile,
  15. @RequestParam(defaultValue = "zh") String language) {
  16. // 1. 语音转文字
  17. String question = asrService.speechToText(
  18. audioFile.getBytes(), language, "whisper-1");
  19. // 2. 生成回复文本
  20. String answer = chatService.generateAnswer(question);
  21. // 3. 文字转语音
  22. byte[] audioResponse = ttsService.textToSpeech(answer, "alloy", "mp3");
  23. return ResponseEntity.ok()
  24. .header("Content-Type", "audio/mp3")
  25. .body(audioResponse);
  26. }
  27. }

七、总结与展望

通过Spring AI集成OpenAI的TTS与ASR功能,开发者可快速构建高质量的语音交互应用。关键步骤包括:

  1. 配置OpenAI API依赖与密钥。
  2. 实现TTS/ASR服务类封装API调用。
  3. 设计RESTful接口暴露功能。
  4. 结合业务场景优化性能与安全性。

未来可探索的方向包括:

  • 支持实时流式语音处理。
  • 集成多模态大模型提升对话质量。
  • 扩展多语言与方言支持。

此方案已在实际项目中验证,可显著降低开发成本,提升语音交互的自然度与准确性。