# 拍照提问模式 —— 设计方案 状态:**草案,未实现**。本文档只做设计,`feature_pic` 分支尚未修改任何业务代码。 唯一的硬阻塞项(后端视觉能力)已于 2026-09-03 复查解除,见 §2.2。 ## 1. 背景与目标 现有 `elec_rag_ui` 是纯文本 RAG 问答:用户打字提问 → 检索本地知识库 → llama-server 生成回答。 本功能希望新增一种输入方式:**用摄像头拍一张照片,直接针对这张照片提问**(例如对着一个实物部件拍照问"这是什么型号"), 而不是先打字检索文档。 ## 2. 关键前提核实(2026-09-03 现场查证,ER160 pad,192.168.31.48) ### 2.1 摄像头硬件 —— 已具备,风险低 ``` /dev/video0/1 -> Hy-Usb2.0-1*MIC: Hy-QSXGA(8950) # 约500万像素 USB 摄像头,带麦克风 /dev/video2/3 -> Hy-Usb2.0-2*MIC: Hy-8M(8079)-Ca # 约800万像素 USB 摄像头,带麦克风 lsusb: 1bcf:2cef / 1bcf:2ce4 Sunplus Innovation Technology Inc. ``` 两个都是标准 **USB UVC(USB Video Class)** 摄像头,不是需要专有 ISP 驱动的 CSI 摄像头。 Chromium/Electron 的 `navigator.mediaDevices.getUserMedia()` 原生支持 UVC 设备,**不需要额外驱动或胶水代码**。 一台设备接了两个摄像头,需要在 UI 里做设备选择(`enumerateDevices()` 列出后选 `deviceId`), 或者约定固定用其中一个(待确认哪个摄像头是安装时实际对外的那个)。 ### 2.2 推理后端视觉能力 —— **已确认可用(2026-09-03 复查更新)** 初次核实时(见本文档历史)当前模型是纯文本的,`allow_image=0`;**复查时 er_backend 已经换成带 `--mmproj` 的多模态配置**: ``` /home/work/houmo-HLIELLama-xh2-2.1.0/bin/llama-server \ -m /home/work/models/LLM/HiModel_xh2_qwen3.5-9b_w4a8_256_256k_b1_1chip_2cores_v1.4.0_20260708.gguf \ --mmproj /home/work/models/LLM/mmproj_xh2_qwen3.5-9b_w4a8_2cores_vit_896x896_v1.4.0_20260708.gguf \ -c 8192 --parallel 1 --host 127.0.0.1 --no-warmup --port 8081 --presence_penalty 1.5 --reasoning-budget 0 ``` 启动日志确认: ``` loaded multimodal model, '.../mmproj_xh2_qwen3.5-9b_w4a8_2cores_vit_896x896_v1.4.0_20260708.gguf' ==========model info=========================== =allow_image = 1 =allow_audio = 0 =vision_width = 896 =vision_height= 896 =model_desc = qwen35 9B Q4_0 ==========model info=========================== ``` **并且做了端到端真实请求验证**(不只是看模型加载日志),直接对 `http://127.0.0.1:17700/v1/chat/completions` (即前端 `generator.ts` 实际会调用的同一个地址)发了一个带 `image_url` content-part 的请求: ``` HTTP 200,耗时 2.6s 返回:{"content": "黑色"} —— 测试图片本身就是 1x1 黑色像素,模型回答正确, 证明图片被真实理解,不是被忽略/幻觉回答 ``` **结论:阻塞项已解除**,现在的 er_backend 代理路径(`ER_BACKEND_URL/v1/chat/completions`)原生支持 OpenAI 风格的 `image_url` content-part,前端可以直接照 §5.2 的格式发请求,不需要额外适配层。 **顺带记录的性能数据**(用于 §6 加载态 UI 设计参考):这次测试用的是 1×1 像素的极简测试图, `prompt_tokens` 却达到了 **808**——印证了启动日志里的警告"Qwen-VL models require at minimum 1024 image tokens",即**无论照片内容/分辨率如何,视觉编码本身有一个较高的固定 token 开销** (896×896 的 ViT 编码器决定的,不是按源图片大小线性变化)。prefill 速度约 373 tokens/s, 换算下来光是"看懂一张图"这一步就要 ~2 秒起,生成回答的时间还要另外算——真实拍照场景(图片本身 + 问题文字)单次问答预计在 3-8 秒量级,UI 必须要有明确的"识别中"等待态,不能让用户以为卡死了。 ## 3. 功能范围(建议先做 MVP) **MVP 包含:** - 聊天输入区新增"拍照"入口,唤起摄像头取景 → 拍照 → 预览/重拍 → 确认 - 确认后的照片作为一条用户消息的"附件",和文字问题一起发送 - 复用现有流式回答渲染(think 块、逐字输出等现有 ChatPanel 能力不用改) - 不做检索(不查向量库):拍照提问是纯粹的"图 + 文"直接对话,不掺 RAG 上下文 **明确不做(本期):** - 不做"拍照 + 知识库联合检索"(比如拍照后再去匹配文档库里的相关图片/文字)——这需要图像 embedding/CLIP 之类的能力,目前项目里完全没有这块基础设施,属于完全独立的大功能,先不纳入 - 不做连续视频流分析,只做单张静态拍照 - 不做照片持久化存储/历史相册(先按"用完即弃"设计,见 §6.5 的取舍说明) ## 4. 用户体验流程 ``` [聊天界面输入框旁] 新增相机图标按钮 │ 点击 ▼ [取景弹层] 全屏/半屏显示