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.yaml 的 llm-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 兼容即可
使用
- 会话里选好你的文本模型(任意)
- 点输入框旁的「视觉代理」开关(变蓝,显示「视觉代理 · 你的模型名」)
- 正常聊天 = 你的模型;让 agent 看某张图(
read_image)= 自动转发视觉服务商 - 想换视觉服务商:设置 → 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