首页 / DeepSeek Harness 入门教程 / 配置体系:patch 与覆盖层

DeepSeek Harness 入门教程

配置体系:patch 与覆盖层

本教程共 32 篇 · 第 9 篇 · 更新于 2026-08-15 · 约 5 分钟阅读

配置patchcordis.yml覆盖层dump-config

本节目标:掌握 cordis.patch.yml 的写法、按 id 定位条目的规则,以及四层配置叠加顺序,学会用 —dump-config 查看最终配置树。

dsh 没有传统的「配置文件大全」。它的配置由一层层 patch 叠出来,每一层都是 YAML 文件。这一章把 patch 语法和叠加规则讲透,你就能读懂任何一份 dsh 配置。

配置项:cordis.yml 的基本单元

cordis.yml 是一个配置项的列表。每个配置项可以带这些字段:

- id: greeter          # 稳定标识,patch 靠它定位
  name: './greeter.ts' # 插件模块:相对路径、绝对路径或 npm 包名
  config:              # 传给插件的配置(可选)
    greeting: Hello
  disabled: false      # true 时保留条目但不挂载

name 是模块指定符。loader 会挂载每个配置项,各项并发启动。列表位置不保证加载先后,顺序由服务依赖(inject)决定。

patch:按 id 定位条目

patch 文件与 cordis.yml 同构,都是配置项列表。区别在语义:patch 按 id 定位已有条目并替换其整个 config,或插入新条目。看一个实际例子——用 --patch 覆盖层插入本地插件:

# scratch-plugin/cordis.yml
- insert:
  - id: hello
    name: '/absolute/path/to/my-plugin.ts'  # 本地插件必须用绝对路径

insert 是加载本地插件时的显式写法。修改既有配置则直接给出 id 和新的 config,例如把某插件的超时从 5 秒改成 60 秒,只需在 patch 里写:

- id: dsh-bash-local
  config:
    timeoutMs: 60000
Warning

patch 按 id 替换的是条目的整个 config,不是合并键值。漏写一个键,它的默认值或出厂值就没了。改配置前先 --dump-config 看原样,再动笔。

四层叠加顺序

第 7 章讲过组合顺序,这里落到文件层面:

  1. bundle 序:profile 列出的每个 bundle 的 patch(如 dsh-basecordis.patch.yml
  2. profile patch$DSH_HOME/profiles/<name>/cordis.patch.yml
  3. home 级 patch$DSH_HOME/cordis.patch.yml
  4. —patch 覆盖层:命令行传入的任意 YAML
dsh web --patch ./scratch-plugin/cordis.yml

靠后的层覆盖靠前的层。出厂配置写在 bundle 层;个人偏好写 home 层;临时调试写 --patchid 相同则后层替换前层,这是整个配置体系唯一的核心规则。

可以想成贴便利贴:越晚贴的越靠上,盖住下面同位置的内容。patch 不跟你商量,同 id 直接整条替换。

显式 id 有多重要

id 为配置项提供稳定标识,使 loader 能区分「修改现有条目」与「先删后加」。没有 id 的配置项,每次读取都会获得一个新生成的 id——只要配置文件有任何编辑,即使它自身文本没变,也会被当作先删除再添加,重新挂载一次。

热重载(HMR)按 id 比较配置项,只挂载、卸载或重新配置发生变化的部分。所以:自己写的插件条目,永远显式写 id。

人话版:id 是配置项的身份证。没有身份证,每次读文件都当新人,重新挂载一遍;有了 id,系统才知道你是回头客,只更新你的资料。

配置校验与计算值

每个插件导出一个同名 Config schema(用 Schemastery 定义),loader 在运行 apply 前校验 config。配置不合法,插件直接加载失败,绝不带病启动:

ValidationError: invalid config:
  - $.targets expected array but got not-an-array (at targets)

loader 还支持 !!js 标签,在加载时计算配置值:

- id: demo
  name: './config-demo.ts'
  config:
    greeting: !!js process.env.DEMO_GREETING ?? 'Hello'

!!js 只在 config 与条目 disabled 字段内有效。按平台或环境门控一行插件是常见用法:

- id: pwsh
  name: '@deepseek-ai/dsh-pwsh-local'
  disabled: !!js process.platform !== 'win32'

查看最终配置树

配置叠了几层,难免想确认最终结果。两个命令不启动即可查看:

# 完整组合树(含 profile/home/--patch 各层)
dsh --profile web --dump-config

# 仅部署默认(不含用户层)
dsh --profile web --dump-default-config

打印出的任何条目,都可以由你自己的 patch 替换。官方还有一个生成的参考文档 config-catalog:每个可加载包原样列出其 config: 声明(含 JSDoc),并标注 Requires: 注入的服务键。想查「这个插件能配什么」,先翻它。

改配置没生效,八成不是语法错,而是改在了被覆盖的层上。先 dump 看最终树,再动手。

Tip

排查思路:插件没生效 → 先看它是否卡在 PENDING(依赖未满足);配置没生效 → 先 --dump-config 看最终树里 id 是否被后层覆盖。两步能解决绝大多数配置问题。

Warning

版本基线 @deepseek-ai/dsh 0.1.0-rc.6 处于快速迭代期。!!js 求值、patch 语义等细节以 dsh --version 实测和官方 config-catalog 为准。

小结

  • 配置是一层层 patch 叠出来的,每层都是 YAML 文件。
  • patch 按 id 定位条目,替换整个 config,不做深度合并。
  • 四层顺序:Bundle 序 → Profile patch → home patch → --patch
  • 自己写的插件条目永远显式写 id,热重载才能只动该动的部分。
  • 配置不合法直接加载失败;!!js 可在 config 里注入计算值。