系列教程
41 节
Codex 教程
按顺序阅读,循序渐进掌握相关 AI 工具与实战方法。
从「ChatGPT (Codex) 教程」开始
上一篇的 greet 工具把问候语写死在代码里,不同部署想换就得改代码。这篇让插件接受 cordis.yml 传入的配置,做到「配置与代码分离」。
做法是在插件中导出一个 Config 接口和同名的 Schemastery schema,默认值直接写在 schema 字段上:
// 文件路径:scratch-plugin/src/my-plugin.ts
import type { Context } from '@deepseek-ai/cordis'
import Schema from '@deepseek-ai/schemastery'
export const name = 'my-plugin'
// Config 接口:定义插件接受哪些配置项
export interface Config {
greeting: string // 问候语
maxRetries: number // 最大重试次数
verbose?: boolean // 是否输出详细日志(可选)
}
// 同名的 Config schema:默认值写在这里
export const Config: Schema<Config> = Schema.object({
greeting: Schema.string().default('Hello'),
maxRetries: Schema.number().default(3),
verbose: Schema.boolean().default(false),
})
// apply 的第二个参数就是校验后的配置
export function apply(ctx: Context, config: Config) {
console.log(config.greeting) // 用户传入的值或 schema 默认值
}
接口给 TypeScript 类型,schema 给运行时校验与默认值;两者同名是 Cordis 的约定。注意:不要导出普通对象作为 Config,它不满足 Cordis 要求的 Standard Schema 接口。
在插入插件的行里加一个 config 字段:
# 文件路径:scratch-plugin/cordis.yml
- insert:
- id: hello
# 插件路径必须是绝对路径
name: '/absolute/path/to/deepseek-harness/scratch-plugin/src/my-plugin.ts'
config:
greeting: 'Hi there, izzi!'
maxRetries: 5
插件加载时,Cordis 会通过导出的 schema 校验配置,并填充未提供字段的默认值——上面没写 verbose,它会取默认值 false。
需要更严格的约束时,用 Schemastery 表达:
export interface Config {
apiKey: string // 必填
timeout: number // 超时毫秒数
mode: 'fast' | 'accurate' // 只能取这两个值之一
}
export const Config = Schema.object({
apiKey: Schema.string().required(),
timeout: Schema.number().default(30000),
mode: Schema.union(['fast', 'accurate']).default('fast'),
})
Schema 在插件加载时执行校验;配置不合法,插件直接加载失败并给出明确错误信息——配置错误要「响亮」,让无效配置在加载阶段就暴露。
Harness 的约定是:凡是不同部署可能取不同值的参数,都必须定义为配置字段。
// 错误:把超时时间硬编码
const TIMEOUT = 30000
// 正确:定义为配置字段,默认值由 schema 提供
export interface Config {
timeoutMs: number // 默认 30000
}
检验标准一句话:能否在 cordis.yml 中改变这个值,而不需要修改代码?能,就是合格的可调参数;不能,就把它提成配置字段。硬编码会把「改配置」变成「改代码加重新部署」,是生产事故的常见来源。另外,对服务或已注册资源的引用不要走配置,需要依赖注入。
修改 cordis.yml 中某个插件的 config 会触发插件热替换(HMR):框架卸载旧实例并加载新实例。由于注册都属于 effect 并会自动清理,替换后不会残留旧实例的注册。