ARCHITECTURE · 03
DeepSeek Harness 插件系统:新行为应该挂在哪里
直接答案
在 DeepSeek Harness 里,扩展能力的方式是"把插件挂载到其他插件旁边":插件向共享上下文注册服务、工具或事件监听,这些注册都是可逆副作用,卸载时撤销。官方规则是"Plugins, not loop changes"——新行为挂在已记录的扩展点上,而不是去改智能体循环本身。插件怎么工作:挂上去,撤销掉
dsh 的扩展模型一句话能说清:把插件挂载到其他插件旁边。插件的各项注册(服务、工具、命令、事件监听)都是副作用,插件卸载时这些注册被撤销——这是底层 Cordis 框架"可逆注册"机制的直接应用(见 Cordis 框架页)。
官方有一条开发规则叫"Plugins, not loop changes":新行为要挂在已记录的扩展点上;如果确实要改 agent-loop 本身,必须同步更新官方架构文档。这条规则对普通用户的意义是:你看到的一切功能差异,理论上都能用"装了/没装哪个插件"解释。
新行为归属表:想加功能,先找对钩子
出自官方 docs/architecture.zh.md:
| 你想加什么 | 应该挂到哪里 |
|---|---|
| 新的模型提供方 | 向 ctx.llm 注册适配器 |
| 面向模型的能力(工具) | 向 ctx.tools 注册 |
| shell 执行能力 | 向 ctx.shell 注册后端 |
| 用户命令 | 向 ctx.commands 注册 |
| 后台工作 | 向 ctx.jobs 注册 |
| 拦截请求 / 工具 / 轮次 | 监听 agent/*、tools/* 事件 |
安装不等于生效:插件包与组合包的区别
树外插件的安装命令是 dsh plugin --profile <name> add <package>,它把一个树外组合包装进指定的 profile(配置档案)。
但有个常见误区:插件包不等于组合包(bundle)。dsh plugin 也能安装普通依赖包;一个没有 dsh.bundle 声明的包会保留为普通依赖,并提示它不是 profile 配置层。也就是说"安装成功 ≠ 成为组合包层"。本站教程的验证方法是用 --dump-config 打印机器实际启动的配置树,确认条目真的挂进去了(官方事实:--dump-config 行为见官方架构文档;教程完整验证流程见《插件安装与验证》)。组合包与 patch 层的展开见配置分层页。
热更新的边界:patch 层能热更,Bundle 层要重启
- 用户 patch 层热更新(官方事实):profile 和 home 目录下的
cordis.patch.yml变更会由watchUserPatches监听并事务式重新组合;如果读取或解析失败,保留最后可用的配置树继续运行。
- Bundle 层变更需重启(教程实测,非官方承诺):本站教程实测确认,Bundle(组合包)成员列表在 profile 启动时确定,安装、更新、删除 Bundle 后必须重启才生效。注意:这条是教程实测结论(基线版本 0.1.1-rc.2),官方文档没有直接这样表述,后续版本可能变化。
作用域规则:全局、归属与遮蔽
注册要么全局生效,要么归属于一个 scope key(作用域键;活跃 agent 就是它自身作用域的 key)。两条关键规则:
- 带作用域的注册不会向下继承给 subagent(子智能体);子树行为靠 lineage(谱系)数据表达。
- 遮蔽(shadowing)规则是"最具体者胜出"——离当前作用域最近的注册生效。
声明合并:插件不改源码也能加类型
dsh 的可扩展类型通过 TypeScript 的声明合并(declaration merging)扩展。官方定义了六个规范 Map:ContentBlockMap、MessageSourceMap、FinishReasonMap、TurnTriggerMap、TurnEndReasonMap、SessionEventMap。插件不用修改源包,就能往这些 Map 里加自己的变体——这就是插件能新增会话事件类型的机制。
Agent 预设:按会话组装的插件包
Agent 预设(preset)是按会话的插件组装:创建会话时,ctx.agentPresets 把预设自带的 cordis.yml 挂载到该 agent 的作用域下。内置预设有 standard、code、minimal、cordis(创造模式)四个,源码在官方仓库 apps/cli/config/agent-presets/ 目录。四个预设怎么选,见教程《Agent 模式》。
注意:创造模式(cordis 预设)不是"代码模式"的别名,而是高信任模式——它提供的 cordis_mount 工具能把模型生成的 JavaScript 直接作用于当前运行时,官方要求按 Shell access(命令行执行权限)级别看待它。普通用户日常用 standard 就好。
EVIDENCE
证据与来源
本页包含:官方事实 / 教程实测
| # | 事实声明 | 状态 | 来源 |
|---|---|---|---|
| 1 | 扩展方式是挂载插件,注册为可逆副作用 | 官方事实 | |
| 2 | "Plugins, not loop changes"规则 | 官方事实 | |
| 3 | 新行为归属表(llm / tools / shell / commands / jobs / 事件) | 官方事实 | |
| 4 | dsh plugin --profile <name> add <package> 安装方式 | 官方事实 | |
| 5 | 插件包 ≠ 组合包,无 dsh.bundle 声明的包保留为普通依赖 | 教程实测本站已验证内容 |
|
| 6 | 用户 patch 层 HMR:watchUserPatches 事务式重组、失败保留最后可用树 | 官方事实 | |
| 7 | Bundle 成员列表启动时确定,安装 / 更新 / 删除 Bundle 必须重启 | 教程实测CV1 要求标注,非官方表述;基线 0.1.1-rc.2 |
|
| 8 | 六个规范 Map 的声明合并机制 | 官方事实 | |
| 9 | 作用域规则:不继承给 subagent、最具体者胜出 | 官方事实 | |
| 10 | Agent 预设机制与四个内置预设(standard / code / minimal / cordis) | 官方事实 | |
| 11 | 创造模式为高信任模式,cordis_mount 按 Shell access 级看待 | 教程实测本站已验证内容 |
|