From 77f2847e55bd532582bb3cc40aa3d6a574b2c540 Mon Sep 17 00:00:00 2001 From: hhs <386998068@qq.com> Date: Fri, 12 Jun 2026 11:51:07 +0800 Subject: [PATCH 1/2] vault backup: 2026-06-12 11:51:07 --- .../AI 视觉对话助手.md | 18 +++++++++--------- .../AI 视觉对话助手}/成本控制.md | 6 +++--- .../AI 视觉对话助手}/用户故事.md | 6 +++--- .../AI 视觉对话助手}/视觉理解.md | 6 +++--- .../AI 视觉对话助手}/语音交互.md | 6 +++--- 5 files changed, 21 insertions(+), 21 deletions(-) rename AI 视觉对话助手.md => 课题一/AI 视觉对话助手.md (68%) rename {AI 视觉对话助手 => 课题一/AI 视觉对话助手}/成本控制.md (97%) rename {AI 视觉对话助手 => 课题一/AI 视觉对话助手}/用户故事.md (96%) rename {AI 视觉对话助手 => 课题一/AI 视觉对话助手}/视觉理解.md (96%) rename {AI 视觉对话助手 => 课题一/AI 视觉对话助手}/语音交互.md (96%) diff --git a/AI 视觉对话助手.md b/课题一/AI 视觉对话助手.md similarity index 68% rename from AI 视觉对话助手.md rename to 课题一/AI 视觉对话助手.md index 07aef6f..d0a88a0 100644 --- a/AI 视觉对话助手.md +++ b/课题一/AI 视觉对话助手.md @@ -17,17 +17,17 @@ create time: 2026-06-12 11:13 | 维度 | 关键问题 | 详见 | | -------- | ------------------------ | ---- | -| **视觉理解** | 如何准确理解摄像头画面中的人物、物体、场景? | [[AI 视觉对话助手/视觉理解]] | -| **语音交互** | 如何让对话像真人交流一样自然、低延迟? | [[AI 视觉对话助手/语音交互]] | -| **成本控制** | 实时视频流 + LLM 推理,如何避免账单爆炸? | [[AI 视觉对话助手/成本控制]] | +| **视觉理解** | 如何准确理解摄像头画面中的人物、物体、场景? | [[视觉理解]] | +| **语音交互** | 如何让对话像真人交流一样自然、低延迟? | [[语音交互]] | +| **成本控制** | 实时视频流 + LLM 推理,如何避免账单爆炸? | [[成本控制]] | > [!question] 思考 > 这三个维度之间存在天然的张力——提升视觉精度意味着更高分辨率和更频繁的采样,但这会直接推高带宽和推理成本。如何在设计中做好取舍? ### 项目目标 -1. **[[AI 视觉对话助手/用户故事|用户故事规划]]**:明确"AI 能看、能听、能说"需要覆盖哪些场景 -2. **[[AI 视觉对话助手/成本控制|成本控制策略]]**:从架构设计层面融入运营成本意识 +1. **[[用户故事|用户故事规划]]**:明确"AI 能看、能听、能说"需要覆盖哪些场景 +2. **[[成本控制|成本控制策略]]**:从架构设计层面融入运营成本意识 ### 需交付物 @@ -37,7 +37,7 @@ create time: 2026-06-12 11:13 - 成本控制技巧的构思 vs 实际采用的方案 ## 关联笔记 -- [[AI 视觉对话助手/视觉理解]] -- [[AI 视觉对话助手/语音交互]] -- [[AI 视觉对话助手/成本控制]] -- [[AI 视觉对话助手/用户故事]] +- [[视觉理解]] +- [[语音交互]] +- [[成本控制]] +- [[用户故事]] diff --git a/AI 视觉对话助手/成本控制.md b/课题一/AI 视觉对话助手/成本控制.md similarity index 97% rename from AI 视觉对话助手/成本控制.md rename to 课题一/AI 视觉对话助手/成本控制.md index 9bc13f8..2ec663a 100644 --- a/AI 视觉对话助手/成本控制.md +++ b/课题一/AI 视觉对话助手/成本控制.md @@ -123,6 +123,6 @@ async function routeQuery(image: string, question: string) { ## 关联笔记 -- [[AI 视觉对话助手/视觉理解]] -- [[AI 视觉对话助手/语音交互]] -- [[AI 视觉对话助手/用户故事]] +- [[视觉理解]] +- [[语音交互]] +- [[用户故事]] diff --git a/AI 视觉对话助手/用户故事.md b/课题一/AI 视觉对话助手/用户故事.md similarity index 96% rename from AI 视觉对话助手/用户故事.md rename to 课题一/AI 视觉对话助手/用户故事.md index 8f5ce61..e015368 100644 --- a/AI 视觉对话助手/用户故事.md +++ b/课题一/AI 视觉对话助手/用户故事.md @@ -91,6 +91,6 @@ sequenceDiagram ## 关联笔记 -- [[AI 视觉对话助手/视觉理解]] -- [[AI 视觉对话助手/语音交互]] -- [[AI 视觉对话助手/成本控制]] +- [[视觉理解]] +- [[语音交互]] +- [[成本控制]] diff --git a/AI 视觉对话助手/视觉理解.md b/课题一/AI 视觉对话助手/视觉理解.md similarity index 96% rename from AI 视觉对话助手/视觉理解.md rename to 课题一/AI 视觉对话助手/视觉理解.md index d1ee955..cc6187b 100644 --- a/AI 视觉对话助手/视觉理解.md +++ b/课题一/AI 视觉对话助手/视觉理解.md @@ -103,6 +103,6 @@ const response = await openai.chat.completions.create({ ## 关联笔记 -- [[AI 视觉对话助手/语音交互]] -- [[AI 视觉对话助手/成本控制]] -- [[AI 视觉对话助手/用户故事]] +- [[语音交互]] +- [[成本控制]] +- [[用户故事]] diff --git a/AI 视觉对话助手/语音交互.md b/课题一/AI 视觉对话助手/语音交互.md similarity index 96% rename from AI 视觉对话助手/语音交互.md rename to 课题一/AI 视觉对话助手/语音交互.md index b1461ca..7fb6ff8 100644 --- a/AI 视觉对话助手/语音交互.md +++ b/课题一/AI 视觉对话助手/语音交互.md @@ -113,6 +113,6 @@ graph TD ## 关联笔记 -- [[AI 视觉对话助手/视觉理解]] -- [[AI 视觉对话助手/成本控制]] -- [[AI 视觉对话助手/用户故事]] +- [[视觉理解]] +- [[成本控制]] +- [[用户故事]] From 9322d9be2a4d7af9e5f4ad182e0b6458b2d008c4 Mon Sep 17 00:00:00 2001 From: hhs <386998068@qq.com> Date: Fri, 12 Jun 2026 14:43:41 +0800 Subject: [PATCH 2/2] vault backup: 2026-06-12 14:43:41 --- 课题一/AI 视觉对话助手.md | 2 + 课题一/AI 视觉对话助手/项目架构与技术栈.md | 287 +++++++++++++++++++++ 2 files changed, 289 insertions(+) create mode 100644 课题一/AI 视觉对话助手/项目架构与技术栈.md diff --git a/课题一/AI 视觉对话助手.md b/课题一/AI 视觉对话助手.md index d0a88a0..50d9e12 100644 --- a/课题一/AI 视觉对话助手.md +++ b/课题一/AI 视觉对话助手.md @@ -35,8 +35,10 @@ create time: 2026-06-12 11:13 - 设计文档,覆盖: - 计划实现 vs 最终实现的用户故事 - 成本控制技巧的构思 vs 实际采用的方案 + - [[项目架构与技术栈|项目架构设计]]与技术选型 ## 关联笔记 +- [[项目架构与技术栈]] - [[视觉理解]] - [[语音交互]] - [[成本控制]] diff --git a/课题一/AI 视觉对话助手/项目架构与技术栈.md b/课题一/AI 视觉对话助手/项目架构与技术栈.md new file mode 100644 index 0000000..91a8fc3 --- /dev/null +++ b/课题一/AI 视觉对话助手/项目架构与技术栈.md @@ -0,0 +1,287 @@ +--- +tags: [AI, 架构设计, 技术栈, 端云协同, WebSocket, 微服务] +create time: 2026-06-12 14:32 +--- + +# 项目架构与技术栈 + +## 概述 + +本文档设计 AI 视觉对话助手的**分层架构**与**技术选型**。核心设计原则:**前端做轻量预处理,后端做智能编排,云端 AI 服务按需调用**——在保证交互体验的同时控制成本。 + +## 正文 + +### 整体架构 + +```mermaid +graph TB + subgraph Client["浏览器客户端"] + UI["React UI"] + CAM["摄像头/麦克风"] + EDGE["边缘预处理"] + WS_C["WebSocket Client"] + end + + subgraph Gateway["Go 后端网关"] + WS_S["WebSocket Server"] + SESSION["会话管理"] + ROUTER["模型路由"] + ORCH["AI 编排器"] + end + + subgraph AI["云端 AI 服务"] + LLM["多模态 LLM"] + STT["语音识别"] + TTS["语音合成"] + end + + CAM --> EDGE + EDGE -->|"关键帧 + 语音片段"| WS_C + WS_C <-->|"双向实时通信"| WS_S + WS_S --> SESSION + SESSION --> ROUTER + ROUTER --> ORCH + ORCH --> LLM + ORCH --> STT + ORCH --> TTS + TTS -->|"音频流"| WS_S + LLM -->|"文本流"| WS_S +``` + +三层各司其职: + +| 层级 | 职责 | 关键约束 | +|------|------|---------| +| **客户端** | 媒体采集、边缘预处理、UI 渲染 | 浏览器资源有限,模型需轻量 | +| **Go 网关** | 会话管理、模型路由、AI 服务编排 | 高并发、低延迟、状态管理 | +| **AI 服务** | LLM 推理、语音识别、语音合成 | 按量计费,需控制调用频率 | + +> [!question] 思考 +> 为什么要单独加一层 Go 网关,而不是让前端直连 AI API?原因有三:1)API Key 安全性;2)统一的速率限制和成本管控;3)多模型路由逻辑集中在一处便于维护。 + +### 技术栈选型 + +#### 前端 + +| 技术 | 选型 | 选择理由 | +|------|------|---------| +| 框架 | **React 18 + TypeScript** | 组件化开发,类型安全,生态成熟 | +| 构建 | **Vite** | 开发热更新快,构建产物小 | +| 实时通信 | **WebSocket (原生 API)** | 浏览器原生支持,无需额外依赖 | +| 边缘推理 | **ONNX Runtime Web** | 浏览器端跑轻量模型(VAD、关键帧检测) | +| 语音检测 | **@ricky0123/vad-web** | 基于 WebRTC VAD,纯前端零延迟 | +| 媒体采集 | **MediaDevices API** | 浏览器原生摄像头/麦克风访问 | + +#### 后端 + +| 技术 | 选型 | 选择理由 | +|------|------|---------| +| 语言 | **Go** | 高并发 goroutine 模型,适合长连接管理 | +| WebSocket | **gorilla/websocket** | Go 生态最成熟的 WebSocket 库 | +| 会话存储 | **Redis** | 高速 KV 存储,适合会话状态和上下文缓存 | +| 配置管理 | **Viper** | 支持多格式配置,环境变量覆盖 | +| 日志 | **Zap** | 高性能结构化日志 | + +#### AI 服务(按需选型) + +| 能力 | 主选方案 | 备选方案 | 选型考量 | +|------|---------|---------|---------| +| 多模态 LLM | **GPT-4o** | Claude Sonnet | 视觉理解能力强,API 成熟 | +| 语音识别 STT | **Deepgram** | FunASR 自部署 | 流式识别延迟低(<500ms) | +| 语音合成 TTS | **OpenAI TTS** | Edge TTS(免费) | 音质自然,支持流式 | +| 轻量分类 | **GPT-4o-mini** | Haiku | 模型路由时的复杂度判断 | + +> [!tip] 混合策略 +> 不必绑定单一厂商。Go 网关的模型路由层可以统一封装不同 AI 服务的调用接口,按场景动态切换。比如简单识别用 GPT-4o-mini,深度分析用 GPT-4o,TTS 用免费的 Edge TTS 降低成本。 + +### 核心交互流程 + +一次完整的"用户提问 → AI 回答"流程: + +```mermaid +sequenceDiagram + participant B as Browser + participant G as Go Gateway + participant S as STT Service + participant L as LLM Service + participant T as TTS Service + + B->>B: VAD 检测到语音开始 + B->>B: 捕获当前摄像头帧 + B->>G: WebSocket 发送 [音频流 + 图像帧] + G->>S: 转发音频流 + S-->>G: 流式返回识别文本 + G->>L: 发送 [图像 + 识别文本 + 历史上下文] + L-->>G: 流式返回回答文本 + G-->>B: WebSocket 推送回答文本 + G->>T: 发送回答文本 + T-->>G: 流式返回音频 + G-->>B: WebSocket 推送音频流 + B->>B: 播放音频 + 渲染文字 +``` + +> [!info] 关键优化 +> 注意 LLM 文本流和 TTS 音频流是**并行推送**的——客户端先展示文字,同时开始播放语音,用户感知延迟大幅降低。 + +### 后端架构设计 + +Go 网关的核心模块: + +```mermaid +graph TD + subgraph Server["Go Gateway"] + WS["WebSocket Hub"] + SM["Session Manager"] + MR["Model Router"] + AO["AI Orchestrator"] + RL["Rate Limiter"] + CACHE["Context Cache"] + end + + WS --> SM + SM --> MR + MR --> AO + SM --> RL + SM --> CACHE +``` + +各模块职责: + +| 模块 | 职责 | 关键实现 | +|------|------|---------| +| **WebSocket Hub** | 管理所有客户端连接,广播/定向推送 | goroutine per connection | +| **Session Manager** | 维护用户会话状态、对话历史 | Redis + TTL 过期策略 | +| **Model Router** | 根据请求类型选择 AI 模型 | 规则引擎 + 成本阈值 | +| **AI Orchestrator** | 编排多路 AI 调用(并行/串行) | context 取消 + 超时控制 | +| **Rate Limiter** | 防止单用户过度消耗 API 额度 | 令牌桶算法 | + +Go 后端核心代码结构: + +```go +// AI 编排器:并行调用 LLM 和 TTS +func (o *Orchestrator) ProcessQuery(ctx context.Context, req *QueryRequest) (*QueryResponse, error) { + ctx, cancel := context.WithTimeout(ctx, 10*time.Second) + defer cancel() + + // 并行:LLM 推理 + 准备 TTS + llmCh := make(chan string, 1) + go func() { + resp, _ := o.llm.Chat(ctx, req.Image, req.Text, req.History) + llmCh <- resp + }() + + 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 +} +``` + +### 前端架构设计 + +```mermaid +graph TD + subgraph App["React App"] + MAIN["App Root"] + CAM_M["CameraManager"] + MIC_M["MicManager"] + EDGE_M["EdgeProcessor"] + WS_M["WebSocketManager"] + CHAT["ChatPanel"] + VIDEO["VideoPreview"] + end + + MAIN --> CAM_M + MAIN --> MIC_M + MAIN --> WS_M + MAIN --> CHAT + MAIN --> VIDEO + CAM_M --> EDGE_M + MIC_M --> EDGE_M + EDGE_M --> WS_M +``` + +核心 Hook 设计: + +```typescript +// useVisionSession —— 封装一次完整的视觉对话会话 +function useVisionSession() { + const [messages, setMessages] = useState([]); + const wsRef = useWebSocket("ws://localhost:8080/ws"); + + // 摄像头管理 + const videoRef = useRef(null); + const { captureFrame } = useCamera(videoRef); + + // VAD 语音检测 + const { isSpeaking } = useVAD({ + onSpeechEnd: async (audio) => { + const frame = captureFrame(); + // 同时发送图像帧和语音片段 + wsRef.current?.send(JSON.stringify({ + type: "query", + image: frame.toDataURL("image/jpeg", 0.7), + audio: encodeAudio(audio) + })); + } + }); + + // 接收 AI 回复(文本 + 音频) + useEffect(() => { + wsRef.current?.on("message", (data) => { + const { text, audio } = JSON.parse(data); + setMessages(prev => [...prev, { role: "assistant", text }]); + if (audio) playAudio(audio); + }); + }, []); + + return { messages, videoRef, isSpeaking }; +} +``` + +### 部署架构 + +```mermaid +graph LR + subgraph CDN["CDN"] + STATIC["静态资源"] + end + + subgraph LB["负载均衡"] + NGINX["Nginx"] + end + + subgraph App["应用层"] + GW1["Gateway-1"] + GW2["Gateway-2"] + end + + subgraph Storage["存储层"] + REDIS["Redis"] + end + + USER["用户浏览器"] --> CDN + CDN --> STATIC + USER -->|"WebSocket"| NGINX + NGINX --> GW1 + NGINX --> GW2 + GW1 --> REDIS + GW2 --> REDIS + GW1 -->|"API Calls"| AI["AI Services"] + GW2 -->|"API Calls"| AI +``` + +> [!tip] WebSocket 与负载均衡 +> WebSocket 是长连接,Nginx 需要配置 `proxy_set_header Upgrade` 和 `ip_hash` 或 sticky session,确保同一用户的请求始终路由到同一个 Gateway 实例。 + +## 关联笔记 + +- [[视觉理解]] +- [[语音交互]] +- [[成本控制]] +- [[用户故事]]