目 录CONTENT

文章目录

Pi Durable 从入门到精通:从一个开源小助手,到你自己的 Hermes

传家宝VPS
2026-10-13 / 0 评论 / 0 点赞 / 5 阅读 / 0 字
RackNerd Mobile Leaderboard Banner

你有没有遇到过这种情况:让 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. 官方想解决的五件事

官方文章是用一句句“我们希望……”展开的,我把它归成五件事:

  1. 哪里都能跑,一直跑下去:本地、服务器、云上都可以,一段对话可以无限延续;
  2. 崩了能接上:笔记本休眠、容器重新部署、内存耗尽,进程没了也能从中断的地方继续;
  3. 很多段对话同时跑:一个 Harness 里可以同时跑任意多段对话,互不卡住,还能从任何一条消息分叉出去;
  4. 应用状态一起存:待办、计划、工单这些状态,和对话记录存在一起,两者不会对不上;
  5. 几个人一起用:多个客户端可以连到同一段对话上,谁都能插一句。

3. 五个词,先混个脸熟

后面会反复出现这几个词,我先用大白话解释一遍:

  1. Harness:整套让 Agent 干活的机制,负责存东西,也负责同时跑好几段对话;
  2. 会话:你和 Agent 的一段对话,有完整的记录,也记着这段对话用的模型、工具和指令;
  3. 任务:调一次模型、执行一次工具、做一次压缩,都算一个任务,任务每走一步都会存一次进度;
  4. Document:一份带格式的 JSON,用来放待办、计划这类应用状态,跟着对话记录一起保存;
  5. 扩展:把系统提示、工具、钩子和任务打成一个包,会话需要哪个就按名字装上。

想看完整的说法,官方原文在 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

这个小助手只是一个开始。把上面这些特性组合一下,日常能做的东西还挺多:

  1. 个人助理:提醒、待办、长期记忆,就是这次小助手做的事;
  2. 群聊机器人:一个频道一段对话,每个讨论串一个分叉,同时进行。官方也说了,后面会介绍他们用 Pi Durable 做的 Slack 机器人;
  3. 问题分流机器人:官方提到的另一个例子是 GitHub 问题分流。可以想象成每来一个问题就开一段对话,再派子 Agent 去查;
  4. 长时间的研究和盯梢:等一个结果、隔一阵子再查一次、几件事同时搜,中间断了也能接上;
  5. 团队一起用的 Agent:几个人同时看着同一段对话,谁都能插话;
  6. 编程 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,可以按这个顺序往上加:

  1. 先让对话能存档:崩了能接上,这是地基;
  2. 加一本记事本:记住你的偏好和待办;
  3. 加后台任务:到点主动找你;
  4. 加子 Agent:复杂的活拆出去办;
  5. 接入口和通知:接一个 Telegram 或飞书机器人当入口,一个聊天对应一段对话;再接一个通知渠道,让提醒能推到手机上。

小助手的仓库已经做到了第 4 步,你可以直接拿它当起点,先跑起来,再补第 5 步,然后按需要加工具。Pi Durable 的工具是通过执行环境去操作文件和命令的,这个环境可以是本机,也可以是一台远程机器。

不用一次做完。每加一步,它就更像一个长期在线的助手。

小助手只是一副骨架,你真正想要的那个 Agent,就是在这副骨架上一点点长出来的。

3. 不想自己管服务器

那也可以交给 Cloudflare。Cloudflare 的 Agents SDK 已经能直接运行 Pi Durable,状态就存在 Durable Object 自带的 SQLite 里,模型可以用 Workers AI。

不过文档里也写明了现在的限制:工具调用还没有审批这一步,超过 15 分钟的流式模型调用可能会被打断,会话暂时还不能删除,后台任务每 30 秒才检查一次。

五、踩坑和常见问题

1. 我踩过的几个坑

  1. 照着 README 写,工具结果全是空的。 GitHub 上的 README 已经比 1.1.0 发布版新了。README 里工具返回结果用的字段名,发布版里换了一个;README 提到的一个关闭事件,发布版里也还没有。解决办法很简单:先锁定版本,再去看这个版本对应的源码和示例,别只看 README。

  2. 用假模型做测试,工具调用被当成了最终回答。 我先用一段写死的“假模型”剧本测流程,结果它一调用工具,对话就结束了。原因是那条带工具调用的回复,没有标明“这是在调用工具”,框架就当它已经答完了。

  3. 一加内网防护,所有网页都抓不了。 抓网页的工具要防止被引去访问服务器内网,我用 Node 自带的地址黑名单来拦内网 IP。结果把 IPv4 映射到 IPv6 的那一段也放进同一个名单后,所有 IPv4 地址都被判成命中,正常网页全被拦了。那一段要单独放一个名单,只拿来查 IPv6。

  4. 先查 IP 再抓网页,还是防不住。 我一开始是先解析域名、确认不是内网,再去抓。可抓的时候会重新解析一次,中间完全可以换成别的地址。后来改成解析一次,就固定连这个校验过的 IP。

  5. 本地测试时,正常网站被当成了内网。 我电脑上开着代理软件,它会把域名解析成 198.18 开头的假 IP,看起来就像内网地址。这不是程序的问题,放到服务器上就正常了。

  6. 挂在 nginx 后面,前端收不到实时更新。 nginx 默认会把响应攒起来再一起发,实时推送就变成了最后一次性出来。要把代理缓冲关掉。

  7. 在容器里,看不出进程到底重启没有。 Docker 里进程编号永远是 1,重启前后看不出区别。所以我在运行状态里加了“第几次启动”和启动时间,用它们来判断。

2. 常见问题

  1. 进程挂了,Pi Durable 会自己复活吗?
    不会。它负责从存档接着做,但得有别的东西把进程重新拉起来,比如 Docker 的自动重启或者一个守护脚本。进程起来以后,还要让 Harness 把没做完的任务捡回来。

  2. 恢复的时候,所有工具都会重新跑一遍吗?
    不会。只有声明了“可以安全重跑”的工具才会再跑;没声明的,模型会收到“这次调用被打断了”。会写数据的工具,要保证跑两遍也只写一次。

  3. 怎么拿到所有会话的列表?
    1.1.0 里没有现成的接口。小助手左边那个列表,是我用一份 Document 自己记的,每次新建或分叉会话时一起登记。

  4. 跑一次要花多少 token?
    像“抓网页、等一会儿、再总结”这样的多步任务,我实测一次大约 1.2 万 token。工具调用越多,花得越多。

  5. 可以直接放到公网上吗?
    至少加一个访问密码。能抓网页、能执行命令的工具,还要防止被人利用去访问服务器内网。

  6. 提醒能推到手机上吗?
    小助手现在不行,提醒只是写回对话里。想推到手机,需要另外接一个通知渠道。

六、它现在的边界

Pi Durable 还在实验阶段,API 会变,README 和发布版之间已经对不上过。它是一个库,得自己写代码去搭;如果你只是想找一个现成的聊天工具,现在还用不上它。

但如果你想做一个长期在线、断了能接上、记得住事、到点会主动找你的 Agent,它值得你现在就开始了解。仓库就在那里,先跑起来,再按自己的需要一步步往上加。

最后送你一句话:

先让它断了能接上,再让它记得住,最后让它自己动起来。

关于作者

小墨同学|Pi 深度玩家|AI Spark 联合创始人|Pi 蓝皮书作者|@xiaomovps

延伸阅读

下面是我在 X 上发过的 Pi Durable 相关内容,可以按需要接着看。

  1. Pi 1.0 与 Pi Durable
  2. Pi Durable 的 Document
  3. Pi Durable 社区 3 个最佳实践
  4. Pi Durable 手册,能从头读到尾
  5. Pi Durable 社区 5 个新玩法
  6. 从零开始理解 Agent Harness(译文)
  7. 从零开始理解上下文压缩(译文)

参考资料

  1. Pi Durable 小助手源码(GitHub)
  2. Pi Durable 官方原文
  3. Pi Durable 中文授权译文(Pi 蓝皮书)
  4. Pi Durable README
  5. Cloudflare Agents SDK 运行 Pi Durable
  • 2026-10-10(整理配图):本人已放入封面。文中用到的封面、13 张截图、3 张原理图和演示视频,统一放进本文的附件目录,按出现顺序编号 00–16;旧的标注版截图、早期截图、重复的带黑边封面和原 原图/、v2/ 子目录全部删除。
广告 广告
博主关闭了所有页面的评论