Back to home

WEIHAOLEE

dsh-plugin-vision-fallback

DeepSeek HARNESS 视觉代理插件

Stars
0
Language
JavaScript
Created
Aug 17, 2026
Updated
Aug 17, 2026

Introduction

dsh-vision-fallback(视觉代理)

给 DeepSeek Harness(DSH)的 text-only 会话加一个「视觉代理」开关:

  • 文本请求完全不干预 —— 原样走你原来选的模型(哪个都行,Flash/Pro/其他)
  • 含图请求自动转发 —— 直接把你当前消息里的图片 + 这句话发给视觉模型(OpenAI 兼容,默认火山方舟豆包),不带任何历史上下文
  • 开关式使用 —— 输入框旁一个「视觉代理」开关,点开即用,点关恢复原状
  • 多视觉服务商 —— 设置页「Vision 模型」里可增删服务商、设默认、测试连接,热生效

⚠️ 诚实声明(请先读)

这个插件是作者用 deepseek-v4-pro 通过 vibe coding(人机来回试错式开发)写出来的。 作者并不是 DSH 的开发者,对 DSH 内部机制的理解大量来自读源码 + 踩坑 + 猜, 不保证正确、不保证稳定,有 bug 是常态。它目前只在一个人的 Windows 机器上、 配合 deepseek-v4-pro + 火山方舟豆包跑通过。请自行评估、自行修改,出问题别指望作者。 具体的不确定点和已知坑见文末 不确定与已知问题


工作原理

你在会话里选了任意文本模型,然后点开「视觉代理」开关
        │
        ├─ 纯文本消息 ──→ 你原来的模型(插件只是把历史里的旧图片块剥掉后原样转发)
        │
        └─ 当前消息带图 ──→ 视觉服务商(只发:这张图 + 这句话,无历史/无 system/无工具)
                            ↑ 可在「设置 → Vision 模型」面板换服务商

开关的本质是:开启时把会话的模型切到本插件注册的 vision-fallback 路由 (因为 DSH 的 read_image 要求当前路由声明图片输入,纯文本模型过不了这个门槛), 同时记住你原来的模型;关闭时恢复。所以开启后模型选择器里会显示「视觉代理」, 这是机制使然,不代表你的文本模型变了。

目录结构

lib/index.js         宿主插件:注册路由、设置 schema(llm-vision-fallback 段)、凭据解析、模型发现
lib/adapter.js       VisionFallbackAdapter:路由判定(仅最后一条消息带图才走视觉)+ SSE 流式翻译
lib/translate.js     OpenAI 兼容 SSE → DSH StreamChunk 协议(改写自官方 dsh-llm-deepseek)
lib/serialize.js     视觉请求序列化:只发最后一条消息;原图直发;文本历史图片剥离
client/index.js      浏览器半:输入框旁「视觉代理」开关 + 设置页「Vision 模型」面板
cordis.patch.yml     bundle patch:插入插件行
test/vf-smoke.mjs    冒烟测试:文本透传 + 真实视觉请求(自包含,无需外部图片)

安装

# 1. 安装进 profile
dsh plugin --profile web add D:\dsh-vision-fallback

# 2. 把插件加入 profile 的 bundle 列表
#    编辑 %DSH_HOME%\profiles\web\package.json,在 dsh.profile.bundles 里追加:
#    "@local/dsh-vision-fallback"

# 3. 插件依赖自包含
cd D:\dsh-vision-fallback
pnpm install

# 4. 重启 dsh web
dsh web

坑:dsh plugin add 会以 link: 方式把插件链入 profile,Node 解析插件内部 import 时 会还原到真实路径,所以插件目录里必须有自己的 node_modules(上面第 3 步)。 另外 package.json 的 exports必须保留 "./package.json" 条目, 否则 client-modules 扫描会报 ERR_PACKAGE_PATH_NOT_EXPORTED 并永久缓存“不是客户端包”。

配置

热生效于 %DSH_HOME%\settings.yamlllm-vision-fallback: 段:

llm-vision-fallback:
  defaultProvider: ark        # 含图请求走哪个服务商
  providers:                  # 可配多个,面板里也可管理
    ark:
      displayName: 豆包(火山方舟)
      baseUrl: https://ark.cn-beijing.volces.com/api/v3
      model: doubao-seed-2-1-turbo-260628
      apiKeyEnv: ARK_API_KEY  # 凭据引用:key 本身存在 DSH 凭据库,绝不在配置文件里
  • API Key 通过 DSH 凭据服务写入(设置页/凭据入口),本仓库不含任何密钥
  • 想加服务商(硅基流动 / 百炼千问 / GLM / OpenRouter / 本地 vLLM…):只要 OpenAI 兼容即可

使用

  1. 会话里选好你的文本模型(任意)
  2. 点输入框旁的「视觉代理」开关(变蓝,显示「视觉代理 · 你的模型名」)
  3. 正常聊天 = 你的模型;让 agent 看某张图(read_image)= 自动转发视觉服务商
  4. 想换视觉服务商:设置 → Vision 模型 面板

开发与测试

node test\vf-smoke.mjs    # 文本透传(假dispatch) + 真实视觉请求;凭据读 %DSH_HOME%\.credentials.yaml

不确定与已知问题

开发性质

  • vibe coding 产物,作者对 DSH 内部 API(LlmAdapter seam、slots、RPC 信封)的理解靠读源码试错,不保证符合官方意图
  • 仅验证环境:Windows 11 + deepseek-v4-pro + 火山方舟豆包(单个账号);其他系统/服务商未测

使用中需要注意

  • 宿主侧(lib/)改动必须重启 dsh web;客户端(client/)改动刷新页面即可
  • 视觉请求只发最后一条消息(图片 + 文字):多轮"追问上一张图"的场景不适用,追问时请重新发图
  • 原图直发、不做压缩:超大图可能超过豆包的图片 token 上限("Total tokens of image and text exceed max message tokens")
  • 视觉回复的 max_tokens 被钳制在 8192
  • 视觉服务商必须 OpenAI 兼容(/chat/completions + SSE + /models
  • 开关开启期间会话路由挂在 vision-fallback 上:若插件卸载/停用,该会话会失效,需手动切回原模型

已知坑(都在这上面摔过)

  • link: 安装 + Node realpath → 插件目录必须自包含依赖(见安装第 3 步)
  • package.json exports./package.json → 设置面板永远不加载
  • 客户端 RPC 返回是 {result:{ok,value}} 信封,忘了解包 = 面板永远“不可写”
  • 历史里有旧图片时曾把所有文本请求都发给视觉模型 → 现已改为“仅最后一条消息带图才路由”
  • 视觉模型不认 developer 角色、不认 thinking 参数 → 已做归一化/剥离

未做 / 可能坏的地方

  • 手写 client bundle(未走官方 tsdown 构建链),HMR 无支持
  • 多图同时读、并发切换开关、子代理会话里的表现未验证
  • 推理强度(off/high/max)透传只验证过 deepseek-official 一家
  • 官方「模型」设置页也会显示本插件的 provider 行,但它不理解本插件的配置结构——请在专属面板里改配置

License

MIT