From 87b6407e2e6204fd5581d35d77dd24611c2ec46e Mon Sep 17 00:00:00 2001 From: hhs <386998068@qq.com> Date: Sat, 13 Jun 2026 13:18:17 +0800 Subject: [PATCH 1/3] =?UTF-8?q?docs:=20=E8=A1=A5=E5=85=85=20AI=20=E7=BC=96?= =?UTF-8?q?=E6=8E=92=E5=B1=82=E6=8E=A5=E5=8F=A3=E8=A7=84=E8=8C=83=E4=B8=8E?= =?UTF-8?q?=20tts=5Faudio=20=E9=9F=B3=E9=A2=91=E6=92=AD=E6=94=BE=E6=96=B9?= =?UTF-8?q?=E6=A1=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 03-接口文档: 新增第三章 AI 服务层接口(STT/LLM/TTS 三个 Service interface + 接入约定) - 03-接口文档: 新增第四章 AI 编排器(句子级流式并行策略、Orchestrator 实现、错误降级表) - 03-接口文档: 锁定 tts_audio 音频格式为 audio/mpeg(MP3 24kHz),新增前端 AudioPlayer 播放方案 - 02-系统架构: 更新 Orchestrator 代码为句子级流式并行实现 - README.md: 更新 03-接口文档描述,补充 AI 服务层和编排器关键词 --- docs/02-系统架构.md | 46 ++++--- docs/03-接口文档.md | 295 +++++++++++++++++++++++++++++++++++++++++++- docs/README.md | 2 +- 3 files changed, 322 insertions(+), 21 deletions(-) diff --git a/docs/02-系统架构.md b/docs/02-系统架构.md index cd904f5..b0f65a5 100644 --- a/docs/02-系统架构.md +++ b/docs/02-系统架构.md @@ -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` 第三、四章。 + ## 前端组件 | 组件 | 职责 | diff --git a/docs/03-接口文档.md b/docs/03-接口文档.md index 3aa530e..f3a0e94 100644 --- a/docs/03-接口文档.md +++ b/docs/03-接口文档.md @@ -143,11 +143,53 @@ interface TTSAudioMessage { type: "tts_audio"; request_id: string; audio: string; // Base64 编码的音频片段 - mime_type: string; // "audio/mp3" 或 "audio/pcm" + mime_type: string; // "audio/mpeg" is_last: boolean; // 是否为最后一片 } ``` +**音频格式规范**(前端播放依赖此约定): + +| 属性 | 值 | 说明 | +|------|------|------| +| 编码 | `audio/mpeg`(MP3) | 浏览器 `