dsh-plugin-vision(dsh 识图 + 生图插件)
August 14, 2026 · View on GitHub
English | 中文
让 DeepSeek Harness(dsh)拥有识图和生图能力的可插拔插件,两个工具:
image_analyze(识图):通过 dsh 的沙箱fs服务读取图片文件(遵循工作区与权限策略),发送到 OpenAI 兼容的视觉接口(chat/completions+image_url内容块),返回文字描述或回答image_generate(生图):把文字提示发送到 OpenAI 兼容的生图接口(images/generations),把生成的图片保存到工作区并返回文件路径。生图前会自动做一轮 Prompt 工程化(见下文)
接口地址、模型、密钥全部可配置——官方 OpenAI、各类中转/代理、自建 OpenAI 兼容网关都可以用。
为什么需要这个插件:dsh 自带的 DeepSeek 适配器不支持图片内容(识图会报
UNSUPPORTED_CONTENT)。本插件把「图片 → 文字」和「文字 → 图片」交给专门的模型完成,所以你的主 agent 模型完全不需要支持图片。
特性
- 完全可插拔:出现在「设置 → 插件 → 插件列表」里,配置修改可热更新
- 识图通过沙箱文件系统读图,工作区与权限策略照常生效
- OpenAI 兼容:
baseUrl、model、密钥随意配置 - 识图支持 png / jpeg / gif / webp,带大小上限和超时保护
- 生图自动保存到工作区(默认
generated-<时间戳>.png,可指定路径),只允许写入工作区内 - 生图自动 Prompt 工程化:不指定额外模型——由 dsh 当前会话正在用的模型(如 DeepSeek)先理解需求,把它改写成结构化 Image Prompt(Goal / Main subject / Composition / Visual style / Lighting and color / Details / Text / Constraints 八段式),并自动从官方尺寸列表选择画幅;模型或接口出错时优雅降级为原始提示词,不会阻断生图
环境要求
- 已安装并运行 DeepSeek Harness Web 版(先装 Node.js,然后
npx -y @deepseek-ai/dsh web) - 识图需要一个 OpenAI 兼容接口背后的视觉对话模型,例如
gpt-4o、gpt-4o-mini、gpt-4.1 - 生图需要一个 OpenAI 兼容的生图模型,例如
gpt-image-1、gpt-image-2、dall-e-3 - ⚠️ 文生图模型不能识图、视觉模型通常也不能生图——两类模型各司其职,分别配
model和generateModel
🚀 不想自己动手?让 dsh 的 agent 帮你装(推荐)
直接把下面整段话复制给你的 agent(就是你现在正在聊天的这个),它会自己完成安装:
请帮我安装 dsh-plugin-vision 识图/生图插件:
执行
git clone https://github.com/WUDIFIVE/dsh-plugin-vision.git(克隆到临时目录)把克隆下来的
dsh-plugin-vision文件夹整个复制到~/.dsh/profiles/web/dsh-plugin-vision(如果目标已存在,先删除旧的再复制)在
~/.dsh/profiles/web/cordis.patch.yml末尾追加以下内容(密钥填在apiKey字段,不要填进apiKeyEnv):- insert: - id: vision name: './dsh-plugin-vision/lib/index.js' config: apiKey: sk-你的密钥 baseUrl: https://api.openai.com/v1 model: gpt-4o generateModel: gpt-image-2 imageSize: 1024x1024 detail: auto timeoutMs: 120000 maxImageBytes: 15728640 maxTokens: 1024检查「设置 → 插件 → 插件列表」里出现
vision且状态为启用如果写入
~/.dsh需要权限批准,提示我点允许即可
💡 提示:如果 agent 提示需要权限,点「允许」即可;配置改完通常会自动热更新,如果没生效就重启
dsh web。
或者,如果你的电脑已经配好 pnpm,可以直接给 agent 这一条命令:
dsh plugin --profile web add github:WUDIFIVE/dsh-plugin-vision
装完后让 agent 在 ~/.dsh/profiles/web/cordis.patch.yml 追加 name: dsh-plugin-vision(短名)的条目(见下文「正式安装」)。
安装(手动)
macOS / Linux
1. 把插件装进 profile(正式方式,需要 pnpm):
dsh plugin --profile web add github:WUDIFIVE/dsh-plugin-vision
发布到 npm 后也可用:
dsh plugin --profile web add dsh-plugin-vision。 启用 pnpm:corepack enable,或npm install -g pnpm。
2. 在 profile 补丁里加条目 —— 追加到 ~/.dsh/profiles/web/cordis.patch.yml:
⚠️ 常见错误(很多人在这里写错过):
apiKey填密钥本身;apiKeyEnv填「环境变量名」(比如OPENAI_API_KEY)。两者二选一即可:要么apiKey: sk-xxx直接写死密钥,要么不写apiKey、把密钥放进环境变量或 Web「设置 → 模型」页的凭据里。不要把密钥字符串填进apiKeyEnv——插件会把apiKeyEnv的值当成一个环境变量的名字去查找,然后报VISION_CREDENTIAL_MISSING。
- insert:
- id: vision
name: dsh-plugin-vision
config:
apiKey: sk-你的密钥 # ← 密钥写这里(或留空,改用环境变量/凭据)
# apiKeyEnv: OPENAI_API_KEY # ← 这是「环境变量名」,不是密钥!二选一
baseUrl: https://api.openai.com/v1
model: gpt-4o # 识图模型(视觉对话模型)
generateModel: gpt-image-2 # 生图模型(文生图模型)
imageSize: 1024x1024 # 生图默认尺寸
detail: auto
timeoutMs: 120000
maxImageBytes: 15728640
maxTokens: 1024
3. 重启 Web UI(或等配置热更新生效):
dsh web
打开「设置 → 插件 → 插件列表」,应能看到 vision 处于启用状态。
Windows(PowerShell)
同样三步,路径换成 Windows 写法:
# 1. 安装(需要 pnpm:corepack enable,或 npm install -g pnpm)
dsh plugin --profile web add github:WUDIFIVE/dsh-plugin-vision
# 2. 把上面的条目追加到:
# $HOME\.dsh\profiles\web\cordis.patch.yml
# (密钥同样填 apiKey,别填进 apiKeyEnv)
# 3. 重启
dsh web
免 pnpm 的拷贝方式(macOS / Linux / Windows 通用)
没有 pnpm 时,把插件文件夹复制进 profile 目录,用相对路径引用:
# macOS / Linux
cp -R dsh-plugin-vision ~/.dsh/profiles/web/
# Windows PowerShell
Copy-Item dsh-plugin-vision -Recurse $HOME\.dsh\profiles\web\dsh-plugin-vision
然后条目里的 name 写成 './dsh-plugin-vision/lib/index.js'(相对路径,不要写短名)。插件依赖会从 profile 的 hoisted node_modules 向上解析,无需额外安装。
配置项
| 字段 | 默认值 | 说明 |
|---|---|---|
apiKey | "" | 密钥本身。留空则走凭据/环境变量(二选一,见上方警示) |
apiKeyEnv | OPENAI_API_KEY | 环境变量名(不是密钥!),插件会去查这个名字对应的值 |
baseUrl | https://api.openai.com/v1 | OpenAI 兼容 API 根地址(自动拼接 /chat/completions、/images/generations) |
model | gpt-4o | 识图模型 id(视觉对话模型) |
generateModel | gpt-image-1 | 生图模型 id(文生图模型) |
imageSize | 1024x1024 | 生图默认尺寸(Prompt 工程化选不出合法尺寸时兜底) |
promptEnhance | true | 生图前是否启用 Prompt 工程化(用当前会话模型改写提示词并选画幅) |
promptEngineerMaxTokens | 1600 | Prompt 工程化这一轮的最大 token 数 |
allowedSizes | 官方尺寸列表 | Prompt 工程化可选的画幅白名单:1024x1024、1536x1024、1024x1536、2048x2048、2048x1152、3840x2160、2160x3840 |
detail | auto | 识图 auto / low / high,图片采样精细度 |
timeoutMs | 120000 | 单次调用超时(含图片上传/生成) |
maxImageBytes | 15728640 (15 MiB) | 识图图片大小上限 |
maxTokens | 1024 | 识图返回文字上限 |
defaultPrompt | Describe this image in detail... | 识图未给问题时使用的提示词 |
密钥解析优先级:配置 apiKey → 凭据服务(Web「设置 → 模型」页写入的)→ 环境变量 apiKeyEnv。
使用方法
识图(image_analyze)
agent 需要识图时会自动调用,参数:
path(必填):图片路径——绝对路径,或相对工作区根目录;支持 png / jpeg / gif / webpquestion(可选):针对图片的具体问题;省略时默认详细描述图片
示例对话:
看一下工作区里的
docs/架构图.png,用中文总结里面的模块关系看看
screenshots/login-bug.png,报了什么错?表单字段是什么状态?读取
scans/receipt.jpg,提取总金额和日期
注意:聊天里直接上传的图片对工具不可见(dsh 的 DeepSeek 适配器本身也拒绝图片上传)。先把图片存到磁盘,再给它路径。
生图(image_generate)
agent 需要生图时会自动调用,参数:
prompt(必填):用户的图片需求(自然语言即可,不用自己写英文提示词)output_path(可选):保存路径(相对工作区,必须在工作区内);默认generated-<时间戳>.pngsize(可选):本次生成尺寸,覆盖自动选择;合法值同allowedSizes(官方尺寸列表)
内置 Prompt 工程化:生图前,插件会用 dsh 当前会话正在用的模型(比如 DeepSeek,不需要额外配置或计费)把 prompt 改写成八段式结构化 Image Prompt,并自动从 allowedSizes$ 中选择画幅——头像/图标选 1:1,横版宣传图选 1536 \times 1024 等,竖版海报选 1024 \times 1536 或 2160 \times 3840,高清大图选 2048 系列。返回结果带 $enhanced 标记(本次是否应用了增强),增强失败会自动降级为原始提示词 + 默认尺寸。
示例对话:
帮我生成一张图:一只戴粉色领带的黄色卡通猫,站在阳光明媚的办公室里,用
output_path: docs/logo.png保存画一张末伏主题的节气海报,向日葵和落日,竖版
生成结果会保存到工作区,agent 会告诉你文件路径,之后随时可以再用 image_analyze 分析自己刚生成的图(识图生图闭环)。
工作原理
image_analyze(path, question?) image_generate(prompt, output_path?, size?)
│ │
├─ ctx.fs.resolve/stat/readBytes ├─ [Prompt 工程化] ctx.llm.stream()
├─ 识别图片类型(png/jpeg/gif/webp 魔数) │ 用当前会话的 provider/model(即 dsh 正在用的模型)
├─ data:image/...;base64 │ 把需求改写成八段式结构化 Prompt
└─ POST {baseUrl}/chat/completions │ 并自动选择官方尺寸(allowedSizes)
messages: [{role:user, content:[ │ ↓ 失败则降级为原始提示词 + 默认尺寸
{type:text, text:question}, ├─ POST {baseUrl}/images/generations
{type:image_url, image_url:{url:dataUrl, detail}} │ {model, prompt(增强后), n:1, size, response_format:"b64_json"}
]}] ├─ 解码 base64 → 识别类型 → 确定扩展名
→ choices[0].message.content └─ 写入工作区(默认 generated-<时间戳>.png)
本地测试
git clone https://github.com/WUDIFIVE/dsh-plugin-vision.git
cd dsh-plugin-vision
npm install # 安装本地测试用的 @deepseek-ai/* 依赖
node test/smoke.mjs
冒烟测试共 25 项:模块导出、两个工具注册、识图请求体(base64 data URL、模型、问题)、Prompt 工程化(会话模型驱动、结构化改写、画幅自动选择、显式尺寸优先、非法尺寸回退、失败降级、无会话模型降级)、生图请求体与落盘、路径越界拦截、密钥解析顺序、各类错误路径。fetch 与 ctx.llm 已 mock,不需要真实密钥。
故障排查
| 错误码 | 含义 |
|---|---|
VISION_FS_UNAVAILABLE | 部署中没有 fs 服务 |
VISION_IMAGE_NOT_FOUND | 识图:文件不存在或不是普通文件 |
VISION_IMAGE_TOO_LARGE | 识图:超过 maxImageBytes,请先压缩/裁剪 |
VISION_UNSUPPORTED_IMAGE | 识图:不是 png/jpeg/gif/webp |
VISION_CREDENTIAL_MISSING | apiKey/apiKeyEnv 对应的密钥未配置——最常见原因:把密钥填进了 apiKeyEnv |
VISION_PROVIDER_ERROR | 接口错误——包含上游返回的原始信息(密钥错、模型不存在、模型不支持该接口等) |
VISION_EMPTY_RESULT | 识图:模型返回了空内容 |
VISION_GENERATE_INVALID_PROMPT | 生图:提示词为空 |
VISION_GENERATE_EMPTY_RESULT | 生图:接口没返回有效图片 |
VISION_GENERATE_PATH_OUTSIDE_WORKSPACE | 生图:保存路径超出工作区,已拒绝写入 |
VISION_ABORTED | 工具调用被取消 |
常见现象与对策:
- 报
该接口暂不支持该模型调用/ 模型不存在:模型 id 写错了,或该模型不支持你正在用的接口(例如把文生图模型gpt-image-2填进了识图的model)。识图用视觉对话模型(如gpt-4o),生图用文生图模型(如gpt-image-2),两个字段别混 - 报
VISION_CREDENTIAL_MISSING且提示里出现sk-...字样:你把密钥填进apiKeyEnv了,改到apiKey(见上方警示)