Agent 框架都在喊“可扩展”,但多数只是给你几个钩子接口而已!
DSH 把所有 Agent 组件都做成了插件,连驱动循环本身都可以被替换;Pi 则把核心收束到极致,其余全部交给扩展去生长。两种设计都宣称自己“可组合”,但实现思路截然相反。这篇文章不聊哪个更好,只拆开看它们到底怎么做到的。
DSH 于 2026 年 8 月 13 日以 MIT 协议开源,发布当天 GitHub 星标数就超过了一万,不到两天逼近九万五。这套框架基于 Cordis 插件元框架构建,Cordis 只负责三件事:插件的加载、卸载和依赖关系管理。它不承载任何 Agent 的具体能力——没有模型调用逻辑、没有工具注册表、没有会话管理。DSH 的全部业务组件都是独立的 Cordis 插件,包括模型适配器、工具注册表、会话日志、审批策略,甚至驱动 Agent 运转的主循环本身。
极简派与插件派,两种哲学在同一个战场上短兵相接
Pi 的设计哲学是“激进极简主义”:默认不提供 MCP、不提供计划模式、不提供子 Agent。它的核心只保留四个基础工具——read、write、edit、bash——以及一条不到 1000 Token 的系统提示词。Pi 的创始人 Mario Zechner 把这种思路概括为:你刻意不做什么,比你做什么更重要。Pi 本质上就是一个 while 循环:调用 LLM、执行工具、再调用。其余一切——计划、待办、沙箱、自定义 UI——都通过扩展系统加进来。
DSH 走的是另一条路。它把 Cordis 的源码直接 vendor 进自己的仓库,改了个 scope 叫 @deepseek-ai/cordis,然后把公司写的每一个包都设成对它的 peer dependency。这不是“使用一个第三方库”,而是整个产品都构建在 Cordis 之上。默认部署中,DSH 搭载了 159 个插件,LLM、会话、热模块重载插件跟其他所有东西摆在同一个列表里,每一个都可以单独开关。Pi 像 Vim,DSH 像 Emacs。这个比喻不严格,但抓住了核心:一个给你最小内核让你自己长,一个给你完整平台让你任意拼。
一次工具调用失败,在 Pi 和 DSH 里是完全不同的故事
Cordis 与普通插件系统的核心区别在于“可逆副作用”。多数插件系统都有 dispose() 或 unload(),问题是一个事件监听器或定时器没清掉,插件虽然停了,副作用还留在进程里。Cordis 把一次副作用写成:e : Γ → Γ × (Γ → Γ)——副作用改变上下文时,还要返回一个逆操作。如果加载时按 A→B→C 的顺序注册了工具、监听器和定时器,卸载时就按 C⁻¹→B⁻¹→A⁻¹ 的顺序清理。工程上就是一个 LIFO 清理栈。
这套机制支撑了 DSH 的“创造模式”。选择这一预设后,Agent 可以检查当前运行时的插件树,动态挂载或卸载临时插件。模型可以临时写一个事件监听器、注册一个新工具、提供一个服务,任务完成后再卸掉。这相当于让汽车在高速公路上给自己换发动机。临时插件只存在于进程内存里,不写文件、不装包、不改配置,重启即消失。自修改 Agent 的难点在于写完之后怎么把组件干净地拿下来:一次自我修改留下的事件监听器、打开的连接、注册的服务,如果没有明确的回收路径,系统运行几个小时就会变成一堆无人认领的残留。DSH 的做法是把动态插件放进已有的插件生命周期里,跑在 Cordis 的 Context 和 Effect 机制下,注册项有确定的清理路径。
Pi 的扩展走的是另一条路。它的扩展叫 Extension,基于 TypeScript,在扩展点上通过钩子塞逻辑。Pi 没有依赖注入,没有插件间依赖管理,加载顺序即优先级,也不能卸载。Pi 的架构本质上是“一个核心循环加上无数个深度的 hooks 挂载点”。Session→Agent 外循环→Agent 内循环→工具管道→Provider,每一层都是独立的状态机。扩展可以注册工具、斜杠命令、事件钩子、标志和自定义 Provider。危险操作方面,每个扩展的 hostcall 在执行前都会被能力策略检查。DSH 追求的是“改完能复原”,Pi 追求的是“插进去就能用”。前者的代价是系统复杂,后者的代价是改不了已经跑起来的东西。
长任务不卡死,靠的不是运气而是一份只追加的日志
DSH 的 WebUI 在长任务中感觉流畅,原因很具体。浏览器是 Harness 事件流上的瘦客户端,而不是执行每个工具调用的循环。DSH 把运行存为一份只追加的会话日志,从这些事件中渲染轨迹。Session 是整个交互历史的只追加数据源,LLM 消息历史从它派生,从不单独存储。每次模型请求前,系统从日志重新派生历史。恢复、分叉、检索与回放共享同一份事件流。长任务可以被检查而不会让 UI 成为执行瓶颈。
这个设计还有一个副产品:轨迹视图可以按来源查看系统提示词、思维链、工具调用与结果、子 Agent 调度,以及每一次上下文注入。模型看到的一切都会写入日志。
Pi 解决长任务问题的方式不同。Pi Harness V3 规范把 Agent 设计成可恢复的持久运行时。模型请求和工具调用之前先记录执行意图,完成后写入结果和下一步状态。进程崩溃后,系统可以判断任务停在哪一步、哪些操作可以安全重跑、哪些有副作用不能重执行。Agent 要长期运行,不能在每次崩溃后都从零开始。Pi 让执行状态可以延续。
一个只追加的日志,一个可恢复的状态机。两套方案都解决了长任务的问题,但一个偏重“事后复盘”,一个偏重“事前留痕”。
96.8% 的缓存命中率是怎么来的,以及它为什么不能复制
DeepSeek 的 prefix cache 可以在多个步骤间复用稳定的提示词前缀。有帖子提到 100% 的缓存命中率——那是某次特定运行的结果,不是普遍保证。前缀缓存的命中率取决于提示词前缀的稳定性,而提示词前缀又取决于系统提示词、工具定义、会话历史的组合方式。DSH 的事件溯源设计让每次请求的历史派生都是确定的,这为缓存复用提供了基础——但不保证每次都能命中。
Pi 与 DeepSeek 模型的配合也体现了缓存的价值。有开发者用 Pi 调用 DeepSeek V4 Flash,处理了近 10 亿输入 Token,缓存命中率达到 99.93%,最终只花了 2.65 美元。Pi 完成一次成功任务的平均成本最低,约 0.028 美元。Pi 的工作流设计天然匹配 DeepSeek V4 的前缀缓存机制。缓存命中率不是架构决定的,而是工作流与模型特性匹配的结果。
插件加得越多,系统越强还是越慢,没人说得清
VS Code 的类比在这里成立。一个裸编辑器很快,最终体验取决于上面叠加了什么:插件、语言服务器、钩子、上下文和后台工作。Agent 扩展有同样的取舍:它们可以改进任务,但也会增加提示词 Token、工具模式、事件处理和额外步骤。DSH 默认搭载 159 个插件。每个插件都在贡献能力,同时也在增加系统的认知负担和执行成本。
Pi 的扩展生态也面临同样的问题。有开发者反映,Pi Agent 有些必要工具没有,第三方开发的插件质量参差不齐,需要多个插件就要多次对比。插件堆得多了,维护成本自然上升。DSH 提供了官方配置好的标准和 PTC 模式,不用自己费劲找。但官方配置也意味着选择权被收窄——你要么接受预设,要么自己折腾。
DSH 的 benchmark 机制正在试图量化这个问题。dsh-eval 提供了在 headless dsh profile 上运行 Agent 评估的能力。社区已经有插件实现了“持续自进化”:版本化的、可审计的、可回滚的 Harness 状态,从会话轨迹中提炼,配合 benchmark 驱动的验证循环。但这个思路目前还在早期。对于每个插件,需要测量它对完成质量、首次行动时间、端到端时间、Token 数、缓存命中率、工具调用次数、上下文增长、成本以及长任务恢复能力的边际影响。这不是一个插件听起来有没有用的问题,而是它是否值得留在循环里。
159 个插件同时运行,谁来证明每一个都值回票价
Flask 作者、目前主导 Pi 开发的 Armin Ronacher 公开表示,他不认为 DSH 是完美的,但这是他第一次在这个领域看到新东西,并觉得有必要回头重新审视自己团队的一些选择。这个评价本身就说明了两套设计的分量——它们不是在争谁更好,而是在探索两个不同的方向。Pi 让 Agent 跑得久,DSH 让 Agent 改得动。一个侧重执行状态的延续,一个侧重组成结构的动态重组。
但第三块拼图还缺失着:验证。自进化 Agent 的研究已经识别出评估和安全是核心问题。Agent 可以长期运行、可以修改自己,但如果连“进步”的定义都可以一起被改掉,它很容易优化到只通过自己出的考题。验证器、追踪器和安全边界应该位于自修改循环之外。
一个真正的 RSI 闭环至少要解决三件事:跑得久、改得动、测得准!Pi 解决了第一件,DSH 解决了第二件,第三件将决定这种“进化”是真的变强了,还是只是学会了通过自己出的考试。
能修改自己只是进化的开始,证明自己真的变强了才是 RSI 最艰难的一段路。
DSH 的 benchmark 体系还在建设中。dsh-eval 的 runner 是当前唯一的消费者:接收加载的 benchmark,返回运行记录,report 模块负责持久化和渲染。社区已有插件实现了 benchmark 驱动的验证循环,但 penguin-harness 之前演示的概念(benchmark→评估→优化→接受/回滚)是零代码级执行的——每一个保证都是 prompt 层面的约定。把验证从 prompt 搬到代码里,这是 DSH 下一步要啃的硬骨头。159 个插件同时运行,谁来证明每一个都值回票价?这个问题目前还没有答案。