简要结论
从 apply(ctx) 到工具注册、配置校验、事件观察和卸载验证,走完一条最小插件链路。
本练习跟随官方 Cordis 教程的接口,但用一个“项目状态”工具串起插件、配置、工具和事件。命令与包接口可能随 Developer Preview 变化,执行前对照官方仓库当前文档。
1. 认识 apply(ctx)
Cordis 插件通过命名导出提供 apply,Loader 加载后用 Context 调用它:
import type { Context } from '@deepseek-ai/cordis'
export const name = 'project-status'
export function apply(ctx: Context) {
console.log('project-status mounted')
}
name 是诊断元数据。插件描述自己的贡献,cordis.yml 负责组合应用。配置行可能并发启动,依赖顺序应由 inject 表达。
2. 添加可校验配置
import Schema from '@deepseek-ai/schemastery'
export interface Config {
label: string
maxLength: number
}
export const Config: Schema<Config> = Schema.object({
label: Schema.string().default('workspace'),
maxLength: Schema.number().default(200),
})
不同部署会改变的值放进 Config,不要硬编码。Schema 会在加载时验证并填充默认值;配置错误应该尽早、明确地失败。
3. 注册只读 Tool
import type { Context } from '@deepseek-ai/cordis'
import { defineTool } from '@deepseek-ai/dsh-tools'
export const name = 'project-status'
export const inject = ['tools']
export function apply(ctx: Context, config: Config) {
ctx.tools.register(defineTool({
name: 'project_status',
description: 'Return a configured label for the current tutorial workspace.',
parameters: {},
output: {
schema: { type: 'string' },
render: (_args, value) => [{ type: 'text', text: value }],
},
async execute() {
return config.label.slice(0, config.maxLength)
},
}))
}
注册返回的 disposer 会附着到插件生命周期,因此卸载时工具应一并注销。
4. 组合应用
- name: '@deepseek-ai/dsh-system-prompt'
- name: '@deepseek-ai/dsh-tools'
- name: './project-status.ts'
config:
label: 'tutorial-workspace'
maxLength: 80
工具服务需要向系统提示贡献 Schema,因此组合中包含相应系统提示服务。缺少依赖提供方时,插件可能保持 PENDING。
5. 观察结果事件
另建一个观察插件监听 tools/result,只记录工具名、成功状态和有界摘要。观察者不需要知道生产者实现,两者通过服务注册表与事件解耦。
验证清单:
- 启动时插件挂载一次;
- Tool 出现在可用目录;
- 合法调用返回符合 Schema 的值;
- 非法配置在加载阶段失败;
- 修改配置触发热替换后没有重复注册;
- 卸载 Plugin 后 Tool 消失;
- 日志中没有凭据和完整敏感结果。
6. 接入完整 Harness
官方教程提供两条路径:
- 直接通过真实工具执行流水线调用,无需模型 Key;
- 在 Web UI 开发模式中用
--patch挂载本地cordis.yml,再让模型调用。
先完成无模型的确定性测试,再接入 Agent Loop。这样失败时可以区分“插件/工具实现错误”和“模型没有选择工具”。
扩展作业
- 增加一个枚举参数,但保持 Tool 只读;
- 为超长返回实现有界 render;
- 为 Config 添加非法值测试;
- 写一个独立观察插件统计调用次数;
- 记录卸载和 HMR 后注册表是否恢复。
至此,你已经从使用者走到最小扩展开发者。回到教程中心选择架构或安全专题继续深入。