瞳话 Pupil 是一个 AI 视觉对话助手。用户在浏览器中打开摄像头和麦克风后,可以对着当前画面提问;系统会识别语音内容,结合摄像头画面生成中文回复,并支持语音播报。
本项目为七牛云 x XEngineer 暑期实训营题目一「AI 视觉对话助手」提交作品。
当前版本已经完成从采集到回复的完整闭环:
- 摄像头预览和按次画面抓帧
- 按住录音、松开发送的语音输入
- 专用 ASR 语音识别
- AI 结合画面和语音生成回复
- 云端自然音色语音播报,失败时降级为浏览器本地语音
- 多轮对话历史,可手动清空
- 录音过短、静音、重复发送等边界保护
- 中文错误提示和控制台技术详情
- 运行项目并打开
http://127.0.0.1:8000。 - 允许浏览器访问摄像头和麦克风。
- 将物体、文字或场景放到摄像头前。
- 按住 按住说话,说完整一句话后松开。
- 查看识别文本、AI 回复和历史记录;开启 语音播报 后可听到回复。
适合演示的指令:
- 帮我读一下画面里的文字
- 把这个英文翻译成中文
- 我面前有什么需要注意
- 这个东西怎么用
- 刚才你说的内容再简单总结一下
环境要求:
- Windows
- Python 3.11 或兼容版本
- 可访问阿里云百炼 DashScope
- 一个
DASHSCOPE_API_KEY
运行:
start.bat首次启动时,脚本会要求粘贴 DASHSCOPE_API_KEY,并保存到本地 .env。.env 已加入 .gitignore,不会提交到仓库。
浏览器访问:
http://127.0.0.1:8000
请使用 127.0.0.1 访问。部分浏览器会限制非安全上下文里的摄像头和麦克风权限,直接打开 HTML 文件或使用其他地址可能无法授权。
浏览器
├─ 摄像头预览:getUserMedia
├─ 画面抓帧:Canvas JPEG
├─ 麦克风采集:Web Audio API
└─ 语音播放:云端 TTS URL / 浏览器本地 TTS
FastAPI 后端
├─ /api/chat:接收图片和 WAV 音频
├─ /api/tts:生成自然音色语音
└─ /api/reset:清空对话历史
阿里云百炼
├─ paraformer-realtime-v2:语音转文字
├─ qwen-omni-turbo:图片 + 文本生成回复
└─ qwen-tts:回复语音播报
核心流程是“先转写,再看图对话”。前端只在用户松开发送时上传一帧 JPEG 和一段 WAV 音频;后端先用 ASR 把音频转成文字,再把图片、文字和最近对话历史交给视觉模型。相比持续推送视频流,这种方式更稳定,也更容易控制云端调用成本。
为了提高识别率并减少无效调用,前端做了以下本地处理:
- 请求麦克风时启用单声道、回声消除、噪声抑制和自动增益
- 录音链路常驻,避免每次按下按钮重新创建
AudioContext - 保留 240ms 预缓冲,降低句首被截断的概率
- 过短录音不发送云端
- RMS 静音门限过滤无声输入
- WAV 编码前做音量归一化和直流偏移修正
这些逻辑在浏览器侧完成,不额外消耗云端额度。
已采用的控制策略:
- 按句抓帧:每次请求只上传一张 JPEG,不上传连续视频流
- 图片压缩:Canvas 导出 JPEG,质量参数为
0.7 - 语音/视觉分步调用:ASR 使用专用模型,视觉理解使用多模态模型
- 本地误触过滤:录音太短不请求云端
- 本地静音过滤:没有清晰语音时不请求云端
- 对话历史只保存文字,不保存图片 base64
- 历史轮数限制为最近 10 轮,避免上下文持续膨胀
已评估但本版本未实现的方向:
- 画面相似度检测,复用相同画面的理解结果
- 根据问题复杂度切换大小模型
- 更细粒度的本地 VAD
backend/
app.py FastAPI 后端、模型调用和对话历史
requirements.txt 后端依赖
frontend/
index.html 单文件前端页面、录音、抓帧和交互逻辑
docs/
design.md 设计文档
tests/
test_*.py 文档化的静态回归测试
运行:
python -m unittest discover -s tests当前测试覆盖:
- 前端页面结构和核心控件是否存在
- 请求 payload 是否只包含图片和音频
- 示例指令是否可见
- 音频采集优化是否保留
- TTS 播报文本是否不被截断
- ASR 和视觉模型调用参数是否符合当前实现
原创部分:
- 浏览器端录音状态机
- Float32 PCM 到 16-bit WAV 的编码逻辑
- 静音门限、误触过滤、预缓冲和归一化处理
- 前端工作台式 UI
- 端云分步调用流程和多轮历史裁剪
第三方依赖:
fastapiuvicornopenaidashscope
模型能力来自阿里云百炼 API。项目不提交 API key、音频样本或个人敏感数据。