DeepSeek Harness DSH plugin:Context、inject、事件与可逆注册
Cordis 是 DeepSeek Harness 底层以 vendor 方式引入的插件框架,DSH plugin 的一切挂载、依赖与通信都由它定义——在 Cordis 里一切皆插件(来源)。 官方要求插件作者在阅读子系统页面上生成的服务 / 事件参考之前,先掌握五个核心概念:插件是实现 Service 的对象、Context 是服务容器、inject 声明依赖、类型化事件通信、注册是可逆副作用。
DSH plugin 的 Service 与 Context:一切皆插件与服务容器
在 DSH plugin 里一切皆插件:插件本身既可以是带可选 inject 与 apply(ctx) 的函数,也可以是 Service 子类;Context 则是承载这些服务的容器(来源)。 对 DSH插件 作者来说,这套写法对应两点:
- 插件是实现 Service 的对象 — 可以是带可选
inject与apply(ctx)的函数,也可以是Service子类。预期:生命周期由 Cordis 挂载到当前上下文。 - Context 是服务的容器 — 一个服务占据稳定的
ctx.<key>,如ctx.tools、ctx.llm、ctx.sessions。预期:插件按 key 查找服务,不导入具体实现,于是你会看到同一 key 背后的实现被整体替换。
为什么「服务按 key 查找」如此关键:它意味着别人可以换掉某个服务的实现而不动调用方,这正是 能力 Seams 与核心服务 讨论的扩展点分类基础。
DSH plugin 的 inject:用服务依赖声明加载顺序
Context 让实现按 key 查找,inject 则把加载顺序变成依赖关系——你需要按下面三步组织提供方与消费方(来源)。
- 写一个提供方 — 把能力挂到
ctx.<key>上,或用Service子类。预期:其他插件可通过 key 访问。 - 写一个消费方 — 用
inject声明依赖的服务 key。预期:提供方就绪后才启动;未就绪则停在 PENDING。 - 只依赖抽象 — 调用方不导入具体实现。预期:换实现不动调用方。
PENDING 是合法状态而非错误,这也是排查「插件没反应」的入口,具体诊断见 Cordis 组合与热重载。
DSH plugin 的事件与可逆副作用:五种分发模式与 effect
每种事件只有一种分发模式,且只能通过对应方法分发——模式是事件公开约定的一部分(来源)。 对照表:
| 模式 | 是否 await | 分发顺序 | 有返回值 |
|---|---|---|---|
emit | 否 | 按注册顺序观察 | 否 |
waterfall | 否 | 按注册顺序观察 | 是 |
parallel | 是 | 所有监听器并行 | 否 |
serial | 是 | 按注册顺序观察 | 是 |
bail | 否 | 按注册顺序,直到首个 bail 值 | 是 |
ctx.waterfall 是环绕中间件:监听器接收 (...args, next),调用 next() 执行下游并拿到下游返回值供本层包装;不调用 next() 直接返回即短路。只做标注或观察的监听器必须委托,只有拥有决策权的策略监听器才该短路;仅当监听器必须在普通注册之前运行时才用 prepend: true。
每个注册都应有对应的 disposer:要么从 ctx.effect() 返回一个,要么用 Cordis 提供的辅助方法自动处理。如果 teardown 顺序有要求,把相关工作放在同一个 effect 中,确保资源按预期顺序释放。
实践规则一句话:需要拦截 / 策略时优先用事件,需要直接能力调用时优先用服务方法——工具流水线事件属于 ctx.tools,模型流式输出属于 ctx.llm,实时 agent 协调属于 ctx.agents。写完自检三项:是否只依赖服务 key 而非实现;inject 是否覆盖全部依赖;每个注册是否有 disposer。想接着看事件实操,读 DSH plugin 事件系统;想找用这套概念写出的插件,可在 DSH Plugin Hub 检索。
常见问题
Cordis 是 DSH plugin 底层以 vendor 方式引入的插件框架,决定了插件如何挂载、如何依赖、如何通信。官方要求插件作者在阅读子系统页面生成的服务与事件参考之前,先掌握它的核心概念,否则看不懂注册与生命周期语义。
在 DSH plugin 里,上下文是服务的容器,一个服务占据一个稳定的 ctx.<key>,例如 ctx.tools、ctx.llm、ctx.sessions。其他插件通过 key 查找服务,而不是导入具体实现,这正是插件可以互相替换的前提。
DSH plugin 用 inject 声明所需服务,声明后插件会等这些服务就绪才启动。加载顺序因此通过服务依赖表达,而不是手动编排启动序列;缺少提供方时插件会停在 PENDING 而不是报错。
DSH plugin 的注册是可逆副作用:提示词片段、工具 schema、适配器、提供方与监听器都通过 ctx.effect() 或 ctx.on() 安装,reload 与 teardown 时会按预期撤销。因此热重载能安全替换插件,也不会残留监听器。
DSH plugin 的实践规则是:需要拦截与策略时优先用事件,需要直接能力调用时优先用服务方法。工具流水线事件属于 ctx.tools、模型流式输出属于 ctx.llm、实时 agent 协调属于 ctx.agents。
相关术语
- Cordis
- Cordis 是 DSH plugin 底层以 vendor 方式引入的插件框架,提供上下文、服务、依赖注入、类型化事件与可逆副作用这套机制,DeepSeek Harness 建立在它之上。— https://deepseek-harness.github.io/deepseek-harness/reference/cordis-primer
- Context
- Context 是 DSH plugin 中承载服务的容器,每个服务占据一个稳定的 ctx.<key>,插件通过 key 查找服务而非导入具体实现,因此实现可被替换。— https://deepseek-harness.github.io/deepseek-harness/reference/cordis-primer
- Service
- Service 是 DSH plugin 暴露给其他插件的能力单元,插件本身既可以是带 inject 与 apply(ctx) 的函数,也可以是 Service 子类,其生命周期由框架挂载到当前上下文。— https://deepseek-harness.github.io/deepseek-harness/reference/cordis-primer
- inject
- inject 是 DSH plugin 声明服务依赖的字段,插件声明所需服务后会等待它们就绪才启动,从而用依赖关系表达加载顺序。— https://deepseek-harness.github.io/deepseek-harness/reference/cordis-primer
来源
- DeepSeek Harness 官方文档 - Cordis 入门· deepseek-ai
- DeepSeek Harness 官方文档 - Cordis 教程· deepseek-ai