
你有没有遇到过这种情况:让 Agent 去办一件稍微长一点的事,它查了资料、列了步骤,正等着一个结果,这时候电脑合上了,或者服务器重启了。
再打开,聊天记录都在,可事情断了。它做到哪了?哪一步要重来?重来会不会把同一件事干两遍?只能你自己去理。
Pi 1.0 发布的同时,Earendil 放出了一个实验性的新包 Pi Durable,盯的就是这个问题。
普通的 Agent 关心“这一轮怎么回答”,Pi Durable 关心的是“这件事怎么做完”。 进程崩了、机器重启了、换了一台设备,它都能从断开的地方接着往下做。
它发布后的这一周多,我在 X 上陆续发了 9 条相关的帖子,从官方介绍、Document、官方视频,到社区的最佳实践和新玩法。可光读文档、看别人做,总感觉隔着一层。所以这次我自己动手,搭了一个网页版的个人 Agent,叫“Pi Durable 小助手”。

小助手的代码已经开源:github.com/xiaomoBoy/pi-durable-assistant,不填 API Key 也能在本地跑起来看效果。
这篇先讲清楚 Pi Durable 是什么,再说小助手怎么搭,然后对着截图把它的每个特性拆开讲。最后一部分我更想聊的是:有了它,你能造出什么,甚至造一个属于自己的 Hermes。
先说版本:本文基于
@earendil-works/pi-durable@1.1.0。它还在实验阶段,API 会继续变。
一、Pi Durable 是什么
1. 和 Pi 的关系:Pi 是成品,Durable 是底座
Pi coding agent 大家应该比较熟了,它是一个在终端里跑、由一个人盯着用的编程 Agent。进程退了,你看看怎么回事,再让它继续就行。Pi 1.0 就是把这件事做扎实。
Pi Durable 走的是另一条路。它不是来替代 Pi coding agent 的,而是一个通用的框架,拿来造各种各样的 Agent 应用,编程 Agent 也可以用它造。两边共用 pi-ai 这些底层代码,思路也一样:核心尽量小,剩下的交给你改。
可以这么理解:Pi coding agent 是一台装好的电脑,Pi Durable 是一块带断电保护的主板。你拿这块主板去攒自己的机器,突然停电,来电以后它记得刚才做到哪。
所以没有一个叫“Pi Durable”的软件可以直接装来用,你能看到的,都是别人用它做出来的东西。
2. 官方想解决的五件事
官方文章是用一句句“我们希望……”展开的,我把它归成五件事:
- 哪里都能跑,一直跑下去:本地、服务器、云上都可以,一段对话可以无限延续;
- 崩了能接上:笔记本休眠、容器重新部署、内存耗尽,进程没了也能从中断的地方继续;
- 很多段对话同时跑:一个 Harness 里可以同时跑任意多段对话,互不卡住,还能从任何一条消息分叉出去;
- 应用状态一起存:待办、计划、工单这些状态,和对话记录存在一起,两者不会对不上;
- 几个人一起用:多个客户端可以连到同一段对话上,谁都能插一句。
3. 五个词,先混个脸熟
后面会反复出现这几个词,我先用大白话解释一遍:
- Harness:整套让 Agent 干活的机制,负责存东西,也负责同时跑好几段对话;
- 会话:你和 Agent 的一段对话,有完整的记录,也记着这段对话用的模型、工具和指令;
- 任务:调一次模型、执行一次工具、做一次压缩,都算一个任务,任务每走一步都会存一次进度;
- Document:一份带格式的 JSON,用来放待办、计划这类应用状态,跟着对话记录一起保存;
- 扩展:把系统提示、工具、钩子和任务打成一个包,会话需要哪个就按名字装上。
想看完整的说法,官方原文在 Earendil 博客,中文授权译文我放在了 Pi 蓝皮书。
二、搭一个自己的小助手
1. 先想好做什么
我一开始就想得很清楚:做一个网页上的个人 Agent,类似 GPT Dots、Grok Bot 那种助手,但只做最小的版本。能聊天,能抓网页,能记待办和备忘,能定提醒,还能派一个子 Agent 出去办事。
这几个功能不是随手挑的。每一个都对着 Pi Durable 的一个特性:等待对应进度存档,备忘对应 Document,提醒对应后台任务,派活对应子 Agent。这样做出来以后,每个概念都能在界面上找到。
2. 准备的东西不多
一台装了 Node.js 22.13 以上的机器,一个 OpenAI 兼容的模型接口,再装上 Pi Durable、pi-ai 和 chord 三个包,就可以开始了。想让它一直在线,就放到服务器上;我的小助手跑在 Docker 里,只给了 1 核 1G,启动后实际占用大约 35MB。
想直接看现成的,把小助手的仓库克隆下来,npm ci 之后运行 LLM_API=faux npm run dev。这会用一段写死的演示剧本代替真实模型,不用填 Key 就能看到它列待办、等待;等待的时候点一下“模拟进程崩溃”,就能看它怎么恢复。
3. 搭出来是这个样子
后端是 Pi Durable 加 SQLite,前端就一个 HTML 文件。界面就是开头那张图,我还在右上角放了一个小机器人,叫“小 D”,Agent 在干嘛,它就是什么表情。
左边是会话列表,中间是对话,右边从上到下是小 D、记事本、定时提醒、持久任务和运行状态。
这些区域其实都对应着 Pi Durable 的概念:
| 界面上的区域 | 对应的概念 |
|---|---|
| 会话列表 | 会话。存在服务器上,刷新网页、重启后端都不会丢 |
| 记事本 | Document |
| 定时提醒 | 后台任务 |
| 持久任务 | 任务,以及谁归谁管 |
| 运行状态里的“第几次启动” | 用来证明后端真的重启过 |
搭的过程中我也踩了不少坑,放到文末“踩坑和常见问题”里统一说。
4. 先完整跑一遍
我让它去看 pi.dev 的首页讲了什么,等它回答完,又点了一下“模拟进程崩溃”。
可以看到,它先列出待办,再去抓网页,等足 20 秒才总结。点了崩溃以后,网页顶上出现断线提示,小 D 变成“断线中”;没过几秒就连回来了,运行状态里从“第 4 次启动”变成了“第 5 次启动”,待办和回答一样都没少。
三、对着截图,逐个看 Pi Durable 的特性
1. 进度存档:进程挂了,从上一步接着做
打游戏的时候突然停电,再开机是从最近的存档继续,不会让你从第一关打起。Pi Durable 也是这个思路,只是它存得特别勤:调一次模型、执行一个工具,每走一步就存一次。进程一挂,新进程打开同一份存储,看看哪些任务还没做完,各自从最后一次存档的地方继续。
官方拿一个旅行规划 Agent 演示过:子 Agent 同时去查天气、博物馆和火车,三项搜索各是一个任务。我把整个过程画成了一张图。

进程退出的那一刻,天气和博物馆已经查完了,结果都存下来了;火车查到一半。重启之后,前两项直接拿现成的结果,只有火车重新查一次。
在小助手里,我让它抓完网页之后等 20 秒再总结。这 20 秒就是一个正在跑的任务:右边持久任务里,“调用模型”在等,它下面的“执行工具”在跑,倒计时还剩 19 秒。

这时候我点了“模拟进程崩溃”。这可不是假装断一下,服务器会直接把进程退掉,什么收尾都不做。

网页立刻断开,小 D 也跟着变成“断线中”。

过了几秒,进程被拉了起来。右下角的运行状态从“第 5 次启动”变成“第 6 次启动”,启动时间也变了,这已经是一个全新的进程。

那倒计时能不能接上?我之前用真实模型专门测过:还剩 18 秒的时候掐掉进程,重启后显示还剩 11 秒。也就是说,掉线的那 7 秒左右也被算进去了,最后任务照常做完,一步都没重复。
能做到这样,是因为等待工具第一次运行时,就把“几点结束”记在了这个任务自己的小本子上,官方叫它 memo。进程重启后再翻开,看到的还是那个时间点。
它记的是“几点结束”,不是“还剩几秒”,所以断开的时间自然就被算进去了。
不过要注意,被打断的工具,只有声明过“可以安全重跑”才会再跑一次;没声明的,模型会收到一句“这次调用被打断了”,接下来怎么办,由它自己判断。另外,网络一卡,前端可能把同一句话发了两遍,这个也不用担心:每次提交都能带一个编号,同一个编号只会被收一次。
2. Document:Agent 的记事本,和对话记录一起存
聊天记录记下的是“说过什么”,但很多时候我们还需要知道“现在是什么状态”:待办勾了几项,用户有什么偏好,计划推进到哪了。这些要是只埋在聊天记录里,Agent 每次都得从头翻一遍。Pi Durable 的做法是单独放进 Document,等于给 Agent 配了一本记事本。
我对小助手说:“记住:我喜欢简洁、带要点的回答”。它自己判断这句话该长期记着,就写进了右边的备忘录。接着我问它 Pi Durable 是什么,它只回了三句话。

它之所以记得,是因为每次请求模型之前,记事本里的内容都会被放进系统提示。Pi Durable 的系统提示本来就是每次请求前按扩展现拼的,哪一段改了,改动就记在发生的位置上,所以就算重启、分叉,也能还原出模型当时看到的是什么。
待办也一样。我让它列了几项待办,又让它把前两项勾掉。

对话里写着“已完成:买咖啡豆”,记事本里这一项也同时打上了勾。这两件事是在同一次提交里完成的,要么都成功,要么都不算。
这就是官方强调的那一点:状态永远和产生它的记录对得上。
另外,每本记事本都要事先说清楚两件事:它归谁,分叉时怎么处理。我的小助手是一段对话一本,新开对话就是空白的;你也可以让一本记事本归整个存储共用,左边那个会话列表就是这么存的。
3. 后台任务:回答完了,提醒还挂着
前台任务像你正在打的电话,没挂断,线就一直占着。后台任务更像你设的闹钟,电话挂了,它到点照样响。
我跟小助手说“等一下提醒我喝水”。它问我要等多久,我说两分钟。提醒一设好,这一轮就答完了,小 D 也闲了下来。但提醒并没有消失:小 D 头上的气泡在倒数,定时提醒里写着到点时间,持久任务里多出一个正在运行的“定时提醒”。

这时候你可以接着聊别的,甚至直接把网页关了。就算点了“停止”,停下的也只是前台的活,提醒照样在。
两分钟一到,后台任务把“提醒用户喝水”当成一条新消息送回这段对话,模型看到后回了一句“该喝水啦!”。没有人催它,是它自己开的口。

这个提醒记的同样是“几点到点”。之前我也测过:提醒刚设好三秒左右就掐掉进程,重启后它还在等,时间一到照样提醒,而且只提醒了一次。
明天才响的提醒、这一轮结束后还要接着跑的子 Agent,都适合交给后台。
提醒:小助手的提醒只是写回到对话里,不会在手机锁屏上弹出来。想推送到手机,还得另外接一个通知渠道。
4. 子 Agent 和任务树:派出去办,办完交回来
Pi Durable 本身没有内置子 Agent,但自己搭一个只要几行代码:写一个工具,让它新开一段对话,把活交过去,然后等对方的回复。
我在小助手里让它派一个子 Agent 去看看 earendil.com 最近有什么新文章。主 Agent 先写好一段任务说明,交给新开的那段对话去办,自己原地等着。
子 Agent 有自己的对话、自己的记录、自己调用的工具,点进去就能看到它具体干了什么。它和主 Agent 是什么关系,小助手右边的持久任务里会列出三行:主对话的“调用模型”在等,它下面挂着的“执行工具”就是这次派活,再往下一层,是子 Agent 自己的“调用模型”,正在跑。我把这三行背后的关系画成了一张图。

官方把这种关系叫作归属树:任务和对话一层管一层。子 Agent 那段对话,归派它出去的那次工具调用所有;它答完了,回答就作为工具结果交回主对话。
要停的时候,从最底下开始停,每一层先把自己的摊子收拾干净,上一层才算结束。所以你在主对话里点“停止”,子 Agent 也会被一起叫停。
要恢复的时候,按归属去找。派活的那个工具重新跑起来,会先去找原来那个归它管的子 Agent,找到了就接着等,不会再派一个新的出去。
平时 Agent 只会告诉你“正在思考”,有了任务树,你能看清它到底是在等模型、等工具,还是在等子 Agent。
还有一点:不同的对话可以装不同的扩展。我的子 Agent 就被拿掉了“派活”的能力,只能老老实实把交给它的这件事办完,不会再往下派。官方举的例子是,让某个讨论串只能搜索,不能部署。
5. Fork:从某一句话,重新开一条线
官方举了 Slack 的例子:一个频道是一段对话,有人在某条消息下面开了个讨论串,这个讨论串就是从那条消息分出来的另一段对话。两边同时进行,谁也不影响谁。新的那段能看到分叉之前的所有内容,但这些内容并没有复制一份,而是共用的。
先看原来那段对话。它已经全部跑完了,两项待办都勾掉了,喝水的提醒也已经响过。

我在这段对话的第一条消息上点了“从这里分叉”。左边列表的最上面多出了一条“分叉:帮我看看 :https://pi.dev”,新对话里只剩第一条消息,右边的记事本是空的。

为什么是空的?因为在分叉的那个时间点,一项待办都还没有。
分出去的不只是聊天记录,连应用状态也一起回到了那个时间点。
这是 Document 自己决定的。官方给了三种选择:用分叉那一刻的值、用原对话现在的值,或者干脆从空白开始。我的记事本选了第一种;提醒和派活的记录选了从空白开始,所以旧的提醒不会被带到新的分支里。
当然,它也不是时光机。已经抓过的网页、已经发出去的请求、写到外面的文件,不会因为分叉就回到过去。
6. 多端同步和插话:两台设备,看的是同一段对话
刚才那段喝水的提醒,用手机打开是这样的:

和电脑上看到的完全一样。电脑和手机并没有各自存一份记录,服务器上只有一段对话,两边都在订阅它。后打开的那一端,会先拿到当前完整的样子,再继续接收变化,所以中途加进来也不会只看到一半。我测过让两个连接同时订阅,一边发消息,另一边 3 秒内就收到了 4 次更新。
几端都可以往对话里说话,方式有两种。追加是排队,等这一轮答完,再当作下一轮开始;插话是打断,等手头这一步工具做完,就插进正在进行的工作里。
还是那个等 20 秒的任务。倒计时的时候,我勾上了输入框左边的“插话”,发了一句“总结控制在三句话以内”,右下角随即显示“排队中:1 条”(见前面那张等待中的截图)。20 秒一过,这句话就插了进去,最后的总结刚好三句。

电脑上派活、手机上看结果,或者几个人一起盯着同一个 Agent,靠的都是这一点。
7. 压缩:长对话可以一直聊下去
小助手跑的都是短对话,用不上压缩,所以这一节没有截图。我按官方的描述画了一张图。

这张图要分两层看。上面一层是存储,完整的记录一条都不会删;下面一层是每次真正发给模型的内容。
聊得越久,发给模型的东西就越长,慢慢逼近上下文的上限。这时会有一个后台任务开始给比较早的消息写摘要,对话该怎么进行还怎么进行。摘要写好后,在下一轮开始前换进去:系统提示和工具不动,早期的消息换成摘要,最近的消息保留原文。
只有一种情况需要停下来等,就是不换上摘要,下一次请求已经塞不下了。如果模型那边还是嫌太长,它会再压缩一次重试。你也可以随时手动压缩,顺便告诉它摘要时要注意什么。
压缩只改变“这一次发给模型什么”,存储里的原文始终都在。
四、有了它,你能造出什么
1. 日常能做的几类 Agent
这个小助手只是一个开始。把上面这些特性组合一下,日常能做的东西还挺多:
- 个人助理:提醒、待办、长期记忆,就是这次小助手做的事;
- 群聊机器人:一个频道一段对话,每个讨论串一个分叉,同时进行。官方也说了,后面会介绍他们用 Pi Durable 做的 Slack 机器人;
- 问题分流机器人:官方提到的另一个例子是 GitHub 问题分流。可以想象成每来一个问题就开一段对话,再派子 Agent 去查;
- 长时间的研究和盯梢:等一个结果、隔一阵子再查一次、几件事同时搜,中间断了也能接上;
- 团队一起用的 Agent:几个人同时看着同一段对话,谁都能插话;
- 编程 Agent:官方仓库里就有一个用 Pi Durable 做的小型编程 Agent。
社区跑得比我快。我 10 月 9 日整理过一条社区新玩法:有人把它用 Swift 包了一层,做成任何 iOS App 都能接入的 PiDurableKit;也有人直接发帖号召大家用 pi-durable 自己搓 Muse、Dots 或 Grok Bot。
2. 从小助手,到你自己的 Hermes
我的服务器上跑着 Hermes Agent。搭完这个小助手,我回头一想:一个长期在线的个人 Agent,最难做的那几块,Pi Durable 基本都已经给你准备好了。
| 一个长期在线的个人 Agent 需要 | Pi Durable 里对应的能力 |
|---|---|
| 服务器重启、进程崩溃,手上的事不能丢 | 进度存档和崩溃恢复 |
| 记得住你的偏好和待办 | Document |
| 到点会主动找你 | 后台任务 |
| 复杂的活能拆出去一起干 | 子 Agent 和任务树 |
| 同一件事想换个思路再试 | Fork |
| 电脑、手机、几个人一起用 | 多端同步和插话 |
| 一直聊下去也不会撑爆上下文 | 后台压缩 |
从小助手长成你自己的 Hermes,可以按这个顺序往上加:
- 先让对话能存档:崩了能接上,这是地基;
- 加一本记事本:记住你的偏好和待办;
- 加后台任务:到点主动找你;
- 加子 Agent:复杂的活拆出去办;
- 接入口和通知:接一个 Telegram 或飞书机器人当入口,一个聊天对应一段对话;再接一个通知渠道,让提醒能推到手机上。
小助手的仓库已经做到了第 4 步,你可以直接拿它当起点,先跑起来,再补第 5 步,然后按需要加工具。Pi Durable 的工具是通过执行环境去操作文件和命令的,这个环境可以是本机,也可以是一台远程机器。
不用一次做完。每加一步,它就更像一个长期在线的助手。
小助手只是一副骨架,你真正想要的那个 Agent,就是在这副骨架上一点点长出来的。
3. 不想自己管服务器
那也可以交给 Cloudflare。Cloudflare 的 Agents SDK 已经能直接运行 Pi Durable,状态就存在 Durable Object 自带的 SQLite 里,模型可以用 Workers AI。
不过文档里也写明了现在的限制:工具调用还没有审批这一步,超过 15 分钟的流式模型调用可能会被打断,会话暂时还不能删除,后台任务每 30 秒才检查一次。
五、踩坑和常见问题
1. 我踩过的几个坑
-
照着 README 写,工具结果全是空的。 GitHub 上的 README 已经比 1.1.0 发布版新了。README 里工具返回结果用的字段名,发布版里换了一个;README 提到的一个关闭事件,发布版里也还没有。解决办法很简单:先锁定版本,再去看这个版本对应的源码和示例,别只看 README。
-
用假模型做测试,工具调用被当成了最终回答。 我先用一段写死的“假模型”剧本测流程,结果它一调用工具,对话就结束了。原因是那条带工具调用的回复,没有标明“这是在调用工具”,框架就当它已经答完了。
-
一加内网防护,所有网页都抓不了。 抓网页的工具要防止被引去访问服务器内网,我用 Node 自带的地址黑名单来拦内网 IP。结果把 IPv4 映射到 IPv6 的那一段也放进同一个名单后,所有 IPv4 地址都被判成命中,正常网页全被拦了。那一段要单独放一个名单,只拿来查 IPv6。
-
先查 IP 再抓网页,还是防不住。 我一开始是先解析域名、确认不是内网,再去抓。可抓的时候会重新解析一次,中间完全可以换成别的地址。后来改成解析一次,就固定连这个校验过的 IP。
-
本地测试时,正常网站被当成了内网。 我电脑上开着代理软件,它会把域名解析成 198.18 开头的假 IP,看起来就像内网地址。这不是程序的问题,放到服务器上就正常了。
-
挂在 nginx 后面,前端收不到实时更新。 nginx 默认会把响应攒起来再一起发,实时推送就变成了最后一次性出来。要把代理缓冲关掉。
-
在容器里,看不出进程到底重启没有。 Docker 里进程编号永远是 1,重启前后看不出区别。所以我在运行状态里加了“第几次启动”和启动时间,用它们来判断。
2. 常见问题
-
进程挂了,Pi Durable 会自己复活吗?
不会。它负责从存档接着做,但得有别的东西把进程重新拉起来,比如 Docker 的自动重启或者一个守护脚本。进程起来以后,还要让 Harness 把没做完的任务捡回来。 -
恢复的时候,所有工具都会重新跑一遍吗?
不会。只有声明了“可以安全重跑”的工具才会再跑;没声明的,模型会收到“这次调用被打断了”。会写数据的工具,要保证跑两遍也只写一次。 -
怎么拿到所有会话的列表?
1.1.0 里没有现成的接口。小助手左边那个列表,是我用一份 Document 自己记的,每次新建或分叉会话时一起登记。 -
跑一次要花多少 token?
像“抓网页、等一会儿、再总结”这样的多步任务,我实测一次大约 1.2 万 token。工具调用越多,花得越多。 -
可以直接放到公网上吗?
至少加一个访问密码。能抓网页、能执行命令的工具,还要防止被人利用去访问服务器内网。 -
提醒能推到手机上吗?
小助手现在不行,提醒只是写回对话里。想推到手机,需要另外接一个通知渠道。
六、它现在的边界
Pi Durable 还在实验阶段,API 会变,README 和发布版之间已经对不上过。它是一个库,得自己写代码去搭;如果你只是想找一个现成的聊天工具,现在还用不上它。
但如果你想做一个长期在线、断了能接上、记得住事、到点会主动找你的 Agent,它值得你现在就开始了解。仓库就在那里,先跑起来,再按自己的需要一步步往上加。
最后送你一句话:
先让它断了能接上,再让它记得住,最后让它自己动起来。
关于作者
小墨同学|Pi 深度玩家|AI Spark 联合创始人|Pi 蓝皮书作者|@xiaomovps
延伸阅读
下面是我在 X 上发过的 Pi Durable 相关内容,可以按需要接着看。
- Pi 1.0 与 Pi Durable
- Pi Durable 的 Document
- Pi Durable 社区 3 个最佳实践
- Pi Durable 手册,能从头读到尾
- Pi Durable 社区 5 个新玩法
- 从零开始理解 Agent Harness(译文)
- 从零开始理解上下文压缩(译文)
参考资料
- Pi Durable 小助手源码(GitHub)
- Pi Durable 官方原文
- Pi Durable 中文授权译文(Pi 蓝皮书)
- Pi Durable README
- Cloudflare Agents SDK 运行 Pi Durable
- 2026-10-10(整理配图):本人已放入封面。文中用到的封面、13 张截图、3 张原理图和演示视频,统一放进本文的附件目录,按出现顺序编号 00–16;旧的标注版截图、早期截图、重复的带黑边封面和原
原图/、v2/子目录全部删除。
