QP内容库 Logo
首页
文章
文档
默认分类
关于
登录 →
QP内容库 Logo
首页 文章
文档
默认分类 关于
登录
  1. 首页
  2. 文档
  3. DeepSeek Harness
  4. Cordis 框架教程
  5. 6. 组合与 HMR(热模块替换)

6. 组合与 HMR(热模块替换)

  • Cordis 框架教程
  • 发布于 2026-09-30
  • 0 次阅读
目录
当前文章没有目录

English | 中文

到目前为止构建的每项能力都是插件,cordis.yml 则选择应用的插件树。本章会改变这种组合、热重载一个插件,并诊断始终无法加载的插件。

Cordis 配置项不只有名称

Cordis 配置项除了 name 和 config,还接受其他元数据:

- id: greeter          # stable identity for this entry
  name: './greeter.ts'
- id: consumer
  name: './consumer.ts'
  disabled: true       # keep the entry, skip mounting it

id 为 Cordis 配置项提供稳定标识,使 loader 能区分修改现有 Cordis 配置项与先删除再添加。disabled: true 会卸载插件而不删除其 Cordis 配置项;改回原值后,插件以及所有因依赖其服务而处于 PENDING 的插件都会再次加载。

组可以嵌套一份 Cordis 配置项子列表,并将其作为一个单元加载和卸载;isolate 则为一个组提供某项服务名称的独立实例,因此两个组可以各自看到配置不同的 shell 提供方,互不影响。Cordis 入门和服务隔离示例介绍了详细内容。

热模块替换

卸载会释放 effect(第 2 章),加载则遵循依赖关系(第 3 章),因此 HMR 可以先卸载、再加载,以替换正在运行的插件。@deepseek-ai/dsh-hmr 插件会监视文件,并在保存时执行这一过程。

在 tmp/cordis-tutorial 中编写 cordis.yml:

- id: logger
  name: '@deepseek-ai/cordis-plugin-logger-console'
- id: timer
  name: '@deepseek-ai/cordis-plugin-timer'
- id: hmr
  name: '@deepseek-ai/dsh-hmr'
  config:
    root: ['.']
- id: hello
  name: './hello.ts'

列表中增加了两个辅助插件:HMR 通过 Cordis logger 服务记录日志,因此没有控制台导出器时看不到其消息;它还会 inject timer 服务来实现去抖,如果没有 @deepseek-ai/cordis-plugin-timer,它就会永远停在 PENDING,而且不发出任何提示。下一节就讨论这种静默状态。

HMR 通过 Loader 的原生辅助工具读取 Node 的 loader 内部结构。请在 tsx 下运行 Cordis:

node --import tsx ../../vendor/cordis/bin.js

现在编辑 hello.ts,修改日志消息并保存:

hello from my first plugin
2026-07-22 15:44:36 [I] hmr watching [ '.' ]
2026-07-22 15:44:39 [I] hmr reload plugin at hello.ts
hello from my EDITED plugin

旧实例先卸载(其所有 effect 都会回卷),新代码随后加载,apply 再次运行。按 Ctrl-C 停止进程。编辑 cordis.yml 本身也会触发更新:loader 按 id 比较 Cordis 配置项,只挂载、卸载或重新配置发生变化的部分。这就是上述 Cordis 配置项显式携带 id 的原因:不带该字段的 Cordis 配置项在每次读取时都会获得一个新生成的 id,所以只要配置文件发生任何编辑,即使自身文本未变,它也会被视为先删除再添加并重新挂载。

诊断始终无法加载的插件

依赖驱动加载也有另一面:如果插件的 inject 指定了无人提供的服务,它就会一直等待,不输出任何内容。这不是错误,因为 PENDING 是合法状态,提供方可能稍后才挂载。

你可以直接查看这些状态。每个上下文都能枚举插件注册表;创建 diagnose.ts:

import { FiberState, type Context } from '@deepseek-ai/cordis'

export const name = 'diagnose'

export function apply(ctx: Context) {
  setTimeout(() => {
    for (const runtime of ctx.registry.values()) {
      for (const fiber of runtime.fibers) {
        if (fiber.state === FiberState.PENDING) {
          console.log(`${fiber.name} is PENDING — a required service is missing`)
        }
      }
    }
  }, 500)
}

再创建一个依赖无法满足的插件 needs-timer.ts:

import type { Context } from '@deepseek-ai/cordis'

export const name = 'needs-timer'
export const inject = ['timer']

export function apply(ctx: Context) {
  console.log('needs-timer loaded')
}
- name: './needs-timer.ts'
- name: './diagnose.ts'

运行它(直接执行 node --import tsx ../../vendor/cordis/bin.js,按 Ctrl-C 停止):

needs-timer is PENDING — a required service is missing

inject: ['timer'] 没有提供方。向列表添加 - name: '@deepseek-ai/cordis-plugin-timer' 后,插件就会加载。如果插件既不执行任何操作,也不报告任何内容,请检查其 fiber 状态。不加 PENDING 过滤条件进行迭代时,还会看到 loader 自身的插件(Loader、Include)处于 ACTIVE,因为配置文件本身也是通过插件挂载的。

下一章:进入 harness:把相同模式用于真实的 harness 服务。

相关文章

Cordis 教程

English | 中文 Cordis 是 DeepSeek Harness 底层的插件框架:它是一个小型运行时,其中的每项能力,包括工具、LLM(大语言模型)适配器、文件访问乃至 agent loop(智能体循环)本身,都是挂载到共享上下文中的插件。本教程通过动手实践讲解 Cordis:每一章都是

7. 进入 harness

English | 中文 本章会向 harness 的 tools 服务注册一个可由模型调用的工具,通过 harness 工具流水线执行它,并观察结果事件。整个示例无需密钥,也不会调用模型。 工具插件 创建 greet-tool.ts,将它放在 tmp/cordis-tutorial 中: impo

6. 组合与 HMR(热模块替换)

English | 中文 到目前为止构建的每项能力都是插件,cordis.yml 则选择应用的插件树。本章会改变这种组合、热重载一个插件,并诊断始终无法加载的插件。 Cordis 配置项不只有名称 Cordis 配置项除了 name 和 config,还接受其他元数据: - id: greeter

5. 配置

English | 中文 cordis.yml 中的每个 Cordis 配置项都可以携带 config 块,插件则声明一个 schema,在运行 apply 前验证该块。错误配置会导致加载失败,并给出准确的错误:插件绝不会在配置不完整时启动。 可配置插件 创建 config-demo.ts,并将其放

4. 事件

English | 中文 服务支持直接调用;事件让插件无需知道有哪些插件正在监听,就能发出通知。harness 使用事件处理工具结果、模型请求和审批决定等交互。 声明、发出与监听 创建 stats.ts,将它放在 tmp/cordis-tutorial 中。它是一项负责计数并在每次变化时发出通知的服

3. 服务

English | 中文 服务是一个插件提供、其他插件通过 ctx 消费的具名能力。在 harness 中,ctx.tools、ctx.llm 和 ctx.agents 都是服务。消费方只指定 'tools' 之类的能力,而不导入其提供方,因此配置可以选择提供方,无需修改消费方。 提供服务 创建 g

目录
当前文章没有目录

星沉月落夜闻香,素手出锋芒。

Copyright © 2026 quping.com All Rights Reserved. Powered by Halo.
鲁ICP备09092435号