准备开始追踪。

权衡 · zh-CN

崩掉也不丢活:pi-durable 是什么、为什么做、我们怎么选

跟着一次任务在三种架构(pi 正式版 / dsh / pi durable)里的旅程,看清“写日记”和“记账本”的差别,以及我们为什么选 durable 做底座。

事实阶梯

先说人话,再把事实讲到底。

正式版像“边跑边写日记”:活干完才记一笔,进程死了,正在写的这页就没了。dsh 像“日记写得全、还允许多人来看”,但正在写的这页照样会丢。durable 像“账本就是执行计划”:每做一步先记账,账本写到哪,活就干到哪——换个记账员(进程)也能接着干。

故事语法

决策框架

共同目标: 用户提交一句话,模型思考、调用工具、给出答复——这条旅程不该半路蒸发。

pi 正式版(内存循环)

循环活在进程内存里,消息完成后才写日志。简单成熟,但进程一死,正在跑的这轮蒸发。

  • 崩溃时进行中的工作弱匹配

    整轮蒸发,只保住已完成消息

  • 长任务/多端的天花板弱匹配

    循环与单进程、单界面绑死

  • 实现与维护成本强匹配

    简单成熟,无额外存储成本

dsh(服务宿主)

agent 跑在长驻宿主服务里,命令与事件落会话日志、多端可附着;但进行中的一轮仍驻内存。

  • 崩溃时进行中的工作部分匹配

    历史与队列保住,进行中一轮丢

  • 长任务/多端的天花板部分匹配

    多端附着现成,执行本身不持久

  • 实现与维护成本部分匹配

    插件生态强,但宿主复杂度高

pi durable(账本执行)

执行拆成持久化任务:每步先原子提交再展示。进程死了,换个进程从断点接着跑。

  • 崩溃时进行中的工作强匹配

    断点续跑,中断工具可恢复

  • 长任务/多端的天花板强匹配

    存储即真相,天然支持续命/多端

  • 实现与维护成本部分匹配

    API Experimental,热路径有存储成本

决策规则: 短任务、单进程寿命内完成的活,选 A(成熟、简单);需要多端附着与长驻服务,选 B;turn 越长、越怕丢、越要跨进程续命(崩溃/升级/子 agent),选 C。我们的组合:C 做执行底座 + A 的界面原样复用,自研收缩到最小宿主接口层。

追踪模式

跟着一个对象走完整条链路

准备开始追踪。

01

共同目标:一次任务要完整走完

用户提交一句话,模型思考、调用工具、给出答复——这条旅程不该半路蒸发。

ev-r1

参与者

用户输入

提交一个任务:修 bug、写功能、跑测试

ev-r1
提交→ 模型生成

处理

模型生成

读上下文,产出回答或工具调用请求

ev-r1
调用工具→ 工具执行
作答→ 答复落定

处理

工具执行

bash、读写文件、搜索——一轮里可能反复多次,是耗时大头

ev-r2
带回结果→ 模型生成

事件

答复落定

一轮结束:答案、提交的代码、测试结果

ev-r1
场景内证据

这一节的结论依据

默认显示本节依据;播放时会聚焦当前步骤对应的来源。

已验证调研:durable API 全景与能力映射

核心依据24 项 stable 运行时能力逐项映射,6 项缺口清单,全带 file:line。

支持结论用户输入模型生成答复落定

打开原文github.com 查看完整证据记录
已验证调研:stable 功能清单(parity checklist)

核心依据231 行逐项清单:24+3 命令、~90 键位、~71 设置、8 工具、4 运行模式。

支持结论工具执行

打开原文github.com 查看完整证据记录
02

选项 A · pi 正式版:边跑边写日记

循环活在进程内存里,消息完成后才写日志。简单成熟,但进程一死,正在跑的这轮蒸发。

ev-agentloop

处理

内存里的执行循环

流式调模型 → 并行跑工具 → 追加消息 → 再调模型,全是进程内命令式代码

ev-agentloop
边跑边改→ 内存真相

存储

内存真相

会话对象持有全部消息,界面直接读它

ev-agentloop
跑完一条记一条→ JSONL 日记

存储

JSONL 日记

每条消息完成后追加一行,事后落盘

ev-agentloop

处理

界面与循环同体

TUI 驱动循环、订阅事件;换界面等于换整个应用

ev-r2
驱动→ 内存里的执行循环
场景内证据

这一节的结论依据

默认显示本节依据;播放时会聚焦当前步骤对应的来源。

已验证pi 正式版 agent-loop 源码

核心依据runAgentLoop:流式→工具→追加的进程内命令式循环,内存是真相。

支持结论内存里的执行循环内存真相JSONL 日记

打开原文github.com 查看完整证据记录
已验证调研:stable 功能清单(parity checklist)

核心依据231 行逐项清单:24+3 命令、~90 键位、~71 设置、8 工具、4 运行模式。

支持结论界面与循环同体

打开原文github.com 查看完整证据记录
03

选项 B · dsh:宿主 + 可回放的会话账目

agent 跑在长驻宿主服务里,命令与事件落会话日志、多端可附着;但进行中的一轮仍驻内存。

ev-r5

处理

长驻宿主

一切皆插件的服务总线,agent 是宿主里的服务

ev-r5
命令与事件落账→ 会话日志
驱动执行→ 进行中的一轮

存储

会话日志

command/run↔done 落 log,可回放、可审计

ev-r5

参与者

多端 UI

TUI、飞书、路由都可附着同一会话,先答先得

ev-r5
附着会话→ 长驻宿主

处理

进行中的一轮

流式输出、跑一半的工具、排队的输入都只在内存

ev-r5
场景内证据

这一节的结论依据

默认显示本节依据;播放时会聚焦当前步骤对应的来源。

已验证调研:dsh 与 opencode 参考实现

核心依据dsh-tui-pi 自建 shell 成本量化(~5100 行)、dsh 服务面/命令模型、opencode 槽位化 UI。

支持结论长驻宿主会话日志多端 UI进行中的一轮

打开原文github.com 查看完整证据记录
04

选项 C · pi durable:账本即执行

执行拆成持久化任务:每步先原子提交再展示。进程死了,换个进程从断点接着跑。

ev-durable-readme

处理

任务调度器

循环不在应用里:generation 调模型、tool 跑工具,任务链自己推进

ev-durable-readme
先记账再干活→ 任务账本

存储

任务账本

SQLite:条目、任务、文档走一条原子提交线;流式输出 ≤100ms 一批

ev-r1
派任务→ 工具=持久任务
崩溃后读账续跑→ 断点续跑

处理

工具=持久任务

意图先落盘再执行;崩溃后 safe 任务重跑,其余得 interrupted 结果

ev-durable-readme
逐步回写→ 任务账本

处理

断点续跑

resume() 从账本续推:这一轮自己走完,排队的输入还在

ev-spike
场景内证据

这一节的结论依据

默认显示本节依据;播放时会聚焦当前步骤对应的来源。

已验证pi-durable README(官方一手)

核心依据Harness/任务/原子提交/存储语义的第一手来源:先提交再展示,崩溃后从断点续跑。

支持结论任务调度器工具=持久任务

打开原文github.com 查看完整证据记录
已验证P1 原型实测记录

核心依据~590 行胶水(facade 328/事件适配 210/入口 85)跑通核心环,tmux 实测渲染/流式/工具/中止。

支持结论断点续跑

打开原文github.com 查看完整证据记录
05

决策:什么时候选谁,我们选了什么

三种形态各有舒适区;我们的组合是 durable 底座 + 原样复用正式版界面,自研收缩到最小内核。

ev-spikeev-r4

决策

决策规则

短任务怕复杂→A;要多端附着→B;长 turn 怕丢、要跨进程续命→C

ev-r4
按场景选型→ 我们的选择:路线 B

决策

我们的选择:路线 B

durable 做执行底座 + 正式版 TUI 原样复用;其余功能做成可摘除的 extension

ev-spikeev-infer-shrink
原型验证→ 实测依据
承认代价→ 边界与代价

事件

实测依据

原型约 590 行胶水跑通核心环(渲染/流式/工具/中止),约自建先例的 11%

ev-spike

决策

边界与代价

流式节流观感未人工验证;宿主接口层是唯一绕不开的自研内核

ev-r1ev-infer-shrink
场景内证据

这一节的结论依据

默认显示本节依据;播放时会聚焦当前步骤对应的来源。

已验证P1 原型实测记录

核心依据~590 行胶水(facade 328/事件适配 210/入口 85)跑通核心环,tmux 实测渲染/流式/工具/中止。

支持结论我们的选择:路线 B实测依据

打开原文github.com 查看完整证据记录
已验证调研:上游演进轨迹与 merge 基线

核心依据pico 演进链结论(现 API 不会被替代)、别抢先做清单、跟 release tag 合并策略。

支持结论决策规则

打开原文github.com 查看完整证据记录
推断“可摘除 extension”收益推断

核心依据基于 R3/R5 结论的策略推断:官方原生实现后可卸载自有插件;未经长周期验证。

支持结论我们的选择:路线 B边界与代价

这是教学类比或跨来源归纳,没有外部定位链接。

查看完整证据记录
术语表

值得记住的词

一轮(turn / run)
一次模型响应及其工具调用叫一个 turn;从用户输入到最终答复叫一轮 run。
agent loop
流式调模型 → 执行工具 → 再调模型的循环体,agent 的心脏。
工具调用
模型驱动的动作:跑 bash、读写文件、搜索代码。
checkpoint(断点)
任务每一步的存档,崩溃后从最近断点继续。
原子提交
一批变更要么全部落盘、要么全部不落;先记账再展示。
会话日志
按时间记录命令与事件的账目,可回放、可审计(dsh 的形态)。
宿主进程
长驻运行、承载 agent 服务的进程;UI 只是附着者。
extension(插件)
挂进 agent 的功能包;“可摘除”指官方原生实现后直接卸载自己的版本。
证据地图

每个结论依据什么

  1. 已验证pi-durable README(官方一手)

    Harness/任务/原子提交/存储语义的第一手来源:先提交再展示,崩溃后从断点续跑。

    https://github.com/earendil-works/pi/blob/main/packages/durable/README.md
  2. 已验证pi 正式版 agent-loop 源码

    runAgentLoop:流式→工具→追加的进程内命令式循环,内存是真相。

    https://github.com/earendil-works/pi/blob/main/packages/agent/src/agent-loop.ts
  3. 已验证调研:durable API 全景与能力映射

    24 项 stable 运行时能力逐项映射,6 项缺口清单,全带 file:line。

    https://github.com/fan56/dsh-topics-memory/blob/main/docs/pi-durable-coding-agent/research/durable-api-surface.md
  4. 已验证调研:stable 功能清单(parity checklist)

    231 行逐项清单:24+3 命令、~90 键位、~71 设置、8 工具、4 运行模式。

    https://github.com/fan56/dsh-topics-memory/blob/main/docs/pi-durable-coding-agent/research/stable-feature-inventory.md
  5. 已验证调研:dsh 与 opencode 参考实现

    dsh-tui-pi 自建 shell 成本量化(~5100 行)、dsh 服务面/命令模型、opencode 槽位化 UI。

    https://github.com/fan56/dsh-topics-memory/blob/main/docs/pi-durable-coding-agent/research/reference-implementations.md
  6. 已验证调研:上游演进轨迹与 merge 基线

    pico 演进链结论(现 API 不会被替代)、别抢先做清单、跟 release tag 合并策略。

    https://github.com/fan56/dsh-topics-memory/blob/main/docs/pi-durable-coding-agent/research/upstream-roadmap.md
  7. 已验证P1 原型实测记录

    ~590 行胶水(facade 328/事件适配 210/入口 85)跑通核心环,tmux 实测渲染/流式/工具/中止。

    https://github.com/fan56/dsh-topics-memory/blob/main/docs/pi-durable-coding-agent/wayfinder/tickets/006-p1-tui-architecture.md
  8. 已验证pi v1.0.0 发布说明(2026-10-01)

    1.0 与 pi-durable 初版同日发布;durable README 明示 Experimental。

    https://github.com/earendil-works/pi/releases
  9. 类比日记/账本类比

    仅用于建立直觉:事后记录 vs 先记账再干活,不代表实现细节。

    https://github.com/earendil-works/pi/blob/main/packages/durable/README.md
  10. 推断“可摘除 extension”收益推断

    基于 R3/R5 结论的策略推断:官方原生实现后可卸载自有插件;未经长周期验证。

复述检验

现在能用自己的话讲清楚吗?

旧架构不是挺好吗,为什么要做 durable?

崩溃之后 durable 恢复的到底是什么?

我们要自己写多少?上游跑得快会不会白干?