pstack原则10操作幂等化:设计崩溃重试下依然收敛的命令
【免费下载链接】pstack-claudeClaude Code, Codex, Copilot, Pi, OpenCode, Gemini, and Prime Agent versions of Poteto's pstack. Rigorous agent workflows with Cursor primitives translated for other harnesses.项目地址: https://gitcode.com/GitHub_Trending/ps/pstack-claude
pstack 是一套面向 Claude Code、Codex、Pi 等 AI 编程代理(Agent)的技能栈,其中幂等化原则(Make Operations Idempotent)专门解决一个高频痛点:命令、生命周期步骤和处理循环经常在崩溃、重启、重试的环境中运行。如果一次执行中途崩溃后留下的部分状态会改变下一次执行的结果,那么每次重启都会变成一次调试现场。幂等化的目标很简单——无论跑多少次、从哪个断点重启,都收敛到同一个正确终态。
为什么 agent 的命令必须"跑两次也不出错"
人类写脚本,通常假设"跑一次就完事"。但 AI 代理的工作流完全不同:
- 代理会重试:一个长任务失败后,代理会自动重跑
- 会话会中断:网络断开、上下文压缩(compact)、会话恢复(resume)都是常态
- 循环会半路崩:处理循环跑到第 N 步挂掉,留下半成品状态
pstack 对这个原则的原始定义(见 principle-make-operations-idempotent/SKILL.md):
每个改变状态的操作都应回答两个问题:"这个操作跑两次会怎样?""上一次跑到一半崩溃了会怎样?"
如果答案是"取决于留下了什么状态",那么这个操作就需要一个对账(reconciliation)步骤。
幂等的四个设计套路
pstack 给出了四种可复用的收敛模式,这张清单可以直接当作自检表使用:
| 套路 | 做法 | 一句话理解 |
|---|---|---|
| 🔁 收敛式启动 | 启动时扫描已有状态、清理陈旧产物、接管存活会话 | 不假设"干净环境",先对账再干活 |
| 📦 基于内容的清理 | 按内容等价判断,而不是按创建顺序 | 删的是"过时的",不是"排在前面的" |
| 🔓 自愈式锁 | 用 PID 检测陈旧锁,自动接管已死进程留下的锁 | 锁不依赖"正常退出" |
| ⏰ 幂等调度 | 失败的任务干净地重新生成,每个周期后刷新输入 | 重跑不是"续跑",而是"重新算到同一结果" |
项目中的三个真实实现
pstack 的原则不是空谈,仓库里能找到对应的工程实现,值得新手拆解学习:
1. 自愈式锁:PID 判死 + 强制接管
代理编排工具 orch 的存储锁是教科书级的"自愈锁"。它用wx模式(原子创建,已存在则报错)抢占锁文件,写入当前进程 PID;如果锁已存在,先检查持锁进程的 PID 是否还活着——进程死了就接管,进程活着就报错拒绝(见 store.ts 的acquireLock)。这意味着崩溃遗留的锁不会把系统永久卡死,重启后新进程会自动"收尸"。
2. 整文件覆盖:让重跑天然幂等
setup-pstack技能在写入模型配置文件时明确要求"整文件覆盖,使重跑保持幂等"(见 setup-pstack/SKILL.md)。与其设计复杂的"增量合并"逻辑,不如每次重写完整目标状态——目标态写出来,而不是差异叠上去。
3. 原子指针替换 + 内容校验
resume.mjs的暂停/恢复机制把检查点写进独立目录,发布时校验哈希与链接后原子替换latest.json指针,失败发布绝不会被当作可用检查点(见 resume-storage.md)。并发写入互不干扰,读者永远只会看到"上一个完整版本"或"这一个完整版本",不会看到半成品。
上线前的三个自查问题
pstack 给幂等操作定义了一个极简测试,发布任何状态变更命令前过一遍:
- 这个问题连续跑两次会怎样?
- 上一次在每个可能的位置崩溃了会怎样?
- 重新执行会收敛到同一个终态吗?
三条全过,命令才算幂等;任何一条存疑,就补一个对账步骤。
顺带一提,pstack 自己的构建工具也遵循同一原则——CI 中的生成器校验被测试验证"原地盖章且幂等"(见 generate.test.mjs),重复生成不会产生漂移。
如何把幂等原则用在你的项目里 🛠️
不需要大动干戈,从三个最小改造开始:
- 命令启动时先"看一眼":读取当前状态,与目标态比对,只修补差异
- 锁必须能自愈:锁里记录 PID(或心跳时间戳),启动时清理死锁
- 写入走"暂存 + 原子替换":先写临时文件再 rename,读者永远不会读到半截数据
pstack 把这个原则放在 poteto-mode 的核心原则清单里(见 poteto-mode/SKILL.md),并在架构审查环节强制要求:每个状态迁移都要回答"跑两次或中途崩溃会怎样"(见 runner-prompt.md)——让幂等成为设计评审的标配问题,而不只是实现细节。
一句话总结:崩溃和重试不是异常,而是正常运行环境的一部分。把每个命令都设计成"重跑无害、中途崩溃可自愈、终态唯一",你的系统——和代理——才敢放心地按重试键。
【免费下载链接】pstack-claudeClaude Code, Codex, Copilot, Pi, OpenCode, Gemini, and Prime Agent versions of Poteto's pstack. Rigorous agent workflows with Cursor primitives translated for other harnesses.项目地址: https://gitcode.com/GitHub_Trending/ps/pstack-claude
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考