跳到正文

Open Steps

八个技能加两个钩子,让编码 agent 用不懂代码的人也能照着行动的话交代自己的工作。它们各自在指定的时刻起作用——一屏十行、以结论收尾的会话报告;能照着走的步骤;只给一条明确建议的提问;由一个全新 agent 做的「事前验尸」;以及一份常驻的产品全景文件——而同一批文件夹在 Claude Code、Codex CLI、Cursor CLI 与 Gemini CLI 上装法一致。

Screenshot of Open Steps
编辑截图, 1 Oct 2026Open Steps ↗

这是什么

八个技能加两个钩子,写给跑开发但自己不看代码的那个人。每个技能在指定时刻被触发:os-done-or-not 写一份十行、以结论收尾的会话报告;os-step-by-step 把不懂技术的人要做的事编号列出;os-ask-simple 把问题改写成人话并给出唯一一条标好的建议;os-what-could-go-wrong 让一个全新 agent 假定某个难以撤回的决定已经失败;os-whats-next 先合掉已验证的东西,再说还剩什么;os-check-work 回到源头逐条重测另一个会话的说法;os-say-simple 在不丢坏消息的前提下改写任何文本;os-big-picture 维护一份常驻的产品全景文件。两个钩子把路由表和上一份报告放在新会话面前,并在确实有活落地时索要一份报告。同一批文件夹在 Claude Code 上作为插件安装,在 Codex CLI、Cursor CLI 与 Gemini CLI 上则是复制进一个共用的技能目录。MIT 许可,附带一套评测工具,里面的数字由脚本写出而不是手打。

谁做的他自称不是工程师,而是「市场驱动的构建者」:二十年做网络与软件产品,始终站在产品这一侧,如今公司里有五十多名开发者。仓库头五周的 64 次提交里有 50 次是他写的,其余来自另外六个账号,最多的一个 8 次、其次 2 次。他自己回 issue,看别人的贡献时会把分支放进干净检出里跑一遍,而且有过两次直接把人家的修复推回贡献者的分支,而不是再要一轮修改。

它是怎么搭起来的

组成 · 6

它的组织思路是:编码 agent 跟不懂技术的人说的话,是一份有固定格式的文档,而这个格式必须在明确的时刻被强制,不能指望一条泛泛的指示。所以产品是八个文件夹,每个里面一份 SKILL.md——描述写成命令,正文是一列硬规则——旁边各放一个实例;围着它们的是两个制造「时刻」的钩子:一个把路由表和上一份报告放在新会话面前,另一个拿会话开始时记下的指纹去比对仓库,在确实有活落地时索要报告。第二个思路是测量与假设绝不能出现在同一句话里,而且它被用了两遍:对 agent,通过「每个『是』都要说出证据、没查过的写 not checked」这条规则;对这个项目自己的说法,通过一张每个格子都要说明自己是怎么被知道的 README 结果表,以及一套数字由评分器写出的评测。在机器上跑的是纯 shell——两个短钩子、一份被两个钩子共用的指纹算法、一个给两种只认自己 JSON 的工具用的适配器、两个技能调用的小脚本,以及一个 39 KB 的只读安装自检;而报告写在仓库之外,于是它们不进用户的提交、卸载后依然在,并被所有指向同一个文件夹的工具共享。

skills/
产品本体:八个文件夹,每个一份 5,180 到 7,644 字节的 SKILL.md,从写成指令的描述,到步骤,再到一组被文件称为「就是这个技能」的硬规则。七个带一份 references/ 实例;os-big-picture 另带一个 4,024 字节的普查脚本和一份理由文档,os-what-could-go-wrong 另带一个提示脚本、一份 10,614 字节的交接提示和两份实例,大的那份 21,995 字节。
hooks/
四个脚本加它们的测试:一个开场钩子把路由表与上一份报告放到最前;一个停止钩子判断是否真有活落地;一个 6,533 字节的适配器让 Cursor CLI 与 Gemini CLI 通过各自的 JSON 拿到同样两个行为;一个 4,673 字节的指纹脚本被两个钩子刻意共用,好让「到底有没有真活」这个问题无法有两个答案。旁边的测试文件 38,760 字节,比它测的所有东西加起来还大。
evals/
测量本身:一个 9,255 字节的运行器、一个 34,718 字节的评分器、一个 26,529 字节的测试文件(用替身驱动前两者,不调用任何模型)、句子清单、一份同时决定列顺序的小模型注册表、分别由 Claude 与 Codex 生成的结论文档、每种工具一个运行器,以及分布在八个目录里的 36 条夹具流——每个出现过的 bug 都留了一个手工构造的用例。
docs/ 与 commands/
放不进指示里的部分:一份 26,248 字节的文档讲在三个非 Claude 工具上怎么装怎么跑,一份 3,756 字节讲路由表为什么必要,一份 1,339 字节的路由表副本,以及 3,430 字节的输出样式说明页。另有一个 2,572 字节的命令文件,运行安装自检并把结果读回给不愿打开终端的人。
doctor.sh 与 .claude-plugin/
一个 39,257 字节的只读安装自检,报告什么接上了、对看不到的部分写「not checked」,旁边是插件与市场清单,前者锁在 0.4.6。唯一那条工作流在 Linux 与 macOS 上跑两个测试文件、校验插件清单、检查签署行,于是只在某一个平台上成立的写法会变成一条失败的检查,而不是某个人终端里的怪事。
根目录与它的七份 README
一份 29,313 字符的 README,旁边是西班牙语、法语、俄语、乌克兰语、韩语与中文版本,6,125 字节的贡献规则、MIT 许可证、两张展示前后对比的 SVG,以及 issue 模板。整个文件树 99 个文件、约 587 KB,其中评测、钩子和一个技能占了大部分体积。

取舍,以及它替代了什么

  • 把技能描述写成命令,而不是摘要 替代 描述这个技能做什么的说明文

    README 把这一点列为塑造一切的三条决定之一:描述以「ALWAYS invoke this skill…」开头,而用这种写法,技能在测得的运行里会自己触发。它也写明了证据的边界——评测从未把这个措辞和别的写法对比过。

  • 凡是每一轮回复都必须成立的规则,放进工具的常驻指示文件 替代 指望技能自己强制执行

    这是包里的第二条决定:技能无法强制自己被调用,所以一条必须在每轮回复里成立的规则属于 CLAUDE.md、AGENTS.md 或 GEMINI.md,或者 Claude Code 的输出样式,而这个包会说明每一块属于哪一层。路由表之所以要用户手工添加,正是这个原因。

  • 把测到的和假设的分开 替代 一种两种情况读起来都一样的自信结论

    第三条决定,也是每个界面都能看到的一条:每一个「是」都要说出证据,没查过的一律写「not checked」;这也是报告之所以短的原因——agent 不再叙述自己检查的过程,而是直接给出结果。同一条规则也被用在这个项目自己的 README 上:结果表里每个格子都带着七个词之一,说明它是怎么被知道的。

  • 把输出样式保持关闭,并且说出来 替代 那一行会在安装时把它强加给所有人的标志

    样式自己的文档记下了替代方案还会覆盖用户已有的设置,并给出拒绝它的理由:一个选了别的样式、或自己写了一个样式的人,不该因为装了一个不相关的包就静默地失去它;一个前提就是「不要让人意外」的包,没有资格在安装时让人意外。团队可以自己加上那一行,但被要求说出来。

  • 报告写在仓库之外,写进所有工具共用的一个文件夹 替代 把报告存在项目里

    README 给出三个后果:报告不进用户的提交;卸载这个包之后它们还在;让每个工具都指向同一个文件夹,得到的是一份历史而不是四份。它还补了一句:那个路径里的 .claude 只是一个名字。

  • 在明确的时刻改变 agent 的行为,而不只是改变它答案的措辞 替代 重塑每一轮回复的样式层,或只在屏幕上重画的改写器

    这正是这个包与本档案里同类记录的界线,而且维护者在回复 issue 34 时自己说了出来:在明确时刻改变 agent 的行为是产品本身而不是副作用,唯一不变的是事实——只有措辞变了,所有测得的数字保持原样。本档案已收的 Attention Span 做的是另一件事——三个改说话方式的输出样式,把「干的活」与「说的话」分开测;claudish-to-english 则把每条助手消息在屏幕上重画一遍,而记录里保留原文。

  • 借用 ASD-STE100 的思路,但不声称符合该标准 替代 引用一个这个包并不具备的认证

    README 与改写技能都写明了那套人话规则的出处——为航空航天手册写的简化英语,短句、主动语态、一句一个意思——并且两处都加了同一句限定:借用的就是「借用」这个词,这里没有任何东西是针对该标准认证过的。

依据README.md(29,313 字符)、docs/output-style.md、.claude-plugin/plugin.json、hooks/hooks.json、skills/os-done-or-not/SKILL.md、skills/os-ask-simple/SKILL.md、skills/os-say-simple/SKILL.md、CONTRIBUTING.md,以及完整的 99 个文件树及其体积。

制作过程

6 个阶段
  1. 01

    五周、十一个 release,一个自己往前走的包

    仓库建于 2026-08-25T14:24:24Z,v0.1.0 在大约一分钟后的 14:25:44 打上标签。五周之后它有 64 次提交——九月 52 次、八月 12 次,最后一次在 2026-09-30——以及 11 个 release 和 11 个对应的标签,每一个都是正式版,列表里没有预发布也没有草稿,所以这里没有 beta 通道。编号还整整跳过了一个次版本线:v0.1.0,然后 2026-08-31 的 v0.3.1、2026-09-06 的 v0.3.2、2026-09-10 的 v0.3.3、2026-09-11 相隔十二分钟的 v0.4.0 与 v0.4.1、2026-09-13 的 v0.4.2、2026-09-14 的 v0.4.3、2026-09-28 相隔一小时的 v0.4.4 与 v0.4.5,以及 2026-09-30 的 v0.4.6。周围是 1,072 个星、99 个 fork 与 40 个 watcher,4 个 issue 开着,issue 与 pull request 合计 30 个。共有七个账号提交过:作者 50 次,一位贡献者 8 次,另一位 2 次,另有四个账号各 1 次;每一次提交都关联着账号,而只有 2 次带共同作者尾注,其中一条署名 Claude Opus 5。插件清单锁在 0.4.6,文件树 99 个文件,README 有七种语言。

  2. 02

    一份诚实报告由什么构成,一条条规则地看

    os-done-or-not 是这个包的核心技能,而它的 SKILL.md 不是描述格式,而是直接把格式定死。动笔之前,agent 必须先选定 八种结局之一——已上线并已验证、只剩一个动作要你做、卡在等你决定、没做成并已回滚、出了故障、只是调研,另有两种——因为按文件自己的说法,不这么做报告就会出现「fully done: yes」和「safe to close: no」同时成立。接着是一到两句的开头,把最好的结果放最前,绝不按时间顺序;一个两到五行的对勾表;以及四行结论——是否完全做完、是否需要你做什么、是否新增欠账、是否可以关闭。真正防止粉饰的是一组被文件称为「这些规则本身就是这个技能」的硬规则:每一个「是」都要说出证据,拿不出证据就写「not checked」;坏消息单独占一行警示,绝不埋进别的句子里;未处理的安全风险或数据丢失是长度上限的唯一例外,要讲全,而不是靠把结论格写肿。注意事项从另一面讲同一件事:「new debt? no」在确实没有欠账时会被写,在根本没人看过时也会被写,所以只有查过之后才能写「no」;而检查全绿或合并成功,都不等于用户已经拿到。文件还明说,出了错或没做成的那两种结局正是报告开始说谎的地方,而「这个做法失败并已回滚」本身就是一个完整的结果。

  3. 03

    直接的结论:一套不许摆菜单的规则

    凡是必须以一个决定收尾的地方,这个包都会把规则写死到逼出结论。os-ask-simple 先问这个问题该不该到达人面前——能不能自己看一眼就答、有没有约定俗成的默认值——然后用一句人话写清问题,并附上为什么重要、以后会改变什么、是否容易撤回。结构性的选择要过六项检查并以表格呈现,每一行都要答:「not checked」是被允许且诚实的,沉默不是;而一行永远答「否」的检查,用文件的话说,只是装饰。它的硬规则读起来像一份「如何避免给出结论」的反面清单:永远把「什么都不做」列入比较并说明它为什么输了;必须给出建议,因为「视情况而定」不算建议;当检查表这么说时,要明确反对用户自己的想法;没有筛过的东西不许推荐;并且把「这是最有意思的实现方式」当成警惕的理由而不是偏好的理由。os-say-simple 承担文本层面的同类规则,第一条就是句子级的反粉饰条款:不加东西、不丢坏消息,因为一个丢掉警示行的摘要就是靠省略撒的谎。数字保持精确;改写与原文一样真、但不会更真,所以它写「报告说测试通过了」,而不是「测试通过了」;原文含糊就保持含糊;代码和命令是原样字符串。

  4. 04

    四个宿主、三个要手改的文件,和一张写明「到底跑过什么」的表

    技能在所有工具上都是同一批文件夹,不同的只有接线。在 Claude Code 上一条命令注册市场并安装插件,技能和两个钩子一起进来;hooks/hooks.json 把开场钩子挂在 SessionStart、报告钩子挂在 Stop 上。另外三个工具读同一个共用技能目录,所以一句复制命令就为它们三个装好技能;按工具留下的只有路由表——一张写明「什么时候必须用哪个技能」的短表,要手工放进 ~/.codex/AGENTS.md、Cursor CLI 的项目根 AGENTS.md,或 ~/.gemini/GEMINI.md——以及钩子设置:Codex 放在 ~/.codex/config.toml,Cursor 与 Gemini 分别放在 ~/.cursor/hooks.json 与 ~/.gemini/settings.json,并经过 hooks/adapter.sh。适配器把那两个钩子主体原样运行,只翻译进出的东西:交接内容变成 additional_context,索要报告变成 followup_message。在 Gemini 上,停止钩子挂在 AfterAgent,以拒绝的形式发出并把请求当作理由,Gemini 会把它作为下一轮提示交回;而 Cursor 是唯一只能「请求」的,因为那里的停止拦不住。让 README 读起来可信的是它给证据用的词汇表:一张七列的表里,每个格子都要说明这个行为是被计数的、被看到的、被手工喂过输入的、照文档设置的、只在场的、试过但没发生的,还是根本没试过。结果上 Claude Code 落在 85% 到 100%,Codex CLI 是 75 次里 75 次读对了正确的技能,Cursor CLI 与 Gemini CLI 则标为未测量。

  5. 05

    一个不含模型的评分器,以及测量在自身里查出的 bug

    这套评测问 25 句人真的会说的话——每个技能三句,再加一句专门试探两个技能之间的界线——在三个 Claude 模型上各问三次、全程无人在键盘前,另有三句跑题问题;score.py 读工具调用并打印结果,那份结果文件不是作者手打的。2026-09-12 测出的触达率是 Haiku 4.5 85%、Sonnet 5 98%、Opus 5 100%,跑题问题没有一次拉进技能;而文章把漏掉的留在视野里而不是只报分数:Haiku 上有两个技能不可靠,同一批句子测四轮,某个技能分别是 50%、33%、44%、44%——作者的原话是他宁可这么写,也不愿引用最 friendly 的那一轮。接着,测量在自身里查出了毛病。无头运行的每一次技能调用都被拒绝,于是本该测质量的那一组变成拿这个包跟自己对打——2026-08-29 的 234 条流发出 279 次技能调用、零次真正执行;一天之后的 261 条流发出 362 次、执行了 12 次——而一次评测也没有跟机器上的其他会话隔开,因为其中一个技能会列出正在运行的会话:测量期间有三轮去 ping 了发起这次评测的那个会话,另有一轮 ping 了一个两小时前开始干别人项目的不相关会话。两处都已修好并重测:技能工具现在只授予两个质量组,评分器只统计真正执行过的调用,每次运行开始就禁掉两个跨会话工具,于是 2026-09-12 的 270 条流全部封住。

  6. 06

    社区那几轮,以及一个被标为「暂不计划」的 issue

    共有七个账号贡献过,其中最大的一批来自同一个人:六个 pull request,给三个技能补上了实例,做出了让两个钩子在 Cursor CLI 与 Gemini CLI 上都能工作的适配器,做出了一条命令跑完整整一天的评测,还写了生成 README 数字表的脚本。另一位贡献者加了一份常驻的产品地图;维护者把它改名为 os-big-picture 与 BIG-PICTURE.md,并砍掉一个触发词——因为「status」属于工单而不属于项目。第三位贡献了安装自检:一个只打印事实并给出退出码的脚本,维护者提了两处修改后接受。Codex 的运行器则以一个关闭对应 issue 的 pull request 形式进来,附 84 次运行记录。由于首次贡献者的 pull request 在没有一个仓库工具够不着的批准按钮时无法启动工作流,维护者在同一个提交上开了一个镜像 pull request,好让检查跑在那里,随后不合入地关掉它。有一个 issue 被标为暂不计划:一份中文请求要求把术语翻译变成一条绝不参与 agent 决策的强制规则,并要求 Codex 变得像 Claude Code 那样是一个完整插件。答复是:在明确的时刻改变行为正是这个产品本身而不是副作用,而 Codex 没有对等的插件格式,所以在那边的安装方式是复制技能文件并通过它的配置文件接入钩子。

相关档案

全部档案 →