创造模式与内核边界:一切皆插件的递归与自证
真实工具清单:
| 真实工具 | 作用 | 性质 |
|---|---|---|
cordis_inspect_list |
发现 provider / 运行中的 Loader entry(含 Config 状态、分页、packageDir) |
只读 |
cordis_inspect_query |
查询某 provider 的具体方法与类型 | 只读 |
| Plugin Manager 工具 | 安装 / 启停 / 删除组合包 | 写,但走 profile 持久化 |
所以"创造"的通道不是执行模型生成的 TS 代码,而是:
#mermaid-svg-RK3X6ohFq0XIydKR{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-RK3X6ohFq0XIydKR .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-RK3X6ohFq0XIydKR .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-RK3X6ohFq0XIydKR .error-icon{fill:#552222;}#mermaid-svg-RK3X6ohFq0XIydKR .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-RK3X6ohFq0XIydKR .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-RK3X6ohFq0XIydKR .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-RK3X6ohFq0XIydKR .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-RK3X6ohFq0XIydKR .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-RK3X6ohFq0XIydKR .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-RK3X6ohFq0XIydKR .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-RK3X6ohFq0XIydKR .marker{fill:#333333;stroke:#333333;}#mermaid-svg-RK3X6ohFq0XIydKR .marker.cross{stroke:#333333;}#mermaid-svg-RK3X6ohFq0XIydKR svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-RK3X6ohFq0XIydKR p{margin:0;}#mermaid-svg-RK3X6ohFq0XIydKR .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-RK3X6ohFq0XIydKR .cluster-label text{fill:#333;}#mermaid-svg-RK3X6ohFq0XIydKR .cluster-label span{color:#333;}#mermaid-svg-RK3X6ohFq0XIydKR .cluster-label span p{background-color:transparent;}#mermaid-svg-RK3X6ohFq0XIydKR .label text,#mermaid-svg-RK3X6ohFq0XIydKR span{fill:#333;color:#333;}#mermaid-svg-RK3X6ohFq0XIydKR .node rect,#mermaid-svg-RK3X6ohFq0XIydKR .node circle,#mermaid-svg-RK3X6ohFq0XIydKR .node ellipse,#mermaid-svg-RK3X6ohFq0XIydKR .node polygon,#mermaid-svg-RK3X6ohFq0XIydKR .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-RK3X6ohFq0XIydKR .rough-node .label text,#mermaid-svg-RK3X6ohFq0XIydKR .node .label text,#mermaid-svg-RK3X6ohFq0XIydKR .image-shape .label,#mermaid-svg-RK3X6ohFq0XIydKR .icon-shape .label{text-anchor:middle;}#mermaid-svg-RK3X6ohFq0XIydKR .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-RK3X6ohFq0XIydKR .rough-node .label,#mermaid-svg-RK3X6ohFq0XIydKR .node .label,#mermaid-svg-RK3X6ohFq0XIydKR .image-shape .label,#mermaid-svg-RK3X6ohFq0XIydKR .icon-shape .label{text-align:center;}#mermaid-svg-RK3X6ohFq0XIydKR .node.clickable{cursor:pointer;}#mermaid-svg-RK3X6ohFq0XIydKR .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-RK3X6ohFq0XIydKR .arrowheadPath{fill:#333333;}#mermaid-svg-RK3X6ohFq0XIydKR .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-RK3X6ohFq0XIydKR .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-RK3X6ohFq0XIydKR .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-RK3X6ohFq0XIydKR .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-RK3X6ohFq0XIydKR .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-RK3X6ohFq0XIydKR .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-RK3X6ohFq0XIydKR .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-RK3X6ohFq0XIydKR .cluster text{fill:#333;}#mermaid-svg-RK3X6ohFq0XIydKR .cluster span{color:#333;}#mermaid-svg-RK3X6ohFq0XIydKR div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-RK3X6ohFq0XIydKR .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-RK3X6ohFq0XIydKR rect.text{fill:none;stroke-width:0;}#mermaid-svg-RK3X6ohFq0XIydKR .icon-shape,#mermaid-svg-RK3X6ohFq0XIydKR .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-RK3X6ohFq0XIydKR .icon-shape p,#mermaid-svg-RK3X6ohFq0XIydKR .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-RK3X6ohFq0XIydKR .icon-shape .label rect,#mermaid-svg-RK3X6ohFq0XIydKR .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-RK3X6ohFq0XIydKR .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-RK3X6ohFq0XIydKR .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-RK3X6ohFq0XIydKR :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} ① 观察
cordis_inspect_list
cordis_inspect_query
(只读)
② 学习
skill 目录
教怎么写插件/MCP/组合
③ 修改
Plugin Manager
持久化 profile 变更
④ 生效
HMR 重载
(未开 HMR 则重启)
⭐ 这个修正很重要,因为它让"创造"这件事安全了一个数量级。
若真的执行模型生成的 TS(书的说法) 实际的配置层 patch(源码事实) 可审计性 ❌ 代码跑起来就不知道做了什么 ✅ diff 可读、日志可查 可回滚性 ❌ 副作用已发生 ✅ 改回配置即可 失败形态 运行时异常,可能崩进程 ✅ 加载时失败,有错误信息 兼容性 无从检查 ✅ peerDependencies 预检会拒绝(卷五 §1.4) 审查入口 只能审代码 ✅ --dump-config可预览最终组合
但书的直觉是对的 ------Agent 确实能修改承载自己的 Runtime composition 。
只是通道是配置,不是代码。这个区别是本卷的核心。
§1 创造模式到底「创造」什么
1.1 三个层次
| 层次 | Agent 能做什么 | 源码依据 |
|---|---|---|
| ① 观察 Runtime | 列出当前有哪些 provider、Loader entry 的 Config 状态、单个 entry 的 JSON Schema、某个 API 的方法与类型 | cordis_inspect_list / cordis_inspect_query |
| ② 改组合 | 安装 / 启停 / 删除组合包,改 profile 配置 | @deepseek-ai/dsh-plugin-manager/tools |
| ③ 学习怎么改 | skill 目录带 preset 编写规则 | skill-filesystem 的 customSkillDirs 指向 @deepseek-ai/dsh-agent-preset/skills |
1.2 "递归"发生在哪里
普通 Agent 的递归是任务层面的(Agent 调工具 → 工具做完事 → Agent 继续)。
创造模式的递归是架构层面的:
profile 配置 Host Plane Tool Registry Agent(跑在 preset=cordis 里) profile 配置 Host Plane Tool Registry Agent(跑在 preset=cordis 里) #mermaid-svg-bMAAoxHzPd7zTrYy{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-bMAAoxHzPd7zTrYy .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-bMAAoxHzPd7zTrYy .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-bMAAoxHzPd7zTrYy .error-icon{fill:#552222;}#mermaid-svg-bMAAoxHzPd7zTrYy .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-bMAAoxHzPd7zTrYy .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-bMAAoxHzPd7zTrYy .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-bMAAoxHzPd7zTrYy .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-bMAAoxHzPd7zTrYy .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-bMAAoxHzPd7zTrYy .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-bMAAoxHzPd7zTrYy .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-bMAAoxHzPd7zTrYy .marker{fill:#333333;stroke:#333333;}#mermaid-svg-bMAAoxHzPd7zTrYy .marker.cross{stroke:#333333;}#mermaid-svg-bMAAoxHzPd7zTrYy svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-bMAAoxHzPd7zTrYy p{margin:0;}#mermaid-svg-bMAAoxHzPd7zTrYy .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-bMAAoxHzPd7zTrYy text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-bMAAoxHzPd7zTrYy .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-bMAAoxHzPd7zTrYy .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-bMAAoxHzPd7zTrYy .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-bMAAoxHzPd7zTrYy .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-bMAAoxHzPd7zTrYy #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-bMAAoxHzPd7zTrYy .sequenceNumber{fill:white;}#mermaid-svg-bMAAoxHzPd7zTrYy #sequencenumber{fill:#333;}#mermaid-svg-bMAAoxHzPd7zTrYy #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-bMAAoxHzPd7zTrYy .messageText{fill:#333;stroke:none;}#mermaid-svg-bMAAoxHzPd7zTrYy .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-bMAAoxHzPd7zTrYy .labelText,#mermaid-svg-bMAAoxHzPd7zTrYy .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-bMAAoxHzPd7zTrYy .loopText,#mermaid-svg-bMAAoxHzPd7zTrYy .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-bMAAoxHzPd7zTrYy .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-bMAAoxHzPd7zTrYy .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-bMAAoxHzPd7zTrYy .noteText,#mermaid-svg-bMAAoxHzPd7zTrYy .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-bMAAoxHzPd7zTrYy .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-bMAAoxHzPd7zTrYy .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-bMAAoxHzPd7zTrYy .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-bMAAoxHzPd7zTrYy .actorPopupMenu{position:absolute;}#mermaid-svg-bMAAoxHzPd7zTrYy .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-bMAAoxHzPd7zTrYy .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-bMAAoxHzPd7zTrYy .actor-man circle,#mermaid-svg-bMAAoxHzPd7zTrYy line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-bMAAoxHzPd7zTrYy :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Agent 由此知道「这个能力现在长什么样」 cordis_inspect_list当前 Loader entry 目录 + Config 状态cordis_inspect_query(provider)方法签名与类型Plugin Manager:装一个组合包 / 改一行 config配置变更(HMR 监听)⭐ 目录变化 ------ 这个 Agent 自己看到的工具列表也变了下一轮调用时,工具目录已包含新能力
递归点在这里 :
Agent 用 T 工具改变了 T 自己。
这不是"调用自己的方法"那种平凡递归,
而是**"被调用的对象集合本身被改写了"**。
打比方 :普通 Agent 像一个用工具箱干活的工人 ;
创造模式像一个既能干活、又能申请更换工具箱里工具的工人 ------
而他申请的工具箱,正是自己正在使用的那个。
1.3 为什么这件事能成立
因为 dsh 从一开始就把能力做成了可枚举、可查询、可 patch 的形式:
| 可枚举 | cordis_inspect_list 能列出 provider |
|---|---|
| 可描述 | cordis_inspect_query 能给出方法与类型 |
| 可配置 | 每条 entry 有 id,patch 能按 id 替换整个 config |
| 可持久化 | Plugin Manager 写 profile 文件 |
| 可热替换 | HMR 监视配置,卸载 → 重载 |
反过来想 :如果能力是硬编码的(比如
switch (mode) { ... }),它既不可枚举也不可 patch,"Agent 修改自己的 Runtime"就是天方夜谭。
所以「创造模式」不是一个新功能,而是「一切皆插件」的必然推论。
§2 源码实证:cordis preset = standard + 一项
我对顶层 id 做了 diff:
standard 顶层项: 21 | cordis 顶层项: 22
--- 只在 cordis ---
tool-cordis ← 唯一多出来的顶层能力
cordis preset 与 standard 的顶层差异只有一行:tool-cordis。
但它还有两个 config 层面的差异,同样重要:
yaml
# standard:plugin-manager 被硬编码关闭
- id: tool-plugin-manager
name: '@deepseek-ai/dsh-plugin-manager/tools'
disabled: true
# cordis:plugin-manager 由运行时装配状态决定
- id: tool-plugin-manager
name: '@deepseek-ai/dsh-plugin-manager/tools'
disabled: !!js "!ctx.get('profileContext')"
⭐
disabled: !!js "!ctx.get('profileContext')"是一句很漂亮的设计:翻译过来:「只有当 profile 上下文存在时,才禁用这个工具」。
- 在正式 profile 里 (有
profileContext)→ 禁用,出厂状态不给 Agent 装插件的权力- 在无 profile 的场景(测试、嵌入式)→ 启用
同一份 preset 声明,在不同部署形态下自动收放权限 ------
这就是
!!js表达式在 patch 里的真正价值:配置能感知运行时。
再看第三个差异:
yaml
# cordis 独有:skill 目录多挂了一个来源
- id: skill-filesystem
name: '@deepseek-ai/dsh-skill-filesystem'
config:
customSkillDirs:
- !!js ...dirname(...resolve('@deepseek-ai/dsh-agent-preset/package.json')) + '/skills'
customSkillDirs指向的是dsh-agent-preset包自带的 skills 目录 ------也就是**「怎么写 preset / 插件 / MCP 配置」这套知识,本身被打包成 skill 随包发布**。
preset 头部注释说得很准:
「Same persona as
standard: tool descriptions and the skill catalog carry the operating detail,and the skills own the preset-authoring rules.」
§3 为什么创造模式属于高信任能力
3.1 三条理由
理由一:影响范围是 profile 全局的,不是会话级的。
packages/boot/plugin-manager/README.zh.md 原文最后一句:
「......以及安装或删除外部组合包。
在 YAML 中启用 HMR 时,配置变化立即生效;未启用 HMR 时,运行中的组合保留到重启。
改动影响使用该 profile 的全部会话。」
⭐ 这一句是整个风险模型的枢纽:对比卷七讲的两级结构:
操作 影响范围 在 agent.ctx上注册工具只影响这一个 agent tools.restrict过滤只影响一个 scope Plugin Manager 改 profile ⚠️ 使用该 profile 的全部会话 所以这是"跨越作用域边界"的操作 ------
它从一个会话的视角,修改了所有会话共享的 Host 组合。
这就是"高信任"的精确定义。
理由二:它跨越了"预设的能力边界"。
Agent 平时用的是 preset 授予的 32 项。
Plugin Manager 让它能超出这个集合 ------装新包、改别的插件的启用状态。
从"使用被授予的能力"变成"改变能力授予本身"。
理由三:它触及的是唯一的真源。
卷三讲过:模型可见即已记录,Session 日志是唯一真源 。
而 Plugin Manager 改的是配置树 ------配置树决定了工具注册表的内容,
进而决定了后续所有会话日志里能出现什么 。
它是"写入未来的历史"。
3.2 风险边界在哪
| 边界机制 | 作用 | 源码 |
|---|---|---|
| 出厂禁用 | 正式 profile 里 disabled: true(standard)/ 由 profileContext 决定(cordis) |
preset 的 disabled 字段 |
| 兼容性预检 | peerDependencies 与运行时版本比对,不兼容的组合包被跳过 并列入 skippedBundles |
app-boot/src/profile-compatibility.ts(卷五 §1.4) |
| 配置可预览 | --dump-config 打印最终组合;--dump-config-schema 打印 JSON Schema |
卷五 §2 |
| 可回滚 | profile patch 是文件,改回即可 | 卷二 §4 |
| 加载期失败 | required entry 失败 → 启动终止;optional 失败 → 警告继续 | 卷五 §2.2 失败矩阵 |
| 审计 | 会话日志记录这轮做了什么;配置变更本身是 diff 可读的 | 卷三 |
风险边界的本质 :
不是"阻止 Agent 改",而是"让它改的一切都落在可审计、可 diff、可回滚的载体上"。
这与卷四的
writeScopes哲学一致------做不成真锁,就明说是提示;但尽量让可观测。
§4 Cordis Kernel 负责什么
4.1 「不属于任何 Preset」的七条规则
这些是任何 preset 都用不到、但一切都依赖的东西:
| # | Kernel 职责 | 为什么不属于 Preset | 源码 |
|---|---|---|---|
| 1 | 挂载 / 卸载 插件 | preset 是被挂的东西,不能定义挂载机制 | cordis-primer.zh.md |
| 2 | 上下文树与 ctx.<key> 寻址 |
所有 preset 都要通过它访问服务 | packages/core/scope |
| 3 | inject 依赖解析(何时 activate / deactivate) |
preset 只声明依赖,不定义依赖语义 | 同上 |
| 4 | 事件分发(五种模式) | preset 只能监听和分发,不能发明分发语义 | cordis-primer.zh.md#分发模式 |
| 5 | effect 记账与逆序清理 | 清理语义必须全局统一,否则每个插件各写一遍 | 卷一 §4 |
| 6 | 配置条目身份 (id)与 patch 的按 id 替换 |
四个 preset 的行都靠它被覆盖 | 卷五 §1.2 |
| 7 | Fiber 状态机(PENDING→...→DISPOSED) | preset 永远不关心插件的生命周期状态 | 卷一 §2.4 |
4.2 边界的一句话表述
Kernel 定义"机制",Preset 定义"内容"。
Kernel 说「插件怎么挂、依赖怎么解、事件怎么发、清理怎么倒序做」;
Preset 说「我要挂 persona、fs、bash、compaction」。
#mermaid-svg-RWYSR5fZNvOXCa68{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-RWYSR5fZNvOXCa68 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-RWYSR5fZNvOXCa68 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-RWYSR5fZNvOXCa68 .error-icon{fill:#552222;}#mermaid-svg-RWYSR5fZNvOXCa68 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-RWYSR5fZNvOXCa68 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-RWYSR5fZNvOXCa68 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-RWYSR5fZNvOXCa68 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-RWYSR5fZNvOXCa68 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-RWYSR5fZNvOXCa68 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-RWYSR5fZNvOXCa68 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-RWYSR5fZNvOXCa68 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-RWYSR5fZNvOXCa68 .marker.cross{stroke:#333333;}#mermaid-svg-RWYSR5fZNvOXCa68 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-RWYSR5fZNvOXCa68 p{margin:0;}#mermaid-svg-RWYSR5fZNvOXCa68 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-RWYSR5fZNvOXCa68 .cluster-label text{fill:#333;}#mermaid-svg-RWYSR5fZNvOXCa68 .cluster-label span{color:#333;}#mermaid-svg-RWYSR5fZNvOXCa68 .cluster-label span p{background-color:transparent;}#mermaid-svg-RWYSR5fZNvOXCa68 .label text,#mermaid-svg-RWYSR5fZNvOXCa68 span{fill:#333;color:#333;}#mermaid-svg-RWYSR5fZNvOXCa68 .node rect,#mermaid-svg-RWYSR5fZNvOXCa68 .node circle,#mermaid-svg-RWYSR5fZNvOXCa68 .node ellipse,#mermaid-svg-RWYSR5fZNvOXCa68 .node polygon,#mermaid-svg-RWYSR5fZNvOXCa68 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-RWYSR5fZNvOXCa68 .rough-node .label text,#mermaid-svg-RWYSR5fZNvOXCa68 .node .label text,#mermaid-svg-RWYSR5fZNvOXCa68 .image-shape .label,#mermaid-svg-RWYSR5fZNvOXCa68 .icon-shape .label{text-anchor:middle;}#mermaid-svg-RWYSR5fZNvOXCa68 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-RWYSR5fZNvOXCa68 .rough-node .label,#mermaid-svg-RWYSR5fZNvOXCa68 .node .label,#mermaid-svg-RWYSR5fZNvOXCa68 .image-shape .label,#mermaid-svg-RWYSR5fZNvOXCa68 .icon-shape .label{text-align:center;}#mermaid-svg-RWYSR5fZNvOXCa68 .node.clickable{cursor:pointer;}#mermaid-svg-RWYSR5fZNvOXCa68 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-RWYSR5fZNvOXCa68 .arrowheadPath{fill:#333333;}#mermaid-svg-RWYSR5fZNvOXCa68 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-RWYSR5fZNvOXCa68 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-RWYSR5fZNvOXCa68 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-RWYSR5fZNvOXCa68 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-RWYSR5fZNvOXCa68 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-RWYSR5fZNvOXCa68 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-RWYSR5fZNvOXCa68 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-RWYSR5fZNvOXCa68 .cluster text{fill:#333;}#mermaid-svg-RWYSR5fZNvOXCa68 .cluster span{color:#333;}#mermaid-svg-RWYSR5fZNvOXCa68 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-RWYSR5fZNvOXCa68 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-RWYSR5fZNvOXCa68 rect.text{fill:none;stroke-width:0;}#mermaid-svg-RWYSR5fZNvOXCa68 .icon-shape,#mermaid-svg-RWYSR5fZNvOXCa68 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-RWYSR5fZNvOXCa68 .icon-shape p,#mermaid-svg-RWYSR5fZNvOXCa68 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-RWYSR5fZNvOXCa68 .icon-shape .label rect,#mermaid-svg-RWYSR5fZNvOXCa68 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-RWYSR5fZNvOXCa68 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-RWYSR5fZNvOXCa68 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-RWYSR5fZNvOXCa68 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Cordis Kernel
(7 条机制规则)
不属于任何 preset
preset standard
32 项
preset ptc
33 项
preset minimal
4 项
preset cordis
22 项
§5 「一切皆插件」不等于没有内核
5.1 最容易被误解的一点
"一切皆插件"是一条关于「能力层」的陈述,不是关于「机制层」的陈述。
用层次说清楚:
| 层 | 是否"皆插件" | 内容 |
|---|---|---|
| 能力层(Capability) | ✅ 是 | 模型适配器、工具注册表、会话日志、agent loop 本身 |
| 机制层(Mechanism) | ❌ 否,且不应是 | 挂载、依赖解析、事件分发、effect 清理、Fiber 状态机 |
5.2 官方的自证
架构文档的原话(卷一 §1 已引):
「不存在需要打补丁的特权内核 :扩展 dsh 的方式是把插件挂载到其他插件旁边,
而各项注册都是副作用,会在其插件卸载时撤销。」
注意这句话的精确对象:
- 它说的是「不存在需要打补丁的特权内核 」------反对的是"特权功能",不是"内核本身"
- 它说「各项注册都是副作用」------这是 Kernel 提供的机制,不是 Kernel 消失了
5.3 三句必须分清的话
| 陈述 | 对吗 | 澄清 |
|---|---|---|
| 「连 agent loop 都是插件」 | ✅ | agent-loop 是 @deepseek-ai/dsh-agent-loop,可被替换 |
| 「内核没有特权」 | ⚠️ 要限定 | 没有特权功能 ;但 Kernel 保留了基础语义 |
| 「一切皆插件 = 没有内核」 | ❌ 错 | Kernel 是那 7 条机制规则,它不属于任何 preset,所以也不需要是插件 |
打比方 :
「一切皆插件」像乐高积木全是一套接口 ------
房子、桥、机器人都是同一批零件拼的。
但"接口标准"本身不是一块积木,它是这套积木能拼在一起的前提。
如果连接口标准都可以被随意替换,你就拼不出任何东西了。
5.4 一个可验证的判据
如果某样东西能被一个 preset 替换,它就是"能力";不能被替换,它就是"机制"。
用这个判据检验:
- 工具集能被 preset 换 → ✅ 能力
- agent loop 能被换 → ✅ 能力
inject的语义能被换吗? → ❌ 不能,它是机制- effect 的逆序清理能被换吗? → ❌ 不能,它是机制
§6 「DSH 就是微内核操作系统」------哪里对,哪里不对
这个类比很有传播力,但它对了一半,也错了一半。分开讲。
6.1 对的地方(四条)
| 微内核 OS | dsh | 共同点 |
|---|---|---|
| 内核极小,只做基础机制 | Kernel 只有 7 条机制规则 | ✅ 同构 |
| 功能全在插件/服务里 | 模型、工具、会话、loop 全是插件 | ✅ 同构 |
| 进程间用消息传递 | 插件间用事件(emit/waterfall...) |
✅ 同构 |
| 服务注册表 | ctx.<key> 服务注册表 |
✅ 同构 |
6.2 错的地方(五条,每条都有后果)
| # | 微内核 OS | dsh | 后果 |
|---|---|---|---|
| 1 | 特权级隔离:用户态 / 内核态是硬件级边界 | 无隔离:插件全在同一进程、同一权限 | ⚠️ 插件不能被当作不可信代码(这正是 Creative 属于高信任的原因) |
| 2 | 跨进程 = 真隔离:一个插件崩了内核还活着 | 同进程 :apply 抛异常可能让 required entry 启动失败 |
⚠️ 卷五 §2.2 的失败矩阵就是证据 |
| 3 | 调用是系统调用(同步、受控、可审计) | 进程内直接方法调用 + 事件 | 性能好,但无边界 |
| 4 | 热插拔通常受限(内核模块热插拔很难) | HMR 是一等公民 | ✅ dsh 比 OS 更激进 |
| 5 | Kernel 不可被插件替换(物理上做不到) | Kernel 机制不可换,但 agent loop 可换 | 🔄 层次不同:可换的在更上层 |
6.3 我会怎么改这个类比
dsh 不是微内核操作系统,dsh 是「一个微内核式的插件内核 + 一个事件溯源的状态机」。
后半句才是它真正的独特之处:
- 微内核 解释了它的能力层
- 事件溯源 解释了它的状态层(Session 日志、投影、重放)
- 这两件事在 OS 世界里没有对应物------OS 的状态是内存中的可变结构,不是只追加日志
一句话 :
「dsh 是微内核 OS」这个类比解释了 60% 的架构;
剩下 40%------可观测性、投影、可回放------需要「事件溯源」这个第二类比。
§7 四套 Preset 横向反证:用卷七的概念重新解释
你的问题:"你在 Task 2 观察到的 4 套 Preset 差异,现在能用 Task 3/4 的概念解释了吗?"
答案是:可以,而且解释得比当时更干净。
7.1 同一能力维度的四种组合
| 能力维度 | standard | ptc | minimal | cordis |
|---|---|---|---|---|
| 角色(Persona) | 动态(可被 complete 覆盖) |
同 standard | 固定 complete: true |
同 standard |
| 提示词来源 | persona + instructions + time | 同 standard | 只有 persona,无 instructions、无 time | 同 standard + skill 承担编写规则 |
| 工具呈现 | native(默认) |
ptc(只给 run_code) |
native |
native |
| 上下文策略 | compaction + pruner | 同 standard | 只有 basic,无 pruner | 同 standard |
| Runtime 能力 | --- | --- | persistent-shell(isolate terminals) |
tool-cordis + plugin-manager 条件启用 |
7.2 用三个概念解释这些差异
差异一:同一维度可以有不同组合 → 因为 Preset 是清单不是开关
四个 preset 在"工具呈现"这一维上,standard/minimal/cordis 都是隐式 native,
只有 ptc 显式声明 tool-presentation: mode: ptc。
"没声明"和"声明了 native"是同一件事------因为缺省值由部署给。
差异二:会话级能力必须显式 → 因为 Scope 只隔离,不发明
minimal 显式关掉 agent-instructions 和 includeRuntimeContext,
不是因为 Kernel 不支持,而是因为"少给"是一种组合选择 ------
Kernel 提供机制,preset 决定给不给。
差异三:能力可被观察和修改 → 因为 Host/Agent 双平面
cordis 多出来的 tool-cordis 不是新能力,是"读 Host 的能力目录"这个能力 。
它能成立,是因为Tool Registry 本来就在 Host Plane 上 ------
Agent Plane 只是获得了读它的通道。
这三点合起来就是"一切皆插件"的完整含义 :
① 能力可组合 (清单)→ ② 组合可隔离 (Scope)→ ③ 组合本身可被观察与修改(双平面对话)
第三条是前两条的自然结果 :
如果能力都在 Host 上有条理地注册着,"列出它们"就是免费的。
§8 概念地图:以 Harness 为中心
#mermaid-svg-x2XGGcvAoXCBW2mq{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-x2XGGcvAoXCBW2mq .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-x2XGGcvAoXCBW2mq .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-x2XGGcvAoXCBW2mq .error-icon{fill:#552222;}#mermaid-svg-x2XGGcvAoXCBW2mq .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-x2XGGcvAoXCBW2mq .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-x2XGGcvAoXCBW2mq .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-x2XGGcvAoXCBW2mq .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-x2XGGcvAoXCBW2mq .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-x2XGGcvAoXCBW2mq .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-x2XGGcvAoXCBW2mq .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-x2XGGcvAoXCBW2mq .marker{fill:#333333;stroke:#333333;}#mermaid-svg-x2XGGcvAoXCBW2mq .marker.cross{stroke:#333333;}#mermaid-svg-x2XGGcvAoXCBW2mq svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-x2XGGcvAoXCBW2mq p{margin:0;}#mermaid-svg-x2XGGcvAoXCBW2mq .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-x2XGGcvAoXCBW2mq .cluster-label text{fill:#333;}#mermaid-svg-x2XGGcvAoXCBW2mq .cluster-label span{color:#333;}#mermaid-svg-x2XGGcvAoXCBW2mq .cluster-label span p{background-color:transparent;}#mermaid-svg-x2XGGcvAoXCBW2mq .label text,#mermaid-svg-x2XGGcvAoXCBW2mq span{fill:#333;color:#333;}#mermaid-svg-x2XGGcvAoXCBW2mq .node rect,#mermaid-svg-x2XGGcvAoXCBW2mq .node circle,#mermaid-svg-x2XGGcvAoXCBW2mq .node ellipse,#mermaid-svg-x2XGGcvAoXCBW2mq .node polygon,#mermaid-svg-x2XGGcvAoXCBW2mq .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-x2XGGcvAoXCBW2mq .rough-node .label text,#mermaid-svg-x2XGGcvAoXCBW2mq .node .label text,#mermaid-svg-x2XGGcvAoXCBW2mq .image-shape .label,#mermaid-svg-x2XGGcvAoXCBW2mq .icon-shape .label{text-anchor:middle;}#mermaid-svg-x2XGGcvAoXCBW2mq .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-x2XGGcvAoXCBW2mq .rough-node .label,#mermaid-svg-x2XGGcvAoXCBW2mq .node .label,#mermaid-svg-x2XGGcvAoXCBW2mq .image-shape .label,#mermaid-svg-x2XGGcvAoXCBW2mq .icon-shape .label{text-align:center;}#mermaid-svg-x2XGGcvAoXCBW2mq .node.clickable{cursor:pointer;}#mermaid-svg-x2XGGcvAoXCBW2mq .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-x2XGGcvAoXCBW2mq .arrowheadPath{fill:#333333;}#mermaid-svg-x2XGGcvAoXCBW2mq .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-x2XGGcvAoXCBW2mq .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-x2XGGcvAoXCBW2mq .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-x2XGGcvAoXCBW2mq .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-x2XGGcvAoXCBW2mq .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-x2XGGcvAoXCBW2mq .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-x2XGGcvAoXCBW2mq .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-x2XGGcvAoXCBW2mq .cluster text{fill:#333;}#mermaid-svg-x2XGGcvAoXCBW2mq .cluster span{color:#333;}#mermaid-svg-x2XGGcvAoXCBW2mq div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-x2XGGcvAoXCBW2mq .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-x2XGGcvAoXCBW2mq rect.text{fill:none;stroke-width:0;}#mermaid-svg-x2XGGcvAoXCBW2mq .icon-shape,#mermaid-svg-x2XGGcvAoXCBW2mq .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-x2XGGcvAoXCBW2mq .icon-shape p,#mermaid-svg-x2XGGcvAoXCBW2mq .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-x2XGGcvAoXCBW2mq .icon-shape .label rect,#mermaid-svg-x2XGGcvAoXCBW2mq .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-x2XGGcvAoXCBW2mq .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-x2XGGcvAoXCBW2mq .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-x2XGGcvAoXCBW2mq :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} ⚙️ Composition(组装层)
📜 状态与可观测
🧩 Agent Plane(按 Scope 隔离)
🏠 Host Plane(进程共享 · 单例)
折叠
贡献挂进
读
读
全局生效
提供 7 条机制
提供实例(只读)
写入事实
喂给模型
决定挂什么
限定可见
改变呈现形态
改变组合
🔧 Cordis Kernel(机制层 · 不属于任何 Preset)
挂载/卸载
inject 依赖解析
事件分发 5 模式
effect 逆序清理
Fiber 状态机
条目 id 与 patch 替换
🎯 HARNESS
Agent = Model + Harness
Tool Registry
所有工具在此注册
Model Route
provider · cache
Session Store
Persistence
JSONL · generation
Execution World
fs · shell · subprocess
Safety
sandbox · approval
Scope Key
= 活跃 Agent 对象
Preset
能力贡献清单
Tool Presentation
native | ptc
compaction 实例
isolate
planMode 实例
isolate
cordis_inspect
读 Host 目录
Trace / SessionEvent
仅追加日志
Projection
deriveMessages
Profile
Bundle
cordis.patch.yml
影响该 profile 的
全部会话
8.1 图的读法(三句话)
- 实线 = 数据/实例流向 ;虚线 = 观察或反向影响
- Kernel 只向下提供机制,从不被 Preset 反向定义
- 唯一的反向箭头是
cordis_inspect读 Host,和 Plugin Manager 改 Composition ------这就是"创造"
8.2 依赖/从属关系速查表
| 概念 | 依赖谁 | 被谁依赖 |
|---|---|---|
| Cordis Kernel | 无(最底层) | 一切 |
| Composition(profile/bundle/patch) | Kernel 的条目机制 | Preset |
| Preset | Composition(被挂载)+ Kernel(被解析) | Agent 的能力集合 |
| Scope Key | Agent 对象自身 | 所有 scoped 注册 |
| Host Plane | Kernel | Agent Plane、cordis_inspect |
| Tool Registry | Host | Agent 的工具可见子集 |
| Model Route | Host | 请求构造、缓存命中 |
| Tool Presentation | Preset 声明 | 决定模型看到什么 schema |
| Session / Trace | Persistence | Projection |
| Projection | Trace | 模型历史、UI、fork |
§10 为第 4 章(亲手写 Skill / Tool / Hook)做的准备
10.1 三种扩展物的落点对照
| 你要写的东西 | 它挂在哪里 | 作用域 | 撤销方式 |
|---|---|---|---|
| Tool(模型可调) | ctx.tools.register(defineTool(...)) |
Agent (在 agent.ctx 上) |
effect 自动 |
| Skill(知识/流程) | 一个 SKILL.md 或 <name>.md,放进 skill 根目录 |
Agent(JIT 加载) | 移除文件 + watcher 失效 |
| Hook(拦截/策略) | ctx.on(event, listener) 或 ctx.waterfall(...) |
全局或 Agent(scope-filtered) | effect 自动 |
| Service(能力本体) | super(ctx, 'name') + declare module |
Host(若要共享) | 卸载 provider |
10.2 写之前必须先想清楚的两个问题
问题一:这是"能力"还是"策略"?
- 能力 → 放 Preset 的
config.plugins- 策略 → 放 Hook(
ctx.waterfall)问题二:作用域是什么?
- 只要这一个 agent → 在
agent.ctx上注册(默认)- 所有 agent 都要 → 在 Host 上注册(默认不做,先问"真的需要全局吗")
10.3 第 4 章的建议路径
#mermaid-svg-qIA3usjQobZuOdLV{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-qIA3usjQobZuOdLV .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-qIA3usjQobZuOdLV .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-qIA3usjQobZuOdLV .error-icon{fill:#552222;}#mermaid-svg-qIA3usjQobZuOdLV .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-qIA3usjQobZuOdLV .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-qIA3usjQobZuOdLV .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-qIA3usjQobZuOdLV .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-qIA3usjQobZuOdLV .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-qIA3usjQobZuOdLV .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-qIA3usjQobZuOdLV .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-qIA3usjQobZuOdLV .marker{fill:#333333;stroke:#333333;}#mermaid-svg-qIA3usjQobZuOdLV .marker.cross{stroke:#333333;}#mermaid-svg-qIA3usjQobZuOdLV svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-qIA3usjQobZuOdLV p{margin:0;}#mermaid-svg-qIA3usjQobZuOdLV .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-qIA3usjQobZuOdLV .cluster-label text{fill:#333;}#mermaid-svg-qIA3usjQobZuOdLV .cluster-label span{color:#333;}#mermaid-svg-qIA3usjQobZuOdLV .cluster-label span p{background-color:transparent;}#mermaid-svg-qIA3usjQobZuOdLV .label text,#mermaid-svg-qIA3usjQobZuOdLV span{fill:#333;color:#333;}#mermaid-svg-qIA3usjQobZuOdLV .node rect,#mermaid-svg-qIA3usjQobZuOdLV .node circle,#mermaid-svg-qIA3usjQobZuOdLV .node ellipse,#mermaid-svg-qIA3usjQobZuOdLV .node polygon,#mermaid-svg-qIA3usjQobZuOdLV .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-qIA3usjQobZuOdLV .rough-node .label text,#mermaid-svg-qIA3usjQobZuOdLV .node .label text,#mermaid-svg-qIA3usjQobZuOdLV .image-shape .label,#mermaid-svg-qIA3usjQobZuOdLV .icon-shape .label{text-anchor:middle;}#mermaid-svg-qIA3usjQobZuOdLV .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-qIA3usjQobZuOdLV .rough-node .label,#mermaid-svg-qIA3usjQobZuOdLV .node .label,#mermaid-svg-qIA3usjQobZuOdLV .image-shape .label,#mermaid-svg-qIA3usjQobZuOdLV .icon-shape .label{text-align:center;}#mermaid-svg-qIA3usjQobZuOdLV .node.clickable{cursor:pointer;}#mermaid-svg-qIA3usjQobZuOdLV .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-qIA3usjQobZuOdLV .arrowheadPath{fill:#333333;}#mermaid-svg-qIA3usjQobZuOdLV .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-qIA3usjQobZuOdLV .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-qIA3usjQobZuOdLV .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-qIA3usjQobZuOdLV .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-qIA3usjQobZuOdLV .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-qIA3usjQobZuOdLV .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-qIA3usjQobZuOdLV .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-qIA3usjQobZuOdLV .cluster text{fill:#333;}#mermaid-svg-qIA3usjQobZuOdLV .cluster span{color:#333;}#mermaid-svg-qIA3usjQobZuOdLV div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-qIA3usjQobZuOdLV .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-qIA3usjQobZuOdLV rect.text{fill:none;stroke-width:0;}#mermaid-svg-qIA3usjQobZuOdLV .icon-shape,#mermaid-svg-qIA3usjQobZuOdLV .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-qIA3usjQobZuOdLV .icon-shape p,#mermaid-svg-qIA3usjQobZuOdLV .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-qIA3usjQobZuOdLV .icon-shape .label rect,#mermaid-svg-qIA3usjQobZuOdLV .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-qIA3usjQobZuOdLV .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-qIA3usjQobZuOdLV .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-qIA3usjQobZuOdLV :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Step 1
写一个 Skill
(最轻,无代码风险)
Step 2
写一个 Tool
(注册到 agent.ctx)
Step 3
写一个 Hook
(wrap 一个事件)
Step 4
改一个 Preset
(把你的东西加进去)
Step 5
用 cordis_inspect
验证它真的挂上了
为什么这个顺序:
| Step | 风险 | 反馈速度 | 能学到什么 |
|---|---|---|---|
| 1 Skill | 最低(只是 Markdown) | 秒级 | skill 的发现优先级 + JIT 加载 |
| 2 Tool | 低(无副作用时) | 秒级 | defineTool 的 schema/output/render |
| 3 Hook | 中(影响全局行为) | 秒级 | waterfall 的包裹与否决语义 |
| 4 Preset | 中(影响组合) | 分钟级(HMR) | 组合与作用域 |
| 5 验证 | --- | --- | 用 cordis_inspect_list 确认挂上了 |
Step 5 是最容易被跳过、但最有价值的一步 :
你会亲眼看到自己的条目出现在运行中的 Loader 目录里。
"我的代码真的进了 Runtime"这个确认,对理解本章至关重要。
§12 参考(全部为源码锚点)
创造模式(本章核心证据)
packages/extensions/tool-cordis/README.zh.md(只读检查工具的官方声明)packages/bundle/web-app/presets/cordis.patch.yml(22 项,tool-cordis+ 条件 plugin-manager + agent-preset skills 目录)packages/boot/plugin-manager/README.zh.md(「改动影响使用该 profile 的全部会话」)packages/extensions/{cordis-host-runner,cordis-client-runner,ui-cordis}/
Kernel 职责
docs/cordis-primer.zh.md------ 五概念 + 分发模式packages/core/scope/src/{index,store}.tsvendor/cordis/------ 内核源码
Preset 与组合
packages/bundle/web-app/presets/{standard,ptc,minimal,cordis}.patch.ymlpackages/preset/agent-preset/·packages/preset/agent-preset-registry/packages/core/agent-tool-presentation/README.zh.md
失败与兼容(风险边界)
packages/boot/app-boot/README.zh.md§2.2 失败矩阵 · §1.4 兼容性预检packages/boot/app-boot/src/{profile-compatibility,profile-sanitize}.ts