- 02-系统架构: Redis/PostgreSQL 标注已实现,模块表新增 Auth/Store/Migrations,更新表设计和前端组件 - 03-接口文档: config 新增 scenario 字段,Manager 接口补全 UpdateTitle/ListByUser,配置结构体同步,扩展接口替换为实际 Repository - 04-技术选型: 持久化层标注已实现 - 06-语音交互: TTS Voice 更正为 mimo_default - 11-持久化与用户系统设计: 所有 Phase 标记完成 - PLAN_BACKEND/PLAN_USER_MODULE: 标记完成状态 - README: 新增实现状态总览,补充文档索引
12 KiB
12 KiB
CamTalk 后端完善计划
✅ 状态:全部完成。 所有 Phase 已实现并通过测试(约 122 个测试函数)。本文档保留作为历史参考。
Context
后端当前是一个骨架:main.go 启动 Gin 服务器,ws/handler.go 实现了 WebSocket 连接生命周期和消息分发,models/models.go 定义了所有协议消息类型,config/config.go 实现了 Viper 配置加载。但所有业务逻辑都是 TODO 桩——没有 Session Manager、没有 AI 服务客户端、没有编排层、没有日志/错误工具、没有测试。前端已基本完成,正在等待后端提供真实的 AI 管道。
目标:按设计文档(docs/03-接口文档.md 为最高依据)逐步填充所有业务模块,使端到端的 STT → LLM → TTS 流式管道可用。
分阶段实施
Phase 1:基础设施(logger、errors、config 接入、graceful shutdown) ✅
目标:为后续模块提供日志、错误码、配置等基础能力,替换 main.go 中的硬编码值。
| # | 任务 | 文件 | 说明 |
|---|---|---|---|
| 1.1 | 实现 Zap 日志封装 | internal/logger/logger.go |
提供 Init(level, format) 和全局 *zap.SugaredLogger,替换所有 log.Printf |
| 1.2 | 实现错误码常量 + WS 错误发送工具 | internal/errors/codes.go |
10 个错误码常量 + SendWSError(client, code, requestID, err) |
| 1.3 | main.go 接入 config.Load() | cmd/server/main.go |
用 cfg.Server.Host:Port 替换硬编码 :8080,初始化 logger |
| 1.4 | 添加 graceful shutdown | cmd/server/main.go |
signal.NotifyContext + http.Server.Shutdown,10s drain |
| 1.5 | 添加 .gitignore | backend/.gitignore |
排除 server 二进制、.env、tmp/ |
CORS:不在此处实现,生产环境由 Nginx 反向代理统一处理跨域。
Phase 2:Session Manager ✅
目标:实现会话生命周期管理,让 WS handler 能追踪会话、存储对话历史。
| # | 任务 | 文件 | 说明 |
|---|---|---|---|
| 2.1 | 定义 SessionManager 接口 | internal/session/manager.go |
方法:Create, Get, UpdateConfig, GetHistory, AppendMessage, SetActiveRequest, ClearActiveRequest, Touch, Destroy |
| 2.2 | 实现内存版 SessionManager | internal/session/memory.go |
sync.RWMutex + map[string]*sessionEntry,TTL 30 分钟,历史上限 20 条 |
| 2.3 | 实现 Redis 版 SessionManager | internal/session/redis.go |
session:{id}:meta Hash + session:{id}:history List,TTL 刷新,选配 |
| 2.4 | 编写 Session Manager 测试 | internal/session/memory_test.go |
覆盖 Create/Get/Expire/Destroy/AppendMessage/History 上限 |
| 2.5 | WS handler 接入 SessionManager | internal/ws/handler.go |
ServeWS 接收 session.Manager 参数;connected 消息后创建会话;query 时 Touch + SetActiveRequest;config 时 UpdateConfig;断开时不销毁(自然过期) |
Phase 3:AI 服务层接口 + 实现 ✅
目标:定义并实现三个 AI 服务客户端,每个服务一个独立包。
| # | 任务 | 文件 | 说明 |
|---|---|---|---|
| 3a. STT | |||
| 3.1 | STT 接口定义 | internal/ai/stt/stt.go |
Service 接口:Recognize(ctx, audio []byte, opts Options) (string, error)。Options: Encoding, SampleRate, Language |
| 3.2 | Deepgram 实现 | internal/ai/stt/deepgram.go |
WebSocket 连接 wss://api.deepgram.com/v1/listen,发送 PCM 音频,接收转录结果,5s 超时 |
| 3.3 | STT 测试(mock) | internal/ai/stt/deepgram_test.go |
httptest/WebSocket mock,验证连接、发送、超时 |
| 3b. LLM | |||
| 3.4 | LLM 接口定义 | internal/ai/llm/llm.go |
Service 接口:ChatStream(ctx, req Request) (<-chan Chunk, error)。Request: Image, Text, History, Language。Chunk: Delta, Done, TokensUsed, Model |
| 3.5 | OpenAI 实现 | internal/ai/llm/openai.go |
POST /v1/chat/completions + stream: true,SSE 解析,10s 超时,image 以 data:image/jpeg;base64,... 传入 |
| 3.6 | System Prompt 定义 | internal/ai/llm/prompt.go |
中文视觉助手提示词,根据 Language/DetailLevel 动态构建 |
| 3.7 | LLM 测试(mock) | internal/ai/llm/openai_test.go |
httptest mock SSE 流,验证流式解析、超时、错误处理 |
| 3c. TTS | |||
| 3.8 | TTS 接口定义 | internal/ai/tts/tts.go |
Service 接口:SynthesizeStream(ctx, textStream <-chan string, opts Options) (<-chan Chunk, error)。Chunk: Audio []byte, IsLast |
| 3.9 | OpenAI 实现 | internal/ai/tts/openai.go |
POST /v1/audio/speech 模型 tts-1,逐句发送,返回 MP3 流,5s/句超时 |
| 3.10 | TTS 测试(mock) | internal/ai/tts/openai_test.go |
httptest mock,验证逐句合成、超时 |
Phase 4:AI Orchestrator(核心编排) ✅
目标:实现 STT → LLM → TTS 流式并行管道,这是后端最关键的业务逻辑。
| # | 任务 | 文件 | 说明 |
|---|---|---|---|
| 4.1 | Orchestrator 接口 | internal/orchestrator/orchestrator.go |
ProcessQuery(ctx, sessionID, req, history, sender) — 接收查询并执行管道 |
| 4.2 | Sender 接口 | internal/orchestrator/sender.go |
抽象 WS 推送:SendSTTResult, SendLLMChunk, SendLLMDone, SendTTSAudio, SendError,便于测试 |
| 4.3 | 管道实现 | internal/orchestrator/pipeline.go |
① stt.Recognize() → 发送 stt_result ② llm.ChatStream() 并行消费 token → 发送 llm_chunk + 句子切分 → channel ③ tts.SynthesizeStream() 从 channel 读取 → 发送 tts_audio ④ 流结束 → 发送 llm_done |
| 4.4 | 句子切分器 | internal/orchestrator/splitter.go |
按 。!?\n.!? 切分,buffer size 4 channel |
| 4.5 | 错误降级 | 同上文件 | STT 失败→STT_ERROR+abort;LLM 超时→LLM_TIMEOUT;TTS 失败→静默跳过 |
| 4.6 | Interrupt 支持 | 同上文件 | context cancel 触发所有流中止 |
| 4.7 | Orchestrator 测试 | internal/orchestrator/pipeline_test.go |
mock 三个 AI service + mock sender,验证完整流程、中断、错误降级 |
Phase 5:WS Handler 完整接入 ✅
目标:将 Session Manager + Orchestrator 串入 WebSocket handler,实现端到端消息处理。
| # | 任务 | 文件 | 说明 |
|---|---|---|---|
| 5.1 | Client 扩展 | internal/ws/handler.go |
添加 session.Manager、orchestrator.Orchestrator、context.CancelFunc(用于 interrupt) |
| 5.2 | query 处理 | 同上 | 解码 audio Base64 → stt.Recognize 的输入;Touch 会话;设置 active request;启动 orchestrator.ProcessQuery goroutine |
| 5.3 | config 处理 | 同上 | 调用 session.UpdateConfig() |
| 5.4 | interrupt 处理 | 同上 | 查找 active request 的 cancel func,调用 cancel(),ClearActiveRequest |
| 5.5 | Disconnect 处理 | 同上 | 取消当前活跃请求(如有),不销毁会话 |
Phase 6:REST API 补全 ✅
目标:补全设计文档中的 REST 端点。
| # | 任务 | 文件 | 说明 |
|---|---|---|---|
| 6.1 | Session 路由 | internal/api/session.go |
POST /api/sessions 创建会话,DELETE /api/sessions/:id 销毁会话 |
| 6.2 | Health 更新 | cmd/server/main.go |
从 SessionManager 获取 active_sessions 真实值 |
| 6.3 | 路由注册 | cmd/server/main.go |
统一注册 REST + WS 路由,注入依赖 |
Phase 7:Rate Limiter + Model Router(可选/MVP 后) 📋
目标:防止滥用 + 智能模型选择,MVP 可简化或跳过。
| # | 任务 | 文件 | 说明 |
|---|---|---|---|
| 7.1 | 令牌桶 Rate Limiter | internal/middleware/ratelimit.go |
golang.org/x/time/rate 或自实现,按 session ID 限流 |
| 7.2 | Rate Limiter 中间件 | internal/middleware/ratelimit.go |
在 WS query 路径上检查,超限返回 RATE_LIMITED |
| 7.3 | Model Router | internal/ai/router.go |
规则引擎:简单识别→GPT-4o-mini,深度分析→GPT-4o,暂不实现 o1 |
Phase 8:集成测试 + 文档同步 ✅
| # | 任务 | 文件 | 说明 |
|---|---|---|---|
| 8.1 | WS 集成测试 | internal/ws/handler_test.go |
启动 Gin test server + gorilla websocket client,验证完整 query→stt_result→llm_chunk→llm_done→tts_audio 流程 |
| 8.2 | 文档同步 | docs/03-接口文档.md |
代码实现与文档有偏差时更新文档 |
| 8.3 | go.sum 清理 | backend/ |
go mod tidy 清理无用依赖 |
关键文件清单
backend/
cmd/server/main.go ← Phase 1.3, 1.4, 1.5, 6.2, 6.3
internal/
config/config.go ← 已完成,Phase 1.3 接入
logger/logger.go ← Phase 1.1(新建)
errors/codes.go ← Phase 1.2(新建)
models/models.go ← 已完成,可能小幅扩展
session/
manager.go ← Phase 2.1(新建)
memory.go ← Phase 2.2(新建)
redis.go ← Phase 2.3(新建)
memory_test.go ← Phase 2.4(新建)
ai/
stt/
stt.go ← Phase 3.1(新建)
deepgram.go ← Phase 3.2(新建)
deepgram_test.go ← Phase 3.3(新建)
llm/
llm.go ← Phase 3.4(新建)
openai.go ← Phase 3.5(新建)
prompt.go ← Phase 3.6(新建)
openai_test.go ← Phase 3.7(新建)
tts/
tts.go ← Phase 3.8(新建)
openai.go ← Phase 3.9(新建)
openai_test.go ← Phase 3.10(新建)
router.go ← Phase 7.3(新建)
orchestrator/
orchestrator.go ← Phase 4.1(新建)
sender.go ← Phase 4.2(新建)
pipeline.go ← Phase 4.3, 4.4, 4.5, 4.6(新建)
pipeline_test.go ← Phase 4.7(新建)
api/
session.go ← Phase 6.1(新建)
middleware/
ratelimit.go ← Phase 7.1, 7.2(新建)
ws/
handler.go ← Phase 5.1-5.5(修改)
handler_test.go ← Phase 8.1(新建)
新增依赖
| 包 | 用途 | Phase |
|---|---|---|
go.uber.org/zap |
结构化日志 | 1 |
github.com/redis/go-redis/v9 |
Redis 客户端 | 2.3 |
github.com/gorilla/websocket |
已有,Deepgram WS 也复用 | 3.2 |
执行顺序与依赖关系
Phase 1 (基础设施)
↓
Phase 2 (Session Manager)
↓
Phase 3 (AI 服务层) ← 可与 Phase 2 并行开发
↓
Phase 4 (Orchestrator) ← 依赖 Phase 2 + 3
↓
Phase 5 (WS Handler 接入) ← 依赖 Phase 4
↓
Phase 6 (REST API) ← 依赖 Phase 2
↓
Phase 7 (Rate Limiter + Router) ← 独立,可推后
↓
Phase 8 (集成测试 + 文档)
验证方案
- 单元测试:每个模块独立测试,mock 外部依赖(AI API、Redis)
- 集成测试:
httptest启动 Gin server,用 gorilla/websocket 客户端模拟完整 query 流程 - 端到端手动测试:启动后端 → 打开前端 → 摄像头+麦克风对话 → 验证 stt_result / llm_chunk / tts_audio 消息流
- go vet + go test ./... 通过
设计文档参考
- 接口规范(最高优先级):
docs/03-接口文档.md - 系统架构:
docs/02-系统架构.md - 技术选型:
docs/04-技术选型.md - 成本控制:
docs/08-成本控制.md