先聊个场景:你让 Codex CLI 给 Java 项目加一个查询接口,它几秒钟就把代码写完了,但没写测试、没更新文档、没跑编译,甚至没看一眼项目里已有的工具链。这不是模型不够聪明,而是它缺少一套“做事的方法”。Superpowers 这个名字听起来像游戏外挂,实际是给 Codex CLI 补上这套方法论的技能系统,在社区里经常被叫做 codex superpowers。它不改变模型本身,而是通过一组 Markdown 格式的技能文件,让模型在动手前先读一遍流程,按工程套路干活。这篇文章我会从一个实际使用者的角度,把 superpowers 安装、核心机制、Java 场景落地和踩坑经验一次讲清楚。无论你是刚开始用 Codex CLI,还是已经用了很久但觉得它输出不稳定,这篇内容都值得你往下看。
1. 项目到底在解决什么问题
1.1 Codex CLI 最让我头疼的不是能力,而是“章法”
我刚接触 Codex CLI 的时候,确实被它的单次对话能力惊艳到。给它一个明确的、小范围的任务,比如“把这个方法的空指针判断改成 Optional”,它完成得很好。可一旦任务变成“给订单模块加一个导出功能”,问题就来了:它可能直接改 Controller,跳过 Service 层的权限校验,不更新 OpenAPI 文档,也不管项目的 Maven 依赖规范。模型不是不会写这些代码,而是不知道“在这个项目里,完成一个功能到底要经过哪些步骤”。
你可以说,把步骤写进 prompt 不就行了?没错,但一次性的 prompt 只解决一次问题。真实的工程任务每天都会重复同样的流程:先看现有代码、再确认依赖、然后写实现、补测试、跑构建、更新文档。与其每次重复打字,不如把这些流程沉淀成一份份可维护的文件,让模型自己在需要的时候去读。Superpowers 就是这个思路的落地实现。
这里我还想强调一点:这个“章法”问题不是 Codex CLI 特有的,任何用大模型写代码的工具都会遇到。区别在于,Superpowers 选择了一个非常朴素的技术方案,用普通文本文件作为技能的载体。这个选择让整个系统变得极其透明,模型为什么这么行动,你打开 SKILL.md 就能看到;出了问题,改一行 Markdown 就能修好。在很多号称“智能”的工具里,这种透明性是很难得的。
1.2 skills:把团队经验打包成模型能读的“SOP”
Superpowers 的核心单位叫 skill,一个 skill 就是一个目录,目录里至少有一个 SKILL.md 文件。这个文件不是普通注释,而是一份“操作手册”,里面写清楚这个技能在什么时候用、按什么步骤做、有哪些约束、最后怎么验收。模型在对话中如果判断用户请求匹配这份手册,就会先把它读进上下文,再开始处理任务。
我个人的理解是:这等于把公司的 onboarding 文档、团队 code review 规范和常用技术方案模板全部翻译成了模型能直接读取的上下文。以前这些知识散落在 wiki、群聊和资深工程师的脑子里,现在整理成文件,交给模型按步骤执行。对个人开发者来说,它的价值同样明显,你可以把自己最常踩的坑写进 skill,让模型下一次帮你规避掉。我在用的很多 skill 其实都是从一次失败的重构经验里提炼出来的。
1.3 为什么这种“朴素方案”能在社区里流行起来
身边有不少同事问过我,Superpowers 是不是用了什么黑科技。答案是并没有。它的流行恰恰因为它足够朴素:纯文本、目录结构、Git 管理,没有任何额外服务。你用 GitHub 就能做版本管理,用 VS Code 就能编辑,用 diff 工具就能审查技能变更。这让我想起早期我们用 dotfiles 管理开发环境配置,思路完全一样,把可重复的智慧编码成文件。
另外,它和 Claude Skills 的思路同源,很多设计理念都很像:用文本文件描述任务流程,用描述文本作为触发条件,用 Git 做版本管理。社区里很多人说 Superpowers 是“把 Claude Skills 带到了 Codex CLI”,这个评价不算夸张。它没有引入复杂的数据库或服务端,全部东西就是文件夹里的 Markdown,离开命令行就能读懂,放进仓库就能共享。对工程师来说,这种“低魔法”的设计非常友好,你不需要学习一套新框架,只要会写 Markdown,就能给模型定义工作流。
2. 安装与初始化指南
2.1 动手前先确认这四样东西
在装 Superpowers 之前,请确认你的环境已经满足基本要求。首先,Codex CLI 必须已经安装并且完成登录验证,因为 Superpowers 本质上是它的扩展,Codex 本身不可用的话,后面全都白搭。其次,确认本机有 Git,因为主流的安装方式是直接 clone 仓库。第三,确认你有对用户目录的写入权限,后面要创建~/.codex/skills这个软链接。第四,Windows 用户建议使用 WSL 或 Git Bash,原生 cmd 在软链接和权限处理上会绕很多弯路,我不推荐。
如果你还没有装 Codex CLI,可以先跑一遍官方快速开始,至少熟悉codex的交互模式和codex exec的非交互用法。我个人的建议是先用它完成几次简单开发任务,比如“给现有代码补测试”或者“解释一段看不懂的逻辑”,确认你已经能熟练和它协作,再来安装 Superpowers,否则你很难判断一个异常究竟是技能导致的,还是 Codex 本身没用明白。
2.2 安装步骤:clone 下来,把 skills 放进 Codex 认得的位置
Superpowers 的安装方式在不同版本里有过调整,目前社区里比较稳的做法是把整个仓库 clone 到本地,然后把它的 skills 目录链接到 Codex 配置目录下。我自己的操作是这样:
git clone https://github.com/obra/superpowers.git ~/superpowers mkdir -p ~/.codex ln -s ~/superpowers/skills ~/.codex/skills如果提示~/.codex已经存在,就把最后一行软链接命令直接执行。装完以后,务必重新打开一个codex会话,让配置重新加载。有些版本支持通过包管理器直接安装,但我还是更喜欢 clone 的方式,因为后续更新只要git pull,而且你能随时查看和修改 skill 文件本身。注意,如果你在团队里使用,最好让所有人都用同样路径,否则每个人的技能库版本会出现漂移。
2.3 初始化配置与目录结构
装完之后,你的技能目录会分成两类:一类是 Superpowers 仓库自带的通用技能,另一类是你自己写的项目技能。我习惯在~/.codex/skills下按“领域/技能名”再细分一层,比如java/maven-check、java/spring-crud、review/conventional-commit。这样目录结构一展开,就知道这个技能是给哪个场景用的,找起来也快。
如果你希望某些技能只对特定项目生效,更推荐把它们放到项目仓库的.codex/skills目录里,随项目一起提交。这样团队成员 clone 项目后,Codex 读到的技能就和项目约定保持一致了。通用技能放用户级目录,项目专属技能放仓库目录,这个分层我越用越觉得重要,它本质上是在区分“个人习惯”和“团队规范”。
2.4 快速验证到底生效没有
装完最怕的是“看起来装了,实际上没读”。我一般会这样验证:在 Codex CLI 里输入一句和某个 skill 描述高度匹配的请求,比如我写了一个 Java 相关的 skill,就问它“请给我这个 Spring Boot 项目新增一个用户查询接口,按照项目里的流程来做”。然后观察模型输出,如果它主动说“我先看一下相关技能规范”,或者行为明显变规范,说明 skill 被加载了。
另一个更直接的办法是开 verbose 日志,Codex CLI 会输出它读取了哪些文件,在输出里搜skill关键词就能确认。第一次装完,我建议不要贪多,先只放一两个自己最常用的小 skill,把链路跑通再慢慢扩充。不然如果同时加载了十个 skill,某个行为不对,你根本不知道是哪份文件在起作用,排查起来非常痛苦。
3. 核心机制与 skill 编写方法论
3.1 一个标准 SKILL.md 的结构
我见过很多写得很随意的 skill,效果最好的结构往往都很接近:开头是 YAML 格式的元信息,中间是步骤化的正文,结尾是验收标准。下面是一个简化但完整的模板,你可以直接照着改:
--- name: java-maven-check description: 当用户要求新增或修改 Maven 模块、调整依赖、解决编译错误时使用 when_to_use: 涉及 pom.xml、依赖版本、模块结构或构建失败 --- # 目标 确保所有 Maven 操作符合本项目约定,避免依赖地狱。 # 步骤 1. 先读取根 pom.xml 与父模块,确认依赖版本管理方式。 2. 检查是否已有相同 artifactId 的依赖,避免重复引入。 3. 修改完成后运行 `./mvnw -q -DskipTests compile`。 4. 如果编译失败,先看错误信息确认是依赖问题还是代码问题。 # 验收标准 - [ ] 根 pom 和子模块 pom 的改动都有明确注释。 - [ ] 编译命令通过,或者失败原因被明确记录。这个模板的核心在于:description和when_to_use决定了模型什么时候触发这个 skill;正文里的步骤决定了模型怎么执行;验收标准给了模型一个自我检查的清单。三个部分缺一不可。我见过有人只写 name 和 description,正文只有一句话“请按照最佳实践修改”,这种 skill 基本等于没有,因为模型不知道该按什么标准执行。
3.2 触发机制:description 要像搜索关键词,不要像功能说明书
很多人写 SKILL.md 时,只在 description 里写“用于 Java 项目”,结果模型在任何一个任务里都可能加载它,上下文被占满不说,还经常出现多个 skill 打架的情况。我的经验是把 description 当作搜索引擎的关键词来写,站在用户提问的角度写。比如“当用户说新增接口、改 Controller、加数据库表时使用”,而不是“这是一个 Spring CRUD 工具”。一个 skill 应该对应一类非常具体的任务边界,边界越清楚,触发越准确。
我有一个测试触发准确性的土办法:把 description 写完后,自己对着它模拟十句真实用户可能说的话,看哪些话能命中这个描述,哪些话会误命中。误命中率超过两成,我就马上改描述。这个办法看起来笨,但非常有效,因为模型匹配语义的方式和搜索引擎其实很像,关键词、场景、动作词都会影响它判断。
3.3 好 skill 的四个特征,少一个都会打折扣
第一,步骤必须可验证。不要写“确保代码质量高”这种没法执行的废话,要写“检查是否缺少空指针判断”这种可以逐条对照的项。第二,要包含正例和反例。模型见过反面案例,才知道边界在哪,比如“不要用 Thread.sleep 等待异步结果”比“等待异步结果要优雅”有用得多。第三,要留停止条件。比如“如果发现没有对应的 Repository 接口,先停下来问用户,而不是自己猜”,这一条能防止模型在信息不足时强行续写。第四,要有检查点。每完成一个关键步骤,要求模型输出一个状态标记,中途就能发现问题,不用等它全干完。
这四个特征里,最容易被忽略的是停止条件。我早期写的 skill 总是默认信息足够,结果模型经常凭空捏造一个不存在的配置文件。后来每个 skill 都补上一句“遇到不确定的信息必须向用户确认”,生成内容和项目实际的贴合度立刻上去了。
3.4 用 Git 管理技能库,等于给团队建了一本会自动执行的错误日志
Superpowers 的 skills 目录本身就是普通文件夹,放进 Git 仓库后,团队的最佳实践就能跟着项目仓库一起走。新成员入职,clone 项目的时候顺便就把技能库 clone 下来了,Codex 的表现立刻带上团队风格。我甚至见过有团队把 skill review 加入代码评审流程,谁改了 SKILL.md,都要在 PR 里说明原因并附上验证结果。
这个做法的额外好处是,当你发现模型反复犯同一个错误时,把修复经验写进 skill,下次就不会再犯。我有一次发现模型经常在代码里添加项目并未引入的 Guava 依赖,我就在 Maven skill 里加了一句“引入任何新依赖前,必须先 grep 检查是否已经存在类似功能的依赖”,然后这个问题再也没出现过。这种“错误日志”随着时间越积越厚,模型的表现自然越来越贴合团队习惯。
4. 在 Java 项目里的落地实战
4.1 Java 项目里最值得先写的几个 skill
Java 项目相比其他语言,工程约束更多,依赖管理、构建流程、分层结构、测试框架,每一样都可能让模型翻车。我从实用角度出发,建议优先写四类技能:依赖与构建、分层结构、测试规范、提交与审查。依赖与构建解决“乱引包、乱改 pom”的问题;分层结构解决“Controller 里写业务逻辑”的问题;测试规范解决“测试风格混乱”的问题;提交与审查解决“代码变更无法追溯”的问题。
这四类技能不需要一开始就写得很完整,每类先用一个最小可用版本跑起来,后续遇到新问题再往里面补。Java 项目天然适合做这种技能沉淀,因为它的项目结构和工具链高度标准化,同样的约束可以在绝大多数 Maven 或 Gradle 项目里复用。
4.2 从零写一个 Spring Boot 分层 skill
我用得最多的一个 skill 是spring-layered-flow,它强制 Codex 在改动 Spring Boot 项目时按层级思考。下面是精简后的内容:
--- name: spring-layered-flow description: 当用户要求新增 REST 接口、修改 Controller、Service、Repository 或 DTO 时使用 when_to_use: 涉及 Spring Boot 业务代码的增删改查,不用于纯配置修改 --- # 目标 保证业务代码符合项目分层约定。 # 步骤 1. 扫描 Controller、Service、Repository、DTO 目录结构。 2. Controller 只做参数接收、校验和响应封装。 3. 业务逻辑写在 Service 层,事务注解统一加在 Service 方法上。 4. DTO 转换放在独立方法,不允许在 Controller 里手写转换逻辑。 5. 如果涉及数据查询,先确认 Repository 已有方法,避免重复创建。 # 验收标准 - [ ] Controller 里没有直接操作 Repository 的代码。 - [ ] Service 层方法有明确的入参和返回类型。 - [ ] 所有新增文件都落在对应分层目录。这个 skill 写好后,模型生成的代码结构稳定了很多,至少不会出现“一个方法从 Controller 一路写到数据库”的情况。它的价值不在于教模型什么是 Spring,而在于告诉它“这个项目里我们约定怎么组织代码”。这个区别非常重要,因为模型的知识是通用的,但每个项目的惯例是独特的,技能就是用来补足这个差异的。
4.3 依赖与构建纪律技能
Java 项目的依赖和构建是我踩过坑最多的地方。模型为了用一个工具类,可能随手引入一个新依赖,结果版本冲突、传递依赖泛滥、构建时间变长,一连串问题都来了。所以我专门写了maven-dependency-discipline技能,规定模型:改 pom 之前必须看父模块怎么管理版本;优先使用项目已有的依赖;新增版本必须显式说明原因;编译控制用./mvnw -q -DskipTests compile,测试阶段再单独跑。
这套纪律对 Gradle 项目同样适用,只是命令换成./gradlew compileJava。一开始可能觉得这些规则很基础,但真正跑起来就会发现,模型在没有约束时根本不会主动遵守这些约定。技能的作用就是把“资深工程师脑子里默认的规矩”显式写出来。我在几个项目里试下来,加上这个技能之后,因为依赖问题来回返工的次数至少少了一半。
4.4 测试代码规范技能
Java 生态里的测试框架非常多,模型如果没有约束,一会儿写 JUnit 4,一会儿写 JUnit 5,断言方式也不统一。我自己写过一个测试规范 skill,固定了几条硬规则:测试类统一用 JUnit 5;断言用 AssertJ;涉及外部服务必须用 Mockito 的@Mock,而不是自己 new 一个实现;测试方法命名用should_do_something_when_condition。模型遵守这套规范后,生成的测试代码基本可以直接进代码评审,不需要再人工纠正风格。
可能有人会觉得这种规范太死板,但在我看来,模型写代码的最大问题不是风格偏好,而是不稳定。今天用一种写法,明天换一种写法,评审的人心很累。技能把风格固定下来,等于给模型加了一个稳定的“性格”,团队协作的成本会明显下降。
4.5 一个真实工作流的完整演示
假设我在一个 Maven 管理的 Spring Boot 项目里,想加一个“查询店铺订单列表”的接口。如果没有技能,Codex 大概率直接创建 Controller、Service、Mapper 三件套,然后结束。但有了前面几个技能之后,它的处理流程会变成:先扫描项目结构,确认这是一个 Maven 多模块项目;读取父 pom,确认 Spring Boot 版本与已有依赖;检查是否已经有 OrderMapper,有就直接复用;在 Service 层增加分页参数校验,在 Controller 层暴露 REST 端点;再补一个集成测试;运行编译命令确认没有报错;最后输出改动清单和测试结果。
我实测下来的体会是,这种流程感并不是模型变强了,而是它被技能引导着,把以前凭运气完成的事,变成了按步骤完成的确定性过程。真正用起来的时候,你会感觉自己不是在看一个 AI 补全代码,而是在带一个很听话、很勤奋但缺乏经验的实习生,你给它的操作手册越具体,它交付的东西就越接近你想要的样子。
5. 常见问题与排查技巧实录
5.1 装了但没生效:五步排查法
遇到技能不生效,我习惯按一个固定顺序排查:先确认~/.codex/skills里真的有 SKILL.md 文件;再确认文件名称和大小写完全正确;然后看 description 是否和你输入的请求语义匹配;接着检查是否同时加载了太多技能导致上下文冲突;最后在会话里显式要求“请先查看相关技能”测试一次。这五步走完,绝大多数问题都能定位。
我见过一个特别典型的失误:文件名写成了SKILL.MD或者skill.md,模型的加载逻辑可能区分大小写,导致完全没有读取。另一个常见问题是 description 写得太宽泛,比如只写“Java 开发”,用户说“帮我给接口加个缓存”,模型可能觉得这个描述沾边又不够直接,最后干脆不加载。解决方法是把 description 改得更贴近用户原话,并在需要时显式提示它读取。
5.2 模型读了 skill 但不按步骤走:检查点强制法
有人会问,如果模型读了 SKILL.md 还是不遵守,怎么办?这种情况我一般会从两个方向处理:第一,检查步骤是否写得足够“硬”,如果步骤本身是“尽量保证代码质量”这种软话,模型很容易绕过;第二,在步骤里加入强制检查点,比如“第 3 步结束后必须输出:编译结果,测试通过数”,如果模型跳过某一步,你一眼就能看出来。
更激进一点的做法,是在验收标准里写“不满足标准即视为失败,需要重新执行”。这句话对模型的行为约束很有效,因为它会把这个当作任务失败的判据,而不是一个可有可无的目标。我最初觉得这样做太狠,后来发现,正是这种“硬约束”让模型的行为变得可预测,反而省去了大量来回沟通的时间。
5.3 多个技能互相打架:边界收敛法
技能越多,触发打架的概率越大。我有一次同时放了spring-crud、rest-api-design和java-testing三个技能,结果一个任务把三个技能全加载了,输出又长又乱。后来我给每个技能的when_to_use都加上了排除条件,明确写“本技能不用于测试编写”“本技能不用于接口设计评审”,并在 description 里收窄边界,把它们变成完全互斥的集合。
收敛边界还有一个好处,就是上下文利用率更高。模型不需要在无关技能的长文本上浪费窗口,更专注在当前任务里,生成质量自然提升。我现在倾向于把技能写得短小精悍,一个技能只解决一个问题,而不是写一个“全能型”技能,那样它看起来功能多,实际触发一次就占半屏上下文,反而什么重点都记不住。
5.4 Java 场景下特有的几个坑
第一个坑是构建命令太慢。模型反复跑mvn test,浪费时间还容易把上下文耗尽,我建议在技能里明确区分编译和测试命令,编译用-DskipTests,全量测试只放在最后做。第二个坑是多模块项目里模型改错 pom,解决方式是技能里强制“先列出模块树,再动手改依赖”。第三个坑是 Lombok 和注解处理器相关的编译错误,模型容易陷入死循环,技能里可以写明“遇到 Lombok 错误时,先检查注解处理器配置,不要盲目改代码”。
这些坑看起来不起眼,但每一个都可能导致任务失败或返工。把它们写进技能,本质上是在给模型补“项目里的潜规则”,这些潜规则在官方文档里根本找不到,只在踩过坑的人的脑子里。技能这种东西,价值就在于它能把这些隐性的知识变成显性的、可复用的文件。
5.5 排查问题速查表
| 症状 | 可能原因 | 解决思路 |
|---|---|---|
| 模型完全不引用技能 | 目录路径错、文件名错、触发描述不匹配 | 检查路径,显式在 prompt 里要求读取 |
| 多个技能同时触发 | description 边界重叠 | 细化 when_to_use,增加排除条件 |
| 读取后不遵守步骤 | 步骤缺少强约束 | 增加固定格式的检查点输出 |
| Java 构建太慢 | 技能未区分编译与测试 | 编译用-DskipTests,最后再跑测试 |
| 修改错误的 pom 模块 | 未先分析模块树 | 步骤里强制先列出模块结构 |
| 引入不存在的依赖 | 缺少新依赖检查步骤 | 技能里增加 grep 检查已有依赖的步骤 |
| 测试风格不稳定 | 缺少测试规范技能 | 固定 JUnit 版本、断言库和命名规则 |
6. 我的使用体会与后续建议
6.1 用技能沉淀个人经验,而不是依赖模型自觉
用了一段时间后,我最大的感受是,Superpowers 不是给模型“加智商”的工具,而是给模型“加纪律”的工具。模型本身的知识容量和能力摆在那里,但如果没有技能约束,它的输出就像没有目录的代码库,什么都有但找不到规律。而技能恰好是那个目录,把散落的知识组织成可执行的流程。
我现在已经形成习惯:每次发现模型犯了一个值得注意的错误,不会只在下一次 prompt 里提醒,而是立刻把这个教训提炼成技能。这个动作并不复杂,但长期积累下来的效果非常明显。我的技能库里大部分内容都不是从网上抄来的,而是从真实项目里一次次跌倒后总结出来的。
6.2 一个小建议:从最痛的那个流程开始
如果你想开始用 Superpowers,我不建议你先去下载一个几百个技能的大仓库。最好的起点是找一个你在项目里重复过最多次、最容易出错的流程,比如“新增一个 REST 接口”“修一个 Maven 依赖冲突”“跑一遍测试并整理失败原因”,把它写成你的第一个 skill,跑通验证。一个能被复用的流程,一定是你自己痛过的流程,而不是别人总结得天花乱坠的流程。
6.3 把技能库当成团队资产来管理
最后再说一个关于协作的建议:如果你在团队里推广 Superpowers,别把它当作个人工具,而是当作团队知识库的一部分。定期 review 技能,让用过的人在 PR 里补充心得,把过时的步骤及时清掉。一个活跃维护的技能库,本质上就是团队工程文化的可视化沉淀,Codex 只是那个忠实的执行者。等到团队规模变大,你回头看时,会发现那些 SKILL.md 比很多耐着性子写的文档更容易被持续维护,因为它们每一条都有明确的触发场景和执行结果,大家愿意改,也愿意用。