# CamTalk 多模态实时 AI 视觉对话助手。用户通过摄像头和麦克风与 AI 交互,AI 理解视觉场景和语音输入后,以文字和语音形式给出自然回应。 - **路演视频**:[哔哩哔哩弹幕网——七牛云第四批议题1](https://www.bilibili.com/video/BV1dDJK6cE5S/) - **线上体验**:http://8.161.227.145:9000 > ⚠️ **注意**:由于线上地址使用 HTTP 协议,浏览器默认禁止在非 HTTPS 环境下调用摄像头和麦克风。需要按以下步骤配置 Chrome 浏览器: > > 1. 在浏览器地址栏中输入 `chrome://flags/#unsafely-treat-insecure-origin-as-secure`,回车 > 2. 将 **Insecure origins treated as secure** 选项设置为 **Enabled**(已启用) > 3. 在输入框中输入 `http://8.161.227.145:9000` 地址 > 4. 点击右下角弹出的 **Relaunch** 按钮,自动重启浏览器 > > 重启后即可在该 HTTP 地址下正常调用摄像头和麦克风。 ![](docs/pictures/1.png) ## 架构 三层系统,前端做轻量预处理,后端做智能编排,云端 AI 服务按需调用: ```mermaid graph TB subgraph client[浏览器客户端] A1[媒体采集] A2[VAD 语音检测] A3[关键帧检测] A4[UI 渲染] end subgraph gateway[Go 网关 :8080] B1[WebSocket Handler] B2[Session Manager] B3[AI Orchestrator] B4[REST API] B5[Auth 模块] B6[Store 层] end subgraph cloud[云端 AI 服务] C1[STT 语音识别] C2[LLM 多模态推理] C3[TTS 语音合成] end client <-->|WebSocket| gateway gateway <-->|HTTP| cloud ``` **关键模式**:LLM 文本流和 TTS 音频流并行推送,用户先看到文字、紧接着听到语音,感知延迟 < 0.5 秒。 ## 技术栈 | 层级 | 技术 | |------|------| | 前端 | React 18, TypeScript, Vite, @ricky0123/vad-web | | 后端 | Go, Gin, gorilla/websocket, Viper, Zap | | STT | MiMo ASR(默认) / Deepgram | | LLM | DashScope qwen3-vl-plus(默认,通过 eino-ext OpenAI ChatModel 接入) | | TTS | MiMo TTS(默认) / OpenAI TTS | ## 项目结构 ``` CamTalk/ ├── frontend/ # 浏览器客户端 │ └── src/ │ ├── components/ # UI 组件 │ │ ├── LandingPage/ # 登录着陆页 + LoginModal │ │ ├── AuthPage/ # 登录/注册表单 │ │ ├── CameraManager/ # 摄像头流采集 │ │ ├── MicManager/ # 麦克风音频采集 │ │ ├── EdgeProcessor/ # VAD + 关键帧检测 │ │ ├── WebSocketManager/ # WS 连接管理 │ │ ├── ChatPanel/ # 消息展示 │ │ ├── VideoPreview/ # 摄像头画面预览 │ │ ├── SessionSidebar/ # 对话历史侧边栏 │ │ ├── ConfigPanel/ # 配置面板 │ │ └── Toast/ # 通知提示 │ ├── hooks/ # 自定义 Hooks │ │ ├── useVisionSession.ts # 核心会话 Hook │ │ ├── useSessionList.ts # 对话列表管理 │ │ └── useObservationMode.ts # 观察模式 │ ├── lib/ # 工具库 │ │ ├── websocket.ts # WebSocket 连接管理 │ │ ├── api.ts # REST API 客户端 │ │ ├── auth.tsx # 认证上下文(JWT 管理) │ │ ├── audio.ts # 音频编码 │ │ ├── ttsPlayer.ts # TTS 播放器 │ │ ├── i18n/ # 国际化(zh-CN/en-US/ja-JP) │ │ └── sampling.ts # 采样策略 │ └── types/ # TypeScript 类型定义 ├── backend/ # Go 网关 │ ├── cmd/server/ # 入口 │ └── internal/ │ ├── ai/ # AI 服务抽象层 │ │ ├── llm/ # LLM 提示词与场景 │ │ ├── stt/ # STT 服务(MiMo/Deepgram) │ │ └── tts/ # TTS 服务(MiMo/OpenAI) │ ├── eino/ # Eino Graph 编排层(7 节点 DAG) │ ├── orchestrator/ # Orchestrator 接口 │ ├── session/ # 会话管理(三级存储:Memory/Redis/PG) │ ├── store/ # 持久化层(Repository 接口 + PG/内存实现) │ ├── auth/ # 认证(JWT、bcrypt、中间件) │ ├── ws/ # WebSocket Handler │ ├── api/ # REST API(Auth/Conversation) │ ├── config/ # 配置管理 │ ├── models/ # 数据模型 │ ├── errors/ # 错误码 │ └── logger/ # 日志 ├── migrations/ # 数据库迁移(嵌入式 SQL) ├── docs/ # 设计文档 └── CLAUDE.md # Claude Code 指引 ``` ## 快速开始 ### 前置条件 - Node.js >= 18 - Go >= 1.25 ### 前端 ```bash cd frontend npm install npm run dev # Vite 开发服务器 http://localhost:5173 ``` ### 后端 ```bash cd backend go mod download go run ./cmd/server # 启动网关 :8080 ``` ### 配置 后端配置文件位于 `backend/config.yaml`,支持环境变量覆盖(前缀 `CAMTALK_`)。 ```bash # 最小启动(需要至少一个 AI 服务的 API Key) cd backend CAMTALK_AI_LLM_API_KEY=sk-xxx \ CAMTALK_AI_STT_API_KEY=xxx \ go run ./cmd/server ``` 配置优先级:环境变量 > `config.{env}.yaml` > `config.yaml` > `.env` ## WebSocket 协议 连接地址:`ws://localhost:8080/ws` 所有消息为 JSON 文本帧,统一信封格式 `{type, request_id?, timestamp?}`。 **客户端 → 服务端**:`query`、`config`、`interrupt`、`ping` **服务端 → 客户端**:`connected`、`stt_result`、`llm_chunk`、`llm_done`、`tts_audio`、`error`、`pong` 完整协议见 [docs/02-接口文档.md](docs/02-接口文档.md)。 ## 文档 | 文档 | 内容 | |------|------| | [01-架构设计](docs/01-架构设计.md) | 三层架构、技术栈、数据库设计、部署方案 | | [02-接口文档](docs/02-接口文档.md) | WebSocket 协议、REST API、AI 服务层、编排器、配置管理 | | [03-技术选型](docs/03-技术选型.md) | AI 服务栈、持久化层、前端边缘处理选型 | | [04-用户故事](docs/04-用户故事.md) | 用户场景与优先级 | | [05-语音交互](docs/05-语音交互.md) | VAD → STT → LLM → TTS 全链路 | | [06-视觉理解](docs/06-视觉理解.md) | 帧采样、关键帧检测、多模态输入 | | [07-成本控制](docs/07-成本控制.md) | 采样策略、端云协同、模型分级 | | [08-功能创意](docs/08-功能创意.md) | 功能创意与规划 | | [对话历史技术设计](docs/conversation-history-technical-design.md) | 对话历史功能的前端技术方案 | ## License [MIT](LICENSE) © XEngineers