DeepSeek 多模态视觉桥(dsh-vision-bridge)
dsh-vision-bridge 是 DeepSeek Harness(DSH)的多模态视觉插件。DeepSeek 官方接口是纯文本的:
在 Web UI 贴图后,dsh-llm-deepseek 适配器会因消息中的图片内容块直接抛 UNSUPPORTED_CONTENT。
本插件借鉴 Qwen-MM-Plugins 的思路(VL 描述注入 +
主动视觉工具),以 DSH 原生插件实现「让纯文本的 DeepSeek 模型看见图片」:
- 贴图自动代理:拦截
llm/stream请求,把消息中的ImageBlock交给 OpenAI 兼容的视觉模型 (默认 DashScopeqwen-vl-max)生成结构化中文描述(含图中文字逐字转录),替换为文本块后放行。 同图跨轮次缓存、描述文本稳定(保 KV cache 前缀);VL 失败进入失败冷却并降级为占位文本, 不阻塞会话;会话标题请求自动跳过视觉解析。 - 主动视觉工具:注册
view_image(查看本地图片 / 按问题回答)与ocr_image(逐字转录), 模型可主动查看文件系统中的截图、设计稿、图表。 - 设置页卡片(v0.2.0 起):设置 → 插件 → 插件配置 → 「视觉模型」,可修改端点(来源)/ 模型 / OCR 模型并保存,热更新生效(无需重启);密钥与 harness 官方一致——write-only 不回显明文, 只显示「已配置 / 未配置」徽标,留空保持。
- 模型能力桥接(v0.4.0 重构):运行时探测原生多模态路由并自动跳过视觉桥。
DSH rc.7 起官方
llm-pi-ai适配器(pi-ai 库)原生支持图片,本插件在请求到达时 经ctx.llm.resolveModelInfo()查询inputModalities,含image即直通(不调 VL、 不改写消息),让 pi-ai 原生多模态链路零开销工作;text-only 路由(deepseek-official) 仍走 VL 代理。旧版「给 pi-ai 模型补 image 声明」行为已移除(rc.7 中既有害又无必要)。
零硬 npm 依赖(dsh-settings/schemastery/dsh-tools 动态 import,缺包仅降级对应功能)、
不改 DSH 核心源码、不写会话事件,Windows / Linux / macOS 原生可用(无 Python / uvx / WSL 要求)。
- 设计依据与决策记录:
DeepSeek多模态视觉桥-开发计划.md - 挂载与配置:
docs/挂载指南.md - Qwen-MM-Plugins 调研:
docs/Qwen-MM-Plugins调研报告.md - 许可证:
LICENSE(MIT)
部署
方式一:官方安装(推荐)
仓库已打 dsh-plugin topic,可被 DSH 插件商店 等目录自动收录。
一条命令安装:
dsh plugin --profile web add "github:DreamRift/dsh-vision-bridge"
方式二:手动安装(tgz + bundle)
克隆本仓库,进入项目目录并生成可安装包:
cd dsh-vision-bridge npm pack # 产出 dsh-vision-bridge-0.4.0.tgz在
$DSH_HOME/profiles/web/package.json声明依赖与 bundle(包自带cordis.patch.yml,无需在 profile patch 手写 insert):{ "dsh": { "profile": { "bundles": ["dsh-vision-bridge"] } }, "dependencies": { "dsh-vision-bridge": "file:<本仓库绝对路径>/dsh-vision-bridge-0.4.0.tgz" } }安装 profile 依赖:
cd "$DSH_HOME/profiles/web" pnpm install默认配置(DashScope
qwen-vl-max等)在包内cordis.patch.yml;改配置优先走设置页 「视觉模型」卡片(热更新),高级字段见docs/挂载指南.md§3.2。设置页自动暴露(rc.7 起无需 patch):
settings.describe()列出所有已注册 namespace, 注册即暴露。旧版scripts/patch-api-proxy-namespace.mjs已删除(rc.7 删除了WEB_SETTINGS_NAMESPACES白名单)。内置路由图片准入豁免(deepseek-official 等
inputModalities被 DSH 硬编码为["text"]的路由贴图被拒时必须;DSH 升级后需重跑一次):node scripts/patch-api-proxy-image-admission.mjs详见
docs/挂载指南.md§3.6:deepseek-official无法声明 image, 会被 api-proxy 的MODEL_DOES_NOT_SUPPORT_IMAGES准入检查拦截;本脚本对providerRoutes内已接管的 provider 跳过该准入(图片由视觉桥代理转文字)。 改完需重启 DSH 后端生效。把 VL 服务的 key 写入
$DSH_HOME/.credentials.yaml(明文不进任何配置文件 / 仓库; 也可重启后直接在设置页「视觉模型」卡片里填,效果相同):QWEN_MM_VISION_API_KEY: sk-<your-key>重启
dsh web,启动日志应出现[vision-bridge] 已启用:…与[vision-bridge] 设置页已就绪:…。
工作原理
DSH 的贴图链路本身完整(拖放 → ctx.attachments → 消息中的 ImageBlock),卡在 DeepSeek 适配器
拒绝图片内容。本插件监听 llm/stream waterfall:由于 cordis 的 waterfall next 不接收替换参数,
插件采用 veto + 重入(DSH 官方插件 dsh-session-checkpoint-policy 示范的合法模式)——
不调用 next,而是把替换后的请求打上 Symbol.for 标记重新送入 ctx.llm.stream()。
不含图片的请求走同步直通,零开销。会话日志中的 ImageBlock 保持原样(替换只发生在请求侧,
聊天历史仍显示原图)。rc.7 起在重写前先探测当前路由是否原生支持图片(ctx.llm.resolveModelInfo
的 inputModalities):原生多模态(llm-pi-ai 等)直接直通、不调 VL。机制细节与源码依据见
开发计划 §3.1/§5.2 与 src/dsh/proxy.js 头注。
目录结构
dsh-vision-bridge/
├── DeepSeek多模态视觉桥-开发计划.md # 设计与决策记录(含 DSH 机制调研来源)
├── docs/
│ ├── 挂载指南.md # 挂载到 DSH + 配置 + 验证清单 + 常见问题
│ └── Qwen-MM-Plugins调研报告.md # 上游项目调研
├── package.json # dsh-vision-bridge 包(out-of-tree 插件)
├── src/
│ ├── core/ # 核心库(纯 JS,零依赖,可单测)
│ │ ├── vision-client.js # OpenAI 兼容 VL 客户端(超时 / 429 重试 / 错误分类)
│ │ ├── prompts.js # describe / ocr / ask 三类中文 prompt
│ │ ├── image-utils.js # 格式白名单、扩展名+魔数识别、base64 dataURL
│ │ ├── message-rewrite.js # 不可变重写:ImageBlock → 文本块
│ │ └── describe-cache.js # attachmentId → 描述 LRU(保 KV cache 前缀稳定)
│ └── dsh/ # DSH 适配层
│ ├── index.js # 插件入口 apply(ctx, config)
│ ├── proxy.js # llm/stream 拦截(veto + 重入 + 原生多模态直通)
│ ├── tools.js # view_image / ocr_image 工具注册与执行
│ ├── runtime.js # 共享运行时(日志 / fetch / 凭据解析 / VL 客户端)
│ ├── model-bridge.js # 运行时探测原生多模态路由(llm.resolveModelInfo)并跳过
│ ├── settings.js # 设置页桥接(schema + 热更新)
│ └── config.js # 配置解析(默认值 + 归一化,零依赖)
└── tests/ # node:test,66 个用例(mock fetch,无需 VL key)
测试
node --test tests/*.test.js # 66 个单元/集成测试全绿
覆盖:消息不可变重写(含冻结输入与 tool-result 内嵌)、缓存稳定性与 LRU、 VL 客户端(成功/401/429 重试/超时/取消/畸形响应/网络错误)、veto+重入链路 (直通/替换/降级/strict/失败冷却/标题占位/原生多模态探测直通)、 模型桥探测(resolveModelInfo 命中/TTL 缓存/降级/热更新清缓存/旧字段兼容)、 工具执行(正常/缺凭据指引/OCR 回退)。
致谢
- QwenLM/Qwen-MM-Plugins:核心思路 (VL 描述注入、结构化转述、主动视觉工具)的来源;本项目未复用其代码(Python/MCP 实现改为 DSH 原生 Node 插件)。
No comments yet. Be the first to write one.