DSH plugin 怎么给用户提供配置?插件 Config 定义、Schema 校验与配置文件加载详解
给 DSH plugin 提供配置的标准姿势是:导出 Config 类型 + 同名 Schemastery schema,默认值直接写进 schema(Schema.string().default(...)),apply(ctx, config) 里读到的就是「用户值或默认值」;schema 在插件加载时自动校验,配置不合法就加载失败、错误信息明确(来源);用户在你的插件行 config 字段填值即可,改配置触发热替换、无需重启。
概览:插件配置三步走
插件配置 = 「定义 schema → 交给加载器校验 → 用户填 config」,框架把校验、默认值、热替换全包了,你只负责把参数暴露成配置字段。 整体三步:
- 定义 Config:导出
Config类型 + 同名 Schemastery schema,默认值写进 schema; - 信任校验:配置不合法时插件加载失败,错误信息明确——「配置错误要响亮」;
- 用户侧加载:用户在
cordis.yml的config字段填值,改配置即触发 HMR 热替换。
下面按三步拆开讲,带可复制的代码。
第一步:定义 Config 类型与 Schemastery schema
插件要接受配置,就导出 Config 类型和同名的 Schemastery schema,默认值直接写在 schema 里(来源)。 最小示例:
import type { Context } from '@deepseek-ai/cordis'
import Schema from '@deepseek-ai/schemastery'
export const name = 'my-plugin'
export interface Config {
greeting: string
maxRetries: number
verbose?: boolean
}
export const Config: Schema<Config> = Schema.object({
greeting: Schema.string().default('Hello'),
maxRetries: Schema.number().default(3),
verbose: Schema.boolean().default(false),
})
export function apply(ctx: Context, config: Config) {
console.log(config.greeting) // 用户值或 schema 默认值
}
三个要点:
- 类型与 schema 同名导出:
Config既当类型又当运行时校验器,Cordis 加载时用 schema 校验并填充默认值; - 不要导出普通对象:普通对象不满足 Cordis 要求的 Standard Schema 接口,必须用
Schema.object(...)包一层; - 默认值写进 schema:用户没填的字段自动取默认值,
apply拿到的 config 永远完整。
第二步:Schema 校验——配置错误要响亮
Schema 在插件加载时执行校验,配置不合法插件会加载失败并给出明确错误信息——官方设计原则就是「配置错误要响亮」(来源)。 需要严格校验时这样写:
export const Config = Schema.object({
apiKey: Schema.string().required(), // 必填
timeout: Schema.number().default(30000), // 默认值
mode: Schema.union(['fast', 'accurate']).default('fast'), // 枚举
})
两条设计原则,写插件时对照自查:
- 无硬编码可调参数:凡不同部署可能需要不同值的参数,都必须定义为配置字段——检验标准:能否在
cordis.yml改变这个值而不改代码? - 配置错误要响亮:在 schema 中表达完备约束,让无效配置在加载时就失败,而不是运行到一半才炸。对服务或已注册资源的引用需要依赖注入(服务教程)。
第三步:用户侧配置与 HMR 热替换
用户在你插件的 config 字段填值,改完即触发热替换——框架自动卸载旧实例、加载新实例,旧注册会被清理(来源)。 用户侧写法:
# profile 的 cordis.yml 里,你的插件行
- id: hello
name: './src/my-plugin.ts'
config:
greeting: 'Hi there'
maxRetries: 5
配置加载的三个层级(详见《打包与安装插件》):
- profile 级:profile 目录的
cordis.yml/cordis.patch.yml——插件行的config就在这里填; - home 级:
$DSH_HOME/cordis.patch.yml——各 profile 共享的机器本地偏好; - 热替换:修改某个插件的
config后,框架卸载旧实例并加载新实例,不用重启 dsh;由于注册都属于 effect 会自动清理,替换后不会残留旧注册。
开发时本地验证配置:
# 1. 本地加载插件(--patch overlay 指向源码)
dsh --profile web --patch ./src/my-plugin.ts
# 2. 查看合并后的生效配置(能看到插件那一层)
dsh --profile web --dump-config
# 3. 改 cordis.yml 的 config 后直接观察热替换
写完发布:打包、安装与提交 DSH Plugin Hub
配置做完,插件就可以打包发布了:npm pack 打成 tarball、dsh plugin 装进 profile 验证,再提交到 DSH Plugin Hub 收录。 命令流程:
# 1. 打包成 tarball
npm pack
# 2. 安装进 profile 验证
dsh plugin --profile web add ./my-plugin-0.1.0.tgz
# 3. 验证生效配置
dsh --profile web --dump-config
发布细节见《发布插件到 DSH Plugin Hub》:完成打包后,把插件提交到 DSH Plugin Hub 收录,用户就能在插件中心一键安装、直接在界面改你的配置项——schema 定义得越完整,用户在 Hub 里看到的配置项越清晰。

注意事项
一句话:配置是插件的门面,schema 越完整,用户越少踩坑。 三点提醒:
- 默认值就是文档:把合理的默认值写进 schema,用户不填也能跑,填了就能微调;
- 必填要 required:缺了会崩的参数用
Schema.string().required(),别让错误拖到运行期; - 先本地验证再发布:
--patch+--dump-config把配置加载链路验一遍,再打包上 Hub。
常见问题
三步:导出 Config 类型 + 同名 Schemastery schema(默认值写进 schema),apply(ctx, config) 里直接读;schema 在插件加载时自动校验,不合法就加载失败;用户在你的插件行的 config 字段填值即可,不用改任何代码。
写在 schema 里:Schema.string().default('Hello')、Schema.number().default(3)、Schema.boolean().default(false)。用户没填的字段自动取默认值,apply 拿到的 config 就是「用户值或 schema 默认值」。
Schema 在插件加载时执行校验,配置不合法插件会加载失败并给出明确错误信息——这是官方设计原则「配置错误要响亮」。想要必填字段就用 Schema.string().required(),想要枚举就用 Schema.union([...])。
在插件的行里加 config 字段,如 config: { greeting: 'Hi there' }。不需要重启:修改 cordis.yml 中某个插件的 config 会触发热替换,框架自动卸载旧实例、加载新实例,旧注册会被清理。
用 --patch overlay 本地加载:dsh --profile web --patch ./src/my-plugin.ts,再用 dsh --profile web --dump-config 查看合并后的生效配置;正式发布用 npm pack 打成 tarball 后 dsh plugin --profile web add ./包.tgz 安装验证。
来源
- DeepSeek Harness 官方文档 - 插件配置· deepseek-harness
- DeepSeek Harness 官方文档 - 打包与安装插件· deepseek-harness
- dsh CLI README· deepseek-ai