Bundle
dsh-image-auto-describe
Image auto-describe provider for the DeepSeek Harness apiproxy admission seam: transcribes pasted images through configurable vision routes (Qwen first, GLM fallback) so text-only session models still receive image prompts.
- Source
- oldHan2423
- License
- MIT
- Updated
- Updated 5 days ago
Readme
# 贴图自动识别(dsh-image-auto-describe)
中文 | [English](README.en.md)
**让「不会看图」的 DeepSeek 也能看懂你发的图片。**
一句话:你往对话里贴一张图,这个插件先让一个看得懂图的视觉模型把图片内容读成文字,再把这段文字交给 DeepSeek 继续回答——全程自动,不需要你做任何额外操作。
## 它解决什么问题
DeepSeek Harness 里很多主力模型(比如 deepseek-v4-pro)只处理文字。默认情况下,你贴图发消息会被直接拒绝:
```
Model "deepseek-v4-pro" does not support image input.
```
这个插件把「拒绝」换成「理解」:
```
你贴图发消息
↓
消息被拦下:当前模型不支持图片
↓
插件接手:把图片交给视觉模型
(默认 Qwen3-VL-32B,失败自动换免费的 GLM-4V-Flash)
↓
视觉模型把图里的内容写成文字
↓
这段文字替掉图片,交给 DeepSeek 正常回答
```
实际用起来的效果:
- 截图里的报错、日志、表格、聊天记录,图上的文字会被**逐字摘录**,可以直接接着讨论
- 识别结果会注明是哪个视觉模型识别的,原图在对话里保留可点开对照
- 识别中对话里会出现一个低调的「正在识别图片…」状态,识别完自动变成正式消息
- 所有视觉模型都失败时,退回原来的「不支持图片」提示,**不会假装看懂、不会胡编**
> **注意**:DeepSeek 看到的始终是「文字描述」,不是图片本身。视觉模型没写到的细节,DeepSeek 也无从知道——但这已经覆盖了绝大多数「发截图问问题」的场景。
## 安装
可从插件市场安装,或一条命令:
```sh
dsh plugin --profile web add github:oldHan2423/dsh-image-auto-describe
```
包声明了 `dsh.bundle.patch`,`dsh plugin` 会自动把它接入 profile 补丁层;profile 自己的 `cordis.patch.yml` 仍可按 id 覆盖该行。
### 宿主补丁(装完必做一次)
官方 apiproxy 目前没有公开的图片准入接口,「拒绝贴图」的逻辑是写死的。本仓库附带一个幂等补丁,把那个拒绝点改成这个插件提供的「转写放行」。装好后执行一次(或 Harness 升级恢复原文件后重跑一次):
```sh
node scripts/patch-seam.mjs # 打补丁(幂等,重复跑无害)
node scripts/patch-seam.mjs --unpatch # 回滚(幂等)
```
补丁改动两处:`dsh-host-apiproxy/lib/index.js` 里的一处拒绝分支,以及向它的 api barrel 注入 `IMAGE_AUTO_DESCRIBE_SERVICE` 常量。锚点针对 `0.1.0-rc.6` 的源码形态;版本对不上时报 `MISS` 且不做任何修改,绝不硬改。每次执行都会用 `node --check` 复核被改的文件。打补丁后重启 Harness 宿主生效。
## 要求
- DeepSeek Harness `0.1.0-rc.6`(补丁锚点版本;更新版本的锚点未跟进前会报 `MISS`)。插件把官方 `@deepseek-ai/*` 包作为对等依赖(peer dependency)解析;profile 必须已组合这些包。
- 视觉路由必须已存在于组合好的 `llm` 能力中——例如由 `llm-pi-ai` 插件注册的提供者。默认值期望 `siliconflow`(Qwen/Qwen3-VL-32B-Instruct)与 `zhipu`(glm-4v-flash),且各自 API Key 已配置。
## 配置
| 键 | 类型 | 默认 | 含义 |
| ------------ | ------------------------------------------- | ------------- | ---------------------------- |
| `candidates` | `{ provider: string, model: string }[]`(至少 1 条) | Qwen → GLM | 按顺序尝试的视觉路由,第一条成功者生效 |
| `maxTokens` | 正整数 | `4096` | 每次转写调用的 token 预算 |
Web 的「插件」设置页可直接编辑(路由从已配置的多模态模型里选,无需手填),下一次转写即用新配置,无需重启;把路由清空的编辑会被拒绝。若 Harness 版本的设置页还没有这张卡片,路由保持默认值,可在 profile 补丁中覆盖:
```yaml
- id: image-auto-describe
config:
candidates:
- provider: siliconflow
model: Qwen/Qwen3-VL-32B-Instruct
- provider: zhipu
model: glm-4v-flash
maxTokens: 4096
```
## 行为细节
- 放行的消息保留原图片块——标记为 `presentationOnly`,对话里可预览、可点开原图,但绝不进入模型请求——并追加 `[用户在本条消息中附带了 N 张图片,以下为视觉模型(<model>)的自动识别结果]` 前缀的转写文本;与图片同发的文字跟在 `[用户同时说:]` 之后。Web 转录把转写折叠在「查看图片识别内容」展开项后,对话里只显示图片。
- 转写期间,消息在对话流尾部显示为待定气泡(含图片预览)+「正在识别图片…」状态行。
- 所有路由失败或未产出可用文本时,插件上报失败,保持原拒绝,绝不静默丢弃。
## 模型体验(成本与开销)
每次带图准入对每条被尝试的路由发起一次独立的视觉模型流式调用,受 `maxTokens` 限制(通常第一条路由即成功)。视觉调用是单次无历史请求,转写之间没有 KV 缓存复用。会话模型永远看不到图片字节:只有转写文本进入上下文——token 成本是文字长度,不是图片体积。
## 已知限制与后续工作
- 转写文本替代了模型可见消息中的原图;视觉模型未转写出的图片细节,会话模型无法回答(对话中仍可预览原图)。
- 未配置路由或全部路由失败(无密钥、无额度)时,消息以原错误拒绝,而非降级放行。
- 路由必须已存在于组合好的 llm 能力中(由部署的 llm 提供者插件注册);本插件不注册提供者。
## 来源
本插件起源于 deepseek-harness 工作树(提交 `553ea9e` 与 `d7ca86a`):`packages/host/apiproxy` 中硬编码的 `autoDescribeImages` 补丁被重构为 apiproxy 准入接口之上的独立提供者。本仓库是该插件的独立发行版。MIT 许可。
Install
dsh plugin --profile web add github:oldHan2423/dsh-image-auto-describe
Profile: web
With the hub plugin installed, ask your agent to install it by name — it resolves the same plan shown here.
dsh plugin --profile web add github:stvlynn/dsh.fish#path:packages/dsh-plugin-hub
install dsh-image-auto-describe from the hub
- This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.