21 · 与 Pi 的设计比较:两种可组合的 Agent¶
21.1 比较对象与证据¶
这里比较 DeepSeek Harness main da00f7f5358f2949383b35c14f548bc20187d80c / npm rc.2 与 Pi 官方 earendil-works/pi 的 v1.0.0 提交 a13d35a742c6ef8462812a28fbe1d8c8b7431c32。Pi 课程在独立的 pi.baoer.me;本章重新对照其 Agent loop、SDK 工厂、Session manager、Extension contract 和 Durable runtime,避免仅用营销语或不同年代的包印象比较。
两者都让模型决定工具调用,并由宿主执行、记录、继续请求。不同点主要在“运行时怎么组成”“哪个边界作为公共扩展点”“应用怎样进入核心”。它们并非互斥:个人业务完全可以从一套的工程约束借鉴另一套。
21.2 组合单元:对象/API 分层与生命周期插件树¶
Pi 默认应用以 createAgentSession 组装 AgentSession、资源加载器、工具与状态;你也可以直接取 agent-core 写自己的 in-process 应用。Pi SDK、Pi Agent
dsh 的正式 Node/Python 应用以 named profile 启动,组合固定 launcher 的插件树,再用 patch 替换/插入。Loop 自身也是 provider/plugin,服务能在 scope 中替换,注册随着 fiber 卸载回收。dsh 架构、Cordis fiber
这不是说 Pi 没有插件生命周期。Pi 1.0 monorepo 的 Chord/Durable 层也有服务组合与生命周期;本表比较的是默认 coding-agent 使用路径,不能把某层特性推成整个仓库有或没有。
21.3 工具策略:扩展事件与能力 seam¶
| 问题 | Pi 1.0 默认路径 | dsh 当前路径 |
|---|---|---|
| 给模型增加工具 | Extension API / custom tools | 注入 tools 的 consumer plugin |
| 同一业务工具换存储 | 自己的工具/应用抽象或扩展实现 | 明确 service definition + provider,consumer不必改 |
| 拦截输入或结果 | ExtensionRunner 的相应事件契约 | tools pre/execute/post waterfall,scope策略 |
| 插件关闭后的注册 | 按 Extension/应用各自生命周期 | Cordis fiber effect归属与依赖撤销 |
| 替换 Loop | 取 agent-core或自己组装应用 | 用插件树替换默认loop provider,仍要满足Agent契约 |
Pi 的工具事件也不是无限可变:具体参数、block、结果 replacement、nested authorization 和 mutable input 的作用要按 Extension contract 看;dsh 同样有 gate 与 canonical output 的明确顺序。二者都不能用 post-result 拦截倒转已经写入的文件。Pi Extension types、dsh tools
笔记 Agent 的一个实际迁移问题:在 Pi 可以把自己查数据库的函数做工具;在 dsh 课程中拆成 definition/provider/consumer。前者代码更靠近一次应用调用,后者把 provider swap、scope与卸载变成框架日常语言。若只有两个稳定函数,额外 seam 可能增加学习成本;若同一能力要用于本机/SSH/不同产品载体,统一 seam 更有价值。这是基于结构的工程判断,不是性能基准结论。
21.4 历史与模型请求:都用投影,但记录粒度不同¶
Pi SessionManager 保存 JSONL entry tree,当前分支/history 经 context building、compaction 与 custom message 转换给模型。dsh 保存 append-only typed SessionEvent,request/header/context、系统面更新、assistant settlement 与 tool results 都有具体记录,再 deriveMessages,进行 provider-capability reconciliation。
dsh 明确区分 log-only assistant/attempt、durable assistant/message 内的compact stream与 transient agent/assistant-stream。Pi 的 Agent event、会话 entry 和 model stream 是另一组契约。不要把某个框架的 live chunk 都当作对应 JSONL durable append。Pi SessionManager、dsh Session types
两者都需要分清“历史文件里有”“当前投影里有”“本次provider真正接受了”。dsh 把“model-visible means logged”作为架构约束,并把 request-series/system surface 的能力判断放进 loop;Pi 按它自己的消息转换与 provider compatibility 处理。不要跨框架直接复用原始 message对象与日志parser。
21.5 SDK:in-process session 与 JSON-RPC 子进程宿主¶
Pi createAgentSession 返回本进程对象,宿主直接订阅事件、调用 prompt 和其他 API,适合把应用逻辑紧密嵌入同一 Node 生命周期。dsh TS/Python SDK 启动 CLI subprocess,通过 JSON-RPC 使用窄 methods;runtime tree 的定制主要在 profile/patch/plugins,而非客户端任意修改 loop 内对象。
这产生不同的故障面:Pi 应用需要自己管理同一进程的 listener、AbortController和资源;dsh 客户端需要处理 framing、initialize、child退出、EOF、shutdown和日志 flush。子进程隔开生命周期,并不会自动变成网络/文件/权限安全隔离。Python支持也不代表所有宿主API与TS一一对应。
21.6 MCP、代码执行与 nested tools¶
Pi 1.0 默认产品集成 MCP 和 Code Mode;dsh 有 MCP和PTC/workflow。两边都要逐项检查子调用授权、参数/schema、结果截断、取消与外部进程。不能说“都能运行代码,因此权限机制相同”。Pi默认coding agent、Pi codemode worker和Pi Durable工具路径不是同一执行链。Pi nested tools、Pi codemode host
dsh PTC 的 Node child、workflow internal VM、Python/C2 provider,和stdio MCP SDK spawn也各有不同的宿主。读完本课程10–12后,你应能画出自己的具体链路并指出每个gate;只说“harness会sandbox一切”在两套设计中都不成立。
21.7 Durable、Goal、schedule、Teams 不要横向偷换¶
Pi Durable 是另一个实验 runtime,使用存储先行、任务状态和恢复路径,并不等于 Pi coding CLI 的默认循环已经实现相同保证。dsh 的 Goal、subagent/Teams、jobs、schedule 和 canonical Sessionlog是不同seam,也不自动提供所有外部动作 exactly-once。
比较持久性应具体问:意图何时写?谁持锁?完成结果何时 durable?重启后怎么判定外部动作发生了?dsh webhook 202是内存接受,schedule有flush/任务commit之间的崩溃重复窗口;Pi durable外部system也需要业务幂等。Pi durable tool
21.8 怎样选择¶
如果你希望直接在一个 TypeScript 应用中拿 session对象、快速加工具并深度定制交互,Pi的默认SDK分层很自然。如果你希望模型、loop、数据服务、远程执行世界、界面都经同一插件树与scope管理,或需要TS/Python子进程宿主,dsh提供另一种统一组合方法。
仍应把模型协议支持、真实业务工具、部署约束、团队对Cordis的理解、上游preview变动和测试成本放在同一决策中。本课程未做吞吐/成本/延迟基准,不提供“哪一个一定更强”排名。实际选择可用相同笔记任务在两框架运行,并对照工具拒绝、取消、关闭、持久化、恢复与可维护性。