【免费下载链接】openbot
A local-first desktop workspace for persistent AI teammates. Run Codex, Claude, and Grok with dedicated workspaces, task queues, file sharing, browser control, and agent-to-agent collaboration.
在长任务、无人值守运行或多人(多 Agent)协作中,真正昂贵的事情通常在于判断上一轮 Agent 究竟停在哪一步,而不是重新写代码。OpenBot 的 Marketplace 生产目录收录了 pstack 技能包,其中的poteto-mode提供了一份名为Session pickup的 playbook,把“接手前一轮工作”定义为一条可以执行的恢复流程。本文以该 playbook 为主线,结合仓库中的父级 SKILL 定义、配套的pause-safely、show-me-your-work、recall技能以及安装机制,说明这套恢复点协议如何运作、如何落地,以及容易出错的细节。
这份 playbook 解决什么问题
Session pickup 的开篇只有一句话,却决定了整个流程的姿态:
You own the resume point. Read the prior trail, don't redo it.
也就是说,接手者的职责是拥有恢复点:读完整条前序轨迹,然后从断点继续,而不是把已经做过的事再做一遍。原文见 session-pickup.md。
它在poteto-mode的路由表中有明确的位置:poteto-mode/SKILL.md 把 Session pickup 定义为“从 transcript、cloud-agent URL 或已推送分支恢复或接管前一个 Agent 的在途工作”,并把Pause safely写成它的互补动作——一个负责留干净的检查点,一个负责从检查点冷启动。二者构成一对:停止时不制造歧义,恢复时就不用重新推导。
需要特别区分的是三个容易混淆的入口,这在 recall/SKILL.md 与 poteto-help/SKILL.md 中被显式划界:
| 场景 | 应走的路径 |
|---|---|
| 恢复某一个具体的先前会话、分支或在途任务 | Session pickup playbook |
| 在开始工作前重建最近一段时间的工作上下文(跨多个 chat) | recall技能 |
| 只关心本 chat 从上一条用户消息以来的变化 | ketchup |
| 把重复习惯固化成可复用技能 | automate-me |
选错入口的代价很实际:recall做的是跨会话的上下文重建与“共享记录”扫描,范围更宽;Session pickup 只服务一个明确的恢复对象,要求精确到“上一轮停在哪一行证据上”。
第一步:定位前序轨迹,并守住工作区边界
原文的第一步要求先找到 prior trail(前序轨迹),它可能是三类载体之一:
- 活跃工作区下
agent-transcripts/目录中的本地 transcript(系统提示里会给出具体路径); - 一个 cloud-agent URL;
- 一个已经推送的分支。
关于本地 transcript 的物理结构,recall/SKILL.md 给出了完整约定:
~/.cursor/projects/<slug>/agent-transcripts/<uuid>/<uuid>.jsonl其中<slug>是工作区绝对路径去掉前导斜杠、再把每个/换成-的结果,例如/Users/you/proj变成Users-you-proj;JSONL 的每一行是一条聊天消息。同一份 skill 还说明,reflect、automate-me、eval等流程在列举 transcript 时用的形式类似:
ls -t <agent-transcripts>/*.jsonl <agent-transcripts>/*/*.jsonl <agent-transcripts>/*/subagents/*.jsonl 2>/dev/null | head -10但 Session pickup 在这一步加了一条硬性禁令,而且原文用括号强调:
Do not glob across
~/.cursor/projects/*/, that crosses workspace boundaries and reads private chats from unrelated projects.
这是一条安全边界,并非单纯的风格建议。跨项目通配会把其他项目的私有对话读进当前上下文,既污染判断,也构成隐私越界。同样的警告在 poteto-mode/playbooks/eval.md、reflect/SKILL.md、automate-me/SKILL.md 中重复出现,说明它是整套技能的一致约束,而不是单点规则。
读取顺序:先元数据概览,再末段消息,最后回溯决策点
原文规定的阅读顺序是:“Read the metadata overview and last messages first, then scan back for the decision points.” 先看概览与最后几条消息,能最快拿到时间、状态和最后一次动作;再从尾部向前扫描,找的是决策点(为什么改了方案、为什么放弃了某条路、哪个假设被推翻),而不是逐行通读。
上下文保护:长 transcript 交给子 Agent 解析
长 transcript 直接灌进主线程,会迅速触发上下文劣化。原文因此要求:
Parse a long transcript in a subagent and keep the reduced timeline in the main thread.
这条要求引用的是principle-guard-the-context-window技能。该原则的说明见 principle-guard-the-context-window/SKILL.md,其“为什么”写得很直白:上下文溢出会降低推理质量、产生压缩伪影并中断进展;对应的模式是“为阶段定规模、给范围设上限”。在 Session pickup 里,落地方式就是:子 Agent 读原始 payload,主线程只留压缩后的时间线。
一个可操作的拆分方式是让子 Agent 只回传结构化字段,例如:
- 轮次范围:<起止消息索引> - 目标:一句话 - 已落地的改动:路径 + 关键 diff 摘要(不贴全量 diff) - 决策点:决策 + 依据 + 被否决的替代方案 - 未完成项:TODO 与阻塞原因 - 证据指针:commit SHA / PR 号 / file:line / 产物路径这正好对应show-me-your-work的 evidence 列规范——“Evidence is a pointer, not prose”(见 show-me-your-work/SKILL.md)。把“指针而非散文”当作子 Agent 的返回契约,可以避免恢复时又被一大段叙述淹没。
第二步:重建操作状态
原文把第二步称为“Reconstruct operational state”,并列出四类必须还原的事实:
- 分支与 worktree:当前在哪个分支、哪个 worktree 上工作;
- 已经落地的东西:用
git log、git diff对照 base 看清楚; - 未完成的 todos;
- 已做出的决策。
这一段的语气是全篇最强的一句:
The prior trail is authoritative input. Resist the bias to re-derive it.
前序轨迹是权威输入,要抑制“重新推导一遍”的冲动。这不是要求盲信,而是要求把“重算”和“核验”分开处理:重算属于浪费,核验属于第五步。
可执行的取证命令
结合原文点名的git log与git diff,一个稳妥的状态快照可以这样取(base指当前分支的对比基准,例如origin/main):
# 当前分支、工作区洁净度、worktree 清单 git status --short --branch git worktree list # 相对基准已提交了什么(只看提交标题,避免大输出) git log --oneline --no-merges "$base"..HEAD # 相对基准改动了哪些文件、增删多少行 git diff --stat "$base"...HEAD # 未提交但已存在的工作(这是最容易被漏掉的在途状态) git diff --stat git stash list这里有两处容易忽略的细节:
- 使用
"$base"...HEAD(三点)比较的是“分叉点到现在”的净改动,适合回答“我这个分支相对主干做了什么”;两点比较则会把主干上的新提交也算进来,容易误判“已落地”的范围。 git status与git diff(不带范围)回答的是未提交的在途状态。前一个 Agent 可能停在“改完但没提交”的位置,pause-safely的第三步为此专门要求把未提交编辑收敛成一个wip:提交(见 pause-safely.md)。如果恢复时看到脏工作区,先判断它是“上一轮的半成品”还是“环境噪声”。
如果前序轨迹是已推送的分支,把本地状态与远端对齐通常是必要的一步:
git fetch git log --oneline HEAD..origin/<branch> # 远端有我本地没有的提交吗 git log --oneline origin/<branch>..HEAD # 我本地有未推送的提交吗poteto-mode在子 Agent 协作场景里也给出过同类手段:同一分支上的多次委派之间,用git fetch && git reset --hard origin/<branch>对齐(见 opening-a-pr.md)。注意这是一条会丢弃本地改动的命令,只有在确认本地没有需要保留的工作时才可使用。
第三步:对比“已完成”与“待完成”,命名恢复点
第三步是整套流程的判断核心:
Diff done vs pending. Compare what shipped against what was planned, name the resume point, do not re-run the prior repro or redo completed work.
把“实际交付的”和“原计划要做的”摆在一起对照,然后明确说出恢复点。原文紧接着给了一个非常有用的反模式识别信号:
A "let me verify from scratch" pass means you're treating the trail as untrustworthy when it's authoritative.
“让我从零验证一遍”本身就说明你把权威轨迹当成了不可信来源。区别在于:
| 做法 | 性质 | 代价 |
|---|---|---|
| 重跑上一轮已经跑过的复现步骤 | 重复劳动,且污染判断 | 时间成本 + 可能引入与前序不一致的新结论 |
| 在既有结论上做针对性核验(第五步) | 必要的证据确认 | 低,且可留痕 |
实践上,建议把对照结果写成一张两列清单,并把每一项都挂上证据指针:
已完成(有证据) - 新增 session 恢复文档 -> commit 4f1c9a2 - 修复 worktree 泄漏 -> PR #812, tests green 待完成(无证据) - 补齐 pause-safely 的交叉引用 -> 未见改动 - 在 CI 上验证 lint -> 未见运行记录 恢复点:从“补齐交叉引用”开始;#812 已合并,不重开。这张清单的结构与show-me-your-work的决策日志高度同构(列:ts / phase / decision / why / evidence / result),因此如果前序运行已经维护了decisions.tsv,恢复点几乎可以直接从日志最后几行读出来,而不必重新推导(参见 show-me-your-work/SKILL.md)。
第四步:把剩余工作路由到匹配的 playbook,并选定结论形态
第四步要求两件事:路由与定调。
原文给出的四种 verdict(结论形态)是:
- continue the execution:继续执行原计划;
- ship a finished recommendation:交付一个已完成的建议(工作本身以建议为产物);
- ratify or override a prior conclusion:认可或推翻前一轮的结论;
- postmortem a failed run:对失败运行做复盘。
然后是一句边界声明:
The pickup playbook ends here. The routed playbook owns the rest.
Session pickup 到这一步就结束了。后续步骤由被路由到的 playbook 拥有——它不再干预细节,也不重复它的步骤。这是一个清晰的责任交接点,避免了“恢复流程”和“执行流程”互相污染。
路由对照表
poteto-mode的 Playbooks 列表(SKILL.md)给出了完整的目标集合。按“接手时最常见的剩余工作”整理如下:
| 剩余工作的性质 | 路由目标 |
|---|---|
| 已定位的缺陷,需要复现、定根因、修复并给出运行时证据 | bug-fix.md |
| 新增或变更行为,需从明确的数据形状出发 | feature.md |
| 保持行为不变的结构调整(改名、抽取、内联、去重、移动) | refactoring.md |
| 有明确指标的持续改进(前后测量、决策日志、每次获胜一个提交) | hillclimb.md |
| 只读问题,产物是有引用的答案 | investigation.md |
| 需要把 PR 或 PR 栈推进到可合并 | babysit.md |
| 绿了之后的独立复核与落地 | shipping.md |
| 需要长时间无人值守推进到某个谓词 | autonomous-run.md |
| 跨多阶段、多 PR 的计划型工作 | multi-phase-plan.md |
| 项目级、多天、数十个子 Agent 的常设程序 | orchestrate.md |
| 需要干净地停下来以便下次恢复 | pause-safely.md |
父级 SKILL 还规定了一条配套动作:打开 todolist,并把匹配 playbook 的步骤逐字抄进去,任何决定跳过的步骤要保留并附一行skip: <reason>(SKILL.md)。对接手场景来说,这条规则的价值在于:恢复点一旦命名,就会立刻变成可勾选的清单,而不是停留在叙述里。
路由时还有一条容易忽略的兜底规则:大型或跨切面的工作(跨多个调用点的迁移、野心较大的多部分改动),即使形态上像 Feature,也应走figure-it-out;而“常设项目”才走orchestrate。原文把二者区分得很清楚——前者设计一次定制的严格流程,后者运行一个程序。
第五步:在真实产物上核验继承来的结论
最后一步把“信任”与“验证”缝合起来:
Verify the inherited claims against the original goal on the real artifact (theprinciple-prove-it-worksskill). A passing prior self-report is not the proof.
这里的关键词是real artifact(真实产物)。principle-prove-it-works/SKILL.md 明确排除了几类“廉价证据”:
- 文件修改时间(mtime);
- 输出新鲜度;
- Agent 的自述报告;
- 缓存的截图;
- “它能编译”。
同时给出两条操作性建议:直接检查真实值,而不是缓存或派生的表示;当验证失败时,先怀疑观察方法,再怀疑系统。以及一条提升证据等级的做法:能脚本化的检查就写成脚本,让审阅者可以重跑同一比较,而不是相信一次性的肉眼判断。
在 Session pickup 语境下,可以把“继承的结论”映射成具体的核验动作:
| 继承的结论 | 真实产物上的核验 |
|---|---|
| “测试已通过” | 实际运行该测试命令,或读取 CI 上对应 SHA 的运行记录 |
| “这个 bug 已修复” | 在目标表面上重放最小复现步骤,观察行为 |
| “性能提升了 X%” | 按benchmark-checklist重新测量,并解释这个数字受什么限制 |
| “接口已按新契约返回” | 直接请求该接口,读取实际响应字段 |
| “文件已生成” | 打开文件读内容,而不是看目录里是否存在 |
注意第五步与第三步的分工:第三步禁止的是“重做已完成的工作”,第五步要求的是“对关键断言做定向验证”。二者并不矛盾——前者针对劳动,后者针对断言。原文用一句话把边界钉死:前一轮的自我报告通过,不构成证明。
收尾:回复必须交付的四件事
Session pickup 的 Reply 契约只有一行,但四个要素缺一不可:
Reply:where the prior agent stopped, what you inherited vs redid (ideally nothing redone), the resume point, and the outcome.
- 前一个 Agent 停在哪里;
- 你继承了什么、重做了什么(理想情况是“什么都没重做”);
- 恢复点;
- 结果。
“继承 vs 重做”这一项是这套协议的自检装置:它把“我有没有浪费前一轮的工作”变成必须显式回答的问题。如果这一栏写了大量“重做”,通常意味着第一步或第二步的取证方式出了问题。
回复的写法还受父级 SKILL 的 “Writing the reply” 约束(SKILL.md),其中几条对恢复报告尤其相关:
- 短句、陈述句,一句话一个意思;
- 不制造未经验证的链接、引用或 transcript 指针,只引用本次会话真正读过的产物;
- 每个断言在同一句里带上它的证据或标签:实测、推断、还是猜测;
- 精简不能成为删内容的借口——细节、权衡、选择、待决项都要保留。
最后一条很重要:Session pickup 的回复容易被写成“已接手,继续中”这种空壳。按规范,它必须交代清楚断点、继承内容、恢复点与结果,同时保持句子短。
与前序轨迹的协同:pause-safely 留点,show-me-your-work 留痕
Session pickup 的质量,很大程度上取决于上一轮有没有留下可读的检查点。仓库中与它直接配合的两个技能值得一并理解。
pause-safely:让下一次恢复有东西可读
pause-safely.md 的四步与 pickup 的第一步严丝合缝:
| pause-safely 步骤 | 产出的可恢复物 |
|---|---|
| 在安全边界停下,取消嵌套子 Agent | 明确的停止位置,不留半执行动作 |
| 不为暂停做不可逆操作(不开 PR、不推送,除非本来就有) | 状态不会因暂停而改变 |
把未提交编辑收敛为一个清晰的wip:提交 | 磁盘上的真实状态,pickup 可直接用 |
| 在上下文之外写 resume note(意图、进度、已验证项、下一步、关键文件、坑) | 一份不依赖会话记忆的恢复说明 |
原文甚至给出了文件命名建议:上下文压缩触发时写到/tmp/<slug>-resume.md;如果已存在show-me-your-work决策轨迹,则指向它而不是复制它。这与 pickup 的“不要把主线程塞满原始载荷”是同一个设计取向:指针优先,避免副本漂移。
还有一个容易忽略的语义:pause-safely 是显式触发的。“继续”、“我去睡了,继续跑”、“不要停”都不构成暂停指令,反而属于继续执行。这条边界避免了“以为在暂停、其实被要求继续”的状态错位。
show-me-your-work:让恢复点可以被审计
show-me-your-work维护一份单表 TSV 决策日志,一决策一行,evidence 列只放指针(commit SHA、PR 号、file:line、产物路径),result 列写谓词状态(如tests green、reverted、pixel-diff 0、INCONCLUSIVE、open)。规则是只追加:错误判断用新行取代,绝不编辑或删除历史。
对 Session pickup 而言,有两条细节直接影响日志读写:
- 一次 pickup 就是一次新的 run。原文规定:一个 run 指一次 Agent 会话,包括其后续轮次;“A pickup, a replacement agent, or a new chat starts a new run.” 当本次 run 往已有日志追加时,它的第一行 phase 必须是
start,且该行的 evidence 要写明是哪个 run(例如 agent id),并在ts范围上标出“此前那些不是本 run 写的行”(show-me-your-work/SKILL.md)。 - 审计用 transcript,不用记忆。同一 skill 要求运行结束前用本 run 的 transcript 反查日志是否说了真话,且审计只修正日志、不改写历史。
这两条合起来解释了为什么 Session pickup 把“读取轨迹”放在第一步而不是最后一步:轨迹既是恢复输入,也是后续审计的基准。
与 recall 的边界再确认
recall的第 1 步就把“恢复某一个具体的前序 chat”明确让给session-pickup;第 3 步则强调“对一两个 chat 直接搜索即可,不必扇出”,第 6 步要求输出胶囊式简报(Capsule / Threads / Problems / Next move)。这套输出契约与本篇的 Reply 契约形态不同、目标不同:recall面向“我最近在做什么”,pickup 面向“这一条工作线断在哪里,我从哪继续”。混用会导致恢复报告里塞进大量与本次恢复无关的线程。
在 OpenBot 中获取并调用这套 playbook
这份文档并不是独立发布的文件,而是 pstack 技能包的一部分。根据 production-catalog/README.md:
pstack是来自cursor/plugins固定 commit 的skills/与agents/的原样副本,采用 MIT 许可;- 构建时它被发布为一个Skill
pstack,压缩包内含索引SKILL.md、LICENSE、NOTICE.md,以及把每个skills/目录写成skills/pstack-<folder>/; - 应用安装时把其中每一个都装成独立的 skill 文件夹,与
pstack并列,但共用一个 lock 条目:一次下载、一张安装收据; - 构建会在 Markdown 中把指向其他 pstack 技能的链接、
/<name>命令和<name>提及改写为pstack-<name>,并移除disable-model-invocation,以便$pstack-<name>在所有 provider 下都能用。
这就是为什么原始文件中写着**principle-guard-the-context-window** skill,而安装后你应该用$pstack-principle-guard-the-context-window这样的名字去引用它。
catalog.json中的 pack 定义(catalog.json)确认了这一点:slug 为pstack,aliasPrefixes为["principle-"],描述中说明它安装全部 52 个 pstack 技能,调用形式是$pstack-<name>,例如$pstack-poteto-mode、$pstack-how、$pstack-why。
安装目录与生效位置
安装落点由 docs/architecture/skills-and-plugins.md 规定:
- OpenBot 会把安装的每个 skill 同时写到
<workspace>/.agents/skills/<slug>与<workspace>/.claude/skills/<slug>,因为 Claude Code 不读.agents/skills;它复制文件而不建链接; .openbot/skills-lock.json记录文件哈希,.openbot/skills-disabled/存放被禁用的技能,捆绑技能带.openbot-managed.json标记;- 一个 folder 缺少
SKILL.md就不算技能;SKILL.md不符合规范、或位于 provider 不读取的目录时,会标记problem,且不会作为 chat tag 提供。
这意味着排障时有两个直接检查点:.openbot/skills-lock.json里有没有对应条目,以及目标目录下是否存在带SKILL.md的文件夹。由于 pack 的“一次安装、多文件夹、单锁条目”设计,pstack的启用、禁用和卸载会作用于全部文件夹,而不是单个技能。
最小使用流程
结合 README 的本地审阅步骤(production-catalog/README.md),一个可复现的路径是:
bun run api:migrate:local bun run marketplace:seed:local bun run dev --isolated然后在应用内的 Marketplace 里搜索OpenBot(Skills 或 Agents 视图),安装pstack。README 明确指出:本地种子只把已批准的目录记录写入当前 worktree 的本地账户数据库、把 bundle 写入本地预览桶,不会重置 Electron profile、不会清空其他 listing、也不会自动创建 Agent。
装好之后,在会话中通过$pstack-<name>调用。恢复场景下,先进入$pstack-poteto-mode,再按其路由表打开 Session pickup 的步骤。
一份可直接照做的接手检查表
把五步压缩成可勾选的清单,便于在真实接手时逐项确认:
[ ] 1. 定位轨迹 [ ] 只读活跃工作区的 agent-transcripts/,未跨 ~/.cursor/projects/*/ 通配 [ ] 先读元数据概览与末段消息,再回溯决策点 [ ] 长 transcript 由子 Agent 解析,主线程只留压缩时间线 [ ] 2. 重建状态 [ ] git status / git worktree list [ ] git log --oneline base..HEAD [ ] git diff --stat base...HEAD [ ] 未提交改动与 stash 已检查 [ ] 3. 对比完成度 [ ] 已完成项逐条附证据指针 [ ] 待完成项逐条列出 [ ] 恢复点已用一句话命名 [ ] 未重跑上一轮的复现步骤 [ ] 4. 路由 [ ] 剩余工作已匹配到具体 playbook [ ] verdict 已选定(continue / ship / ratify-or-override / postmortem) [ ] todolist 首项已逐字抄入该 playbook 的步骤 [ ] 5. 核验 [ ] 关键继承断言已在真实产物上验证 [ ] 证据可重跑,或已说明为何只能一次性观察 [ ] 回复 [ ] 断点 / 继承与重做 / 恢复点 / 结果 四项齐全 [ ] 每个断言带证据或标签常见失败模式
把“接手”当成“重做”。表现是恢复报告里出现大段“我重新验证了一遍全部内容”。按第三步的判断,这等于宣称前序轨迹不可信;正确做法是把重算降级为第五步的定向核验。
跨项目通配读 transcript。一次~/.cursor/projects/*/就足以把无关项目的私有对话拉进上下文。原文在四个不同技能里重复这条禁令,说明它不是可选的谨慎,而是硬边界。
把原始 transcript 灌进主线程。后果不是“慢”,而是推理质量下降与压缩伪影。子 Agent 解析、主线程只留时间线是明确要求,不是优化项。
跳过路由,直接在 pickup 里改代码。原文写明 “The pickup playbook ends here.”。越过这一行意味着后续工作没有对应的验证契约——尤其是prove-it-works要求的真实产物验证,以及各 playbook 自带的回复项。
用一个passing self-report当作证明。前一轮说“测试通过”不构成证据。要么重跑命令,要么读取对应 SHA 的 CI 记录。
恢复报告写成状态播报。“已接手,正在继续”丢掉了断点、继承内容、恢复点与结果四项中的三项,下一次接手又要从零定位——这正是这套 playbook 想消除的循环。
小结
Session pickup 只有十一条,但它把“接手”从一种靠运气的上下文猜测,变成了一条可执行、可审计、可交接的协议:先定位权威轨迹并守住工作区边界,再重建真实操作状态,接着显式命名恢复点,然后把剩余工作交给对应的 playbook,最后在真实产物上核验继承来的断言。它刻意把“重算”和“核验”分开,把“恢复”和“执行”分开,并用一句 “You own the resume point” 明确了责任归属。
配套阅读建议按这个顺序展开:先看父级路由表 poteto-mode/SKILL.md,再看互补的 pause-safely.md 与留痕规范 show-me-your-work/SKILL.md,核验依据在 principle-prove-it-works/SKILL.md,上下文保护在 principle-guard-the-context-window/SKILL.md,安装与生效机制则见 docs/architecture/skills-and-plugins.md 与 marketplace/production-catalog/README.md。
【免费下载链接】openbot
A local-first desktop workspace for persistent AI teammates. Run Codex, Claude, and Grok with dedicated workspaces, task queues, file sharing, browser control, and agent-to-agent collaboration.
相关推荐
pstack-claude 会话恢复实战:用 Session Pickup Playbook 无缝接管未完成的 Agent 工作
pstack claude 会话恢复实战:用 Session Pickup Playbook 无缝接管未完成的 Agent 工作 导读 在长时间、多阶段或跨会话
人工智能AI 技能AI 插件开发工具Genkit JS 智能体人机协同(Human-in-the-Loop)实战:用 Interrupt 暂停 Agent 轮次并在恢复点继续执行
Genkit JS 智能体人机协同(Human in the Loop)实战:用 Interrupt 暂停 Agent 轮次并在恢复点继续执行 导读 :本文聚焦
AI 技能AI 插件Automatonymous状态机核心概念解析:事件、状态与转换的完整教程
Automatonymous状态机核心概念解析:事件、状态与转换的完整教程 Automatonymous是一个功能强大的.NET状态机库,为开发者提供了一种优雅
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考