dsh-tool-vision
给 DeepSeek Harness(DSH)外挂读图能力的插件:当主模型(如 deepseek-v4-flash,本身不支持图像输入)需要读取图片时,它调用插件注册的 read_image_vision 工具;插件读取图片文件,把图片 + 主模型本次按任务构造的 prompt 发给用户配置的可识图模型(多模态),再把该模型返回的文字描述作为工具结果交回主模型。会话中不会注入任何图片块,纯文本主路由可正常续写。
特性
- 零构建步骤:纯 ESM JavaScript,
lib/直接入库——从 GitHub、npm 或 tarball 安装都不需要构建脚本,也无需 pnpmallowBuilds白名单。 - 复用 DSH 自身的 LLM 基础设施:provider、密钥、重试、代理都走 DSH 常规模型设置(如
llm-pi-ai.providers.<name>)。 - prompt 由主模型按任务决定:插件没有固定 prompt,每次调用时由主模型决定问什么。
- 能力前置校验:配置的模型未声明
image输入时直接拒绝,图片字节不会离开本机。 - 附件安全:图片字节经附件服务校验(magic-byte、大小上限),且绝不进入会话历史。
工作原理
主模型(无视觉) ──read_image_vision(file_path, prompt)──▶ dsh-tool-vision
│
│ 读取文件 → attachments.saveImage(校验/持久化)
│ llm.stream({provider, model, messages:[图片+prompt]})
▼
用户配置的视觉模型(如 xiaomi/mimo-v2.5)
│
▼ 文字描述
主模型 ◀──────────── 工具结果(path / provider / model / description)──┘视觉模型只看到图片和 prompt,看不到对话历史——主模型必须把完成任务所需的全部上下文写进 prompt。
环境要求
- 已安装 DeepSeek Harness(
dshCLI 在 PATH 中) - 一条已注册且模型声明了 image 输入的 LLM 路由。内置示例:
xiaomi路由的mimo-v2.5(在 Web 模型设置页或settings.yaml的llm-pi-ai.providers.xiaomi配置,并设置其apiKeyEnv对应密钥,如XIAOMI_API_KEY)。
安装
任选其一(下面以 web profile 为例,其他 profile 请用 --profile <name>):
# 从 npm 安装
dsh plugin --profile web add @pzqian123/dsh-tool-vision
# 从 GitHub 安装(无构建步骤,不需要 allowBuilds)
dsh plugin --profile web add github:pzqian123/dsh-tool-vision
# 从本地 tarball 安装
npm pack
dsh plugin --profile web add .\pzqian123-dsh-tool-vision-<version>.tgz> 装完后需要重启 dsh web(或该 profile 的进程) —— bundle 列表在启动时读取。
配置
配置分三层,全部写在你自己的文件里——插件包不携带任何默认值,未配置视觉路由前工具会拒绝调用。
第 1 层 — 视觉路由(端点 + 模型):settings.yaml
路由注册在 ~/.dsh/settings.yaml 的 llm-pi-ai.providers.<名字> 下(也可用下面的 Web 模型设置页完成)。
目录内置路由 — pi-ai 内置目录认识的 provider(如 xiaomi、openai、anthropic)只需填密钥引用名,端点和模型清单自动来自内置目录:
llm-pi-ai:
providers:
xiaomi:
apiKeyEnv: XIAOMI_API_KEY自定义 OpenAI 兼容端点 — 手写路由、协议、端点和模型清单。视觉模型的 input 必须包含 image,否则工具的能力校验会在图片字节离开本机前直接拒绝调用:
llm-pi-ai:
providers:
my-vision:
displayName: My Vision Gateway
apiKeyEnv: MY_VISION_API_KEY
api: openai-completions
baseURL: https://gateway.example.com/v1
models:
- id: vision-1
name: Vision Model 1
contextWindow: 131072
maxTokens: 8192
input: [text, image] # ← 视觉模型必须有第 2 层 — API key:~/.dsh/.credentials.yaml(或环境变量)
密钥由凭据服务存储,绝不写进 settings.yaml。第 1 层的 apiKeyEnv 引用就是密钥的名字:
MY_VISION_API_KEY: sk-你的密钥…或者不写文件,直接导出同名环境变量。
第 3 层 — 让插件指向该路由:profile 的 cordis.patch.yml
在 profile 的用户补丁层(如 ~/.dsh/profiles/web/cordis.patch.yml)把视觉路由写进 tool-vision 行的 config:
- id: tool-vision
config:
provider: my-vision # 第 1 层的路由名
model: vision-1 # 第 1 层的模型 id
# maxTokens: 1024 # 可选:视觉模型最大输出 token 数(默认 1024)
# timeoutMs: 120000 # 可选:单次视觉调用总超时毫秒数(默认 120000)配置通过 HMR 热生效,改完无需重启。
推荐做法:用 Web 模型设置页
设置 → 模型页可以用表单完成第 1、2 层,比手写 YAML 更省事:
- 选目录内置 provider,只填一个 API key 输入框——页面通过凭据服务只写存储,并自动为你记录
apiKeyEnv引用(派生名为<路由名>_API_KEY)。 - Add a custom provider 卡片:填 Provider ID(必须以小写字母开头)、端点、协议、至少一个模型——也可以点 Fetch available models 直接从端点拉取模型列表。
- 注意:页面不编辑模型的
input字段;自定义视觉模型需要在settings.yaml里补input: [text, image]。
小提示
- 配置可以让 agent 干:不用手改 YAML。在任意 DSH 会话里直接说:"安装 dsh-tool-vision,并配置成 xiaomi/mimo-v2.5"(或你有的任何 provider/模型)。agent 会执行
dsh plugin add、写入tool-vision行、并通过凭据服务保存 API key——把 key 在同一句话里告诉它即可,它会写进~/.dsh/.credentials.yaml,不会留在聊天记录里。 - 安装也可以让 agent 干:让 agent 按上面的命令执行即可。唯一需要你手动做的是重启
dsh web(agent 运行在同一个进程里,重启不了自己);安装/卸载后都需要重启。 - 改配置免重启:
tool-vision行的配置走 HMR 热生效;只有安装/卸载需要重启。 - 直接说"读这张图"就行:不需要手动调工具,主模型需要看图时自己会选
read_image_vision。 - 从小图开始:先用小图测试(附件上限默认 5MB);如果视觉模型回答被截断,让它用更窄的 prompt 或调大
maxTokens。 - 主路由支持视觉时不会多余转发:主模型能直接收图时,
read_image_vision会拒绝调用并提示改用内置read_image,图片不会被冗余发送到配置的视觉 provider。 - 密钥别写进 settings.yaml:密钥在
~/.dsh/.credentials.yaml(或环境变量),provider 配置里的apiKeyEnv只是引用它的名字。
使用
直接让主模型读图即可,例如:
> 读取 D:\images\截图.png,逐字告诉我图中写了什么
模型会调用 read_image_vision 并按任务给出 prompt。工具目录中同时存在 harness 自带的 read_image 和本插件的 read_image_vision,系统提示与工具自身行为会把两者分清楚。
各路由下用哪个工具
- 纯文本主路由(如
deepseek-v4-flash):内置read_image会拒绝(路由无法承载图片);模型改用read_image_vision,把图片转发给配置的视觉模型并拿回文字描述。 - 支持视觉的主路由:模型直接用内置
read_image看图。此时read_image_vision会拒绝调用——转发是多余的,还会把图片发到另一个 provider——并报错提示改用read_image。
工具契约
file_path | PNG/JPEG/WebP/GIF 图片路径,由 DSH 文件系统后端解析 |
prompt | 必填;你对视觉模型的指令(它只看到图片和这个 prompt) |
| 输出 | { path, provider, model, prompt, description, truncated } |
隐私说明
图片字节会发送给你在 DSH 模型设置中配置的视觉 provider(同一个 provider/密钥)。会话中的其他内容不会发送。描述以纯文本形式存入会话。
故障排查
| 现象 | 原因 / 处理 |
|---|---|
| 调用报"read_image_vision is not configured" | 未配置 tool-vision 行 config,按上文补 provider/model |
| 报"no adapter registered for provider" | provider 路由未注册:在模型设置页 / settings.yaml 配置 llm-pi-ai.providers.<name> |
| 报"does not declare image input" | 目标模型无视觉能力,换可识图模型(其模型条目 input 含 image) |
| 报"no credential for provider route" | 该 provider 的 apiKeyEnv 对应密钥未配置(Web 模型设置页或 ~/.dsh/.credentials.yaml) |
| 报"exceeds the X-byte attachment limit" | 图片超过附件大小上限(默认 5MB),压缩后再读 |
| 报"extension declares ... but the bytes use a different image format" | 文件扩展名与真实格式不符,改名或转换 |
| 视觉模型返回空/超时 | 检查网络、密钥额度;超时可调大 timeoutMs;输出截断可调大 maxTokens 或让主模型用更窄的 prompt 重试 |
开发
dsh-tool-vision/
├── package.json # 声明 dsh.bundle(bundle 清单)
├── cordis.patch.yml # 插入 tool-vision 行的补丁层
├── lib/index.js # 插件实现(纯 ESM,无构建步骤)
├── README.md
└── README.zh-CN.md本地迭代:
npm pack
dsh plugin --profile web remove @pzqian123/dsh-tool-vision
dsh plugin --profile web add .\pzqian123-dsh-tool-vision-<version>.tgz> 注意:pnpm 对本地目录依赖会建符号链接,运行时依赖会从真实路径解析失败,因此始终用 tarball(或 GitHub/npm)安装。
配置项一览(Config schema)
| 字段 | 类型 | 默认 | 说明 |
|---|---|---|---|
provider | string | "" | 视觉模型所在 provider 路由名(必配,否则调用报错) |
model | string | "" | 视觉模型 id,须声明 image 输入(必配) |
maxTokens | number | 1024 | 视觉模型最大输出 token 数 |
timeoutMs | number | 120000 | 单次视觉调用总超时(毫秒) |
License
MIT