DeepSeek Harness 插件

Flyvhidbwo/dsh-vision-proxy

Star 数 ★ 6 分类 工具与能力 收录于 2026-08-14 npm dsh-vision-proxy

DeepSeek 大脑 + 自动识图:GUI 附加的每张图片自动经 OpenAI 兼容 VLM 转译成文字,再交给纯文本的 DeepSeek 作答——有 key 自动走快速通道(默认 qwen3.7-flash,支持百炼/智谱/OpenRouter 等任意 OpenAI 兼容端点),无 key 自动探测本地 Ollama(零配置,图片不出本机)。

安装

# npm 包(预构建)

dsh plugin --profile web add dsh-vision-proxy

# GitHub 源码(首次需按提示配置 allowBuilds 构建授权后重试)

dsh plugin --profile web add github:Flyvhidbwo/dsh-vision-proxy

GitHub 来源的插件在安装时会在你的机器上执行构建脚本。请只安装可信来源,并尽量锁定 commit(github:owner/repo#sha)。

README

English | 简体中文

保持 DeepSeek 作为对话大脑,图片照样直接发。DeepSeek Harness 打造:GUI 附加图片自动转译,纯文本 DeepSeek 也能识图。

为什么需要它

DeepSeek Harness 原生按模型声明的 inputModalities 决定是否放行图片附件。DeepSeek 的 chat-completions 线路是纯文本的,所以选中 DeepSeek 时附加图片会被原生拒绝。已有的视觉插件提供 view_image工具(适用于文件路径),但 GUI 图片附件对纯文本模型依然失败

本插件补上这个缺口:注册一条新提供商路由(deepseek-vision),包装真正的 DeepSeek 适配器——对外声明支持图片输入(附件预检放行),并在请求流里把每张附加图片转译成文字后再委托给 DeepSeek。对话仍然由 DeepSeek 作答,识图只是附加能力。

用户附加图片 ──▶ deepseek-vision 路由 ──▶ 经 VLM 转译(OCR+版式+细节)
                   │                        │
                   ▼                        ▼
            DeepSeek 作答 ◀── 纯文本对话(图片已替换为 [图片转译] 文字)

特性

  • 绝不卡死。匿名端点强制 20 秒超时上限(免费档挂起也拖不住整轮对话);匿名端点遇到 HTTP 429 立即失败(不做无意义的 Retry-After 等待);刚失败(429/超时)的端点进入 60 秒冷却并被跳过。
  • 多模型、多厂商。任何 OpenAI 兼容 VLM 端点都行——百炼/Qwen、QwenCloud 国际站、智谱、OpenRouter、本地 Ollama、或你自己的端点。每条 fallbackModels 都可以带各自独立的 baseURL/model,一个安装即可串联多家。
  • 零配置本地路径autoLocalOllama(默认开)启动时探测 http://localhost:11434,检测到 Ollama 就自动加入降级链——图片不出本机,免 key 免注册。
  • 快速且明确的失败。没有 key 也没有本地 Ollama 时,转译在几秒内失败并给出可操作指引(配置 VISION_API_KEY / DASHSCOPE_API_KEY 或安装 Ollama)——绝不静默卡住。
  • 有 key 自动提速。导出 VISION_API_KEY / DASHSCOPE_API_KEY 后自动走你配置的付费端点(默认百炼 qwen3.7-flash——快、便宜、不限速;百炼/QwenCloud/智谱/OpenRouter 或任意 OpenAI 兼容端点均可);没有 key 的条目会被跳过而不是失败。
  • 安装时一问式确认postinstall 询问你是否有 VLM API key。非交互环境自动跳过,安装永不卡死。启动时打印 PRIVACY NOTICE 标明当前使用的端点。
  • 降级链 + 错误分类rate_limit / quota / auth / region / model_not_found / context_too_large / http 分类给出可操作提示。
  • 内容哈希缓存。转译结果按图片字节的 SHA-256 缓存(进程内,上限 200)——同一张图每个进程最多转译一次,重新附加或换对话也命中。
  • 自动降采样(可选)。装有 sharp 时,超过 maxImagePixels 的图片转译前自动缩小——大截图更快;没有 sharp 则优雅降级原图直发。
  • 兼容 read_image。原生 read_image 工具在该路由下同样可用(它的能力门禁读取同一份模型信息)。

支持的模型与厂商

一套配置(baseURL + model,可选 apiKey)覆盖所有后端:

场景 baseURL model 说明
百炼(国内)——默认主模型 https://dashscope.aliyuncs.com/compatible-mode/v1 qwen3.7-flash / qwen3-vl-flash 便宜、快、不限速。密钥:千问平台 sk-ws-… 或百炼 sk-…
本地 Ollama(自动探测) http://localhost:11434/v1 第一个视觉模型 装了就零配置可用;图片不出本机
QwenCloud(国际) https://dashscope-intl.aliyuncs.com/compatible-mode/v1 qwen3-vl-plus 国际版
智谱(免费档) https://open.bigmodel.cn/api/paas/v4 glm-4.6v-flash 免费档仍需注册智谱(免费)key
任意 OpenAI 兼容端点 你的端点 你的模型 OpenRouter、火山 Ark、vLLM、各类网关……插件只讲 /chat/completions

⚠️ 不再内置任何第三方匿名免费端点作为默认兜底。实测中匿名免费端点(如 OVHcloud AI Endpoints)限速极严且会无响应挂起——作为默认只会复现"卡死"体验。如果你仍想用某个匿名端点,请通过 fallbackModels 自行添加并设 anonymous: true(20 秒超时上限依然生效)。

key 读取顺序:配置 apiKey$VISION_API_KEY$DASHSCOPE_API_KEY。匿名端点(anonymous: true)和本地主机无需 key;无 key 的非匿名条目自动跳过。

快速开始

dsh plugin --profile web add dsh-vision-proxy

安装时会问你一个问题——你有 VLM API key 吗? 回答 y 走付费快速通道,回答 N(默认)走本地/零配置路径。重启 dsh web,在模型选择器里选 DeepSeek + 自动识图,然后把图片粘贴进任意对话——完事。

pnpm ≥ 10 默认拦截依赖构建脚本——首次安装会以非零码退出并提示 Ignored build scripts: dsh-vision-proxy, sharp。请批准两者(插件的安装确认提示 + sharp 的可选二进制),然后重跑一次安装完成 bundle 注册:

# 写在 profile 的 pnpm-workspace.yaml 里
allowBuilds:
  dsh-vision-proxy: true
  sharp: true
dsh plugin --profile web add dsh-vision-proxy   # 批准后重跑

npm 官方源太慢? dsh plugin --profile web add dsh-vision-proxy --registry=https://registry.npmmirror.com(参数会转发给 pnpm)。

现场演示:真实对话中的识图

一段 deepseek-vision 路由上的真实对话(DeepSeek-V4-Flash 作为大脑):用户粘贴了一张表情包并问 "你看到了什么",图片被 VLM 自动转译,DeepSeek 基于文字完整作答——单步,约 7.6 秒。

左图:模型选择器显示 deepseek-vision 路由(DeepSeek + 自动识图)已选中——这正是图片附件得以放行的原因。右图:DeepSeek 基于转译文字给出的完整回答。

用户粘贴表情包 + "你看到了什么"
  → 图片块经 VLM 自动转译(OCR + 版式):
      "我是吃白饭的 / 蓝色大肥鱼! (理直气壮.jpg) — Q版蓝发女仆装少女,
       身后蓝鲸尾巴,端碗举筷,表情兴奋"
  → DeepSeek 基于文字对表情包做完整视觉分析

两条自主路径都覆盖:view_image 工具(任意路由,支持文件路径与 URL)和图片块自动转译(deepseek-vision 路由——对话中途附加的图片)。

配置

bundle 已自带合理的默认配置(见上方策略说明),一般无需改动。要覆盖时,请在 profile 中写 id 定向覆盖,不要用 insert(见下方警告):

# $DSH_HOME/profiles/web/cordis.patch.yml —— 用户层覆盖示例
- id: dsh-vision-proxy
  name: 'dsh-vision-proxy'
  config:
    baseURL: https://dashscope.aliyuncs.com/compatible-mode/v1
    apiKey: 'sk-…'          # 或留空读环境变量(Windows 下直写这里最可靠)
    model: qwen3.7-flash
    maxTokens: 4096
    timeoutMs: 120000       # 匿名端点无论如何都会被强制 20s 上限
    maxImagePixels: 4000000
    marker: '[图片转译]'
    autoLocalOllama: true
    fallbackModels: []      # 可自行添加 {model, baseURL, apiKey?, anonymous?, timeoutMs?}

⚠️ 不要写成 - insert: [{id: dsh-vision-proxy, …}] dsh 的 patch 语义里 insert 是往条目列表追加——bundle 自带的条目和你写的同 id 条目会同时存在并被实例化,deepseek-vision adapter 会被注册两次(行为未定义)。顶层 - id: 条目才会命中既有行并整体替换其 config;未列出的键回落到插件 zod schema 的 .default() 值(如 maxTokens=4096timeoutMs=120000autoLocalOllama=true),所以只写 apiKey/model 也能工作。

默认值 含义
providerId deepseek-vision 模型选择器中显示的路由 id
innerProvider deepseek-official 被包装的现有适配器路由
baseURL DashScope 兼容模式 OpenAI 兼容 VLM 端点(任意厂商,含 Ollama)
apiKey '' VLM 密钥;回退读取 $VISION_API_KEY,再回退 $DASHSCOPE_API_KEYWindows 下环境变量变更可能不生效,直写这里最可靠
anonymous false 跳过 Authorization 头(用于免注册端点;受 20s 超时上限约束)
model qwen3.7-flash 视觉模型 id(如 Qwen2.5-VL-72B-Instructqwen3-vl-flashglm-4.6v-flashqwen3-vl:4b
maxTokens 4096 VLM 输出上限(思考型模型先耗推理 token,预算给足)
timeoutMs 120000 VLM 请求超时(匿名端点无论如何都被强制 20s 上限)
maxImagePixels 4000000 超过该像素数的图片转译前自动降采样(装有 sharp 时;0 关闭)
marker [图片转译] 每条转译文本前加的前缀标记
autoLocalOllama true 启动时探测 http://localhost:11434;检测到则前置进降级链
localOllamaModel '' 指定 Ollama 模型 id;留空自动选本地 Ollama 报告的第一个视觉模型
fallbackModels [] 降级链:{model, baseURL?, apiKey?, anonymous?, timeoutMs?},每条可指向不同厂商;无 key 的非匿名条目自动跳过

Windows 上关于 API key 的说明dsh --profile <name> --dump-config 会原样打印组合后的配置(写在 cordis.patch.yml 里的 key 会出现在明文输出中),但另一方面,进程启动后设置的环境变量(explorer.exe 会缓存旧环境)可能永远到不了正在运行的 dsh。如果你明明导出了 key 却看到 skipped — no API key请把 apiKey 直接写进插件配置——这是 Windows 上唯一可靠的方式。(注意:dsh rc.6 不加载 .env 文件,那不是替代方案。)

安装后验证

dsh --profile web --dump-config | grep -A3 dsh-vision-proxy   # 应恰好一个条目(注意:会明文打印配置,含 key)
  1. 重启 dsh web → 模型选择器出现 DeepSeek + 自动识图
  2. 向对话粘贴图片 → 应看到 [图片转译] 标记后 DeepSeek 作答。
  3. 没有 key 也没有本地 Ollama 时,回合应在数秒内快速失败并给出指引消息——这就是预期的防卡死行为。

行为说明

  • 只有含图片块的消息才会被处理;纯文本对话零开销直达 DeepSeek。
  • 匿名端点:20 秒硬超时上限、HTTP 429 立即失败(不重试)、失败后触发 60 秒端点冷却——连发图片不会反复踩坏端点。
  • 全部链路条目都失败才报错,错误会列出每一次尝试并附可操作指引。
  • 转译结果按图片内容哈希进程内缓存(永不落盘)。
  • 启动时打印一行摘要——路由 id、被包装的提供商、VLM 模型、端点、超时、maxTokens、key 来源与降级列表(key 本身从不打印),外加 PRIVACY NOTICE 和 Ollama 探测结果。
  • 测试:14 个单测,GitHub Actions 在 Node 22/24 上运行(含防卡死快速失败、冷却跳过、Ollama 探测用例)。
  • 转译质量:密集 UI 截图可能丢失小字细节——这是视觉模型的能力上限,不是插件 bug。OCR 重度场景建议换更强模型(如 qwen3-vl-plus)或调大 maxTokens

排障

现象 原因与解决
明明导出了 VISION_API_KEY 仍报 skipped — no API key Windows 在 explorer.exe 里缓存环境变量,运行中的 dsh 读不到新值。把 apiKey 直写进插件配置,重启 dsh
安装时报 Ignored build scripts: dsh-vision-proxy, sharp pnpm ≥ 10 默认拦截依赖构建脚本。在 profile 的 pnpm-workspace.yamlallowBuilds: {dsh-vision-proxy: true, sharp: true},然后重跑安装
发布当天安装报 ERR_PNPM_MINIMUM_RELEASE_AGE_VIOLATION pnpm 11 默认 minimumReleaseAge 为 1 天(供应链策略)。在 profile 的 pnpm-workspace.yamlminimumReleaseAge: 0,或给 dsh plugin add--config.minimum-release-age=0,然后重跑
匿名端点报 all N vision model(s) failed … rate_limit 匿名免费档限速极严且可能挂起。配置 key 或改用本地 Ollama
新装无 key 时约 20 秒后失败 没有 key 也没有本地 Ollama——这是预期的快速失败路径。安装 Ollama 或配置 key
npm 官方源下载慢 使用 --registry=https://registry.npmmirror.com(参数转发给 pnpm)

隐私

转译会把图片字节(base64,HTTPS)发送到配置的 VLM 端点——图片数据会离开你的机器,除非 baseURL 指向本地服务(如 Ollama)。除 harness 自身的附件存储外不持久化任何东西。敏感图片请使用自己的端点或本地模型——或者不安装本插件。

实现原理(给插件开发者)

本插件只使用 rc.6 上稳定的公共接口:

  • ctx.llm.registration(innerProvider).adapter —— 拿到被包装的适配器;
  • ctx.llm.registerAdapter([providerId], proxyAdapter) —— 注册新路由(无 DUPLICATE_ADAPTER 冲突);
  • 代理 resolveModelinputModalities 覆盖为 ['text', 'image'] —— 满足附件预检(api-proxy)与 read_image 门禁(dsh-tool-fs);
  • 代理 stream 转译图片块(结构 { type: 'image', attachment },字节经 ctx.get('attachments').readImage(ref) 获取),再 yield* 原样转发内部适配器的流。

许可证

MIT

内容来自项目 README(GitHub)↗

链接

同类插件

查看整个分类 →