Skip to content

Repository files navigation

🤖 AI 视觉对话助手 (AI Vision Assistant)

七牛云 × XEngineer 暑期实训营「第四批次议题」选题一

以摄像头画面为输入,通过自然语言与 AI 对话——让 AI 帮你"看"身边的东西,问它任何问题。


📺 演示视频

点击观看完整演示视频

🚀 快速启动

🌐 在线体验(无需部署)

作者已部署可用的线上版本,直接用 Chrome 浏览器访问即可:

https://ava.542000.xyz

授权摄像头后即可立刻开始视觉对话,无需任何配置。


💻 本地运行

环境要求:Go ≥ 1.23 · Chrome 浏览器

1. 配置环境变量

cp .env.example .env
# 编辑 .env,填入你的 Mimo API Key
变量名 说明 示例值
MIMO_URL Mimo API 地址 https://token-plan-cn.xiaomimimo.com/v1
MIMO_KEY 你的 API Key sk-xxxxxx
MODEL_OK 模型名称(支持逗号分隔多个,优先选 omni/vision/vl) mimo-v2-omni

2. 启动服务

cd backend && go run ./cmd/server

3. 打开浏览器

访问 http://127.0.0.1:5173,授权摄像头后即可开始视觉对话。


☁️ 生产部署

项目采用前后端分离部署方案,详见 DEPLOYMENT.md

部分 平台 说明
后端 Railway 根目录 Dockerfile 自动构建,配置 MIMO_URL / MIMO_KEY / MODEL_OK 环境变量
前端 Cloudflare Pages 发布目录 frontend/public,无需构建步骤,修改 config.js 中的后端地址

📋 开发流程

本项目完整经历了从 0 到 1 的产品开发周期,共五个阶段:

产品设计  ──►  MVP 实现  ──►  产品上线  ──►  测试维护  ──►  文档编写
   📐         💻              ☁️           🔧            📝

📐 阶段一:产品设计

梳理核心需求与技术可行性,产出以下设计文档(见 设计文档/ 目录):

  • 需求文档:明确用户场景、功能边界与非功能性约束
  • 产品流程图:端到端交互流程,覆盖摄像头授权 → 事件相机抽帧 → Mimo 问答 → 空间画像更新全链路
  • 可行性分析:浏览器端帧差事件相机方案论证,避免持续视频流上传
  • 空间画像格式设计Profile(scene + objects + confidence)数据结构定义

💻 阶段二:MVP 实现

按前后端分离架构逐步实现:

模块 实现内容
Go 后端 HTTP 服务、Mimo 代理、帧缓存、对话历史、空间画像存储与生成
浏览器前端 摄像头采集、帧差事件相机、事件驱动采样、空间画像渲染
语音交互 Web Speech API 中文识别、TTS 播报、音频频谱可视化
空间画像 12 帧触发生成、8 帧节流更新、双端维护(前端即时展示 + 后端持久化)

☁️ 阶段三:产品上线

采用前后端分离部署:

  • 后端 → Railway 平台,基于根目录 Dockerfile 自动构建 Go 服务
  • 前端 → Cloudflare Pages,发布 frontend/public 静态目录,零构建
  • 线上地址https://ava.542000.xyz

🔧 阶段四:测试与维护

  • 单元测试:覆盖 Mimo 客户端、API Handler、空间画像服务(go test ./...
  • 端到端验证frontend/scripts/verify-browser.mjs 无头 Chrome 自动化脚本,验证摄像头启动与完整对话流程
  • 问题修复:定位并修复后期出现的帧缓存上传错误提示(静默处理非关键后台失败)

📝 阶段五:README 文档编写

按照规范化文档结构完整撰写本 README,涵盖项目简介、快速启动、功能特性、技术架构、项目结构、空间画像机制与开发流程,方便后续贡献者快速上手。


✨ 功能特性

功能 说明
📷 实时视觉问答 摄像头画面直接提问,AI 实时理解并回答
🎙️ 语音输入/播报 Web Speech API 中文语音识别 + TTS 语音播报回答
🧠 空间画像记忆 AI 自动记住画面中的物体及位置,跨轮对话共享上下文
📸 事件相机抽帧 浏览器端帧差算法,按画面变化程度智能选取关键帧
🔥 运动热力图 Canvas 实时渲染帧差热力图与运动区域边框
💬 多对话管理 支持新建、切换、置顶多个独立对话,历史消息持久保存
☁️ 端云协同 浏览器端完成抽帧,云端 Mimo 大模型完成多模态理解

🏗️ 技术架构

┌──────────────────────────────────────────────────────────┐
│                    浏览器端 (原生 HTML/CSS/JS)              │
│                                                            │
│  ┌────────────┐  ┌─────────────────┐  ┌───────────────┐  │
│  │ 摄像头采集  │  │  事件相机 (帧差)  │  │  语音识别/合成 │  │
│  │ VideoCapture│  │ EventCamera     │  │ SpeechController│  │
│  └─────┬──────┘  └───────┬─────────┘  └───────────────┘  │
│        │                 │                                  │
│        └────────┬────────┘                                 │
│                 ▼                                           │
│  ┌──────────────────────────────────────────────────────┐  │
│  │              事件驱动采样器 (EventDrivenSampler)        │  │
│  │   高事件 420ms │ 低事件 900ms │ 静态 2200ms            │  │
│  └──────────────────────┬───────────────────────────────┘  │
└─────────────────────────┼──────────────────────────────────┘
                          │ POST /api/frames (关键帧 + 事件元数据)
                          │ POST /api/vision (查询 + 事件数据)
┌─────────────────────────┼──────────────────────────────────┐
│              后端 (Go 1.23 · 标准库 net/http)               │
│                         ▼                                   │
│  ┌──────────────────────────────────────────────────────┐  │
│  │                    API Handler                        │  │
│  │  /api/vision │ /api/frames │ /api/spatial │ /api/conversations │
│  └──────┬───────────────┬─────────────────┬─────────────┘  │
│         │               │                 │                  │
│         ▼               ▼                 ▼                  │
│  ┌─────────────┐ ┌────────────┐ ┌──────────────────────┐   │
│  │  framecache  │ │conversation│ │   spatialprofile      │   │
│  │  (帧环形缓存) │ │   Store    │ │  LocalClient + Store  │   │
│  │  最多12帧    │ │  (对话历史) │ │  (JSON 文件持久化)    │   │
│  └─────────────┘ └────────────┘ └──────────┬───────────┘   │
│                                              │               │
└──────────────────────────────────────────────┼───────────────┘
                                               │ OpenAI 兼容 API
┌──────────────────────────────────────────────┼───────────────┐
│                    Mimo 云端大模型              │               │
│                                               ▼               │
│        mimo-v2-omni (多模态视觉理解 + 空间画像生成)            │
└───────────────────────────────────────────────────────────────┘
层级 技术 说明
摄像头采集 浏览器 getUserMedia 720p 视频流,Canvas 截帧为 320×240 JPEG
事件相机 原生 JS 帧差算法 16×12 网格亮度差分,阈值 24,避免持续上传视频流
语音交互 浏览器 Web Speech API 中文语音识别 + TTS 播报 + 音频频谱可视化
前端框架 原生 HTML/CSS/ES Module 零构建工具依赖,模块化组织
后端框架 Go 1.23 + 标准库 net/http 零外部依赖,静态文件 + REST API 一体服务
帧缓存 内存环形缓冲(最多 12 帧) 按事件分数动态选取 1/2/4 帧发送给模型
空间画像 内存 + JSON 文件持久化 每 12 帧首次生成,之后每 8 帧增量更新
多模态模型 Mimo (OpenAI 兼容接口) mimo-v2-omni,同时处理图像理解与空间画像生成
部署 Railway (后端) + Cloudflare Pages (前端) Docker 镜像部署,前端静态托管

📁 项目结构

XEngineer-04-01/
├── backend/
│   ├── cmd/
│   │   ├── server/main.go               # 主服务入口,装配所有依赖并启动 HTTP 服务
│   │   └── spatial-profile/main.go      # 空间画像独立服务入口(可选独立部署)
│   ├── internal/
│   │   ├── api/
│   │   │   ├── handler.go               # HTTP 路由、请求校验、静态文件服务
│   │   │   └── handler_test.go          # API 集成测试
│   │   ├── config/
│   │   │   └── config.go                # .env 配置加载,自动选择视觉模型
│   │   ├── conversation/
│   │   │   └── store.go                 # 对话历史内存存储(增删查、置顶排序)
│   │   ├── eventmeta/
│   │   │   └── event.go                 # 事件相机元数据归一化(分数裁剪、运动框过滤)
│   │   ├── framecache/
│   │   │   └── store.go                 # 帧环形缓冲(最多 12 帧,按事件分数选帧)
│   │   ├── mimo/
│   │   │   ├── client.go                # Mimo OpenAI 兼容多模态请求封装 + Prompt 构造
│   │   │   └── client_test.go           # Mimo 客户端单元测试
│   │   ├── spatial/
│   │   │   └── graph.go                 # 空间画像知识图谱(实体 upsert、属性合并)
│   │   └── spatialprofile/
│   │       ├── client.go                # 空间画像客户端(LocalClient / HTTPClient)
│   │       ├── model.go                 # Mimo 空间画像生成模型(12帧→场景+物体)
│   │       ├── server.go                # 空间画像独立 HTTP 服务路由
│   │       ├── server_test.go           # 空间画像服务测试
│   │       ├── store.go                 # 空间画像持久化存储(内存缓存 + JSON 文件)
│   │       └── types.go                 # Profile 数据结构、Normalize/ToContext 转换
│   └── go.mod
├── frontend/
│   ├── public/
│   │   ├── js/
│   │   │   ├── app.js                   # 主应用逻辑,组装各模块、管理对话与帧处理循环
│   │   │   ├── api-client.js            # 后端 REST API 调用封装
│   │   │   ├── config.js                # API 基地址配置(本地开发 / 生产部署切换)
│   │   │   ├── event-camera.js          # 浏览器端帧差事件相机(16×12 网格、运动框检测)
│   │   │   ├── sampler.js               # 事件驱动采样器(动态采样间隔)
│   │   │   ├── spatial-graph.js         # 前端空间画像管理(Map 存储、upsert 合并)
│   │   │   ├── speech.js                # Web Speech API 语音识别/合成 + 音频可视化
│   │   │   ├── ui.js                    # UI 渲染工具(消息气泡、热力图、实体卡片)
│   │   │   └── video-capture.js         # 摄像头管理(getUserMedia、Canvas 截帧)
│   │   ├── index.html                   # 单页应用入口
│   │   └── styles.css                   # 全局样式(响应式三栏布局)
│   ├── scripts/
│   │   └── verify-browser.mjs           # 无头 Chrome 端到端验证脚本
│   └── package.json
├── 设计文档/                              # 需求、流程与可行性设计文档
├── .env.example                          # 环境变量模板
├── Dockerfile                            # Railway 后端 Docker 镜像构建
├── railway.json                          # Railway 部署配置
├── wrangler.toml                         # Cloudflare Pages 前端部署配置
└── package.json                          # 根目录开发编排命令(npm run dev)

🧠 空间画像机制

空间画像是本项目的核心记忆系统,让 AI 能在多轮对话中持续"记住"它看到过的场景和物体。

数据结构

{
  "scene": "桌面上摆放着电脑、水杯和书本",
  "objects": [
    { "name": "水杯", "description": "位于画面右侧,白色马克杯", "confidence": 0.92 },
    { "name": "笔记本电脑", "description": "位于画面中央,屏幕亮起", "confidence": 0.98 }
  ],
  "updatedAt": "2026-06-14T10:30:00Z"
}

生成与更新流程

摄像头帧缓存 (最多 12 帧)
         │
         │ 累计到 12 帧时首次触发
         │ 之后每新增 8 帧触发一次
         ▼
  spatialprofile.MimoModel.Generate()
         │  将 12 帧关键帧 + 已有画像发给 Mimo
         │  Mimo 返回新的 scene + objects JSON
         ▼
  spatialprofile.Store.Set()           ← 内存缓存 + JSON 文件持久化
         │
         ▼
  下次视觉问答时注入 SpatialContext    ← 作为历史记忆上下文传给 Mimo

关键设计原则

设计 说明
异步后台更新 空间画像更新在 goroutine 中执行,不阻塞视觉问答响应
当前帧优先 Mimo 被明确告知:当前图片永远优先于历史空间画像,二者冲突以图片为准
增量合并 有历史画像时执行更新模式,当前帧不可见的旧物体会被删除或改写
双端维护 前端 SpatialGraph 即时展示,后端 Store 按 session 持久化,多轮共享
置信度过滤 每个物体携带 confidence 字段(0-1),低置信度物体可被后续帧覆盖
触发节流 首次 12 帧触发,之后每 8 帧才再次触发,避免频繁调用 Mimo API

About

七牛云 × XEngineer 暑期实训营「第四批次议题」我们选择题目一“AI 视觉对话助手”。项目将实现一个结合摄像头、麦克风与多模态 AI 的对话应用,使 AI 能看见画面、听懂语音并进行回应。同时,我们计划借鉴事件相机“只关注变化”的思想,在普通摄像头上模拟事件触发机制,通过画面变化检测控制关键帧上传,并维护空间画像,记录场景中的物体、位置关系与变化历史,从而提升连续对话理解能力并降低端云协同成本。

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages