Claude Code与Codex CLI的Agentic Skills框架:从提示词到技能工程
1. 从“superpowers”说起这套技能框架到底在解决什么问题第一次看到“superpowers”这个词是在一个开发者社群里有人贴了一张截图里面是一套围绕 Claude Code 和 Codex CLI 构建的 agentic skills framework。当时我的第一反应是又是一个包装概念的东西。但仔细看完它的结构之后我改变了看法——它其实在试图回答一个非常具体的问题当 AI 编程助手从“补全代码”进化到“自主执行任务”之后我们该怎么组织它的能力才能让它在真实项目里稳定干活而不是每次都靠运气这个问题的背景是这样的。Claude Code 和 Codex CLI 这类工具本质上是一个跑在终端里的 agent。你给它一个任务它会自己读文件、改代码、跑命令、看报错、再改循环往复直到任务完成或者卡住。听起来很美好但实际用起来你会发现同一个任务有时候它一次就做对了有时候它会在同一个坑里反复横跳浪费大量 token 和时间。差别往往不在于模型本身而在于你怎么给它定义任务边界、怎么组织项目上下文、怎么设计验证回路。superpowers 这套框架的核心思路就是把“怎么跟 agent 协作”这件事从玄学变成工程。它把常见的开发任务拆成一组可复用的 skill技能每个 skill 定义了明确的输入、输出、约束条件和验证方式。你可以把它理解成给 agent 写的一份“岗位操作手册”——不是告诉它具体怎么做而是告诉它在什么场景下应该遵循什么流程、检查什么、避免什么。这套东西适合谁如果你只是偶尔用 Claude Code 改个脚本、跑个一次性任务那可能不需要这么重的框架。但如果你每天都要跟 agent 协作项目有一定复杂度涉及多文件修改、测试验证、依赖管理那这套方法论能帮你省下大量反复沟通和纠错的成本。下面我会从设计思路、核心机制、实操落地、常见坑四个层面把这套框架拆开讲清楚。2. 框架整体设计为什么是“技能”而不是“提示词”2.1 从提示词工程到技能工程的转变大多数人用 Claude Code 的方式是打开终端输入一段自然语言描述等它执行。这种方式在简单任务上没问题但一旦任务涉及多个步骤、多个文件、多个验证环节问题就来了。你写的提示词再详细agent 在执行过程中也可能因为上下文丢失、优先级混乱、验证缺失而跑偏。superpowers 的做法是把“提示词”升级成“技能”。一个 skill 不是一段静态的文本而是一个结构化的定义包含几个关键要素触发条件什么情况下应该激活这个 skill。比如“当任务涉及修改现有测试文件时”或者“当需要新增依赖时”。执行流程分步骤的操作序列每一步都有明确的输入和预期输出。约束规则哪些事情绝对不能做哪些事情必须先确认。比如“不允许直接修改生产环境配置文件”。验证标准怎么判断这一步做完了、做对了。比如“所有现有测试必须通过”或者“新增代码的行覆盖率不低于 80%”。回退策略如果验证失败应该怎么处理。是重试、回退到上一个稳定状态还是上报给人类。这种结构化的好处是agent 在执行时有了明确的“轨道”不会因为上下文窗口里的信息太多而迷失方向。同时因为每个 skill 都是独立的你可以根据项目需要组合不同的 skill形成一套适合自己团队的协作流程。2.2 为什么选择 Claude Code 和 Codex CLI 作为载体这套框架目前主要围绕 Claude Code 和 Codex CLI 两个工具展开这不是偶然的。这两个工具的共同特点是它们都是终端原生的 agent能够直接访问文件系统、执行 shell 命令、读取命令输出。这意味着 agent 不仅能“说”还能“做”而且做的结果能被立即验证。相比之下那些只在编辑器里做代码补全的工具虽然也能提升效率但它们的能力边界被限制在“生成文本”这个层面。你没法让一个补全工具去跑测试、看日志、根据报错调整方案。而 Claude Code 和 Codex CLI 可以形成一个完整的闭环读代码 → 改代码 → 跑测试 → 看结果 → 再改。superpowers 要做的就是让这个闭环更可控、更可重复。另一个原因是这两个工具都支持通过配置文件和环境变量来定制行为。Claude Code 有CLAUDE.md这样的项目级指令文件Codex CLI 也有类似的配置机制。superpowers 利用这些机制把技能定义注入到 agent 的运行时环境中让 agent 在执行任务时自动加载相关的 skill而不需要你每次手动输入。2.3 核心设计原则约束比自由更重要这套框架最反直觉的一点是它花了大量精力在“限制 agent 能做什么”上而不是“让 agent 能做更多”。这跟很多人的直觉相反——大家通常觉得给 AI 的自由度越高它就越能发挥创造力。但在实际工程场景里创造力往往不是瓶颈稳定性才是。我举个例子。你让 Claude Code 帮你重构一个函数如果没有约束它可能会顺手把旁边的变量名也改了把 import 顺序也调整了甚至把不相关的注释也删了。这些改动单独看可能都没问题但合在一起就可能导致代码审查时难以定位真正的变更点或者引入意料之外的副作用。superpowers 的做法是在 skill 里明确规定“只修改目标函数体内的代码不触碰函数签名、不调整 import、不删除任何注释”。这样 agent 的行为就变得可预测了。这种“约束优先”的设计思路在 agentic skills framework 里是一个关键的分水岭。它意味着你不是在“使用”一个 AI 工具而是在“管理”一个执行者。管理的关键不是给它多少自由而是给它多清晰的边界。3. 核心机制拆解技能定义、加载与执行3.1 技能定义的结构与写法一个典型的 skill 定义通常是一个 Markdown 文件或者 YAML 文件放在项目的特定目录下比如.superpowers/skills/。它的结构大致如下name: refactor-function trigger: 当任务涉及重构单个函数且不改变其外部行为时 steps: - 读取目标函数及其所有调用点 - 确认函数签名和返回值类型 - 在函数体内进行重构保持输入输出不变 - 运行相关测试确认全部通过 constraints: - 不修改函数名、参数列表、返回值类型 - 不修改函数外的任何代码 - 不删除或修改现有注释 validation: - 所有调用点编译通过 - 相关测试用例全部通过 - 代码差异仅限目标函数体内 fallback: 如果测试失败回退到重构前的版本并报告失败原因这个定义里trigger决定了什么时候加载这个 skill。steps是执行流程constraints是硬性规则validation是完成标准fallback是失败处理。这五个部分缺一不可因为它们共同构成了一个完整的“任务契约”。写 skill 定义的时候有几个经验性的原则。第一trigger要尽量具体避免模糊匹配。比如“当任务涉及重构”就太宽泛了“当任务涉及重构单个函数且不改变其外部行为时”就明确得多。第二steps要按顺序排列每一步都应该是可验证的。如果某一步没法验证那它就不应该出现在 steps 里。第三constraints要写成“不做什么”而不是“尽量做什么”。因为 agent 对否定指令的执行力通常比肯定指令更强。3.2 技能加载机制怎么让 agent 知道该用哪个 skill技能加载有两种模式自动匹配和显式调用。自动匹配模式下agent 会根据当前任务的描述去匹配已注册的 skill 的trigger条件。比如你输入“帮我重构一下calculateTotal这个函数”agent 会扫描所有 skill 的 trigger发现refactor-function的 trigger 匹配上了就自动加载这个 skill 并按照它的流程执行。显式调用模式下你直接在指令里指定 skill 名称比如“用refactor-function这个 skill 来重构calculateTotal”。这种方式适合你对任务类型非常明确、不想让 agent 自己判断的情况。两种模式各有优劣。自动匹配更省心但依赖 trigger 写得足够准确显式调用更可控但需要你记住 skill 的名称和适用场景。实际使用中我通常会把两者结合起来日常任务用自动匹配关键任务用显式调用。加载机制的技术实现通常是通过在CLAUDE.md或 Codex CLI 的配置文件中注入一段“技能索引”告诉 agent 有哪些 skill 可用、各自的 trigger 是什么。当 agent 开始执行任务时它会先读这个索引然后根据任务描述决定加载哪个 skill。这个过程对用户是透明的你不需要手动干预。3.3 执行引擎skill 是怎么被一步步执行的当一个 skill 被加载后agent 会按照steps里的顺序逐步执行。每一步执行前agent 会检查当前状态是否满足该步骤的前置条件执行后会检查是否满足该步骤的验证标准。如果某一步验证失败agent 会根据fallback策略决定是重试、回退还是上报。这里有一个关键设计每一步的验证是独立的。也就是说即使前面的步骤都通过了如果某一步的验证失败整个 skill 的执行也会被中断。这看起来有点严格但正是这种严格保证了最终结果的可信度。我见过太多这样的情况agent 改完代码跑了一下测试看到没有报错就认为完成了但实际上测试根本没覆盖到修改的代码路径。有了独立的验证步骤这种问题就能被及时发现。执行过程中agent 会维护一个“执行日志”记录每一步的输入、输出、验证结果和耗时。这个日志在排查问题时非常有用。比如某个 skill 执行失败了你可以翻日志看到底是哪一步出了问题、当时的上下文是什么、agent 做了什么决策。这比事后猜测要高效得多。4. 实操落地从零搭建一套可用的技能框架4.1 环境准备与工具安装在开始搭建之前你需要先确保 Claude Code 和 Codex CLI 至少有一个能正常运行。这两个工具的安装方式略有不同但基本流程都是下载安装包 → 配置 API 密钥或登录账号 → 验证安装成功。对于 Claude Code安装完成后你可以在终端里输入claude命令如果能看到交互界面就说明安装成功了。Codex CLI 类似输入codex命令后如果能进入交互模式就没问题。如果你在 Ubuntu 上安装可能需要额外处理一些依赖库的问题比如确保libc版本符合要求。Mac 上安装通常更顺利因为系统环境比较统一。安装完成后建议先跑一个简单的任务测试一下比如让它“在当前目录下创建一个 hello.txt 文件并写入 Hello World”。这个任务足够简单能帮你快速确认 agent 的基本功能是否正常。4.2 项目初始化创建技能目录与配置文件在你的项目根目录下创建一个.superpowers目录里面再建一个skills子目录。这个目录结构是 superpowers 框架约定的agent 会自动去这里查找 skill 定义。然后在项目根目录下创建或修改CLAUDE.md文件如果用的是 Claude Code或者对应的 Codex CLI 配置文件。在这个文件里你需要添加一段技能索引告诉 agent 去哪里找 skill、有哪些 skill 可用。一个典型的索引配置如下## Skills 本项目使用 superpowers 技能框架。所有 skill 定义位于 .superpowers/skills/ 目录下。 可用 skill 列表 - refactor-function: 重构单个函数不改变外部行为 - add-test: 为指定函数或模块新增测试用例 - fix-bug: 根据报错信息定位并修复 bug - add-dependency: 新增项目依赖并更新配置文件这段配置的作用是让 agent 在启动时就知道有哪些 skill 可用。当它遇到匹配的任务时会自动去加载对应的 skill 定义文件。4.3 编写第一个 skill以“新增测试”为例我们以add-test这个 skill 为例完整走一遍编写流程。假设你的项目里有一个utils.py文件里面有一个parse_date函数你想让 agent 为它新增测试用例。首先在.superpowers/skills/目录下创建add-test.md文件内容如下name: add-test trigger: 当任务涉及为现有函数或模块新增测试用例时 steps: - 读取目标函数或模块的源代码 - 识别函数的输入参数、返回值类型和边界条件 - 检查项目中已有的测试文件和测试框架 - 按照项目现有的测试风格编写测试用例 - 运行新增的测试确认全部通过 constraints: - 不修改被测试的源代码 - 不删除或修改已有的测试用例 - 测试文件命名和目录结构遵循项目现有约定 validation: - 新增测试用例全部通过 - 测试覆盖了正常路径、边界条件和异常路径 - 代码风格与项目现有测试一致 fallback: 如果测试运行失败检查测试代码本身是否有误修正后重试如果连续三次失败报告失败原因并停止写完之后你可以直接在 Claude Code 里输入“用 add-test 这个 skill 为parse_date函数新增测试用例”。agent 会加载这个 skill按照 steps 逐步执行。执行过程中它会先读utils.py找到parse_date函数分析它的参数和返回值然后去项目里找现有的测试文件参考它们的写法来生成新的测试用例。这里有一个实操心得在 skill 的 steps 里加入“检查项目现有约定”这一步非常重要。因为不同的项目用的测试框架可能不一样有的是 pytest有的是 unittest有的是 jest。如果不检查现有约定agent 可能会用错框架导致测试跑不起来。我刚开始用的时候没注意这一点结果 agent 给一个 pytest 项目生成了 unittest 风格的测试虽然逻辑没错但跟项目风格完全不搭还得手动改。4.4 技能组合与流程编排单个 skill 能解决单一类型的问题但真实项目里的任务往往是复合的。比如“修复一个 bug 并补充测试”就涉及fix-bug和add-test两个 skill。superpowers 支持技能组合你可以在一个 skill 的 steps 里引用另一个 skill。比如你可以定义一个fix-bug-with-test的复合 skillname: fix-bug-with-test trigger: 当任务涉及修复 bug 且需要补充测试时 steps: - 调用 fix-bug skill 定位并修复 bug - 调用 add-test skill 为修复后的代码新增测试用例 - 运行完整测试套件确认没有引入回归 constraints: - 修复和测试必须针对同一个 bug - 不修改与 bug 无关的代码 validation: - bug 被修复且新增测试通过 - 完整测试套件全部通过 fallback: 如果完整测试套件失败回退到修复前的状态并报告失败原因这种组合方式让 skill 框架变得非常灵活。你可以根据项目的实际需要把基础 skill 组合成更复杂的流程。而且因为每个基础 skill 都是独立验证的组合后的流程也保持了可追溯性——如果最终结果有问题你可以逐层排查是哪个环节出了错。5. 常见问题与排查技巧实录5.1 技能不触发或触发错误这是最常见的问题。你明明定义了一个 skill但 agent 执行任务时没有加载它或者加载了错误的 skill。原因通常有几个trigger 写得太宽泛或太狭窄。太宽泛会导致误触发太狭窄会导致该触发的时候不触发。解决办法是先用几个典型任务测试 trigger 的匹配情况根据结果调整措辞。比如“当任务涉及修改代码时”就太宽泛了几乎任何任务都会匹配上“当任务涉及修改 Python 文件中第 42 行到第 58 行的代码时”又太狭窄稍微换个行号就不匹配了。比较合适的粒度是“当任务涉及重构单个函数且不改变其外部行为时”这种级别。skill 文件没有被正确索引。检查CLAUDE.md或 Codex CLI 配置文件里的技能索引是否包含了这个 skill 的名称和路径。如果索引里没有agent 根本不知道这个 skill 存在。skill 文件格式有误。YAML 对缩进和特殊字符很敏感一个多余的空格就可能导致解析失败。建议用 YAML 校验工具检查一下文件格式。5.2 执行过程中卡住或反复重试有时候 agent 会在某一步反复重试消耗大量 token 但就是不成功。这种情况通常是因为fallback策略没有定义清楚或者验证标准太严格导致 agent 永远达不到。我遇到过一个典型案例一个 skill 的验证标准是“所有测试通过”但项目里有一个已知的、跟当前任务无关的测试是失败的。agent 每次跑完测试都看到有失败就认为自己的任务没完成然后反复重试。解决办法是在验证标准里加上“排除已知失败的测试”或者“只运行与当前任务相关的测试”。这个经验告诉我验证标准必须考虑项目的实际状态不能假设项目是完美的。另一个常见原因是 agent 对某一步的理解有偏差导致它一直在用错误的方式执行。这时候可以检查执行日志看看 agent 在这一步的输入输出是什么然后调整 steps 里的描述让它更明确。5.3 技能之间的冲突与优先级当多个 skill 的 trigger 同时匹配一个任务时agent 需要决定加载哪个。如果没有明确的优先级规则它可能会随机选一个或者同时加载多个导致行为混乱。解决办法是在 skill 定义里加一个priority字段数值越小优先级越高。或者在CLAUDE.md里定义一个全局的优先级顺序。比如Skill 优先级从高到低 1. fix-bug 2. refactor-function 3. add-test 4. add-dependency这样当任务同时匹配多个 skill 时agent 会按照优先级选择最高的那个。如果确实需要同时使用多个 skill那就应该定义一个复合 skill而不是让 agent 自己组合。5.4 常见问题速查表问题现象可能原因排查方法解决措施skill 不触发trigger 不匹配或索引缺失检查 trigger 措辞和索引配置调整 trigger 或补充索引触发错误 skilltrigger 过于宽泛或优先级冲突查看执行日志确认加载了哪个 skill收窄 trigger 或设置优先级执行卡住fallback 缺失或验证标准过严检查执行日志中卡在哪一步补充 fallback 或放宽验证标准结果不符合预期constraints 不够明确对比执行前后的代码差异细化 constraints 描述token 消耗过大steps 过于冗长或反复重试统计各步骤的 token 消耗精简 steps 或优化 fallback6. 进阶技巧让技能框架真正融入日常开发6.1 技能版本管理与团队共享当你的 skill 数量多起来之后就需要考虑版本管理了。我的做法是把.superpowers/skills/目录纳入 Git 管理每个 skill 的修改都走正常的代码审查流程。这样有几个好处一是可以追溯每个 skill 的变更历史知道某个约束是什么时候加的、为什么加二是团队成员可以共享同一套 skill保证大家的 agent 行为一致三是新人加入时可以直接复用现有的 skill不需要从零摸索。如果团队规模比较大还可以考虑把 skill 拆分成“基础技能”和“项目技能”两层。基础技能是通用的比如add-test、fix-bug这种可以跨项目复用项目技能是针对特定项目的比如“按照本项目的 API 规范新增接口”。基础技能放在一个共享仓库里项目技能放在各自的项目仓库里通过符号链接或者包管理工具来引用。6.2 根据项目特点定制验证标准验证标准是 skill 框架里最需要根据项目特点定制的部分。不同的项目对“完成”的定义不一样。有的项目要求所有测试通过有的项目要求代码覆盖率不低于某个阈值有的项目要求通过 lint 检查有的项目要求性能指标不能退化。我的经验是验证标准应该分层必须通过的比如编译通过、核心测试通过和建议通过的比如覆盖率、lint。必须通过的标准放在validation里不通过就中断执行建议通过的标准放在constraints里不通过只警告不中断。这样既能保证基本质量又不会因为一些非关键问题导致 agent 反复重试。另外验证标准最好能自动化执行。比如“所有测试通过”可以通过运行pytest或npm test来验证“代码风格一致”可以通过运行eslint或black --check来验证。如果验证标准需要人工判断那它就不适合放在 skill 里应该作为人工审查的环节。6.3 与现有开发流程的集成superpowers 框架不是要取代现有的开发流程而是要融入其中。我的做法是把 skill 执行作为开发流程的一个前置环节在提交代码之前先用 agent 跑一遍相关的 skill确保代码符合基本质量要求然后再走正常的人工审查和 CI 流程。这样做的好处是人工审查可以更聚焦在架构设计、业务逻辑这些真正需要人类判断的地方而不是浪费在“这个函数有没有测试”“代码风格对不对”这些可以自动化检查的事情上。同时因为 skill 执行有完整的日志记录人工审查时也可以参考这些日志了解 agent 做了哪些改动、为什么这么改。还有一个技巧是把常用的 skill 组合封装成一条命令。比如你可以定义一个pre-commit的复合 skill包含“运行 lint”“运行测试”“检查代码差异”三个步骤。每次提交前跑一下这个 skill就能快速确认代码没有明显问题。这比手动跑一堆命令要高效得多。6.4 持续优化从执行日志中学习skill 框架的一个隐藏价值是它会产生大量的执行日志。这些日志记录了 agent 在每一步的决策和结果是优化 skill 定义的宝贵素材。我通常会定期翻看执行日志关注几个指标哪些步骤的失败率最高、哪些 skill 的 token 消耗最大、哪些约束经常被触发。失败率高的步骤说明描述不够清晰或者验证标准不合理需要调整token 消耗大的 skill 说明 steps 可能过于冗长需要精简经常被触发的约束说明这个约束可能太严格了需要考虑放宽或者拆分成更细的规则。这个过程有点像调参先定义一个初始版本然后根据实际运行数据不断调整直到 skill 的行为稳定且高效。我自己的经验是一个 skill 通常需要经过三到五轮调整才能达到比较理想的状态。第一轮是功能验证确保它能跑通第二轮是边界测试看看它在异常情况下表现如何第三轮是效率优化减少不必要的步骤和 token 消耗后面几轮就是根据实际使用中的反馈做微调了。7. 一些踩过的坑和真实体会刚开始用这套框架的时候我犯过一个很典型的错误把 skill 定义写得过于详细恨不得把每一步的代码都写进去。结果 agent 执行时反而变得很死板遇到稍微不同的情况就不知道变通了。后来我意识到skill 定义应该定义“做什么”和“不做什么”而不是“怎么做”。具体的实现方式应该留给 agent 根据实际情况判断。比如“为函数新增测试”这个 skill你只需要告诉它要覆盖正常路径、边界条件和异常路径不需要告诉它具体用哪个断言方法、怎么组织测试类。这些细节让 agent 自己决定就好。另一个坑是忽略了 skill 之间的依赖关系。有一次我定义了一个add-dependencyskill它会修改package.json并运行安装命令。但另一个fix-bugskill 在执行过程中也可能需要新增依赖而它并不知道add-dependency的存在结果就是它自己手动改了package.json但没有运行安装命令导致后续步骤全部失败。后来我在fix-bug的 steps 里加了一步“如果需要新增依赖调用 add-dependency skill”这个问题才解决。所以定义 skill 的时候一定要考虑它可能跟哪些其他 skill 产生交互提前把依赖关系理清楚。还有一个体会是不要试图用 skill 框架解决所有问题。有些任务就是适合人类直接做比如架构设计、技术选型、代码审查。skill 框架擅长的是那些重复性高、流程明确、验证标准清晰的任务。把不适合的任务硬塞进 skill 里只会增加维护成本降低整体效率。我现在的做法是只把那些我每周都要做、每次做法都差不多、做完之后能自动验证的任务写成 skill其他的还是手动处理。最后分享一个提高 skill 复用率的小技巧在写 skill 的时候尽量把项目相关的配置抽成参数。比如add-test这个 skill不要硬编码测试框架是 pytest 还是 jest而是定义一个test_framework参数让 agent 在执行时根据项目实际情况填充。这样同一个 skill 就能在不同项目之间复用了。参数化的程度越高skill 的通用性就越强维护成本也越低。