让纯文本模型也能看图:消息中出现图片占位符时模型调用 vision_describe 工具,插件把本轮图片引用与提问一起转交给多模态视觉模型识别,主模型失败时自动用备用模型重试。配置在设置页完成并通过官方 settings API 持久化到 settings.yaml,热重载不丢。
安装
# GitHub 源码(首次需按提示配置 allowBuilds 构建授权后重试)
dsh plugin --profile web add github:Yinxe/deepseek-harness-plugins#path:/plugins/vision-bridge
装任何插件都等于在你的机器上跑第三方代码,权限和你本人一样大——能读你的文件、用你的凭据、访问网络,工具审批管不到它。GitHub 来源的插件还会在安装时执行构建脚本——pnpm 默认拦截,所以安装可能停在 ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED 或 ERR_PNPM_IGNORED_BUILDS;dsh 会打印出需要添加的确切键名,把它加进该 profile 的 pnpm-workspace.yaml 的 allowBuilds 下,重跑一次即可装上。放行构建本身就是一次信任判断:请只安装可信来源,并尽量锁定 commit(github:owner/repo#sha)。
README
DeepSeek Harness(DSH)视觉桥接插件:让纯文本模型也能“看图”。当用户消息里出现图片占位符 [image omitted because this model accepts text only; attachment sha256:…] 时,模型调用 vision_describe,插件把本轮图片引用 + 提问交给多模态视觉模型识别;主模型失败时自动用备用模型重试。配置通过官方 settings API 持久化到 profile 条目 dshp-vision-bridge 的 config:,设置页改动即时热更新,重启不丢。
设计原则:配置只留用户真正要决定的。视觉模型只有开关、主模型、备用模型三项;详细度是工具参数,单次图片数固定 4 张。图片只存 leaf 字段的 owned copy,会话级 LRU,无密钥、无外部依赖、卸载即干净。
安装
方式一(推荐):克隆 monorepo 安装 —— 更新只需 git pull
# 1. 克隆 monorepo(lib/ 构建产物已提交,clone 下来就能用,无需 build)
git clone git@github.com:Yinxe/deepseek-harness-plugins.git
cd deepseek-harness-plugins
pnpm install
# 2. 本地安装到 profile(路径按你执行命令时的 cwd 解析)
dsh plugin --profile web add ./plugins/vision-bridge
# 3. 重启生效
dsh web
- 更新:仓库内
git pull+dsh web(lib 已提交,未改 src 无需 build)。 - 改源码后:
pnpm --filter @dshp/vision-bridge build重打lib/host.js + lib/client.js,再重启;client 半强刷页面即可。 - 验证:设置 → 视觉模型能看到页面;或先发一张图再问“这张图里有什么?”,纯文本模型应自动调用
vision_describe。
一键 AI 安装:把下面这段发给你的 DSH AI 即可:
帮我安装视觉桥接插件(monorepo Yinxe/deepseek-harness-plugins,子目录 plugins/vision-bridge,包名 @dshp/vision-bridge):
1. git clone monorepo 并 pnpm install
2. dsh plugin --profile web add ./plugins/vision-bridge
3. dsh web 重启,确认无报错,设置页出现「视觉模型」即成功
方式二:从 Release 安装(无需 clone;更新需手动重跑命令)
dsh plugin --profile web add \
https://github.com/Yinxe/deepseek-harness-plugins/releases/download/latest/dshp-vision-bridge-latest.tgz
dsh web # 重启生效
历史版本(兼容旧版 DSH)
main 永远跟随最新 DSH。旧版 DSH 用户按 compat.json 的 tag 到 Releases 找对应 Release:
# 以 v0.2.0-rc.2 为例(DSH 0.2.0-rc.2)
dsh plugin --profile web add \
https://github.com/Yinxe/deepseek-harness-plugins/releases/download/v0.2.0-rc.2/dshp-vision-bridge-v0.2.0-rc.2.tgz
dsh web # 重启生效
更新
| 安装方式 | 更新命令 | 说明 |
|---|---|---|
| 方式一 clone(推荐) | 仓库内 git pull + dsh web |
最快;未改 src 免 build |
| 方式二 Release | 重跑同一条 add 命令 + dsh web |
URL 直装对 update 免疫 |
| 方式三 git 依赖 | dsh plugin --profile web update @dshp/vision-bridge + dsh web |
一条命令;git 解析约 35s/插件 |
功能
| 部分 | 内容 |
|---|---|
Host(src/host/ → lib/host.js) |
注册 vision_describe;监听 agent/inbox/inserted + llm/stream 缓存图片(按 attachmentId 去重,20 张/会话、50 会话 LRU);模型发现走 settings.describe() + llm.listConfigurableProviders() 与 llm.listProviders()/listModels() 两条来源;注入系统提示;启用且选好主模型时接管发送门禁;同源 JSON 路由供设置页。 |
Client(src/client/ → lib/client.js) |
「设置 → 视觉模型」:启用开关、主/备模型下拉、刷新列表、测试路由。开关/标签/按钮/菜单全部用官方 dsh-client-ui-primitives,颜色走 --dsw-* token。 |
| 同源路由 | GET /ext/dshp-vision-bridge/state(模型 + 配置)、POST /ext/dshp-vision-bridge/config(保存补丁)、GET /ext/dshp-vision-bridge/check(探活主/备路由),均带同源校验与 body 上限。 |
| 工具 | vision_describe,输出 { description, model },模型侧渲染为纯文本。 |
模型工具:vision_describe
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
question |
string |
✅ | 主模型结合当前对话上下文生成的看图提示词,写清想从图片确认的具体内容;插件原样转给视觉模型,不追加固定后缀。 |
image |
integer |
只看第几张图(从 1 开始,多图时用);留空分析本轮最近 4 张。 |
question是主模型自己生成的提示词:想读报错就写报错,想转录就写“逐字转录”,插件不再提供detail之类的固定模板。
返回:
{ "description": "视觉模型返回的文本", "model": "provider/model" }
配置项
| 字段 | 类型 | 默认 | 说明 |
|---|---|---|---|
enabled |
boolean |
true |
总开关。关闭后 vision_describe 直接报错。 |
primary |
{provider, model} | null |
null |
主视觉模型;未选择时 vision_describe 临时用候选列表第一项,但发送门禁不会接管。 |
fallback |
{provider, model} | null |
null |
备用模型,主模型失败时重试一次;与主模型相同则不重试。 |
配置视觉模型
候选来自两处并集去重:
- 设置里的模型目录:
llm.listConfigurableProviders()给出每个 provider 的settingsNs+settingsPath,再用settings.describe()读取models[]中input含image的模型。 - 运行时 provider:
llm.listProviders()+llm.listModels(provider)中inputModalities含image的模型。
在 设置 → 模型 中编辑多模态模型,勾选 image 输入即可。等价 YAML:
llm-pi-ai:
providers:
openrouter:
models:
- id: qwen/qwen2.5-vl-32b-instruct
name: Qwen2.5 VL 32B
input: [text, image] # ← 关键:声明支持图片输入
保存后回到 设置 → 视觉模型 点「刷新列表」。推荐至少配两个视觉模型,一个主模型、一个备用模型。
使用
- 发图:在对话里粘贴或上传图片(一次可多张)。
- 提问:纯文本模型看到占位符后调用
vision_describe,把图片和问题一起发给视觉模型。 - 查看结果:
description以tool-result回到模型上下文,模型据此继续回答。
进阶:
- 多图时用
image: 2指定第二张。 - 问题由主模型按上下文生成:想读某行报错就写那行报错,想转录就写“逐字转录”,不需要额外开关。
- 设置页的「测试路由」只检查路由可解析性与 image 能力声明,不发起真实推理。
验证
pnpm --filter @dshp/vision-bridge test # node --check 双 bundle + CSS Module 静态检查
pnpm --filter @dshp/vision-bridge build
设置页自检:打开 DSH Web → 设置 → 视觉模型,确认:
- 模型列表出现你在 设置 → 模型 中勾选 image 的模型;
- 切换主/备模型后刷新页面仍保持(持久化);
- 点「测试路由」显示主/备路由可用。
端到端:发一张截图并问“这张图里有什么?”,观察模型是否调用 vision_describe 且返回非空 description。
工作原理
用户发图(content: [{type:'image'}, {type:'text'}])
├─ agent/inbox/inserted ─┐
└─ llm/stream ───────────┼─→ 图片缓存 Map<sessionId, Map<attachmentId, ImageRef>>
│ 只存 attachmentId/mediaType/bytes/width/height/name
│ 按 attachmentId 去重;20 张/会话、50 会话 LRU
纯文本模型看到占位符 → vision_describe({question, image?})
├─ 取会话缓存 → image 序号过滤 / 最近 4 张
├─ question 原样透传(不拼固定后缀)
└─ describeWithFallback()
├─ 主模型 → llm.stream({provider, model, messages:[image…, text]})
└─ 失败 → 备用模型重试一次(用户取消不重试)
关键细节:
- 发送门禁:启用且选好主模型时包装
llm.resolveModelInfo,给缺 image 的模型补上inputModalities,让纯文本模型可以接收图片;请求侧仍由 llm 层按真实能力把图片投影成占位符。探活使用未包装的原函数,避免“自证可用”。 - 模型发现:0.2.x 的 settings 服务没有
get(ns),统一用settings.describe();provider 的命名空间和路径来自llm.listConfigurableProviders(),不再硬编码llm-pi-ai/llm-deepseek。 - 提示词:
question由主模型结合当前对话生成,插件只做 trim + 4000 字符截断,不写死“描述这张图片”之类的兜底句,也不追加detail后缀。 - 流式归一:
text-delta增量优先,block-end只在同一 index 没有增量时兜底;finish的error/aborted转成异常,空返回触发 fallback。 - 持久化:
POST /config逐字段校验后调用settings.update(NS, patch),写入 profile 条目config:并原地热更新;配置只认dshp-vision-bridge,不读旧 key / 旧文件。
配置(cordis.patch.yml 覆盖)
- id: dshp-vision-bridge
name: '@dshp/vision-bridge'
config:
enabled: true
primary: { provider: 'openrouter', model: 'qwen/qwen2.5-vl-32b-instruct' }
fallback: { provider: 'openrouter', model: 'openai/gpt-4o-mini' }
代码结构
src/host/
index.ts apply 装配:缓存、门禁接管、系统提示、工具、路由
config.ts NS + schemastery Config(3 个 volatile 字段)
types.ts 领域模型 + llm/settings 最小服务接缝
http.ts json / sameOrigin / readBody
cache.ts 会话图片缓存(去重 + LRU)
vision.ts 模型发现、单次调用、主备 fallback、问题拼装
src/client/
index.tsx 只导出 inject / apply,注册 settings.section
VisionSection.tsx 设置页
components.tsx Row + Select
api.ts state / config / check 路由封装
types.ts 协议 + slots/ctx 接缝
styles.module.css 版式(构建期内联)
lib/host.js Host 单文件 ESM(提交物)
lib/client.js Client 单文件 CJS(提交物)
cordis.patch.yml bundle 挂载行
常见问题
- 没有可用的视觉模型:到 设置 → 模型 给多模态模型勾选 image 输入,保存后点「刷新列表」。也可以在条目
config:里直接写primary/fallback。 - 报“本轮没有找到可用的图片”:确认图片是上传/粘贴的附件,不是图片 URL 文本;重试一次让
agent/inbox/inserted重新入缓存。 - 报“视觉桥接已关闭”:设置页打开开关。
- 设置页没有「视觉模型」:确认 profile
package.json的dsh.profile.bundles含@dshp/vision-bridge,重启后硬刷新浏览器。 - 从 1.x 升级:
detail/maxImages/promptTemplate已移除。旧条目config:里残留的这三个键不会被读取,可手动删除;primary/fallback/enabled原样可用。图片提示词由主模型按上下文生成,单次图片数固定 4 张。
卸载
dsh plugin --profile web remove "@dshp/vision-bridge"
dsh web
配置保存在 profile 条目 dshp-vision-bridge 的 config:,删除该分节即回默认值。
移植说明
本目录是原 ~/.dsh/plugins/vision-bridge/lib/index.js(JS,816 行)的 TypeScript 重写:
| 原实现 | 现文件 |
|---|---|
lib/index.js 的 ctx / 工具 / 路由装配 |
src/host/index.ts |
| 图片缓存与 block 扫描 | src/host/cache.ts |
模型发现 / llm.stream / fallback |
src/host/vision.ts |
| 设置页与同源路由调用 | src/client/VisionSection.tsx、src/client/api.ts |
构建:pnpm --filter @dshp/vision-bridge build(lib/ 是提交物,改 src/ 后必须重打并一起提交)。
免责声明
本插件只做图片转交,不存储图片原图,不写入除 profile 条目 config: 之外的任何用户文件。视觉模型的费用、额度与内容政策由对应 provider 决定。
链接
同类插件
liustack/modlens★ 4725
为纯文本模型架起视觉桥梁:粘贴图片,输出结构化 JSON 证据(OCR、版面、语义)。
ysr666/dsh-vision-router★ 1211
为纯文本 Agent 提供视觉能力:内置免 Key 视觉链 + 像素级视觉工具(看图问答、定位、裁剪、像素对比、取色、OCR、矢量化、抠图、截图);粘贴图片即可用。
Anionex/dsh-vision-toolkit★ 922
让纯文本模型处理视觉任务:粘贴图片后自动切换到 Vision Toolkit 变体,支持图片问答、多图比较、长截图 OCR、截图还原前端 UI、元素定位与像素对比。默认无需 API Key——图片经作者自建的免费服务处理,每台机器每天 100 张;也可改为指向自己的服务商。
SAOS-3624/dsh-video-storyboard★ 384
把视频(本地文件,或 B 站 / yt-dlp 链接)压成一张可寻址的宫格图:每格烧编号、对应精确时间、挂台词,底部还有同时间轴的音频包络;video_zoom 可对任意窗口高清重看——纯文本模型因此能「看」视频,而不是读别人写的摘要。
dickpy/dsh-imagegen★ 167
面向 DSH Web GUI 的 AI 生图插件:通过可配置的 OpenAI 兼容端点(gpt-image-2 / gpt-image-1 / dall-e-3)实现文生图与图生图,提供 api_url/api_key 设置卡片与侧边栏分栏生图工作台。
fandc520/dsh-comfyui★ 159
让 DeepSeek Harness 的 Agent 直接驱动本地或远程 ComfyUI:comfyui_run / comfyui_object_info / comfyui_workflow 工具生成与编辑图像、视频,附带工作流库(图工作流提取:按分量 / 主流程 / 整体)、加载区分辨率自动匹配、实时队列、SDXL 与 Wan 2.1 模板、配套 skill 与同源媒体代理。
社区评论
评论公开保存在 GitHub Discussions。加载评论会连接 GitHub 和 Giscus;发表内容需要 GitHub 账号。