dsh-image-vision-bridge:把图片转成文本描述喂给 DSH 主模型

前言

在 DeepSeek Harness(DSH)里做智能体开发,常会遇到一个别扭的问题:主模型是纯文本模型,用户却往对话里发截图。dsh 0.1.1+ 对这种情况做了内置降级——请求不会报错,但模型只能看到一个图片占位,实际看不到图片内容。想让模型真正基于图片回答,要么换主模型,要么自己写一层转发逻辑。

dsh-image-vision-bridge 解决的就是这个问题:它把用户消息中的图片自动发给视觉模型(默认是 opencode-go 路由上的 mimo-v2.5),把返回的文本描述喂给主文本模型,聊天记录保持原图显示。DSH 的理念是「一切皆插件」,图片理解这类能力正好可以用插件补上。下面介绍它的原理、安装和配置。

这是什么

dsh-image-vision-bridge 是一个 DSH 宿主插件,由 Icestab 维护,许可证为 MIT,当前版本 0.1.2。它的工作位置在 llm/stream 水线上:把发给主模型的请求里的图片块(含 tool-result 嵌套)替换为视觉模型生成的文本描述,构造的是重写后的请求,原请求对象与会话日志不被修改。

它声明了 dsh.bundle,是标准的可分发 bundle,安装时自动插入插件行,不需要手改 cordis.patch.yml。插件不修改 dsh 安装、不写 dsh 目录、不碰会话日志。

核心功能

  • 水线改写:在 llm/stream 水线上把主模型请求中的图片块(含 tool-result 嵌套)替换为视觉模型 mimo-v2.5 生成的文本描述,原请求对象与会话日志不被修改。
  • 聊天保持原图:图片消息原样进入 agent 并写入会话日志,聊天记录显示的就是用户发的图;描述只进模型、不进聊天。
  • 进程内缓存:描述结果按附件 id 缓存,重试和后续轮次不会重复调用视觉模型。
  • 失败降级:视觉调用失败时降级为一段失败说明文本,不打断对话;用户取消时错误照常抛出。
  • 多种安装方式:支持 npm / GitHub / 本地目录 / tarball 安装,另提供不通过 dsh plugin 的手工平铺安装。
  • 可配置项enabledprovidermodelmaxTokensmaxDescriptionCharsprompt

安装与启用

标准安装

本包是标准 bundle,用 dsh plugin add 一条命令即可,GitHub 方式可以锁定版本:

dsh plugin --profile web add github:Icestab/dsh-image-vision-bridge#c67b4b3

也可以改用 npm 包名、本地目录或 tarball:

dsh plugin --profile web add dsh-image-vision-bridge              # npm
dsh plugin --profile web add ./dsh-image-vision-bridge            # 本地目录
dsh plugin --profile web add ./dsh-image-vision-bridge-0.1.0.tgz  # tarball

必做配置:让主模型声明可接收图片

这一步插件无法替用户完成。主机的 API 边界(dsh-host-apiproxy)会校验消息与当前模型的输入模态,主模型若不声明 input 含 image,图片消息会被直接拒绝,客户端提示「当前模型不支持图片」。

先编辑 $DSH_HOME/settings.yaml(也可通过 Web 界面的 Models 页维护,该文件热重载、免重启),在 llm-pi-ai.providers.<路由> 下为主模型加 modelOverrides

llm-pi-ai:
  providers:
    opencode-go:
      modelOverrides:
        deepseek-v4-pro:
          input: [text, image]

这条声明只是放行 API 边界:插件在水线上就把图片换成了文本描述,主模型请求里不会真的出现图片块。

然后重启 dsh web——web profile 已禁用 HMR,必须重启插件才生效。

手工平铺安装(可选)

如果不想走 dsh plugin,可以先复制包目录到 profile 的模块解析路径:

cp -r ./dsh-image-vision-bridge "$DSH_HOME/profiles/node_modules/"

再在 $DSH_HOME/profiles/<name>/cordis.patch.yml 中加入插件行:

- insert:
    - id: image-vision-bridge
      name: 'dsh-image-vision-bridge'
      config:
        provider: opencode-go
        model: mimo-v2.5

settings.yaml 的 modelOverrides 配置同样是必做前提,改完同样重启 dsh web。注意:以后若在 profile 里运行过 dsh plugin add/install,pnpm 可能清掉这个手工放置的目录,重新执行上面的 cp 命令即可恢复。

配置

六个配置项的作用分别是:enabled 设为 false 时完全透传、不做桥接;provider 是视觉模型所在的 LLM 路由(必须已在 settings.yaml 的 llm-pi-ai.providers 里配置);model 是视觉模型 id;maxTokens 限制视觉调用的最大输出 token;maxDescriptionChars 限制注入主模型前的描述长度;prompt 是发给视觉模型的指令。默认走 opencode-go 路由上的 mimo-v2.5,默认复用 OPENCODE_GO_API_KEY

bundle 默认配置可以在 profile 自己的 cordis.patch.yml 里按行 id image-vision-bridge 重写(后层胜出)。自定义示例:

- insert:
    - id: image-vision-bridge
      name: 'dsh-image-vision-bridge'
      config:
        model: mimo-v2.5
        maxTokens: 4096
        prompt: 'Describe this image in English, including all visible text.'

自测

安装后可以先跑一遍离线自测,确认插件在你当前环境下工作正常:

cd "$DSH_HOME/profiles"
node node_modules/dsh-image-vision-bridge/test/transform.test.mjs

作者已在 DeepSeek Harness 0.1.0-rc.6 与 0.1.1-rc.2(@deepseek-ai/dsh、dsh-llm 同版本、cordis 4.0.1)上测试,11 项离线自测均通过。插件的 peerDependencies 为 @deepseek-ai/cordis ^4.0.1@deepseek-ai/dsh-llm ^0.1.0-rc.6,均为 optional。

适用场景与注意

适合的场景:

  • 主模型固定用纯文本模型(如 deepseek-v4-pro),但用户会发截图、照片,希望模型能基于图片内容回答;
  • 希望聊天记录保持原图显示,不出现「图片解析结果」之类的中间文本;
  • 环境里已有一个配置好的、可以调用视觉模型的 LLM 路由。

使用前需要注意:

  • 非官方承诺的用法:插件会重写进入水线的请求,而框架文档要求监听器只读不改。升级 dsh 前,建议先在临时 profile 里冒烟测试——发一张图即可。
  • 与内置降级互补:dsh 0.1.1+ 内置的图片占位降级不报错但模型看不到图片内容,本插件提供的是真正的视觉描述,二者互补。
  • 运行权限:插件以当前 dsh 进程的权限运行,安装前建议先检查源码与许可证(本项目为 MIT)。

小结

dsh-image-vision-bridge 做的事情很单一:把图片变成文本描述,让纯文本主模型也能处理图片输入,同时不污染聊天记录。如果你的 DSH 环境里已有可用的视觉模型路由,装上插件、加一条 modelOverrides、重启 dsh web 就能跑通。

  • GitHub:https://github.com/Icestab/dsh-image-vision-bridge
  • 社区目录:https://www.skillhub.cn/plugins/Icestab/dsh-image-vision-bridge
羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜