一切皆插件:官宣与源码对照
发布文里说的四种模式、插件生态,在 deepseek-harness 仓库里对应哪个文件?本课一条条对上。
下面的演示把四份插件清单做成了可切换的面板。点上面四个模式按钮,看插件卡片怎么亮、怎么灭:绿色是新增,红色是移除,琥珀色是同名但配置变了。底部字幕会告诉你每一步发生了什么。先玩明白,后面讲的思路都在这块面板里演过一遍。
它解决什么问题。想象你在用一个单体架构的 Agent 产品,想换掉它的会话日志格式。你得 fork 仓库,在几十万行源码里找到日志实现,改完重新构建,之后官方每发一版你都要重新合并一次补丁。这还只是日志这种边角能力,要是想换 agent loop 主循环,基本等于重写产品。能力和产品源码焊死在一起,任何深度定制都会变成长期维护负担。
思路是什么。DSH 把内核缩到最小。vendor 进仓库的 Cordis 框架只做三件事:把插件装进共享上下文、把插件卸下来、把每次注册记成可逆的副作用,插件卸载时自动回滚。业务逻辑一行都没有。然后所有能力搬进 packages/,49 个分组、219 个包,全部以插件形式存在:模型适配器是插件,工具是插件,会话日志是插件,连 agent loop 主循环本身也是插件。根 AGENTS.md 第 3 行用加粗英文写着「everything is a plugin」。官方文档的原话:
Cordis 是 dsh 底层的框架:插件向共享上下文贡献服务、类型化事件和可逆的副作用。产品的每一部分都是插件,包括模型适配器、工具注册表、会话日志,以及 agent loop(智能体循环)本身,因此每一部分都可以从配置替换。
不存在需要打补丁的特权内核:扩展 dsh 的方式是把插件挂载到其他插件旁边,而各项注册都是副作用,会在其插件卸载时撤销。
docs/architecture.zh.md · 第 11、13 行想给 DSH 加能力,也不用碰它的仓库。树外(out-of-tree,指官方仓库之外的)插件用 dsh plugin --profile <name> add <package> 装进 profile,运行时挂载,卸载时注册的副作用自动回滚。README 还约定插件仓库统一打 dsh-plugin 话题标签,方便互相发现。发布文邀请大家共建生态,机制是现成的。
为什么长期成立。微内核思想比这份代码老得多。操作系统课上的 Mach 和 L4,浏览器的扩展体系,VS Code 的插件生态,走的都是同一条路:变化快的能力放外圈,几乎不变的装卸机制放核心。DSH 明年把 agent loop 重写一遍,Cordis 的装卸逻辑一行不用动;换个语言把整个 harness 再写一遍,这个分层照样管用。所以记这门课的结构比记它的代码划算,代码只是这个思路的某一版实现。
它解决什么问题。多数产品的模式是硬编码的:代码里散着一堆类似 if (mode === 'lite') 的分支,模式数量在写代码的那一刻就定死了。想新增一个模式,要改代码、过测试、等发版;想微调某个模式里的一个能力,还是这套流程。用户更没得选,只能在官方给的几个套餐里挑。
思路是什么。DSH 里一个模式就是 apps/cli/config/agent-presets/ 下的一个目录,目录里两个文件。preset.yml 只有 3 行,管 UI 上的展示名和排序;agent.cordis.yml 是插件清单,启动时 Cordis 照着清单逐行挂载,输出一个组装好的 Agent。切换模式就是换一份清单重新组装,源码里没有任何模式分支。四种模式的差异,看四张卡就够了:
标准模式
agent-presets/standard/ · 251 行- 给谁用
- 日常写代码的人,这是默认档。
- 与其他模式的关系
- 它就是基准:23 个插件全开(macOS 视角),文件编辑、shell、检索、计划、子代理、工作流都在。其余三个模式全部描述成对它的加减。
- 背后的思路
- 先定义一个能力齐全的参照系,别的组合才有资格用一句话说清自己。
PTC 模式
agent-presets/code/ · 262 行- 给谁用
- 跑多步长任务、嫌一次一个工具调用往返太慢的人。
- 比标准多了什么少了什么
- standard 一行不动,末尾多挂一个 tool-presentation,配置
mode: code。模型改写一段 TypeScript 小程序,run_code 一次执行原本要五次往返的操作。 - 背后的思路
- 改的只是工具的呈现方式,能力本身没变,所以差异只配拥有一行。
极简模式
agent-presets/minimal/ · 62 行- 给谁用
- 跑模型基准测试的人。
- 比标准多了什么少了什么
- 只剩 6 个插件。persona 一句话写死(
complete: true,别的插件想追加提示词也加不进去),工具只有持久 bash 和 str_replace_editor,没有 compaction(上下文压缩)。 - 背后的思路
- 把 harness 的变量排干净,剩下的表现就是模型本身。
创造模式
agent-presets/cordis/ · 262 行- 给谁用
- 想让 Agent 造 Agent 的人。
- 比标准多了什么少了什么
- standard 全套之上加 tool-cordis 工具集、一个教组合写法的 skill,persona 也换了版本。Agent 能在运行时检查并挂载自己的插件,写出的组合能存成新 preset。
- 背后的思路
- 组装器自己也是插件,所以能开放给 Agent 用。文件头注释提醒把这个模式的会话当 shell 权限对待。
顺带点破一个营销词。code/preset.yml 第 1 行写 name: PTC 模式,但目录叫 code,源码注释和文档里这套机制叫 Code Mode,全仓库找不到名为 PTC 的实现。PTC 只活在 UI 文案层,跟人聊源码时说 Code Mode 才对得上号。
为什么长期成立。这条思路有个通行的名字,配置即架构:把系统之间的行为差异收敛进一份声明式清单,架构问题就降维成文本问题。想知道两个模式差在哪,diff 两份 YAML;想造新模式,复制目录改几行;出了问题,回滚清单就行。Kubernetes 用 YAML 声明集群,Docker 用 Dockerfile 声明镜像,同一个思路在不同层面反复出现。DSH 的插件实现哪天全部重写,清单这层抽象照样成立。
一切皆插件的价值放到同行里才看得清。同一个问题,想给 Agent 加一个新能力,需不需要动它的仓库源码,三家给出三种答案:
DSH:插件树
不需要改仓库能力就是一个树外 npm 包。dsh plugin --profile <name> add <package> 装进 profile,运行时挂载,卸载时注册副作用自动回滚。模式级差异也只是 YAML 里增删几行。
出处:packages/bundle/README.zh.md 第 13 行;docs/architecture.zh.md 第 13 行
Claude Code:产品单体
看情况还原源码是一棵 TypeScript 单体源码树(restored-src/src/,入口 main.tsx),改内建功能要动产品源码。对外留了 hooks、MCP、Skills 这些扩展口,能加工具和拦截点,换不掉会话日志这类深层实现。基于已公开证据(还原源码目录结构)。
Grok Build:Cargo Workspace
需要改仓库根 Cargo.toml 的 members 数组列了 79 个 workspace 成员(本地计数),能力按 crate 切分、编译期组合。新增能力要新建 crate、改根清单、重新编译。切分细节见 12-1 · 79 个 Workspace 成员如何组成产品。
三家没有绝对优劣。Grok 用编译期组合换 Rust 的类型和性能保证,Claude Code 用单体换产品迭代速度,DSH 用插件树换运行时可拔插。只是如果你想要一个可替换、可审计的运行时,DSH 是三家里唯一让第三方无需 fork 仓库就能替换深层能力的。
从清单推演行为差异
把 standard/agent.cordis.yml 里 id: compaction 的整个 group(第 137 至 155 行)删掉,得到的会话和极简模式在上下文压力下的表现是否等价?再对照 minimal/agent.cordis.yml 的 persona 三个字段(第 8 至 13 行),说出除了压缩之外还差哪两点。