返回

DeepSeek Harness 配置覆盖:写一个可验证、可回退的 patch

以关闭额外的会话标题模型请求为例,解释 dsh 0.2.0-rc.2 的 patch 顺序、config 替换语义、配置导出和运行验证,并保留原配置以便回退。

你已经能运行任务,现在想让脚本执行时少发一次生成会话标题的模型请求。这个需求不需要重写插件,先找到对应条目,写一个只影响它的覆盖层。

本文以 CLI 0.2.0-rc.2 为准。先完成profile 初始化,使用独立的 tutorial-ci。本轮检查组合配置的变化;0.1.5-rc.1 下观察到的实际标题请求变化,会明确作为历史运行结果说明,不替代新版的模型验收。

先保存现状,再找目标条目

在安装 CLI 的项目目录导出:

npx --no-install dsh --profile tutorial-ci --dump-config > before.yml

在输出中查找 session-title。本版本包含两个相关 ID:

ID 职责
session-title 提供会话标题能力与 fallback 配置
session-title-llm 基于模型生成标题

这次要关闭的是后者。保留标题服务,才能继续使用它的非模型 fallback。先看真实配置,避免凭插件包名或标题里的一两个词猜 ID。

用外部 patch 试验,不覆盖原文件

创建一份明确可回退的文件:

cat > ci-no-title.patch.yml <<'EOF'
- id: session-title-llm
  disabled: true
EOF

npx --no-install dsh --profile tutorial-ci \
  --patch ./ci-no-title.patch.yml --dump-config > after.yml
diff -u before.yml after.yml

应当看到 session-title-llm 的 disabled: true,而 session-title 仍保留。导出中的来源注释能帮助定位是哪一层改了条目。

这个 patch 目前只作用于带 --patch 的调用。省略参数即可恢复原方案,不用先修改长期配置。

配置变了,还要确认行为变了

通过同一个 profile 和 patch 发起任务:

npx --no-install dsh --profile tutorial-ci \
  --patch ./ci-no-title.patch.yml --json \
  "Read tutorial-input.txt and report its port field." \
  > patched-events.jsonl 2> patched.stderr

验证时分别观察任务结果、会话标题以及模型请求记录。事件输出是投影,持久化会话日志与模型侧请求记录可能提供不同信息;如果某种输出本来就不包含标题请求事件,不能把“搜不到”当作没有请求的证明。

旧版 0.1.5-rc.1 的运行记录中,禁用前出现过 session/title-llm-request,禁用后该事件消失而会话标题仍生成。这说明该场景的验证思路可用,但不保证新版事件名称、输出范围与旧日志完全相同。新版应以一次相同任务的前后对照重新检查。

config 的覆盖不是逐字段合并

下面是一个容易产生误解的 patch:

- id: session-title
  config:
    maxTitleBytes: 999

它会用新对象替换该条目的 config。组合配置中原有的 fallbackMaxWords、fallbackMaxBytes 等字段不会因为你没写就自动留在这个对象里。至于插件随后是否补默认值,是插件自己的配置逻辑,要另行核对。

这两层区别很重要:导出的字段消失,不等于运行时必然没有默认值;覆盖整个对象,也不等于安全地修改了一个字段。

需要保留已有配置时,先导出当前对象,把需要保留的字段或表达式一并写入覆盖层,再对比最终结果。尤其注意 !!js 表达式:把动态读取命令行值的表达式换成字面量,可能同时改变参数的效果。

本例使用 disabled,不触碰 config,因此修改范围更容易核对。覆盖语义见固定版本 patch 实现。

覆盖层按什么顺序生效

正常顺序是:按 bundles 列表叠加各 bundle 的 patch,再叠加 profile 的 cordis.patch.yml,最后叠加命令行 --patch 指定的文件。多个命令行 patch 按传入顺序处理,后面的操作会影响前面组合出的结果。

这是逐项 patch 的处理过程,不能简单理解成任意 YAML 的递归合并。匹配 ID、插入条目、禁用和替换配置分别有自己的语义。profile 组合声明解释了层的来源和顺序。

没生效时,先查 ID 和 stderr

一个打错的 ID 可能只产生警告,随后继续处理配置。命令退出码为 0,不能证明每个目标都匹配了。

排查时检查三件事:用的是哪个 profile;目标 ID 是否来自该 profile 的当前导出;stderr 是否出现未匹配条目或其他警告。ID、npm 包名和模型工具名不一定相同。

确认外部 patch 达到目的后,再把对应条目合并进 $DSH_HOME/profiles/tutorial-ci/cordis.patch.yml。先备份并保留文件中已有的数组条目,不要用本文的两行示例覆盖整份长期配置。

修改完成的标准是:最终配置符合预期,实际任务行为也符合预期,并且你知道怎样撤回。给既有能力做调整用 patch;添加新能力则回到社区插件的选择与验证。

最后更新于 2026年10月15日 00点00分00秒