0d99d06f06ae34b0e043f7d803d1aee9bde61090
CamTalk
多模态实时 AI 视觉对话助手。用户通过摄像头和麦克风与 AI 交互,AI 理解视觉场景和语音输入后,以文字和语音形式给出自然回应。
- 路演视频:哔哩哔哩弹幕网——七牛云第四批议题1
- 线上体验:http://8.161.227.145:9000
⚠️ 注意:由于线上地址使用 HTTP 协议,浏览器默认禁止在非 HTTPS 环境下调用摄像头和麦克风。需要按以下步骤配置 Chrome 浏览器:
- 在浏览器地址栏中输入
chrome://flags/#unsafely-treat-insecure-origin-as-secure,回车- 将 Insecure origins treated as secure 选项设置为 Enabled(已启用)
- 在输入框中输入
http://8.161.227.145:9000地址- 点击右下角弹出的 Relaunch 按钮,自动重启浏览器
重启后即可在该 HTTP 地址下正常调用摄像头和麦克风。
架构
三层系统,前端做轻量预处理,后端做智能编排,云端 AI 服务按需调用:
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
前端
cd frontend
npm install
npm run dev # Vite 开发服务器 http://localhost:5173
后端
cd backend
go mod download
go run ./cmd/server # 启动网关 :8080
配置
后端配置文件位于 backend/config/config.yaml,支持环境变量覆盖(前缀 CAMTALK_)。
# 最小启动(需要至少一个 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。
文档
| 文档 | 内容 |
|---|---|
| 01-架构设计 | 三层架构、技术栈、数据库设计、部署方案 |
| 02-接口文档 | WebSocket 协议、REST API、AI 服务层、编排器、配置管理 |
| 03-技术选型 | AI 服务栈、持久化层、前端边缘处理选型 |
| 04-用户故事 | 用户场景与优先级 |
| 05-语音交互 | VAD → STT → LLM → TTS 全链路 |
| 06-视觉理解 | 帧采样、关键帧检测、多模态输入 |
| 07-成本控制 | 采样策略、端云协同、模型分级 |
| 08-功能创意 | 功能创意与规划 |
| 对话历史技术设计 | 对话历史功能的前端技术方案 |
License
MIT © XEngineers
Languages
Go
53.5%
TypeScript
34%
CSS
11.7%
Shell
0.3%
Dockerfile
0.3%
Other
0.2%
