这是最后一章。前面 12 章拆了 cordis、profile、seam、agent loop、模型、工具、会话、上下文、沙箱、委派、界面。现在退后一步:dsh 这整套"全插件化"设计,到底给我们留下了什么可迁移的判断?哪些该抄,哪些不该抄?
写这一章时有个背景值得记住:dsh 于 2026-08-13 开源 v0.1(MIT 许可证),官方口号"一切皆插件",社区一夜之间涨到数万 star。这套架构正在被成千上万人审视 —— 它的成与败,都会成为 agent 工程界的重要案例。
以下十条不依赖 dsh 的具体实现,任何做 agent 运行时(或类似的长期运行系统)的人都值得抄作业。
作为能力 seam 拆分中的 Service Definition 角色,它只依赖 cordis(及 harness 错误基类),绝不依赖后端。 —— dsh-sandbox/README.zh.md
迁移价值:接口层只依赖 IoC 容器(或不依赖任何东西),实现层随便换。这是 dsh 一切可替换性的基础。你的项目哪怕只拆两个 seam,也能享受"换后端不改调用方"。
服务会在拥有它的 fiber 卸载时自动注销。 —— cordis/src/service.ts
迁移价值:长运行系统的最大隐患是"卸载不干净" —— 监听器残留、定时器泄漏、临时状态污染。cordis 用 fiber 把"注册 → 自动清理"绑定死。如果你不想引入 cordis,至少要在自己的框架里立同样的规矩:所有注册必须返回 disposer。
inject 告诉 Cordis 哪些服务必须在插件运行前存在。 —— cordis/README.md
迁移价值:插件系统的经典坑是"加载顺序靠配置文件里谁写在前面"。dsh 全部用 inject 声明依赖,顺序由容器保证。你的配置里如果还有"把 A 放 B 前面"的注释,这就是要重构的信号。
第 7 章的 agent/pre-step waterfall、第 4 章的 fs/write-intent、第 10 章的 approval —— dsh 的事件不只是"发生了告诉你",而是"发生了你决定要不要发生"。
迁移价值:决策点应该做成可拦截的事件,而不是写死在调用链里。这样"加一个策略"永远比"改一段逻辑"安全。识别方法:如果你发现代码里越来越多的 if (policyX) 嵌套,就该把它抽成事件门禁。
第 8 章:会话日志 append-only,消息历史是派生物;投影、压缩、恢复都从日志重建。
迁移价值:任何需要审计、恢复、重放的系统,都应该事件溯源。dsh 证明了它不只在金融系统里有价值 —— agent 的每一步(token 流、工具调用、审批)都能从日志精确重放,这是调试和信任的基础。
第 9 章:compaction / pruner 都只是往日志追加 replace 节点,原始事件永在。
迁移价值:压缩不丢数据 = 回放确定 + 可审计 + 可反悔。很多人做上下文管理直接"截断删掉",代价是历史不可恢复。追加式遮蔽是更好的答案。
第 10 章:沙箱后端探测失败抛 SANDBOX_UNAVAILABLE,审批无应答视为拒绝,遥测默认 DISABLED。
迁移价值:默认不开放,开放要显式。dsh 的每个安全相关默认都是保守的:权限默认 workspace-write、遥测默认关、危险的 tool-cordis 默认不装。这条判断最简单,也最常被违反。
第 7 章:超时、溢出、重复提醒都是 tools/* 事件的监听器,工具本体只是执行器。
迁移价值:给系统加"跨所有操作"的能力(超时、重试、审计、指标)时,不要改每个操作,而是包一层流水线。dsh 的工具流水线是个极好的模板。
第 6 章:每篇 README 都有「模型看到什么 / Token 影响 / KV Cache 影响」。
迁移价值:上下文预算应该像内存预算一样被每个模块负责。dsh 用文档规范把它变成公共责任。你的团队如果多人给 prompt 加料,这个纪律能防止"prompt 悄悄膨胀"。
第 12 章:plan mode 是软引导(模型自觉),沙箱/审批是硬强制(系统执行),两者互不读写。
迁移价值:别让"建议"承担"强制"的职责。计划模式做成了安全边界、提示词做成了权限控制 —— 这是 agent 系统最常见的失败模式。告诉模型"应该怎么做"是一层,系统强制"必须怎么做"是另一层,两层必须分开。

配图说明:同一道题的两种答案。左侧 Pi(减法哲学:4 个核心包、刻意不做子 Agent/权限弹窗/计划模式、核心几百行可读完、门槛低)问"去掉一切能去掉的,剩下的最少核心是什么";右侧 dsh(全插件化:185 个包、四种委派、沙箱+审批+预设、9927 字符系统提示词、先懂 cordis 才能改)问"拆开一切能拆开的,每个决策点能不能独立演进"。两个答案在各自坐标系里都成立。
| 维度 | Pi(减法) | dsh(全插件化) |
|---|---|---|
| 核心主张 | 不需要的就不构建 | 每个决策点都留可替换位置 |
| 包数量 | 4 个核心 | 185 个 dsh 包 + cordis 底座 |
| 循环实现 | agent-core 约几百行 | 唯一循环包 1295 行 |
| 工具 | 4 核心 + 3 辅助,固定 | 27 个(配置决定,可增可减) |
| 子 Agent | 刻意不做(复杂度) | 四种机制(spawn/fork/workflow/ralph) |
| 权限弹窗 | 刻意不做(弹窗疲劳) | approval seam + 权限预设 |
| 计划模式 | 刻意不做(写 plan.md) | plan-mode 软引导 |
| 上下文压缩 | 内置(pi-agent-core) | 三件套 + 事件溯源遮蔽 |
| 扩展方式 | TS 文件 + 热重载 | cordis 插件 + 四层配置 patch |
| 可观测性 | 事件订阅 | 事件溯源日志 + 逐 token 记录 |
| 入门门槛 | 低(核心可读完) | 高(要先懂 cordis 和 patch) |
| 适合的读者 | 想知道"最少需要什么" | 想知道"最多能拆成什么" |
两句话总结两个项目:
两个问题都成立,答案不同,因为它们的目标不同:Pi 要的是"一个能读完的极简工具",dsh 要的是"一个能长期演进的平台"。
第 4 章列过部分代价,这里汇总成一张完整的账:
| 代价 | 表现 | 严重度 |
|---|---|---|
| 理解门槛 | 不懂 cordis 就无法改任何行为 | 高 |
| 调用链长 | ctx.fs.read() 经四层 + 事件 | 中 |
| 类型跳转 | 接口在定义包,实现在 provider 包 | 中 |
| 配置两套账 | host 平面 / agent 平面,查能力要看两处 | 中 |
| 小包爆炸 | 185 个包,新读者先被吓住 | 低(文档兜底) |
| 抽象冗余 | 部分 seam 只有单实现 | 低 |
| 配置语义坑 | patch 是整体替换不是合并 | 低(有规范) |
| 版本不稳 | rc 版本明示破坏性变更 | 高(产品角度) |
最重要的代价是理解门槛。dsh 的一切优点都建立在你先花时间理解 cordis 之上。对个人开发者,这个门槛可能劝退;对团队或平台型产品,这笔学费值得。
一句话判据:你的系统未来会不会在多个平台/多个后端上长期演化?会,dsh 的作业值得抄;不会,抄十条判断里的某几条就够了,别抄全套。
如果只带走三样:
回到第 1 章的开场:185 vs 4,不是一个数字压另一个数字。
DeepSeek Harness 用 185 个包回答了一个 Pi 用 4 个包回答的问题,而且两个答案在各自的坐标系里都是合理的。真正值得带走的,不是"哪个项目更好",而是:
agent 运行时需要的不是某个具体设计,而是对每个决策点的清醒选择 —— 做不做子 agent、要不要审批、日志存什么、压缩怎么裁、默认开还是关。Pi 和 dsh 各自的取舍,是你做选择时最好的两份参考。
本教程的 13 章到这里结束。所有引文、数据、实测路径都列在每章的「动手复核」里 —— 你可以打开自己的 ~/.dsh,把每一章的关键结论重跑一遍。
拆别人的架构,最好的收获不是答案,是问题清单。