dsh-vision-plugins
August 14, 2026 · View on GitHub
DeepSeek Harness(dsh web)的委托式识图插件对:让纯文本主模型(如 deepseek-v4-flash)也能"看图"——聊天框直接粘贴/上传图片会自动调用视觉模型(默认 mimo-v2.5)识别,图片从不进入主模型上下文;主模型是原生多模态模型时则图片直通、原生识别。
解决的问题
DSH 的请求层有两道闸门:
- apiproxy 发送闸门:当前模型未声明
image输入模态时,带图消息直接被拒(MODEL_DOES_NOT_SUPPORT_IMAGES); - LLM 适配器:请求内容含图片而模型未声明 image 输入时抛
UNSUPPORTED_CONTENT。
纯文本模型(deepseek-v4-flash / deepseek-v4-pro 等)本身不接收图片,所以"粘贴图片"和"模型读图"在原生 DSH 里都不可用。本插件对在模型与网关之间加了一层自动委托:
用户在聊天框粘贴图片
→ 发送闸门放行(设置里给纯文本模型声明 input: [text, image])
→ vision-inline 在 agent/pre-step 钩子接管
→ 读取附件 → mimo-v2.5 详细识别
→ 图片块替换为文字描述(【用户上传的图片,已由视觉模型识别】…)
→ 主模型拿描述继续推理
按模型能力自动分流
判断依据是 pi-ai 模型目录(opencode-go.json)的原生 input 模态,不受 settings.yaml 里为过闸门声明的 input 影响:
| 主模型 | 粘贴图片 | read_image 工具 |
|---|---|---|
| 纯文本(deepseek-v4-flash/pro、qwen3.7-max、glm-5.x、hy3、mimo-v2.5-pro、minimax-m2.7) | 自动转视觉模型文字描述 | 被守卫拒绝(防网关报错) |
| 原生多模态(mimo-v2.5、qwen3.7-plus、minimax-m3、kimi-k2.6/k2.7/k3、qwen3.6-plus、grok-4.5) | 图片直通模型,原生识别 | 可用 |
| 未知模型 | 按纯文本处理(安全兜底) | 被守卫拒绝 |
文件
| 文件 | 作用 |
|---|---|
plugins/vision-tool.mjs | 模型可调用的 vision 工具:给定图片路径,用视觉模型识别并返回文字描述(用于"帮我看看 <路径>"场景) |
plugins/vision-inline.mjs | 自动发图识图:agent/pre-step 钩子里把消息中的图片块替换为视觉模型描述;按模型能力分流;注册 read_image 守卫 |
install/cordis.patch.insert.yml | 挂载两个插件到 profile 补丁的 insert 片段 |
install/settings.model-input.snippet.yaml | settings.yaml 中给纯文本模型声明 input: [text, image] 的示例 |
examples/vision-test.html | 测试图源文件(渲染成 PNG 后可用于验证) |
安装
以 ~/.dsh 为 DSH home、web profile 为例(dsh web / DeepSeek Harness Desktop 通用):
-
复制插件到 profile 目录:
cp plugins/vision-tool.mjs plugins/vision-inline.mjs ~/.dsh/profiles/web/ -
挂载插件:编辑
~/.dsh/profiles/web/cordis.patch.yml,把install/cordis.patch.insert.yml里的 insert 块追加进去。 -
声明图片输入:编辑
~/.dsh/settings.yaml,给纯文本主模型(如 deepseek-v4-flash)的条目加上input: [text, image](参考install/settings.model-input.snippet.yaml)。多模态模型本来就在目录里声明了 image,无需改动。 -
重启服务:Ctrl+C 停掉
npm exec @deepseek-ai/dsh web后重新运行(或重启桌面 App)。HMR 在 web profile 里被禁用,必须重启。 -
验证:新会话里直接粘贴一张图片,或对
vision工具说"看看 <图片路径>"。
配置
两个插件共用的核心配置(写在 cordis.patch.yml 对应行的 config: 里):
| 键 | 默认值 | 说明 |
|---|---|---|
model | mimo-v2.5 | 视觉模型 id(同一网关的其他多模态模型:qwen3.7-plus / minimax-m3 / kimi-k3 / grok-4.5 等) |
baseUrl | https://opencode.ai/zen/go/v1 | OpenAI 兼容端点 |
apiKeyEnv | OPENCODE_GO_API_KEY | API key 来源:优先 credentials 服务,其次环境变量,最后 ~/.dsh/.credentials.yaml |
timeoutMs | 120000(tool)/ 60000(inline) | 视觉模型调用超时 |
maxImageBytes(tool) | 16 MB | 单张图片大小上限 |
textOnlyModelIds(inline) | [] | 额外指定必须走文字转换的模型 id(覆盖目录判断) |
API key
插件不存储密钥。按以下顺序解析 apiKeyEnv 指向的 key:
- DSH credentials 服务(
~/.dsh/.credentials.yaml,与 DSH 其他凭据同源); - 进程环境变量;
~/.dsh/.credentials.yaml直接读取(兜底)。
注意事项
- read_image 守卫:纯文本模型会话里
read_image会被拒绝(它会把图片块塞进模型上下文,而"声明了 image 的纯文本模型"会在网关层被 400 拒绝)。看图片统一用vision工具或直接粘贴图片。 - 不要在纯文本模型上真正声明图片能力:
input: [text, image]只是让发送闸门放行的配置声明;若图片真的进入 deepseek-v4-flash 的请求,网关会返回unknown variant 'image_url'错误。转换插件保证图片永远不会到达纯文本模型。 - 多模态直通:把会话主模型切成 mimo-v2.5 等原生多模态模型后,图片会直接发给该模型原生识别(不消耗额外的识别步骤)。
测试
examples/vision-test.html 是一张含中文标题、彩色几何图形和数字 42 的测试图源文件,可用 headless Chrome 渲染成 PNG 后验证:
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" \
--headless=new --disable-gpu --window-size=800,500 \
--screenshot=vision-test.png "file://$PWD/examples/vision-test.html"
兼容性
- 目标环境:DeepSeek Harness
0.1.0-rc.6web profile(@deepseek-ai/dsh); - 插件通过 profile 层
cordis.patch.yml挂载,host 平面注册,对dsh web和桌面 App 分发通用; - 视觉网关:opencode.ai(OpenAI-compatible
chat/completions,支持image_url内容块)。
License
MIT