让 DeepSeek Harness 里的纯文本模型能看图。
49.8/100
综合分
44
GitHub 星标
460
npm 周下载
—/5
用户评分
数据截至 2026/10/22 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add dsh-design-qanpm 源 · dsh-design-qa 的发布者账号已校验与本仓库一致
状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:已验证
是什么
dsh 原生插件 · vision
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 13 天前
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查✓ 自动检查通过展开查看检查明细 ↓
以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。
✓npm 包dsh-design-qa @ 0.1.4
✓Node 引擎要求 ^22.19 || >=24 · 基线 Node 22.19 满足
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明
验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/30 09:05:11
安全扫描自动 · 静态分析源码v2.7.0🔵 扫描:含敏感能力尚无人工评估展开查看扫描说明与证据 ↓
安全扫描自动 · 静态分析源码
v2.7.0静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。
可执行外部命令读写/删除本地文件读取剪贴板或密钥环境变量
查看扫描证据(共 60 处,展示前 31 条)
- 读取本地文件lib/index.js:57
data = await readFile(path); - 写入本地文件lib/index.js:337
await mkdir(SPILL_DIR, { recursive: true }); - 写入本地文件lib/index.js:339
await writeFile(path, data); - 写入本地文件lib/index.js:371
await mkdir(SPILL_DIR, { recursive: true }); - 写入本地文件lib/index.js:377
await writeFile(path, (await ctx.attachments.readImage(ref)).data); - 读取本地文件install.mjs:58
if (!existsSync(path)) return - 读取本地文件install.mjs:61
const mine = readdirSync(dir) - 读取本地文件install.mjs:63
.map(entry => ({ entry, time: statSync(join(dir, entry)).mtimeMs })) - 删除本地文件install.mjs:65
for (const { entry } of mine.slice(0, -2)) rmSync(join(dir, entry), { force: true }) - 写入本地文件install.mjs:67
copyFileSync(path, `${path}.bak-${stamp}-${process.pid}`) - 读取本地文件install.mjs:76
if (!existsSync(target)) throw new Error(`找不到 ${target},无法链接到 ${linkPath}`) - 删除本地文件递归install.mjs:77
rmSync(linkPath, { recursive: true, force: true }) - 读取本地文件install.mjs:117
try { return await readlink(`/proc/${pid}/cwd`) } catch { } - 读取本地文件install.mjs:186
try { harvest(await readFile(`/proc/${pid}/environ`, 'utf8'), '\0'); return names } catch { } - 执行外部命令来自配置/变量install.mjs:361
const child = spawn(process.execPath, [fileURLToPath(import.meta.url), '--relaunch-worker'], { - 写入本地文件install.mjs:396
mkdirSync(dirname(RESTART_LOG), { recursive: true }) - 写入本地文件install.mjs:398
writeFileSync(RESTART_LOG, `\n===== ${new Date().toISOString()} 重启 =====\ncwd: ${cwd}\ncmd: ${argvJson ?? command}\n`, { flag: 'a' }) - 执行外部命令来自配置/变量install.mjs:403
if (argvJson === undefined) spawn(command, { cwd, detached: true, stdio, shell: true }).unref() - 执行外部命令来自配置/变量install.mjs:406
spawn(argv[0], argv.slice(1), { cwd, detached: true, stdio, shell: false }).unref() - 写入本地文件install.mjs:442
mkdirSync(dirname(patch), { recursive: true }) - 写入本地文件install.mjs:443
writeFileSync(patch, next.trimStart(), 'utf8') - 写入本地文件install.mjs:478
writeFileSync(settings, next, 'utf8') - 删除本地文件install.mjs:913
if (plan.dropOrig === true) { rmSync(plan.orig, { force: true }); continue } - 删除本地文件install.mjs:916
if (plan.status === 'revert') rmSync(plan.orig, { force: true }) - 删除本地文件install.mjs:922
if (plan.status === 'patch') rmSync(`${plan.path}${ORIG_SUFFIX}`, { force: true }) - 读取密钥环境变量install.mjs:1009
if (!process.env.BAILIAN_API_KEY) missing.push('当前环境没有 BAILIAN_API_KEY(也可在 Web 的 设置→模型 页存进凭据服务)') - 读取本地文件src/index.ts:140
data = await readFile(path) - 写入本地文件src/index.ts:464
await mkdir(SPILL_DIR, { recursive: true }) - 写入本地文件src/index.ts:469
await writeFile(path, data) - 写入本地文件src/index.ts:512
await mkdir(SPILL_DIR, { recursive: true }) - 写入本地文件src/index.ts:522
await writeFile(path, stored.data)
扫描于 2026/11/3(0 天前) · 范围 入口闭包 + 全包扫描 · 来源 npm 发布包
静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。
依赖的 DSH / Cordis 模块
@deepseek-ai/cordis@deepseek-ai/dsh-attachment@deepseek-ai/dsh-llm@deepseek-ai/dsh-tools@deepseek-ai/schemastery给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
功能亮点
- 纯文本模型看图
- 设计还原度质检
- 比对实现与设计稿
为 DeepSeek Harness 做设计还原度质检:给纯文本模型借一只眼睛,再判断实现是否与设计稿一致。随附这套判断背后的基准——四个样例、23 个注入缺陷,以及全部原始模型记录。等 DeepSeek 推出视觉能力,它就自动退休。
最近更新
在 GitHub 查看全部 →v0.1.32026-08-20
· 安装期的退休判据
补丁的存在前提是「本体拒收图片」。上游哪天自己支持了,补丁就从修复变成破坏 —— 它会把模型本来看得见的图换成一行文字指针。
让位此前只在运行时存在(deepseek_vision 查到调用方能看图就自我拒绝);本版补上安装期那一道:install.mjs 会先读 llm-deepseek 声明的 inputModalities,已含 image 就拒绝再打这处补丁,并打印它依据的那行声明。
判断按找到的每一份 DSH 分别做 —— 一台机器上可能装着多份,新的那份退休了不代表旧的那份也该跳过。只认数组字面量:llm-pi-ai 的 [...model.input] 是用户配置,不是上游支持,不该被当成退休信号。还原路径完全不看这个判据 —— 已经打上去的补丁,无论上游变成什么样都必须撤得掉。
· 原始评测输出入库
eval/runs/ 现在带着每个已发布数字背后的逐格模型原文,按各自使用的夹具分开存放,并附上移动端夹具本身,好让横评表可以真正重跑。
同时改正了一处夸大:横评表(24/24 · 21/24 · 18/24)跑的是一组未随仓库分发的移动端仪表盘夹具,而紧挨着的零差异对照是在 evalset/landing 上的另一次运行,另外两个模型从未测过这一项。原先把两者并排陈列,等于同时高估了两边。现在每个数字都标注了出处,其中一行只以聚合数字存在、无法逐格复核,也已明确标出;跑分脚本目前只接通 landing 一组,这一点同样写明。
· 不再重复落盘
spillImages 会跳过已经在磁盘上的图片。
· 其他
· 清理改名遗留:NOTICE 里的旧包名、.gitignore 补 *.dsh-design-qa-orig、新增 .gitattributes
· eval/README.md 说明这套评测为什么存在:它回答的是「借来的这只眼够不够格当判定闭环里的裁判」
Full Changelog:
v0.1.42026-08-20
DSH 0.1.0-rc.8 把 llm-deepseek 的图片准入判断搬了家,本版跟上。不升级的话,在 DeepSeek 路由上粘贴图片会失败。
· 发生了什么
rc.8 给 llm-deepseek 加了一条原生图片通路(imagePart()、serializeMessagesWithImages()、目录模型可配 inputModalities),同时把「模型不支持图片」的判断从 serialize.ts 的 assertTextOnly() 上移到了 adapter.ts,位置在序列化之前。
于是出现一种很隐蔽的失效:旧落点的锚点文本还在、补丁照样打得上、--check-patches 全绿,但没有任何请求再经过它。assertTextOnly() 如今只在「消息里根本没有图片」时被执行到 —— 而那种情况它本来就不抛错。
· 改了什么
落点二从 serialize.ts 改到 adapter.ts。 未声明 image 的模型,其图片块在准入处被换成 [图片 … attachment=] 文字指针;声明了 image 的模型走 else 分支,原生通路一个字节都不动。
改写的是 options 本身 —— 它与随后 this.request(options, …) 用的是同一个变量,且 attachments 保持 undefined,于是自然走 serializeRequest 而非 serializeRequestWithImages。指针仍在通往线路的最后一站才生成,持久化、会话日志、界面渲染看到的都还是真正的图片块。
serialize.ts 保留在落点表里,但只还原、不打补丁。 从表里删掉它,会让从 0.1.3 及更早升上来的用户留下一个 --revert-patches 再也认不出、因而永远清不掉的改动。若安装时发现那份文件仍带着旧补丁,安装器会硬停并要求先还原,而不是在第一代补丁上再叠一层。
落点总数仍是三处,没有增加。
· 从 0.1.3 或更早升级
node install.mjs --revert-patches # 必须先还原,否则安装器会拦住你
node install.mjs --route-only
node install.mjs --restart
· 验证
在真实的 rc.8 工作树上:还原至干净检出 → 六处锚点全部命中 → 补丁写入 → 三个构建产物 node --check 通过 → dsh web 重启并返回 200。
· 关于「官方多模态上线」
顺带实测了一次,结论写在这里免得他人重复劳动:截至本版,官方 API 的 deepseek-v4-pro 与 deepseek-v4-flash 都不接受图片输入(400 unknown variant image_url,同一 key 的纯文本请求返回 200),/models 也只返回这两个模型。rc.8 建好了客户端管道,服务端能力尚未开放。
0.1.3 起内置的安装期退休判据因此不会触发 —— 上游哪天在 inputModalities 里声明 image,安装器会拒绝再打这处补丁并说明原因。
· 同版附带
「提问方式比模型选型更决定成败」那张表,现在标明了哪几行可以复核:评测脚本只实现了「有区别吗」一种问法(tilebench.py 的 FACETS),只有它的 0/30 有逐格原文;0/36 与 0/12 两行没有提示词常量、没有命令、没有输出文件。那张表记录的是真实做过的事,但不是可复现基准,现在也不再这样声称。
Full Changelog:
数据来自仓库的 GitHub Release,可能与插件实际版本不一致。
README
由 DeepSeek 最新模型翻译生成dsh-design-qa
让 DeepSeek Harness 里的纯文本模型能看图。
做这个是为了在 DSH 上实现产品设计这项能力:从设计稿写出实现、再自己判断实现得像不像、不像就修 —— 而 DeepSeek 写得了代码却看不见图,判定那一环做不了。本插件通过一个工具把多模态能力借给它,让它具备执行产品设计功能所需的那只眼睛。
- 任何纯文本模型都能读图。 不只是 DeepSeek —— 你在 DSH 里自己接的那些 OpenAI 兼容端点同样适用(实测过 OpenRouter 上的 z-ai/glm-5.2)。前提是该模型支持 tool calling:它得能自己调 deepseek_vision。官方多模态上线那天,本插件自动让位、可原样留着。
- 把识图做成一个 tool。 图片不进主模型上下文;它看到一行 [图片 …] 提示,需要时自己调 deepseek_vision。不看就不产生任何成本,问什么由模型自己决定。
- 附 eval 与原始输出。 4 组夹具、23 处注入缺陷、四条通过线 —— 回答的是「借来的这只眼够不够格当判定闭环里的裁判」,而不是「模型跑没跑通」。能看见 ≠ 可用于判定:看得见但不主动看、会编、不稳、说不清,四种失效各对应一条通过线。
展开完整文档(README 剩余 1 节)
dsh-design-qa
让 DeepSeek Harness 里的纯文本模型能看图。
做这个是为了在 DSH 上实现产品设计这项能力:从设计稿写出实现、再自己判断实现得像不像、不像就修 —— 而 DeepSeek 写得了代码却看不见图,判定那一环做不了。本插件通过一个工具把多模态能力借给它,让它具备执行产品设计功能所需的那只眼睛。
- 任何纯文本模型都能读图。 不只是 DeepSeek —— 你在 DSH 里自己接的那些 OpenAI 兼容端点同样适用(实测过 OpenRouter 上的 z-ai/glm-5.2)。前提是该模型支持 tool calling:它得能自己调 deepseek_vision。官方多模态上线那天,本插件自动让位、可原样留着。
- 把识图做成一个 tool。 图片不进主模型上下文;它看到一行 [图片 …] 提示,需要时自己调 deepseek_vision。不看就不产生任何成本,问什么由模型自己决定。
- 附 eval 与原始输出。 4 组夹具、23 处注入缺陷、四条通过线 —— 回答的是「借来的这只眼够不够格当判定闭环里的裁判」,而不是「模型跑没跑通」。能看见 ≠ 可用于判定:看得见但不主动看、会编、不稳、说不清,四种失效各对应一条通过线。真值四组齐全、有像素级注入断言, 跑分脚本目前接通的是其中 landing 一组;基准那一节每个数字的逐格模型原文都在 eval/runs/,哪几项没有原文,也在那里标明。
三步装好
环境要求:一个已经能正常对话的 DSH —— 也就是工作区选好了、主模型的 key 配好了,
随便发一句能收到回复。npm 安装或源码运行都可以,Node ^22.19 || >=24(与 DSH 一致)。
macOS / Linux / Windows 通用,安装脚本是一份 Node 实现。
刚下载 DSH 还没配过的话先把这一步做完 —— 本插件只负责识图那条链路(BAILIAN_API_KEY),主模型的 key 是 DSH 自己的事。两者分开:主模型不通,粘图也不会有反应。
1. 拿一个百炼 API Key
去 阿里云百炼控制台 开通并创建 API-KEY。
新用户每款模型送 100 万输入 + 100 万输出 Token,有效期 90 天(官方说明)。
本插件一次识图约 2000 输入 + 400 输出 token,免费额度够看几百次图,日常用基本不花钱。
2. 装插件
dsh plugin --profile web add dsh-design-qa
也可以直接从 GitHub 装(拿到的是 main 上最新的,未必等于 npm 上那版):
dsh plugin --profile web add github:sunxin-ai/dsh-design-qa
3. 补配套并重启
cd "${DSH_HOME:-$HOME/.dsh}/profiles/web/node_modules/dsh-design-qa"
export BAILIAN_API_KEY=<第 1 步拿到的 key>
node install.mjs --route-only
node install.mjs --restart # 冷启动。HMR 是关的,刷新浏览器不算
装好了。在对话框里粘一张图,直接问「这是啥」即可。
图片走粘贴或拖拽进对话框 —— DSH 的输入框没有单独的上传按钮,左下那个 + 是命令菜单不是附件入口,别去找。
也可以直接把图片的绝对路径或 http(s) 地址发给模型,让它自己调 deepseek_vision。
不需要告诉脚本 DSH 装在哪 —— 它从 profile 的 node_modules 自己解析出本体位置,
npm 装的和源码跑的都认。密钥也不经它的手,只写变量名 apiKeyEnv: BAILIAN_API_KEY。
第 3 步顺带改了 DSH 本体三处 —— 点开看改了什么、怎么还原
「在对话框里粘贴图片」这件事插件自己做不到:拦截在 api-proxy 的消息准入里,而 resolveModelInfo 直接返回适配器自述、没有 waterfall,插件改不了适配器硬编码的 inputModalities: ['text']。所以只能改本体,三处:
| 落点 | 改动 |
| dsh-host-apiproxy | 删掉纯文本路由的图片准入拒绝(一个 if 块) |
| dsh-llm-deepseek | 图片准入处不再抛错,改成把图片块换成一行 [图片 … attachment=<id>] 文字指针;声明了 image 的模型照走原生通路 |
| dsh-llm-pi-ai | 同上 —— 这条覆盖你自己接的所有 OpenAI 兼容纯文本端点 |
前两处只让 DeepSeek 路由能粘图;第三处才让「任何纯文本模型都能读图」成立。
改动前原文另存为 <原文件名>.dsh-design-qa-orig,一条命令还原:
node install.mjs --revert-patches
完全不想动本体就加 --no-patches。此时粘贴仍会被拒,但给文件路径、图片 URL 或者附件 id,让模型调 deepseek_vision 一样可用 —— 只是多贴一次路径。
细节见 patches/README.md。
让 DSH 自己装
不想手敲的话,把下面这段整体发给 DSH,它有 bash,会自己跑完:
装 dsh-design-qa,按这五步,不要自己发挥:
1. dsh plugin --profile web add dsh-design-qa
2. cd "${DSH_HOME:-$HOME/.dsh}/profiles/web/node_modules/dsh-design-qa"
3. export BAILIAN_API_KEY=<你的 key> # 用 export,下一条命令也要用到它
4. node install.mjs --route-only
5. node install.mjs --restart # 不要用 pkill,那会杀掉你自己
第 4 步会顺带改 DSH 本体三处(粘贴图片必须的),原文自动备份,
node install.mjs --revert-patches 可一键还原。把第 4 步的完整输出贴回给我。
「不要自己发挥」这句请保留。 三处最容易被自由发挥搞砸:
- 漏掉 --route-only —— 会写进一条与 bundle 重复的插件行,DSH 启动直接抛 duplicate loader entry id,整个 profile 起不来。脚本内置了防护会跳过,但不是所有 agent 都读得懂提示。
- 自己 pkill 重启 —— agent 通常就跑在那个要被重启的进程里,杀掉等于自杀,它拿不到结果也无法确认是否成功。--restart 立即返回,重启在它身后完成。
- 自己编一个 key —— 脚本不代经手密钥,自检会明确报缺少 BAILIAN_API_KEY,它应当回来向你要。
本体补丁没打成会以非零码退出;缺 key、路由没写这类则是自检里的黄色告警(退出码仍为 0)。
所以别只看退出码 —— 让它把输出原样贴回来,看最后那段自检有没有黄字。
DSH 的自修改工具(cordis_define / cordis_run)不能用来做持久安装 ——那套是内存态的:不产生插件文件、不改 cordis.yml、重启即消失。持久安装必须落到文件,所以走上面这条。
引擎为什么是 Qwen:它通过了基准测试
不是随手挑的。基准规范在 eval/。
下面两组数字来自两批实验、两组夹具,逐格原始输出都在 eval/runs/。
三模型横评 —— 6 个定向探针 × 4 种送检方式,跑在一组 mobile dashboard 夹具上。
那组夹具随附于 eval/runs/probe-mobile/,不是 evalset/ 里那 4 组 —— 拿 evalset/ 复现不出这张表:
| 模型 | 定向探针 | 难档(字重 800 vs 500) | 原始输出 |
| qwen3.8-max | 24/24 | 12/12 方向全对 | 逐格可查 |
| qwen3-vl-plus | 21/24 | 1/4 | ⚠️ 只留下聚合数字 |
| moonshot-v1-128k-vision | 18/24 | 8/15 ≈ 随机 | 逐格可查 |
零差异对照 —— 把设计稿和它自己配对,报出的任何差异都是幻觉。这是另一批实验,跑在 evalset/landing 上:qwen3.8-max 6/6 全报一致,0 条幻觉。 横评那组夹具测不出幻觉率(它的 v1 本身就不忠实,模型报的「差异」大多为真), 因此横评表里另外两个模型没有这项数据。
qwen3.8-max 是唯一在难档上稳定的 —— 另外两家在字重方向上等同掷硬币,而方向错的判断比漏检更危险,它会让修复朝反方向走。
换成别的模型
默认值只是默认值。 插件对模型没有任何硬编码假设,换供应商只改两处:
1) $DSH_HOME/settings.yaml —— 加一条你自己的路由 llm-pi-ai: providers: my-vision: api: openai-completions baseURL: https://your-endpoint/v1 apiKeyEnv: MY_VISION_API_KEY models:
- id: your-model-id
input: [text, image] # ← 必须有,否则被门禁拒绝
2) profile 的 cordis.patch.yml —— 覆盖插件行的 config
- id: design-qa
config:
provider: my-vision
model: your-model-id
注意这里不能写 - insert:。 插件行已经由 bundle 层插好了,再 insert 一条同 id 的不是覆盖而是并存,DSH 启动时抛 duplicate loader entry id: design-qa。
上面这种「给出 id + 要改的字段」的写法才是按 id 覆盖。
唯一的硬性要求:那个模型必须真的支持多模态输入,且路由声明了 input: [text, image]。 这是「对端点的声明,不是对端点的检查」(上游 JSDoc 原话)——声明了但端点实际不收图,会在调用时被供应商拒绝,而不是在配置时报错。
换模型后建议用 eval/ 重跑一遍基准(只在 GitHub 仓库里,不随包分发),尤其看难档与零差异对照那两项: 能看见 ≠ 可用,一个召回高但幻觉多、或每次结论都漂移的模型会让判定循环发散。
这两项分属两组夹具:难档用 tilebench.py probe,跑 runs/probe-mobile/ 那组;零差异对照用 tilebench.py pairs,跑 evalset/landing。
工具
deepseek_vision(image_path, question)
看一张图并回答问题。image_path 三选一:
- 文件绝对路径
- http(s) 图片地址 —— 文档、网页里的图直接传 URL。走系统代理(HTTP_PROXY / HTTPS_PROXY / NO_PROXY),上限 20 MB,跟随重定向
- 上下文 [图片 …] 提示里的附件 id(attachment=<id> 或裸 id 都行)
调用方自己就是多模态模型时会被拒绝 —— 它直接看更准也更省,绕一手转述反而丢信息。
这同时是官方多模态上线时的自动让位机制:DeepSeek 声明 image 那天,本工具自己退出。
配置
| 字段 | 默认 | 说明 |
| provider | bailian | 识图路由名,须声明 input: [text, image] |
| model | qwen3.8-max | 识图模型 |
| maxTokens | 4000 | 单次识图输出上限 |
| reasoningEffort | off | 读数式提问不需要思维链 |
提问方式决定成败
以下是实测结论,不是风格偏好。完整版在 skills/design-qa/SKILL.md。
| 提问形式 | 零差异对照的幻觉 | 难档缺陷召回 |
| 「你自己找差异」 | 0/30 | 0/2 |
| 「这个方面有区别吗」 | 0/30 | 0/2 —— 判定题,模型默认答否 |
| 「哪个更大」 | 0/36 | 1/2 —— 留白类被系统性答反 3/3 |
| 「各自是多少」 | 0/12 | 2/2 |
同一个模型、同一批图,召回从 0/2 走到 2/2,幻觉全程为 0。换的只是问法。
这张表只有第二行可以复核。 评测脚本里只实现了一种问法 —— tilebench.py 的 FACETS,五个保真面统统以「有区别吗」结尾,正是第二行;它的 0/30 有逐格原文可查。第一行的开放式提问大致对应 cmd_pairs,但没有单独计过分;「哪个更大」「各自是多少」两行没有任何代码路径 ——没有提示词常量、没有命令、没有输出文件,0/36 与 0/12 这两个网格在脚本里也找不到对应。
这张表记录的是真实做过的事,方向可信,数字请打折扣。细节见 eval/README.md。
读数方向可信,量级不可信:字重真值 800/500 读作 800/700,间距 80/25 读作 72/38 ——被测侧总被拉向参照侧。用它判断「有没有差异、往哪个方向」,不要当测量值;实现侧的精确值用 getComputedStyle 或像素测量取得。
成本
图像 token ≈ 像素数 / 1024(实测 1023–1127 px/token,与长宽比无关)。
| | 均值 | 区间 |
| 单次判定 | 0.037 元 | 0.027 – 0.051 元 |
| 延迟 | 9.0s | 6.6 – 11.6s |
看一次图约 4 分钱。 单价按 12 元/百万输入、36 元/百万输出估算,上线前请在控制台核对。
它什么时候该退休
DeepSeek 官方声明 inputModalities 含 image 的那天。
届时不需要改任何东西 —— 让位在两层上各有一道:
- 运行时:deepseek_vision 查到调用方本身就能看图,自我拒绝并让模型直接看,图片走官方原生通路,绕一手反而丢信息。
- 安装期:install.mjs 会先读 llm-deepseek 声明的 inputModalities。
已经含 image 就拒绝再打那处补丁并说明原因 —— 上游支持之后,那处补丁会把模型本来看得见的图换成一行文字指针,从修复变成破坏。
判断按找到的每一份 DSH 分别做,机器上有多份时互不影响。
另外两处不设退休判据:api-proxy 的门禁对所有路由通用,只要还存在纯文本路由就需要; llm-pi-ai 那处本就按 model.input 动态放行,能看图的端点自然走原生通路。
插件可以原样留着,也可以直接卸载。
什么时候别用这个
只是想「随手看张图」——用 modlens 更省事,零配置、不改本体。
本插件的定位是设计稿保真度判定:要求每条结论可回溯到证据,因此不惜多配一条路由、多改三处本体,换取图片走原生通路、判定可回放。
如果你不需要这个保证,这些成本就是纯负担。
参考
install.mjs 的全部开关
node install.mjs [profile] # 完整安装(不走 dsh plugin add 时用这条)
| 开关 | 作用 |
| [profile] | 目标配置档,默认 web |
| --route-only | 不写插件行。用 dsh plugin add 装过就必须加,见下 |
| --no-patches | 不改 DSH 本体。粘贴图片将仍被拒绝 |
| --revert-patches | 还原本体补丁并退出 |
| --restart | 只冷启动,可从 dsh 自己的进程内部调用 |
| --force | 无视重启前的体检拦截 |
环境变量(都只在自动探测不成时才需要):
| 变量 | 作用 |
| DSH_HOME | DSH 的家目录,默认 ~/.dsh |
| DSH_REPO | DSH 源码仓库根。只在本体自动定位不对时给 |
| DSH_PROCESS_PATTERN | 用来认出 dsh 进程的命令行片段 |
| DSH_CWD | dsh 的工作目录。Windows 上必须给 —— 那里既没有 /proc 也没有 lsof |
| DSH_RESTART_CMD | dsh 的完整启动命令 |
完整安装做六件事,全部幂等、改动前自动备份:软链 node_modules → 软链 skill → 写识图路由 → 写插件行 → 改本体三处 → 自检。
用 dsh plugin add 装过之后,--route-only 不能省
不加它会往 profile 的 cordis.patch.yml 再写一条同 id 的行,与 bundle 提供的那条撞车, DSH 启动时直接抛 duplicate loader entry id: design-qa,整个 profile 起不来 ——不是插件加载失败,是 dsh 根本启动不了。
(脚本已内置防护:检测到本包已作为 bundle 装入就会跳过写入。)
安装后必须冷启动
HMR 是关闭的,插件、skill、profile 补丁、本体改动都不热加载,刷新浏览器不算:
node install.mjs --restart
它从运行中的进程读出原本的启动命令与工作目录再拉起,不会丢掉你启动时带的 --patch 参数;并且立即返回 —— 所以跑在 dsh 里的 agent 也能安全调用(自己 pkill 会把自己一起杀掉)。
新进程继承调用方当前的环境。杀旧进程之前先做三项体检,任一不过就停手并保留旧进程(确认无妨可以 --force):
- 实际要用的那个 node 不满足 DSH 的 ^22.19 || >=24;
- 旧进程持有、而当前 shell 没有的密钥类环境变量(例如只 export 在另一个终端里的 BAILIAN_API_KEY)—— 丢掉它会让插件「装好了却用不了」。只比对变量名,不读值;
- 读到的启动命令被切碎了。Linux 上取的是 /proc 里的精确 argv,不受影响;别的平台只拿得到用空格拼起来的命令行,参数里带空格时会切错 —— 此时用 DSH_RESTART_CMD 显式给出完整命令。
新进程的输出写到 $DSH_HOME/dsh-design-qa-restart.log。
Windows 上还需要显式给 DSH_CWD,否则读不到工作目录、会拒绝重启。
改插件源码
src/index.ts 改完要建到 lib/index.js(DSH 加载的是构建产物):
npx tsdown --entry src/index.ts --format esm --out-dir lib --dts false --no-config
注意 install.mjs 第 1 步会把本目录的 node_modules 换成指向 profile 的软链,而 npm install 又会把它换回真目录 —— 两者互相拆台。所以构建工具建议用 npx 或装在别处,不要 npm install 到本目录。
识图路由长什么样
install.mjs 会写进 $DSH_HOME/settings.yaml;手工配的话:
llm-pi-ai:
providers:
bailian:
displayName: 阿里百炼 apiKeyEnv: BAILIAN_API_KEY # 只写变量名,密钥不落盘 api: openai-completions baseURL: https://dashscope.aliyuncs.com/compatible-mode/v1 compat: thinkingFormat: qwen # 不能省,见下 models:
- id: qwen3.8-max
input: [text, image] # ← 打开图像门禁的那一行
contextWindow: 262144
maxTokens: 8192
reasoningEfforts:
off:
high: high
input: [text, image] 会成为 LlmModel.inputModalities,DSH 的图像门禁查的正是它。
thinkingFormat: qwen 不能省。 不关思维时一次读数会产生 5000+ 字推理(1582 输出 token,关掉后只要 14),读数结果完全相同 —— 113 倍的无谓开销。
卸载
node install.mjs --revert-patches # 1. 先还原本体补丁
dsh plugin --profile web remove dsh-design-qa # 2. 插件行
rm -rf ~/.agents/skills/design-qa # 3. skill 软链(Windows 上可能是复制的目录)
4. 从 $DSH_HOME/settings.yaml 里删掉 llm-pi-ai.providers.bailian 整段
第 1 步不能漏,而且要放在最前面。 只留序列化那处改动的话,粘图后模型会被告知去调一个已经不存在的工具;插件先被摘掉的话,--revert-patches 也就跟着没了。
已知限制
- 本体改动不能自失效。 补丁是磁盘上的文件改动,而卸载插件只摘掉插件行、不会去重写那些文件。
所以卸载必须显式 --revert-patches,顺序见上面的卸载一节。
- 升级 DSH 会冲掉本体改动(文件被新版覆盖)。表现是「粘图又被拒了」,重跑一次 node install.mjs --route-only 即可。这也是有意的:新版 DSH 万一自己支持了图片,补丁不该悄悄留着。
升级后即使备份文件还在,--revert-patches 也只会清掉那份过期备份、不会把新版文件覆盖回旧内容。
- 按代码形态定位锚点,不按版本号。 上游改写了那三处时,脚本会报错并列出文件,而不是打半个补丁。两种形态都会被改到(源码运行的 src/*.ts、npm 安装的 lib/index.js)——无法可靠判断哪份是活的,宁可都改;源码仓库里因此会多出未跟踪的 .dsh-design-qa-orig 备份文件。
- 模型必须支持 tool calling。 整套机制是「模型看到指针 → 自己调工具」,不支持工具调用的纯文本模型只会看到一行 [图片 …] 而无法进一步。配路由前先确认端点支持 tools 参数。
- attachment=<id> 形式只在进程内有效:id → 路径的索引是内存态,重启后失效,需改用文件路径。
- 不支持多图对比:deepseek_vision 一次只看一张图。设计稿与实现的并排对比图,需要调用方自己拼。
- 私有文档的图取不到:飞书、Notion 这类需要登录态的图片,直接传 URL 会 401/403。
需先用对应技能下载到本地,再传路径。工具会在报错里指明这条路,但没有内建凭据通路。
- 自检是宽松匹配:settings.yaml 由 DSH 的设置写入器维护,并会规范化格式,因此自检只做模糊匹配 —— 它查的是「像不像配过」,不是「配得对不对」。预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
sunxin-ai/dsh-design-qa
让 DeepSeek Harness 里的纯文本模型能看图。
相关插件 · 视觉能力
智能体工作台Devin-AXIS/iPolloWork
企业级、本地优先的智能体工作台,面向个人和智能体团队——一个工作区,容纳多个智能体引擎;一套统一体系,管理插件和技能;支…
★ 7,359已汉化DSH
72
开源设计工作台nexu-io/open-design
OpenDesign:首个协作式 AI 设计智能体工作区
★ 105,514已汉化DSH
71.8
多智能体编码工作区spacering-net/codeg
多智能体协作的 AI 编程工作区:汇总 Claude Code、Codex、OpenCode、Pi、Grok Build 等来源的会话。支持桌面应用、自托管服务器或 Docker。
★ 4,289已汉化DSH
71.6
GPT 图像提示词库freestylefly/awesome-gpt-image-2
Prompt as Code | GPT Image 2 / 2.5 提示词与案例库,530+ 个案例、20+…
★ 34,534已汉化DSH
71.5
架构图生成器tt-a1i/archify
把你想理解、规划或分享的事,变成可以互动的可视化作品。
★ 92,675已汉化DSH
71.2
AI 用量桌面小部件Javis603/token-monitor
EN | 简 | 繁 | KO | JA | PT
★ 3,522已汉化DSH
71