ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

superpowers:给Codex CLI装上职业习惯的AI编程技能框架

superpowers:给Codex CLI装上职业习惯的AI编程技能框架

如果你在终端里用过 Codex CLI,大概率经历过这种场面:你说"帮我修一下这个bug",它一顿操作猛如虎,三分钟后你发现它把整个模块的结构都改了;你说"给这个接口补个单元测试",它写完测试顺手改了一堆生产代码,build 还挂了。问题出在哪?不是它不聪明,而是它没有"职业习惯"——它不知道资深工程师在动手之前会先确认需求、先写失败测试、先复现问题。superpowers 这套开源技能框架就是来解决这个问题的:它给 Codex 装上了一套可加载、可扩展的工作流程,让 AI 从一个"聪明的愣头青"变成一个"有章法的老工程师"。这篇文章我会从它的核心机制讲起,一步步带你完成安装、配置、上手实操,最后分享我自己写自定义技能时踩过的坑。适合所有用 Codex CLI(以及关心 AI 编程 Agent 生产方式)的开发者。

1. superpowers到底是什么:一套给Codex装上"职业习惯"的技能框架

1.1 它的核心机制:可加载的SKILL.md

superpowers 本质上是位于 GitHub 上的一份开源技能库(作者是 Jesse Vincent,社区里都叫他 obra),它利用了 Codex CLI 的 skills 机制。Codex 会读取~/.codex/skills/目录下按文件夹组织的技能,每个技能文件夹里有一个核心的SKILL.md文件。这个文件不是给人看的说明书,而是给 Codex 看的"操作手册":开头有一段 YAML 格式的元信息,声明这个技能叫什么、什么时候该用;正文则是 Markdown 格式的步骤化指令,告诉 Codex 遇到这类任务时应该按什么顺序思考、执行什么动作、何时停下来确认。

你可以把它理解成给 AI 准备的"标准作业程序"。人的工作习惯是靠长期训练形成的,但 Codex 每次对话都是一张白纸,除非你把方法写下来让它加载。superpowers 把"先写测试再实现""系统化排查 bug""动手前先出方案"这类方法论,固化成了一个个可以被按需加载的文件。关键是"按需"这两个字——Codex 不会把所有技能都塞进上下文,而是在面对任务时,根据技能描述里的匹配条件,选择性地加载最合适的那一份。这比把几十条规则全部写进 system prompt 要经济得多,也不容易互相冲突。

1.2 为什么需要一套"技能框架"而不是一段万能提示词

很多人第一反应是:我不装 superpowers,我在 prompt 里写清楚"请你先写测试再实现"不就行了吗?我用过一段时间之后可以明确说,提示词和技能框架是两种量级的东西。提示词是一次性的、即兴的、不可维护的。你今天想起来写了"先写测试",明天忘了,Codex 又变回老样子;而且提示词越长,Codex 越容易在长对话里"跑偏",前面强调的约束到后面就被遗忘了。

技能框架的思维正好反过来:把方法论从对话里剥离出来,放进一个固定的、可共享、可版本化的文件里。这个 SKILL.md 可以被多个项目共用,可以被团队所有人共用,甚至可以被其他工具读取。superpowers 里的每个技能都经过作者对真实工作流的提炼,步骤之间还有明确的退出条件,不是一句"请认真测试"能比的。我自己的体会是,装上之后 Codex 的行为模式肉眼可见地变了:它会在改代码之前先问我几个澄清问题,会在写实现之前先让我看到失败测试的输出,会在收尾时主动跑完整测试套件。这不是玄学,是结构带来的改变。

2. 安装与激活:让Codex真正"记住"这些技能

2.1 前置条件与版本检查

开始之前,先确认你的环境里已经装好了 Codex CLI 并且完成了登录认证。在终端执行codex --version,能看到版本号就说明命令行工具本身没问题。如果还没有装,先去 OpenAI 官方的 Codex CLI 文档走一遍安装流程,这里不展开。另外你需要一个能正常工作的 Git,因为 superpowers 目前主要就是通过 Git 仓库分发的。

这里提醒一句:Codex CLI 的 skills 机制在早期版本里并不完善,不同版本对技能目录的扫描方式和加载策略有过调整。我建议先把 Codex 更新到比较新的版本再装 superpowers,否则可能会出现"技能文件都在但 Agent 就是不加载"的诡异情况。以我实测的经验,新版本对SKILL.md的 frontmatter 解析更稳定,匹配描述也更智能。

2.2 两条安装路径:脚本安装与手动安装

第一种方式是用仓库自带的安装脚本。把仓库克隆到本地,然后执行脚本:

git clone https://github.com/obra/superpowers.git cd superpowers ./install.sh

脚本会帮你把技能文件复制到 Codex 的技能目录(通常就是~/.codex/skills/),并且如果它检测到你还没有配置过技能相关设置,会顺便在配置文件里补充必要项。这种方式适合绝大多数人,尤其是不想关心目录结构的用户。

第二种方式是手动安装,我更推荐有一定定制需求的人。你只需要把仓库里的技能目录链接或复制到 Codex 的技能目录:

git clone https://github.com/obra/superpowers.git ~/.codex/skills/superpowers

我手动装的时候,习惯先看一眼~/.codex/目录的现有结构,确认 skills 文件夹是已经存在还是需要自己创建。如果 Codex 在首次运行时已经生成过这个目录,那就直接放进去;如果不存在,创建一个同名目录再放技能文件。这一条对新手很容易踩:有的人把技能克隆到了别的位置,Codex 根本扫不到,然后跑来问为什么没效果——先检查路径再说。

2.3 安装后验证:确认Codex能感知到技能

装完之后不要急着开干,先做验证。确认~/.codex/skills/superpowers/下能看到带SKILL.md的文件夹,比如test-driven-development、debugging、planning这一类。然后在你的项目根目录(或者用户目录下)检查AGENTS.md,这个文件是 Codex 读取项目上下文时的关键入口,superpowers 通常会在里面写入技能路径提示,相当于给 Codex 指路。

最直接的验证方式是在终端启动codex,然后问它:"你现在可以使用哪些技能?"如果它能把 superpowers 里的几个技能名说出来,说明加载成功。如果它一脸茫然,多半是技能目录路径不对,或者AGENTS.md里的技能说明没有生效。按下 Ctrl+C 退出,重新检查一遍路径和配置文件,再开一个新的会话重试。注意一定要开新会话,因为旧会话里的上下文可能已经错过了技能扫描。

3. 核心技能拆解:TDD、深度调试、规划各自解决什么问题

3.1 TDD技能:让测试先行的纪律落地

superpowers 里最有名、也是我日常用得最多的技能之一就是 TDD 技能。它把"测试驱动开发"拆成了一串明确的动作:先写一个会失败的测试,运行它并观察失败信息,然后写最简实现让测试通过,最后回头重构。听起来很简单,但 Codex 没有这个技能的时候,它的默认行为是"直接写一堆实现代码,顺带补个测试",这完全违背 TDD 的顺序感。

有了 TDD 技能之后,Codex 在接到一个功能开发任务时,会明确告诉你"我先写一个失败的测试",然后真的先写测试,再运行,把失败输出贴给你确认。这一步非常关键,因为失败信息本身就是需求的验证——如果测试连失败都不符合预期,说明你对需求的理解有问题。我在实测 Java 项目时发现,这个技能对 JUnit、Maven 这类工具链识别得很好,能自动选择合适的测试命令来运行,减少了很多来回沟通的成本。

3.2 深度调试技能:不再"瞎试"的排查流程

调试是另一个我强烈推荐单独拿出来讲的技能。没有调试技能时,Codex 遇到 bug 的典型反应是:读一遍相关代码,凭直觉猜测原因,然后直接改。运气好了改对,运气不好越改越乱,把问题的现场都破坏了。superpowers 的调试技能强制它走一条严谨的排查链路:先稳定复现问题,再缩小范围到最小复现用例,然后提出若干个可能的原因假设,逐一验证,最后才是动手修复。

这条链路其实就是我们人类排查问题时的标准做法,只是 Codex 默认不会这么干。最让我觉得值的地方是,它会在修复之前先想办法复现,而不是看到报错就猜。有一次我在一个老项目里遇到一个偶发的空指针问题,Codex 加载调试技能后,没有直接改代码,而是先停下来问我"能不能提供一个稳定的触发方式",然后构造出了一个最小复现路径,最终定位到一个并发初始化导致的竞态条件。如果它上来就"修",大概率会把问题掩盖过去。

3.3 规划与任务拆分:动手之前先想清楚

规划技能解决的是"大任务如何下手"的问题。AI 编程 Agent 最怕的就是抽象的大指令,比如"给这个系统加一个支付能力",这种任务连人类都要想半天,Codex 硬冲的结果必然是遗漏需求。规划技能会让它先输出一份结构化的实施计划,包括涉及的模块、数据流变化、风险点、验证方式,并且会反过来向你提问,把模糊的需求变成清晰的条目。

它的价值在于把"思考"和"行动"分开了。没有规划技能时,Codex 的思考和行动是混在一起的,一边想一边写,写错了再改;有了规划技能,它会先交付一份计划,等你确认或者修正之后才开始动手。这个环节虽然看起来多了一步,实际上节省了大量的返工。我在带 superpowers 做 Java 模块开发时,最直观的体验就是:规划阶段把字段、边界条件都理清楚了,后面 TDD 阶段几乎是一路绿灯,这种"慢即是快"的体验很上头。

技能名 | 什么时候用 | 它强制 Codex 做什么
技能核心作用典型触发场景
test-driven-development先写失败测试,再写实现,最后重构新增功能、修复 bug 且有明确预期行为
debugging复现→隔离→假设→验证→修复线上问题、偶发异常、逻辑错误
planning输出结构化实施计划,确认后再行动大模块开发、跨文件重构、新项目起步
code-review按清单审查代码质量与隐患合并代码前、审查 AI 生成的改动

4. 带superpowers实战:从零实现一个Java模块的完整流程

4.1 场景设定与项目背景

为了让你更直观地看到这套技能是怎么协同的,我拿一个最近实际做过的例子来说。项目是一个基于 Spring Boot 的电商服务,Java 17 + Maven + JUnit 5,需求是在订单模块里新增一个价格计算器:原价超过一定阈值时自动打九折,并且要支持后续扩展不同的折扣策略。这个任务不算复杂,但正好覆盖了规划、TDD、重构三个关键动作,非常适合用来演示。

我把项目根目录下的AGENTS.md配置好,让 Codex 知道技能库的位置。然后在终端启动codex,输入:"我们要在订单模块新增一个价格计算器,需求是超过阈值打九折,你先用规划技能把这个任务拆一下。"

4.2 第一阶段:让规划技能先把任务拆明白

Codex 加载规划技能之后,没有直接去建文件,而是先输出了一份计划草稿,内容包括:需要新建PriceCalculator类和对应的PriceCalculatorTest测试类、折扣阈值和折扣率应该作为可配置参数还是写死、接口设计要预留策略扩展点。然后它问了我三个问题:阈值具体是多少?折扣率是固定的 0.9 吗?需要支持按用户等级区分折扣吗?

这三个问题问完,我已经能感觉到规划技能的价值了——它在逼我把需求边界说清楚。我回答了"阈值 80,折扣率固定 0.9,暂时不区分用户等级,但要留扩展接口"。Codex 确认后,在对话里输出了最终的开发计划,并且把任务拆成了三个小步骤:先写失败测试,再实现最简逻辑,最后重构抽出策略接口。这份计划我确认没问题,才进入下一步。

4.3 第二阶段:TDD技能驱动"红灯-绿灯-重构"

确认计划后,我对 Codex 说:"按刚刚的计划,用 TDD 技能开始实现。"它随即加载 TDD 技能,第一步是创建测试类,内容大致是这样的:

package com.example.order.pricing; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.*; class PriceCalculatorTest { @Test void shouldApplyDiscountWhenAmountExceedsThreshold() { PriceCalculator calculator = new PriceCalculator(); double result = calculator.calculate(100.0); assertEquals(90.0, result, 0.001); } }

当时PriceCalculator类还不存在,编译都不会通过。Codex 做的第一件事不是补实现,而是运行mvn test,把编译失败的输出贴出来,然后跟我说:"测试目前失败,失败信息是找不到 PriceCalculator 类,符合红灯预期。"这一步我看得很舒服——它没有跳过红灯直接冲到绿灯,这是 TDD 纪律的核心。

接下来它才创建了最简实现:

package com.example.order.pricing; public class PriceCalculator { public double calculate(double amount) { if (amount > 80) { return amount * 0.9; } return amount; } }

再次运行mvn test,测试通过。Codex 贴出了绿色输出,然后主动进入了第三个阶段——重构。它问我:"当前折扣逻辑直接写死在类里,要不要我抽一个 DiscountStrategy 接口,默认实现是 ThresholdDiscountStrategy?"我同意后,它重构了代码并跑了一遍完整测试,确认行为没变。整个过程里,它遵循着"红灯-绿灯-重构"的节奏,一步都没有乱。

4.4 第三阶段:验证与代码审查收尾

实现完成后,Codex 没有直接说"搞定了"。它主动加载了 code-review 技能,把自己刚才的代码过了一遍,重点检查了几个方面:是否有魔法数字需要提取为常量、测试是否覆盖了边界值(刚好等于阈值的情况)、策略接口是否真的有必要现在抽出来。最终它建议把阈值和折扣率提取成常量,并补充一个边界值测试。我接受了建议,它修改后又跑了一次完整测试,全部通过。

这个完整的流程走下来,我最大的感受是:superpowers 不是在替我做决定,而是把每个阶段的检查点摆到桌面上,让我和 Codex 始终知道当前在干什么、下一步要干什么。对于 Java 项目尤其舒服,因为它对 Maven /JUnit 的认知很强,测试命令、测试结果解读都不需要我反复教。

5. 自己写技能:SKILL.md的格式、编写要诀与踩坑提醒

5.1 SKILL.md的标准结构与YAML头信息

用了一段时间内置技能之后,我自然开始琢磨自己写技能。superpowers 的技能格式其实非常开放,骨架上就是一个带 YAML frontmatter 的 Markdown 文件。最基本的模板长这样:

--- name: commit-message description: Use this skill when writing a commit message to ensure the message is concise, accurate, and follows conventional commit format. --- # Commit Message ## When to use - 在完成一次代码变更后,需要提交 Git commit 时 ## Workflow 1. 查看 `git diff` 和 `git status`,梳理实际变更内容 2. 判断变更类型:feat、fix、refactor、docs、test、chore 3. 按 conventional commits 规范生成标题,控制在 50 个字符以内 4. 如果变更复杂,补充正文说明原因和影响范围 5. 将最终信息直接输出,等待用户确认后执行 git commit

YAML 里的name是技能标识,description是最关键的部分——Codex 就是靠它来判断什么时候应该加载这个技能。正文部分不需要写多么华丽的语言,Codex 不是人类读者,它需要的是清晰、有序、可执行的动作列表。我写熟练之后发现,一个技能的核心竞争力不在于步骤多,而在于"边界清晰":什么时候开始、什么时候停止、遇到异常怎么办,都要写明白。

5.2 描述信息怎么写,Codex才愿意调用

这是我自己摸索了很久才想明白的一点:技能的描述信息必须站在"任务的视角"写,而不是站在"技能的视角"写。什么意思?如果你写"This skill helps you write better code",这种描述太泛,Codex 面对一个具体任务时根本判断不出该不该用它。正确的写法是直接点出触发条件,比如"Use this skill when the user asks you to fix a failing test or implement a feature that requires writing new tests"。

我常用的描述公式是:Use this skill when [具体场景] to [达成目标]。把场景写得越具体,Codex 匹配得越准。另外,可以用when后面接多个候选场景来增加召回率,但别把不相关的场景也塞进去,否则会出现"任务类型不搭,Codex 却强行加载了这个技能"的尴尬情况。比如我一开始给调试技能写的描述太宽,导致它连"给我讲讲这段代码逻辑"的任务都去加载调试流程,明显就不合适。

5.3 我踩过的四个坑与改进经验

第一个坑是技能文件命名不规范。CLI 工具对技能目录的命名是敏感的,目录名最好就是技能名,不要带空格、特殊字符,也别用中文命名,否则在有些版本下会出现扫描不到的情况。

第二个坑是正文里写"如果你觉得……",这种模棱两可的话。AI 会把它当成一个可以自由发挥的空间,结果技能步骤被跳过,行为又开始漂移。我的改进方式是:每个步骤都写成祈使句,并且给出明确判断条件,比如"如果测试输出包含 BUILD SUCCESS,则进入下一步;否则返回第一步重新检查"。

第三个坑是贪大求全。我最早写过一个"全流程开发技能",把规划、写码、测试、审查全塞进一个文件里,结果 Codex 加载之后一顿操作猛如虎,中间没有任何确认点,改得面目全非。后来我拆成了多个单一职责的小技能,让 Codex 根据阶段按需加载,效果立刻好多了。这跟写代码的单一职责原则是一模一样的道理。

第四个坑是忽略 AGENTS.md 的指路作用。技能装好了,但如果AGENTS.md里没有写明技能库的位置,Codex 在新项目里可能根本感知不到这些技能。我现在的做法是在每个项目根目录的AGENTS.md里加一行说明技能目录的路径,并在开头提示"本项目可使用以下技能",这能显著提高技能的加载率。

最后再分享一个小习惯:我每隔一段时间会翻一遍 superpowers 仓库的更新记录,因为技能这种文件的迭代非常快,作者经常会根据真实使用反馈调整步骤顺序和描述措辞。本地克隆的版本如果太久不更新,行为会跟不上上游的设计意图。我现在用的是一个简单的更新流程:进到技能目录下拉最新代码,然后重新跑一次安装脚本,顺手核对一下AGENTS.md里的技能清单有没有变化。这套"安装-验证-更新"的闭环,是我用 superpowers 大半年下来觉得最稳妥的维护方式了。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进