DeepSeek Harness 插件

dsh-plugin-modality-fallback

DeepSeek Harness (dsh) plugin: route one request to a modality-capable fallback model instead of forcing the whole session onto a single model.(英文原文)

跳到安装方式

来源信息

GitHub 仓库
lilei0311/dsh-plugin-modality-fallback
最近更新
2026年8月20日
分类
记忆
GitHub stars
0
载体类型
plugin
目录证据
上游声明已找到 dsh.bundle
证据路径
package.json#dsh.bundle
核对版本
0.1.0-rc.8
上游核对日期
2026-08-20

该证据由上游目录提供。本站没有安装、运行或安全审核这个插件。

安装

默认先复制一段 Prompt,让 Agent 读 GitHub 仓库和源码;需要自己装时再切到命令。

复制这段 Prompt,发给 DSH、Codex 或其他 Agent,让它先读 GitHub 仓库和源码。

请先不要安装或执行任何命令。阅读这个插件的 GitHub 仓库、README 和关键源码,然后用清楚、直接的方式回答以下问题,帮助我判断它是否适合我的需求:

1. 这个插件是什么,解决什么问题;
2. 适合哪些用户和典型使用场景;
3. 安装后如何使用,并给出一个最小使用示例;
4. 有哪些已知限制,以及隐私、安全、兼容性或维护风险;
5. 给出“推荐 / 有条件推荐 / 不推荐”的明确建议和理由。

请区分仓库明确说明、根据源码推断和未知信息。证据不足时请明确说明,不要猜测或照抄 README。

GitHub:https://github.com/lilei0311/dsh-plugin-modality-fallback
插件名:dsh-plugin-modality-fallback
作者:lilei0311

检查来源文件

安装前先看这个插件目录里的 README 和其他文件。

文件资源管理器4 个文件
README.zh.md来源说明 · 只读预览
README 语言

dsh-plugin-modality-fallback

English | 中文

一个 DeepSeek Harness(dsh)插件:把单次请求路由到支持对应模态的备用模型,而不是让整个会话都被锁死在一个模型上。

要解决的问题

dsh 的一个会话(Agent)在整个生命周期里只能选定一个 provider/model。但这个模型未必能接受会话历史中出现的所有模态——目前主要是图片。在没有这个插件的情况下:

  • 内置的 read_image 工具在会话当前模型没有声明支持 image 输入时会直接拒绝执行:"switch to an image-capable model to read images"。
  • ApiProxy 在会话历史里已经有图片、而目标模型不支持图片时,会拒绝发送消息或拒绝切换模型。

这些路径最终都要求用户手动把整个会话切到一个支持图片的模型,用完再切回来——为了处理一张图片,牺牲了会话里其余部分特意选定的模型。

这个插件做了什么

它包裹了 dshagent/request waterfall 事件(这正是 dsh-agent-default-model 自己 README 里标注为遗留问题的扩展点:"per-session selection remains the entry point's responsibility")。在一次请求真正发出之前:

1. 读取会话已推导出的消息历史(agent.session.deriveMessages())。 2. 如果这段历史需要纯文本之外的模态(目前只检测 image),并且其他所有监听器最终解析出的模型没有声明支持该模态(llm.resolveModelInfo(...).inputModalities),就查找为该模态配置的备用路由。 3. 如果配置了,就仅为这一次请求替换 provider/model。会话本身的选择不受影响——下一次请求(等图片滚出上下文,或者用户主动切换模型后)会照常正常解析。

不修改 deepseek-harness 的任何核心代码。这只是一个普通的 Cordis 插件,和你其余的 dsh 组合插件一起加载即可。

安装

这个包自带 dsh.bundle manifest,所以用 dsh plugin 一步就能装好并挂进某个 profile:

dsh plugin --profile web add dsh-plugin-modality-fallback
# 或者直接从 GitHub 装,不需要发布到 npm:
dsh plugin --profile web add github:lilei0311/dsh-plugin-modality-fallback

这会把这个包追加进 profile 的 dsh.profile.bundles,并应用 [cordis.patch.yml](cordis.patch.yml)——插入的插件行默认 fallback: {}(还没配置任何路由,所有请求行为跟没装这个插件之前完全一样)。要配置真正的备用路由,在你自己 profile 或者 $DSH_HOMEcordis.patch.yml 里重新声明这一行的 config(patch 是整个替换 config,所以 id 也要写上):

- id: modality-fallback
  config:
    fallback:
      image: { provider: deepseek-official, model: deepseek-vision }

dsh --profile web --dump-config 可以确认这一行确实生效了。完整的 bundle/profile 机制见 deepseek-harness 的插件安装教程

编程方式使用(自己内嵌 dsh)

import ModalityFallback from 'dsh-plugin-modality-fallback'

await ctx.plugin(ModalityFallback, {
  fallback: {
    image: { provider: 'deepseek-official', model: 'deepseek-vision' },
  },
})

请在 llmagent/agent-loop 插件之后加载它,确保 ctx.llmagent/request waterfall 已经存在。

已知局限

  • 目前只检测 image 模态。 ModelModality 本身是可扩展的词表,但这个插件的内容检测目前只会遍历图片 block。要扩展到其他模态,只需要新增一个内容判定函数,不需要改动路由机制本身。
  • 每次请求最多只解决一个缺失的模态。 如果未来的检测同时发现多个未满足的模态,目前只会路由第一个,其余的会原样透传。
  • read_imageApiProxy 自己的门控不受影响。 它们在请求真正构建*之前*就已经根据会话当前选定的模型做出拒绝判断,所以即便这个插件已经为对应模态配置好了可用的备用路由,它们依然会拒绝。要修复这一点需要改动 deepseek-harness 核心本身(让这些门控在拒绝前先咨询本插件或等价能力)——这超出了一个不改核心代码的插件的范围。
  • 模型能力未知时按"可以"处理。resolveModelInfo(...).inputModalitiesundefined(能力未知)时,插件不会触发路由——这与 ApiProxy 现有的发送/切换模型门控一致,但比 read_image 更宽松(read_image 在能力未知时会直接拒绝)。如果部署方希望在能力未知时也触发路由,应该让对应的 adapter 显式声明 inputModalities
  • 切换路由会丢弃继承的 reasoning effort,而不是把可能不被备用模型支持的 effort 继续透传下去;转而使用备用路由自身 adapter/provider 的默认值。
  • 能力探测失败时会放行,不会拖垮请求。 resolveModelInfo 是 adapter 自己的异步 I/O,有可能失败(网络问题、adapter 返回的元数据校验不过等)。这个插件本来就只是"锦上添花"——帮忙绕开一个缺失的模态,所以探测失败时只会打一条 ctx.logger.warn 警告,路由保持不变,不会让整个请求跟着失败,哪怕这次请求原本选中的模型压根不需要备用路由。探测本身在这次请求需要的模态里一个都没配路由时会直接跳过(默认安装的 fallback: {} 永远不会触发它),所以这条只在你已经配置了路由之后才用得上。

为什么是插件,而不是提交给 deepseek-harness 的 PR

deepseek-harness 目前仍处于早期的开发者预览阶段,其 CONTRIBUTING.md 明确说明项目暂不接受外部 Pull Request。项目自己给出的建议是:做成插件分享出来——这个仓库就是这么做的,并打上了 dsh-plugin 这个 GitHub topic 以便被发现。

License

MIT