📁 项目已开源:Flora233333/dsh-minimal-vision
🎥 介绍视频详见:[开源] DSH 极简模式视觉插件 👀 轻量化+干净
关键词:DeepSeek Harness、极简模式、上下文注入、VLM、结构化 JSON、识图


先把结论写在最前面:

这是一个给 DSH(DeepSeek Harness)极简模式 用的视觉插件。一句话概括它的取舍:

超级轻量,不注册第三个工具、不改写 system prompt,就让极简模式能「看图」

对模型来说,工具面永远只有 persistent-bashstr_replace_editor 两个,一个不多;system prompt 一个字不动。视觉能力通过一条注入在 User 消息之后、默认折叠的 context 进入工作流——需要的时候用一行 Bash 调进来,不需要的时候它完全不存在。

和常见做法的对比:

其他插件的做法 这个插件的做法
注册一个 vision 工具 → 工具面变 3 个 工具面还是 2 个,视觉走 Bash
往 system prompt 里塞视觉说明 system prompt 一个字不动,说明放在 User 之后
把视觉模型注册成聊天模型 Vision 配置独立,不进模型列表
图片直接给多模态接口 本地缓存 + 按需调用,文档永远不出本机
返回一坨自然语言,Agent 自己猜 五个内置任务,每个自带 JSON Schema

如果你也在折腾 DSH 插件,或者单纯被「极简模式看不见图」卡住过,那这篇可以看看。

觉得有用的话,可以给我点个 Star⭐


一、为什么会做这个东西:现有的插件都太「重」了

起因很朴素:我最近有一批需要视觉辅助的活——做 PPT、读论文、让 DS 帮我看图

DSH 生态里视觉相关的插件其实已经有一些了,但我试下来一个共同的问题是:太重。装完之后工具面多出好几个,system prompt 被追加一大段,有的还顺手把视觉模型注册成了聊天模型。功能是有了,但极简模式也就不「极简」了。

而极简模式的价值,恰恰不只是「工具少」:

它的真正价值在于,首轮请求拥有一个干净、稳定的 system prompt 和 tool schema

这不是玄学。我在测试里能观察到一个很直接的现象:当 User 消息之前的 system prompt 和 tool schema 与原生极简模式完全一致时,DS 的思维链里基本只有 "We need…" 和 "Let's…";一旦这个起点被动过,思维链里就开始冒出 "Let me…"。

用词变了,说明模型认为自己所处的场景变了。对于需要稳定复现的场景来说,这个变化是要命的。

那就尴尬了:为了让它「看得见」,我把它变成了另一个模式。

所以这个插件的设计目标从一开始就写死成一句话:

能力要加,但极简模式的「形状」一点都不能动。

也正因为目标这么窄,它才能做得这么小——我 vibe 了一个下午就跑起来了。


二、原理:注入点选在 User 消息之后

整个思路其实非常朴素。关键只有一个字:注入的位置

    ┌─────────────────────────────────────┐
    │  System Prompt   ← 一个字都不动      │
    │  Tool Schema     ← 还是那两个工具    │  与原生极简模式完全一致
    ├─────────────────────────────────────┤
    │  User Message                       │
    │  └─ 折叠 Context(本插件唯一的落点)  │  ← 只在这里加东西
    └─────────────────────────────────────┘

完整链路长这样:

用户拖入图片 / PDF / PPT
          │
          ├─► sharp 预处理(纠正方向 + 铺白底 + 长边 ≤1600px → JPEG)
          │   文档原样保存
          │
          ▼
  $DSH_HOME/cache/dsh-tool-vision/     ← 只落本地
          │
          ▼
  折叠 Context(只含本地路径 + 用法说明)
          │
          ▼
  Agent 自己判断:这题需要「看」吗?
          │
    需要 ─┴─ 不需要 → 正常回答,视觉一次都不调用
          │
          ▼
  persistent-bash 调用 dsh-vision
          │
          ▼
  VLM 返回结构化 JSON → Agent 继续推理

几个关键设计:

① 视觉说明只在第一回合注入一次。 插件挂在 agent/pre-step 事件上,只在 turn === 1 && step === 1 时把用法说明追加成一条 source.kind = 'plugin' 的消息。UI 里它默认折叠,用户的消息气泡保持干净;后续回合只在有新附件时注入路径,不再重复说明。

② 隐藏 context 里只有路径,没有图。 附件在发送时写进本地缓存目录,注入的是 /home/xxx/.dsh/cache/.../xxx.dsv.jpg 这样的绝对路径。文档本身永远不会被发到视觉接口,只有 Agent 明确传给 dsh-vision 的那几张图才会出网。

③ 文档处理仍然是 Agent 自己的活。 PDF / DOC / PPT 的读取、导出、裁剪、拼图,插件一律不碰——Agent 用 Bash 加 Python 干这个本来就很擅长,我没必要替它做决定,更没必要为此再塞一堆依赖进来。插件只负责「把渲染出来的图看懂」这最后一步。

④ 给了一个稳定的启动器。 $DSH_HOME/bin/dsh-vision 是 DSH 启动时自动生成的 shell 包装脚本,里面写死了 Node 路径和 DSH_HOME。注入的说明里也明确要求模型用这个命令,不要自己去拼 profile / node_modules 路径

经验之谈:给 Agent 用的 CLI,一定要提供一个「路径稳定、免思考」的入口。你以为模型会照着说明走,实际上它非常喜欢自作主张地 find 一遍 node_modules,然后拼出一条不存在的路径,再花三轮去 debug 你的插件。一个 4 行的 #!/bin/sh 包装脚本能省掉这一整段。


三、返回结构化 JSON,而不是一段散文

这是我觉得比「能看图」更重要的一点。

如果视觉模型返回的是一段自然语言,主模型就得再解析一遍,还容易被措辞带跑。所以我把它做成了任务化的:五个内置任务,每个任务自带自己的 system prompt 和 JSON Schema,DS 只负责提问题,不需要(也不允许)自己发明 wire-level 的提示词和字段。

任务 用途
custom 默认档。普通描述、解释、对比、聚焦式提问
slide_review 幻灯片排版体检:溢出、重叠、对齐、对比度,带归一化 bbox
figure_semantics 判断一张图「到底是什么」,附带证据和置信度
caption_grounding 图注和图对不对得上
flowchart_extract 流程图 → 节点 / 边的机器可读结构

问题是 DS 自己写的。 比如它会自己发出「识别一下图片左上角是什么」这样的指令,插件把这句话和预设的识图系统提示词、JSON Schema 组装到一起再发给视觉模型。分工很清楚:DS 决定要看什么,插件决定怎么问、以什么格式回来。

调用长这样,一次最多 4 张图:

dsh-vision analyze --task custom \
  --instructions "这张架构图里,缓存层在数据库的哪一侧?" \
  -- /path/to/image.png

配置上不写死任何服务商:支持 OpenAI Chat CompletionsGemini generateContent 两种协议,Base URL、模型 ID、API Key 都在「设置 → Vision」里填,key 由 DSH 凭据服务保管(也认 VISION_API_KEY 环境变量,优先级更高)。填完点一下「测试连接」就知道通没通——它只发一个最小纯文本请求,不上传任何附件。


四、它适合做什么,不适合做什么

这部分我想说得实在一点,免得大家装完期望落空。

✅ 适合:文档类的视觉辅助

  • 做 PPT:让 DS 看一眼渲染出来的稿子,检查有没有文字溢出、图文错位、对比度太低;

  • 读论文:把 PDF 里的图表提出来,问它「这张图在说明什么」;

  • 日常识图:截图、架构图、流程图,问一个具体问题,拿一个结构化答案。

实测下来,PPT 和 PDF 里的图片理解效果都相当不错,做 PPT 的时候确实能派上用场。

❌ 不适合:精细的图像理解和视觉定位

这不是一个 CV 工具。像素级的比对、精确的目标定位、OCR 抠小字这类活,它做不了,也不打算做。它的定位是给文本模型补一双「大致看得清」的眼睛,不是给你一套视觉流水线。

⏳ 另外,慢是正常的。

PPT / PDF 的处理链路里,DS 需要先用 Python 相关工具把图片从文档里提取出来,这一步本身就要花时间,再加上视觉模型的往返。所以整个流程会明显比纯文本对话慢,视频里我甚至把中间过程剪掉了 😅 —— 但这部分开销来自「文档处理」本身,不是插件在拖后腿。


五、踩过的几个坑

① PNG 透明背景直接变黑。 图片统一转 JPEG 送出,透明通道没铺底色的话,白色文字截图会直接糊成一片黑。修法是 sharp().flatten({ background: '#ffffff' }),顺手把 .rotate() 也加上——手机拍的图 EXIF 方向不处理,模型会认认真真地分析一张躺倒的图。

② 有些网关不认 response_format 我为了拿稳定 JSON 加了 response_format: { type: 'json_object' },结果部分 OpenAI 兼容网关直接甩 400 / 422 回来。现在的做法是:遇到这几个状态码,自动去掉这个字段重试一次,靠提示词兜住 JSON 格式。

③ 模型偶尔就是不返回合法 JSON。 这时候最忌讳的是抛错——Agent 会开始疯狂重试,一轮烧掉几万 token。所以解析失败时 CLI 不报错,而是原样返回 raw_text 让 Agent 自己读。注入的说明里我还专门写了一句:不要用 || 串联兜底调用,不要自动重复失败的调用

经验之谈:写给 Agent 用的工具,「失败」要比「成功」设计得更仔细。人看到报错会停下来想,模型看到报错的第一反应是再试一次,换个写法再试一次。给它一个可用的降级结果,比给它一个精确的错误码有用得多。


六、装起来跑

git clone https://github.com/Flora233333/dsh-minimal-vision.git
cd dsh-minimal-vision
npm install
dsh plugin --profile web add .
dsh web

启动后选择「视觉辅助模式」,在「设置 → Vision」里配好视觉模型接口就能用了。

装不上的话有个自检脚本:npx dsh-vision-doctor,会告诉你是包没装进 profile、还是启动器没生成。

支持格式:PNG / JPEG / WebP / GIF / PDF / DOC / DOCX / PPT / PPTX。

关于视觉模型:云端 API 和本地部署都可以。

本地这条路我实测过,用 Qwen3.5-4b 起一个服务,把接口地址填进设置里就行,效果相当不错,速度甚至比走 API 还快一些。用 Ollama 部署同样没问题。对于「不想让图出本机」的场景,这是我更推荐的方式。

⚠️ 兼容性:当前版本只支持 Bash 环境,已在 Ubuntu 和 WSL2 下测试正常。原生 Windows PowerShell 暂未适配,Windows 用户请先在 WSL2 里跑,PowerShell 支持在路上了。


七、一点碎碎念

做完这个插件,我最大的感受是:给 Agent 加能力,和给人加功能,是两件事。

我想保留:

原来的 DSH 极简模式几乎什么都没变。

只是当它真的需要看一眼时,现在有地方可以看了。

一千八百来行 JS,MIT 协议,欢迎来提 Issue / PR,也欢迎直接 fork 改成你自己的插件。

如果帮到你了,点个 Star⭐ 吧,谢谢各位! 🙌

Logo

欢迎加入DeepSeek 技术社区。在这里,你可以找到志同道合的朋友,共同探索AI技术的奥秘。

更多推荐