docs: 补充 AI 编排层接口规范与 tts_audio 音频播放方案
- 03-接口文档: 新增第三章 AI 服务层接口(STT/LLM/TTS 三个 Service interface + 接入约定) - 03-接口文档: 新增第四章 AI 编排器(句子级流式并行策略、Orchestrator 实现、错误降级表) - 03-接口文档: 锁定 tts_audio 音频格式为 audio/mpeg(MP3 24kHz),新增前端 AudioPlayer 播放方案 - 02-系统架构: 更新 Orchestrator 代码为句子级流式并行实现 - README.md: 更新 03-接口文档描述,补充 AI 服务层和编排器关键词
This commit is contained in:
@@ -84,32 +84,48 @@ Browser Go Gateway STT LLM TTS
|
||||
| AI Orchestrator | 编排多路 AI 调用(并行/串行) | context 取消 + 超时控制 |
|
||||
| Rate Limiter | 防止单用户过度消耗 API 额度 | 令牌桶算法 |
|
||||
|
||||
AI Orchestrator 核心代码:
|
||||
AI Orchestrator 核心代码(句子级流式并行):
|
||||
|
||||
```go
|
||||
func (o *Orchestrator) ProcessQuery(ctx context.Context, req *QueryRequest) (*QueryResponse, error) {
|
||||
func (o *Orchestrator) ProcessQuery(ctx context.Context, client MessageSender, req *QueryRequest) {
|
||||
ctx, cancel := context.WithTimeout(ctx, 10*time.Second)
|
||||
defer cancel()
|
||||
|
||||
// 并行:LLM 推理 + 准备 TTS
|
||||
llmCh := make(chan string, 1)
|
||||
// Step 1: STT — 识别用户语音(串行)
|
||||
text, err := o.stt.Recognize(ctx, req.Audio, STTOptions{...})
|
||||
if err != nil {
|
||||
client.SendError(req.RequestID, "STT_ERROR", err.Error())
|
||||
return
|
||||
}
|
||||
client.SendSTTResult(req.RequestID, text, true)
|
||||
|
||||
// Step 2: LLM 流式输出 + 句子切分(并行)
|
||||
llmStream, _ := o.llm.ChatStream(ctx, LLMRequest{Image: req.Image, Text: text, ...})
|
||||
sentenceCh := make(chan string, 4)
|
||||
go func() {
|
||||
resp, _ := o.llm.Chat(ctx, req.Image, req.Text, req.History)
|
||||
llmCh <- resp
|
||||
defer close(sentenceCh)
|
||||
var buf strings.Builder
|
||||
for chunk := range llmStream {
|
||||
client.SendLLMChunk(req.RequestID, chunk.Delta) // 逐 token 推送文字
|
||||
buf.WriteString(chunk.Delta)
|
||||
if isSentenceEnd(chunk.Delta) { // 按 。!?\n 切分
|
||||
sentenceCh <- buf.String()
|
||||
buf.Reset()
|
||||
}
|
||||
}
|
||||
if buf.Len() > 0 { sentenceCh <- buf.String() }
|
||||
}()
|
||||
|
||||
llmText := <-llmCh
|
||||
// LLM 返回后,流式推送给客户端,同时启动 TTS
|
||||
ttsCh := make(chan []byte, 1)
|
||||
go func() {
|
||||
audio, _ := o.tts.Synthesize(ctx, llmText)
|
||||
ttsCh <- audio
|
||||
}()
|
||||
|
||||
return &QueryResponse{Text: llmText, Audio: <-ttsCh}, nil
|
||||
// Step 3: TTS 并行消费句子流
|
||||
ttsStream, _ := o.tts.SynthesizeStream(ctx, sentenceCh, TTSOptions{...})
|
||||
for chunk := range ttsStream {
|
||||
client.SendTTSAudio(req.RequestID, chunk.Audio, chunk.IsLast)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
> **关键优化**:LLM 文本流和 TTS 音频流**并行推送**——客户端先逐 token 展示文字,同时 TTS 逐句子合成并推送音频,用户感知延迟大幅降低。详细的 AI 服务层接口和编排策略见 `03-接口文档.md` 第三、四章。
|
||||
|
||||
## 前端组件
|
||||
|
||||
| 组件 | 职责 |
|
||||
|
||||
Reference in New Issue
Block a user