BoHuYeShan

Back

〇、先纠正一个流传很广的数字#

最近中文技术圈转得很凶的一篇文章说,Pi 默认只给模型四个工具:read、write、edit、bash。

不对。Pi 自己的扩展文档在讲”覆盖内置工具”时列得很清楚:内置工具是 read、bash、powershell、edit、write、grep、find、ls,一共八个。四个工具是那张架构图的简化,不是产品事实。

这个错误不大,但它暴露了那类文章的写法问题:先把两条路线写成哲学对立,再拿细节去凑。Pi 与 DSH 的差异确实存在,但没有”设计时控制 vs 运行时控制”这么戏剧化——两者都是运行时插件系统。把三个真相摆出来,差异只剩三条。

一、Pi:默认面最小,扩展靠约定#

Pi 对自己的定位是一句话:“A minimal, extensible agent harness that you can make your own.” 它刻意不做三件事:subagent、plan mode、内置待办——文档的原话是 “ships with powerful defaults but skips features like sub-agents and plan mode”。

它的扩展是 TypeScript 模块,在 Pi 进程内加载,工厂函数里注册工具、命令、快捷键、provider、事件处理器、渲染器。生命周期是协作式的:会话切换、分叉、重载时,Pi 给旧扩展实例发 session_shutdown,让扩展自己清理状态,然后重新加载、重新绑定、再发 session_start。

注意这一步的性质:Pi 提供的是回调,不是保证。扩展在 session_shutdown 里把定时器、监听器、临时文件清掉,是扩展作者的义务;runtime 手里没有一张”每个副作用对应哪个逆操作”的账本。没清干净,它就留在进程里——这在小规模、单作者、自己装自己用的场景下几乎不出事,因为每一次安装都是人做的显式决定。

代价也在这里:能力边界稳定、开发者深度参与时,这条路最清爽;一旦多人协作、多种 agent 共存,清理责任会被摊薄到每个集成者身上。

二、DSH:一切皆插件,且副作用可撤销#

DeepSeek Harness 的路线是把”插件”推到极致:模型适配器、工具注册表、文件系统、会话存储、子智能体提供者、系统提示词、连 Agent Loop 本身,都是插件。它建在 Cordis 上,而 Cordis 背后有篇 92 页的论文(arXiv 2608.25512),标题就叫《A Programming Paradigm for Spatiotemporal Composability》。

那篇论文把两个维度讲清楚了,这是理解 DSH 的关键:

  • 时间可组合性:一个组件被移除时,它的副作用能被完全撤销。形式化方式是”可逆效果”——每一次 context 变换都携带一个逆,由 runtime 持有。
  • 空间可组合性:组件之间的依赖能被声明式表达,并且反应式地管理。

这跟 Pi 的差别不是”控制权在谁手里”,而是有没有一张逆操作的账本。Pi 说”请你自己清理”,DSH 说”运行时替你记住怎么退回去”。前者是纪律,后者是结构。

DSH 里最有争议也最有意思的是 dsh-tool-cordis:Agent 可以检查当前运行环境,在沙箱里定义工具或服务,然后临时挂载到当前进程。官方文档自己把边界写死了——只在进程内有效,重启即消失,不写进项目配置。所以这叫”运行时自我改装”,不叫”自进化”:发现缺口、生成能力这一步做到了,版本管理、持久化、回归测试、权限审计、能力淘汰一步都没做。

工具面也顺带纠正一下那张对比图:Pi 是八个内置工具,DSH 的工具目录里我数到二十五个 dsh-tool-* 包(bash、fs、fs-search、lsp、web、subagent、todo、skill、jobs、schedule、cordis、goal、ralph、workflow……)。所谓”DSH 默认工具比 Pi 多一点”,实际是多一个数量级。

三、OMP 与 Zeta:预置全量,再按需打开#

我们自己的 Zeta 是从 OMP(oh-my-pi)分出来的,而 OMP 是 Pi 的 fork。这个谱系决定了它的气质:能力先给你,用不用自己关。

OMP 的自述是 “The most capable agent surface that ships. complete out of the box, open all the way down.”,数字是六十多个 provider、三十一个内置工具、十四种 LSP 操作、二十八种 DAP 操作、核心约八万行 Rust。

它和 Pi 最实质的机制差异是工具的装载模式。在 Zeta 的代码里,每个工具都声明自己的 loadMode:

  • essential:schema 每轮都发(bash、canvas 这类)
  • discoverable:schema 默认不发,Agent 觉得缺能力时再去装载(ask、ast-edit、ast-grep、checkpoint……)

这正好接上用户常说的那句”模型可以自己决定开哪个工具”:不是模型凭空长出能力,而是能力早就在包里,schema 按需装。上下文成本从”全量定义”降到”按需展开”,这也是 OMP 敢预置三十一个工具的技术前提。

到目前为止,Zeta 相对上游 oh-my-pi 领先 2242 个提交(截至 2026-11-01,git rev-list --count omp-upstream/main..main 实测)。

四、差异只剩三条#

把三家的宣传语剥掉,结构上能站住的差异就三条:

维度PiDSHOMP / Zeta
可撤销性协作式回调(session_shutdown),无逆账本可逆效果,runtime 持逆继承 Pi 的回调语义
默认工具面8 个内置目录 25 个工具包31 个内置,discoverable 按需装
发行方式自己装扩展/包官方组合包预置全量,使用者关开关

同一种结构,三组默认值:Pi / DSH / OMP·Zeta

三列不是三种哲学,是同一套插件底座上的三组默认值;差异压缩到可撤销性、默认工具面、发行方式三行。

其余所谓”极简 vs 模块化”,都是这三条的推论:极简是默认面小,模块化是可撤销性有保证,而不是两种世界观。

五、Zeta 的三个模块,实地评价#

这套骨架之上,我们加了三个模块。三个都在 packages/coding-agent/src/ 里,可以逐行看。

Taste(taste/,13 个文件,1944 行)。 不是记忆后端,是一层判决。核心是一个 Beta 后验:

α=1+∑w+,β=1+∑w−,p=α+wj pjudgeα+β+wj\alpha=1+\sum w^{+},\qquad \beta=1+\sum w^{-},\qquad p=\frac{\alpha+w_j\,p_{\text{judge}}}{\alpha+\beta+w_j}

证据按类型加权(明确说过 1.0、被采纳 0.8、未回滚 0.8、工具结果 0.5、推断 0.3、矛盾与回滚 −1.0),判决模型只以伪计数进入。三级判决:T0 不调模型、T1 聊天模型只做分类(它自报的置信度被丢弃)、T2 决策模型给校准概率。衰减用 Weibull,按”上次被使用”计时——一个一直生效的偏好不会过期。注入排序里还有两个常数:BETA_NS = 0.5 是相对显式规则的背离惩罚,GAMMA_NS = 0.2 是类别覆盖奖励。

和 Command Code 那套比,数学是同一个族,实现取向不同:它整套闭源、taste-1 不可替换;我们把判决接到可配置的 judge 角色上,并且与它的 taste.md 格式互通——同一个文件,两边都能读写,机器态(类别、极性、证据计数、墓碑)放在旁边的 state.json。

Memory(memory-backend/)。 五种后端:off、local、hindsight、mnemopi、sharpshooter。local 由持久会话生成摘要与 lessons,注入为 Memory Guidance;learn 工具写 lessons,去重、脱敏、上限一百条、下一会话生效。这套基本是上游 OMP 的血统,优点是管线完整,短板也清楚:冲突解决靠提示词(“以仓库状态为准”),不是结构保证。

Tracking(tools/tracking.ts)。 写在 <project>/.zeta/tracking/:INDEX.md、status.json、按天分片的 actions.<day>.jsonl、压缩摘要、计划镜像。设计上有两个值得抄的细节:status.json 的读改写走文件租约加原子替换,两个会话同时写不会吞掉对方;动作日志按 5MB 轮转、保留三份,读者只做有界尾部读取。它和 memory 的边界写得很明确——tracking 存项目工作状态,memory 存跨项目学到的事实,不许混。这份契约同时服务三种读者:回来接手的人、被压缩过的 agent、以及看面板的协作者。

六、插件集大成者躲不开的那件事#

三家都是”插件集大成者”,所以三家共享同一个头号风险:软件包投毒。

这不是模型能力问题,是分发问题。npm 上任何一条间接依赖都能带 postinstall 脚本;包名打错一个字母就是 typosquatting;不锁版本时,今天装的和明天装的可能不是同一份代码。而插件拿到的权限是什么?Pi 的文档写得很直白:工具和扩展以 Pi 进程的权限运行,项目信任只决定加载哪些资源,不提供沙箱。也就是说,一个恶意扩展等价于一个能改你全盘的 shell。

DSH 的运行时挂载把这个面再推了一层:临时工具不经审计、不落盘、进程重启即消失——安全性靠”没有持久化”,但可追溯性也一起没了。出问题时你连”当时装了什么”都查不到。

要补的四件事,三家都还没补齐:能力清单(manifest 声明需要什么权限)、签名与锁版本、默认拒绝的沙箱、以及装载前可回滚的快照。没有这四样,插件数量涨得越快,出事只是概率问题。

七、结论:能力可以生长,控制权不能蒸发#

Pi 说:复杂度先证明自己有必要存在。DSH 说:复杂度拆成可撤销的结构。OMP 说:全给你,你自己关。

三种说法都对,因为它们回答的是不同问题——Pi 回答”默认装什么”,DSH 回答”装错了怎么退”,OMP 回答”怎么让一次安装覆盖最多场景”。真正该警惕的不是哪一种路线,而是把”能自扩展”当成”能自治理”:Agent 每多造一个工具,就多一份没人审计的代码,多一条没人回滚的路径。

插件系统的成熟度,从来不体现在能装多少,而体现在拆得干净、查得到账、退得回去。

同一种结构,三组默认值:Pi、DSH 与 Zeta 差在哪
https://bohuyeshan.top/2026/11/03/2026-11-03-02-harness-three-defaults/
作者 BoHuYeShan
发布于 2026年11月3日