内容提要
Pi 1.0 发布时推出 Pi Durable,一个约 1.5 万行代码的极简 harness 框架,让 agent 可在任意环境持久运行。它支持内存、SQLite、JSONL 存储,具备 checkpoint 断点续传的故障自动恢复、多对话并行与分叉、插件化扩展(提示词、工具、钩子、任务)、上下文自动压缩、应用状态持久化、动态热插拔及多人协作。工具可标记重放安全性,任务通过 ownership 树实现幂等与级联中止。
延伸解读
持久化运行的关键:存储与检查点
Pi Durable 通过存储层(内存、SQLite、JSONL)和检查点机制实现故障自动恢复。每次运行被分为多个步骤,对应持久化的检查点,进程中断后可从断点续传。存储接口轻量,但同一份存储同时只由一个进程管理,其他客户端需连接该进程访问。这要求部署时注意单点管理,避免多进程直接操作同一存储导致冲突。
工具重放安全性与任务幂等设计
工具可标记 replay 为 safe 或 unsafe(默认)。safe 工具在崩溃恢复后可重试,适合只读操作;unsafe 工具中断后不重试,将中断信息交给模型处理,避免重复副作用。任务通过 ownership 树实现幂等与级联中止:子任务失败或取消时,父任务会触发子任务的 abort 逻辑,确保资源清理。设计工具和任务时需仔细考虑重放安全性。
上下文压缩与多对话并行
Pi Durable 在接近上下文窗口上限时提前在后台总结,不打断对话,也可手动触发。多对话可并行运行,支持从任意节点分叉,新对话继承分叉点前的历史。每个对话可独立配置模型、工具和运行环境,例如 reviewer 使用更便宜的模型和只读工具。这为多用户协作和子代理实现提供了自然支持。
插件化扩展与动态热插拔
插件可定义提示词片段、工具、钩子和任务,并支持覆盖其他插件的工具实现。扩展可在运行时动态热加载或替换,在下一次工具调用时生效。钩子可串行执行,beforeTool 钩子可中断执行,例如部署前审批。应用状态通过 Documents 持久化,支持订阅和分叉时按需快照。这些机制让 harness 灵活适应不同场景。
Q&A
Pi Durable 是什么?它和普通的 Pi 1.0 有什么区别?
Pi Durable 是 Pi 1.0 发布时推出的一个约 1.5 万行代码的极简 harness 框架,让 agent 可以在任意环境持久运行。普通 Pi 1.0 一般运行在终端中,进程挂掉后只能人工手动恢复;而 Pi Durable 支持故障自动恢复、多用户多客户端同时操作、无限长对话,并且可以从故障中自动恢复。
Pi Durable 如何实现故障自动恢复和断点续传?
Pi Durable 将一次运行分为多个步骤,每个步骤对应持久化的 checkpoint。进程中断重启后,通过打开同一存储并调用 harness.resume() 即可从断点继续执行。对于工具调用,可以标记 replay: "safe" 表示恢复后可重试,默认 replay: "unsafe" 则不重试,将中断信息交给模型处理。任务通过 taskid 实现幂等,确保如支付等操作不会重复执行。
Pi Durable 支持哪些存储方式?存储接口有什么特点?
Pi Durable 原生支持内存、SQLite 和 JSONL 三种存储方式。存储接口非常轻量,方便接入任意实现。同一份存储同时只由一个进程管理,其他客户端通过连接这个进程来访问。以 SQLite 为例,完整记录持久化保存在磁盘中,harness 只把当前所需的数据放在内存中,例如活跃对话、正在运行的任务、待提交的任务。
Pi Durable 的插件系统包含哪些部分?如何扩展 agent 能力?
Pi Durable 的插件通过 defineExtension 定义,包含四个部分:sections(提示词片段,每次请求前动态获取最新内容)、tools(工具,可定义重放安全性)、hooks(执行钩子,如工具执行前审批)、tasks(持久化任务)。插件还可以覆盖其他插件的工具实现,支持动态热加载或替换,在下一次工具调用时生效。
Pi Durable 如何处理长对话的上下文压缩?
Pi Durable 会在快到模型上下文窗口上限时,提前在后台总结上下文,然后丝滑继续,不会打断对话。压缩本身也是一个 task。可以通过设置 compaction 参数控制:reserveTokens 指定在超过上下文窗口减去该值后,下一个请求等待摘要;backgroundTokens 指定在此之前多久开始后台摘要。也可以随时手动调用 compact 触发压缩。
Pi Durable 如何支持多对话并行和分叉?
Pi Durable 支持从任意节点分叉,新对话可以访问分叉点之前的所有历史。每个对话可以独立配置模型、thinking level、工具和运行环境,例如 reviewer 可以用更便宜的模型和只读工具。多个对话可以同时运行,相互不阻塞。分叉时可以指定 ownership,决定中止操作的影响范围。
Pi Durable 中的任务(Task)和 ownership 树是如何工作的?
Pi Durable 通过原生 task 执行对话交互,例如模型请求、工具调用、上下文压缩。任务可以定义 phases(阶段)和 abort(中止)逻辑,通过 checkpoint 持久化状态。所有任务形成一个 ownership 树:子任务可以指定 ownership 为父任务,当父任务被中止时,子节点会执行对应的 abort 定义,只有当子节点清理完成后,父节点才结束。任务默认在前台执行,可通过 { background: true } 开启后台任务。
Pi Durable 如何实现多人协作和客户端同步?
Pi Durable 类似 tmux,每个客户端可以 attach 到同一个对话,获取最新的 committed state 并持续同步更新。通过 thread.viewState() 获取当前状态并订阅变化,通过 thread.watch() 获取每一条新的 commit。客户端还可以通过 thread.submit() 发送消息来引导 agent,使用 whenBusy: "steer" 让消息在当前工具调用后加入运行中的工作。