Files
CamTalk/README.md

18 KiB
Raw Permalink Blame History

CamTalk

多模态实时 AI 视觉对话助手

用户通过摄像头和麦克风与 AI 交互AI 理解视觉场景和语音输入后,以文字和语音形式给出自然回应

License: MIT Go Version React TypeScript

路演视频在线体验文档


⚠️ 在线体验提示:由于演示环境使用 HTTP 协议,需配置 Chrome 允许非 HTTPS 下访问摄像头/麦克风:

  1. 访问 chrome://flags/#unsafely-treat-insecure-origin-as-secure
  2. 启用该选项,并在输入框填入 http://8.161.227.145:9000
  3. 点击 Relaunch 重启浏览器

CamTalk 界面截图

核心特性

  • 🎥 多模态理解:摄像头视觉 + 麦克风语音双输入AI 理解完整场景
  • 🗣️ 自然对话:基于 VAD 的端到端语音交互,低延迟流式响应
  • 🚀 实时推送LLM 文本流 + TTS 音频流并行推送,感知延迟 < 0.5 秒
  • 🎭 情景模式:自由对话、面试官、英语老师等多场景支持
  • 💾 对话历史:自动保存会话,支持搜索、重命名、删除、时间分组
  • 🔐 安全认证JWT 双 token 轮转 + Refresh Token Rotation 防重放
  • 📊 三级存储Memory → Redis → PostgreSQL 自动降级,保障可靠性
  • 🌐 国际化:支持中文、英文、日文界面

🏗️ 系统架构

CamTalk 采用三层架构:前端轻量预处理 → Go 网关智能编排 → 云端 AI 按需调用

graph TB
    subgraph Browser["🌐 浏览器客户端"]
        UI["React UI 渲染"]
        VAD["VAD 语音检测"]
        Media["媒体采集"]
    end

    subgraph Gateway["⚙️ Go 网关 (Eino Graph)"]
        WS["WebSocket Handler"]
        Auth["JWT 认证"]
        Session["会话管理 (三级存储)"]
        Orch["AI 编排器 (7节点DAG)"]
    end

    subgraph AI["☁️ 云端 AI 服务"]
        STT["STT (MiMo/Deepgram)"]
        LLM["LLM (qwen3-vl-plus)"]
        TTS["TTS (MiMo/OpenAI)"]
    end

    Browser <-->|"WebSocket<br/>(JWT + query/config)"| Gateway
    Orch --> STT
    Orch --> LLM
    Orch --> TTS

AI 编排流水线Eino Graph

基于 CloudWeGo Eino 框架的声明式 7 节点 DAG

START → STT → History → ChatModel → Msg2Str → Splitter → TTS → Done → END

核心优势

  • 流式处理ChatModel 逐 token 推送Callback AOP 机制实时转发客户端
  • 句子级 TTSSplitter 实时切分句子TTS 逐句并行合成,无需等待完整回复
  • 类型安全Go 泛型 + 编译期检查Graph 拓扑错误在编译时发现

🛠️ 技术栈

层级 技术选型 说明
前端 React 18 + TypeScript + Vite 组件化开发,类型安全,快速热更新
VAD @ricky0123/vad-web (ONNX Runtime) 浏览器端语音活动检测,零延迟
后端 Go 1.25+ + Gin + gorilla/websocket 高并发 goroutine长连接管理
AI 编排 CloudWeGo Eino Graph 声明式 DAGStream 模式Callback AOP
STT MiMo ASR默认/ Deepgram 实时语音识别,多语言支持
LLM DashScope qwen3-vl-plus 多模态推理(通过 eino-ext OpenAI 接入)
TTS MiMo TTS默认/ OpenAI TTS 自然语音合成
存储 PostgreSQL 15 + Redis 7 三级存储架构Memory → Redis → PG
认证 JWT (HS256) + bcrypt 双 token 轮转 + Refresh Token Rotation
配置 Viper + godotenv YAML + .env + 环境变量覆盖
日志 Zap 高性能结构化日志 + Trace ID 追踪

📁 项目结构

CamTalk/
├── frontend/                   # 🌐 浏览器客户端
│   └── src/
│       ├── components/         # UI 组件
│       │   ├── LandingPage/    # 登录着陆页 + LoginModal
│       │   ├── CameraManager/  # 摄像头流采集
│       │   ├── MicManager/     # 麦克风音频采集 + VAD
│       │   ├── WebSocketManager/ # WS 连接生命周期
│       │   ├── ChatPanel/      # 消息展示 + 流式回复
│       │   ├── SessionSidebar/ # 对话历史侧边栏
│       │   └── ConfigPanel/    # 配置面板(主题/TTS/语言/场景)
│       ├── hooks/              # 自定义 Hooks
│       │   ├── useVisionSession.ts  # 核心会话 Hook (~500 行)
│       │   ├── useSessionList.ts    # 对话列表管理
│       │   └── useObservationMode.ts # 观察模式
│       ├── lib/                # 工具库
│       │   ├── websocket.ts    # WebSocket 单例(心跳/重连/订阅)
│       │   ├── api.ts          # REST 客户端401拦截+刷新)
│       │   ├── auth.tsx        # AuthProviderJWT 自动刷新)
│       │   ├── ttsPlayer.ts    # TTS 流式播放队列
│       │   └── i18n/           # 国际化zh-CN/en-US/ja-JP
│       └── types/              # TypeScript 类型定义
├── backend/                    # ⚙️ Go 网关
│   ├── cmd/server/             # 服务入口main.go
│   └── internal/
│       ├── eino/               # 🔥 Eino Graph 编排层7节点DAG
│       │   ├── graph.go        # Graph 构建与编译
│       │   ├── adapter.go      # EinoOrchestrator 适配器
│       │   ├── callback.go     # LLM token 推送回调
│       │   ├── state.go        # 跨节点状态管理
│       │   └── nodes_*.go      # STT/History/Splitter/TTS/Done 节点
│       ├── session/            # 会话管理TieredManager 三级存储)
│       ├── store/              # 持久化层Repository 接口 + PG/内存实现)
│       │   ├── user_pg.go      # PostgreSQL 实现
│       │   └── cached_user.go  # Redis 缓存装饰器
│       ├── auth/               # 认证JWT/bcrypt/中间件)
│       ├── ai/                 # AI 服务抽象层
│       │   ├── llm/            # LLM 提示词与场景
│       │   ├── stt/            # STT 服务MiMo/Deepgram
│       │   └── tts/            # TTS 服务MiMo/OpenAI
│       ├── ws/                 # WebSocket Handler
│       ├── api/                # REST APIAuth/Conversation
│       ├── config/             # 配置管理Viper
│       └── logger/             # 日志Zap + Trace ID
├── migrations/                 # 📊 数据库迁移(嵌入式 SQL
├── docs/                       # 📚 设计文档
│   ├── 01-架构设计.md
│   ├── 02-接口文档.md
│   ├── 08-Eino框架与编排设计.md
│   ├── 10-鉴权体系.md
│   └── 13-日志追踪.md
├── deploy.sh                   # 🐳 部署脚本Docker Compose
├── docker-compose.yml          # 容器编排配置
└── CLAUDE.md                   # 🤖 Claude Code 开发指引

🚀 快速开始

前置条件

  • Node.js >= 18
  • Go >= 1.25
  • PostgreSQL >= 15可选 Docker
  • Redis >= 7可选用于缓存加速

本地开发

1. 克隆项目

git clone https://github.com/yourusername/CamTalk.git
cd CamTalk

2. 配置环境变量

# 复制环境变量模板
cp backend/.env.example backend/.env

# 编辑 .env 文件,填入以下必需配置:
# - CAMTALK_AUTH_JWT_SECRET使用 openssl rand -hex 32 生成)
# - CAMTALK_STORAGE_DSNPostgreSQL 连接字符串)
# - CAMTALK_AI_LLM_API_KEYDashScope API Key
# - CAMTALK_AI_STT_API_KEYMiMo/Deepgram API Key
# - CAMTALK_AI_TTS_API_KEYMiMo/OpenAI API Key

3. 启动后端

cd backend

# 安装依赖
go mod download

# 运行数据库迁移(自动创建表)
go run ./cmd/server migrate

# 启动服务(监听 :8080
go run ./cmd/server

4. 启动前端

cd frontend

# 安装依赖
npm install

# 启动开发服务器http://localhost:5173
npm run dev

5. 访问应用

打开浏览器访问 http://localhost:5173,注册账号后即可开始使用。

6. 代码检查与测试

# 安装 Go 代码检查工具
go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest

# 运行后端代码检查
cd backend
golangci-lint run

# 后端单元测试
go test ./...

# 后端集成测试(需要 PostgreSQL
go test -tags=integration ./...

# 前端代码检查
cd frontend
npm run lint

# 前端测试
npm test

远程部署

方式一Docker Compose推荐

# 1. 克隆代码到服务器
git clone https://github.com/yourusername/CamTalk.git
cd CamTalk

# 2. 配置环境变量
cp backend/.env.example backend/.env
# 编辑 .env 文件,填入生产环境配置

# 3. 一键部署frontend + backend + postgres + redis
./deploy.sh up

# 4. 查看日志
./deploy.sh logs

# 5. 停止服务
./deploy.sh down

部署完成后访问 http://localhost:9000

方式二:手动部署

# 1. 构建前端
cd frontend
npm install
npm run build  # 输出到 dist/

# 2. 构建后端
cd backend
go build -o camtalk ./cmd/server

# 3. 配置 Nginx
# 参考 nginx.conf.example 配置反向代理

# 4. 启动服务
APP_ENV=prod ./camtalk

# 5. 使用 systemd 管理(可选)
sudo systemctl enable camtalk
sudo systemctl start camtalk

环境变量检查清单

部署前确保已配置以下环境变量:

  • CAMTALK_AUTH_JWT_SECRET(使用 openssl rand -hex 32 生成)
  • CAMTALK_STORAGE_DSNPostgreSQL 连接字符串)
  • CAMTALK_AI_LLM_API_KEYDashScope API Key
  • CAMTALK_AI_STT_API_KEYSTT 服务 API Key
  • CAMTALK_AI_TTS_API_KEYTTS 服务 API Key
  • APP_ENV=prod(启用生产环境配置)

配置优先级

环境变量 > config.{APP_ENV}.yaml > config.yaml > .env

通过 APP_ENV=prod 切换生产环境配置(启用限流 + 严格 CORS

📡 WebSocket 协议

连接地址:ws://localhost:8080/ws?token=<jwt>&conversation_id=<uuid>

所有消息为 JSON 文本帧,统一信封格式:

interface BaseMessage {
  type: string;
  request_id?: string;
  timestamp?: number;
}

客户端 → 服务端

消息类型 说明 示例
query 发送视觉+语音查询 {type: "query", image: "base64...", audio: "base64..."}
config 更新会话配置 {type: "config", scenario: "interviewer", language: "en"}
interrupt 中断当前响应 {type: "interrupt", request_id: "xxx"}
ping 心跳保活 {type: "ping"}

服务端 → 客户端

消息类型 说明 触发时机
connected 连接成功 WebSocket 握手后
stt_result STT 识别结果 STT 节点完成
llm_chunk LLM 文本增量 ChatModel 逐 tokenCallback
llm_done LLM 推理完成 Done 节点执行
tts_audio TTS 音频片段 TTS 节点逐句合成
error 错误通知 任意节点失败
pong 心跳响应 响应 ping

心跳机制

  • 客户端每 30 秒发送 ping
  • 服务端 60 秒无消息自动断连
  • 断连后自动重连(指数退避 1s → 30s

完整协议定义见 docs/02-接口文档.md

🔐 认证体系

CamTalk 采用 JWT 双 token 轮转 + Refresh Token Rotation 安全机制:

双 Token 设计

Token 有效期 存储位置 用途
access_token 120 分钟 前端内存(推荐)/ localStorage 访问受保护资源
refresh_token 7 天 httpOnly Cookie推荐/ localStorage 刷新 access_token

Refresh Token Rotation

每次刷新 token 时:

  1. 验证 refresh_token 签名和有效期
  2. 查询数据库中的 SHA256 哈希
  3. 如果哈希不存在 → 检测到 token 复用 → 吊销该用户所有 token
  4. 删除旧 refresh_token生成新 token pair
  5. 返回新 access_token + refresh_token

防重放攻击:旧 refresh_token 立即失效,复用时触发全局吊销,强制所有设备重新登录。

REST API 端点

  • POST /api/auth/register — 用户注册
  • POST /api/auth/login — 用户登录
  • POST /api/auth/refresh — 刷新 token
  • POST /api/auth/logout — 登出(需认证)
  • GET /api/conversations — 获取对话列表(需认证)
  • POST /api/conversations — 创建对话(需认证)
  • GET /api/health — 健康检查

详细设计见 docs/10-鉴权体系.md

💾 三级存储架构

TieredManager 实现会话状态的三级存储,平衡性能与可靠性:

┌─────────────┐
│  L1 Memory  │ ← 微秒级读写,进程内缓存
├─────────────┤
│  L2 Redis   │ ← 毫秒级访问,跨实例共享
├─────────────┤
│ L3 PostgreSQL│ ← 持久化存储,数据可靠性
└─────────────┘

特性

  • 自动降级Redis 故障时自动切换到 Memory + PostgreSQL 模式
  • 灵活配置支持单级Memory、双级Memory + PG、完整三级
  • TTL 管理:会话默认 30 分钟过期,自动清理
  • 写穿透:数据先写 L1异步同步到 L2/L3

📊 数据库设计

系统使用 PostgreSQL 存储持久化数据:

核心表

表名 说明 关键字段
users 用户账户 id (UUID), username (UNIQUE), password_hash (bcrypt)
sessions 对话会话 id (UUID), user_id (FK), title, config (JSONB)
messages 消息记录 id (BIGSERIAL), session_id (FK), role, content, tokens_used
refresh_tokens 刷新令牌 token_hash (PK, SHA256), user_id (FK), expires_at

关系users 1:N sessions 1:N messagesusers 1:N refresh_tokens

迁移管理:使用嵌入式 SQL 文件(backend/migrations/),应用启动时自动执行。

🛡️ 安全特性

  • 🔒 密码安全bcrypt (cost=10) 哈希,自动生成盐值
  • 🔑 Token 安全JWT HS256 签名refresh_token SHA256 哈希存储
  • 🚫 防重放攻击Refresh Token Rotation + 复用检测自动吊销
  • 🌐 传输安全:生产环境强制 HTTPS开发环境 Vite proxy 同源代理
  • 🚦 限流保护:令牌桶算法(生产环境启用),防暴力破解
  • 🔍 日志追踪:全链路 Trace ID请求/响应/错误统一记录

🌍 部署架构

┌─────────────┐
│   Nginx     │ ← 反向代理(静态资源 + API + WebSocket
└──────┬──────┘
       │
┌──────┴───────────────────┐
│  Go Gateway 集群          │
│  ├─ Gateway-1            │
│  ├─ Gateway-2            │
│  └─ Gateway-N            │
└───┬────────────┬─────────┘
    │            │
┌───┴────┐  ┌───┴────────┐
│ Redis  │  │ PostgreSQL │
└────────┘  └────────────┘
    │
┌───┴────────────────────┐
│  外部 AI 服务           │
│  ├─ DashScope (LLM)   │
│  ├─ MiMo (STT/TTS)    │
│  └─ Deepgram (可选)    │
└───────────────────────┘

跨域策略Nginx 统一反代前后端到同一域名,无跨域问题。

水平扩展Gateway 无状态设计,会话状态存储在 Redis/PostgreSQL支持多实例部署。

📖 文档

核心设计文档

文档 内容
01-架构设计 三层架构、技术栈、数据库设计、部署方案
02-接口文档 WebSocket 协议、REST API、AI 服务层、编排器、配置管理
08-Eino框架与编排设计 Eino Graph 7 节点 DAG、节点实现、流式处理、Callback AOP
10-鉴权体系 JWT 双 token 轮转、Refresh Token Rotation、密码安全、中间件
11-令牌桶限流 限流算法、配置策略、生产环境保护
13-日志追踪 Zap 日志、Trace ID 全链路追踪、日志级别

功能文档

文档 内容
03-技术选型 AI 服务栈、持久化层、前端边缘处理选型
04-用户故事 用户场景与优先级
05-语音交互 VAD → STT → LLM → TTS 全链路
06-视觉理解 帧采样、关键帧检测、多模态输入
07-成本控制 采样策略、端云协同、模型分级
09-情景切换 情景模式设计与实现
12-自定义情景 用户自定义情景功能(规划中)

🐛 问题反馈

遇到问题?请提交 Issue,并提供以下信息:

  • 操作系统版本
  • Go / Node.js 版本
  • 错误日志(后端日志 + 浏览器控制台)
  • 复现步骤

📝 版权声明

MIT License © 2024 XEngineers


Built with ❤️ using Go, React, and AI

⬆️ 回到顶部