
1. 从提示词堆砌到能力封装Superpowers 到底在解决什么问题如果你最近在折腾 AI 协作工具大概率已经被skill这个词刷屏了。从 codex skill 到 agent skill从 spring ai skill 到各种 skill 插件、skill 脚本、skill 技能库热词列表里几乎每隔几天就冒出一个新组合。但真正让人困惑的不是skill 是什么而是——为什么我写了一堆提示词换一个项目、换一个模型、换一个同事效果就完全不一样了这个问题的本质是提示词prompt和技能skill根本不是一回事。提示词是一次性对话技能是可复用的能力单元。你写一段帮我重构这个老系统的提示词它只对当前这段代码、当前这个上下文有效但如果你把老系统重构这件事拆成一套可编程的协作协议——输入什么、输出什么、中间经过哪些检查点、失败怎么回滚——那它就变成了一个 skill可以被反复调用、被不同 agent 复用、被工程化地管理。Superpowers 这个项目标题里的可编程 AI 协作协议和Skill 工程化实践说的就是这件事把 AI 协作从聊天升级成协议把零散的提示词升级成可编程的技能资产。它不是一个具体的工具而是一套思路——用类似 DSL领域特定语言的方式描述协作流程让 AI 的能力像函数一样被定义、被组合、被测试。这篇文章适合三类人看一是已经在用 codex、opencode、spring ai 这类工具但感觉每次都要重新调教的开发者二是想把团队里的 AI 使用经验沉淀下来、而不是散落在各人聊天记录里的技术负责人三是刚接触 agent skill、还在纠结skill 和 agent 到底有什么区别的新手。我会从协议设计、Skill 工程化、DSL 表达、老系统重构实战、避坑经验几个角度把这件事讲透。先说一个反直觉的结论大多数团队做 AI 协作失败不是因为模型不够强而是因为协作协议没定义清楚。你让 AI重构这个模块它不知道你的代码规范、不知道你的测试覆盖率要求、不知道哪些接口不能动。这些信息如果每次都靠人临时补充那 AI 就永远只是个高级自动补全。Superpowers 的思路就是把这些隐性知识显性化、协议化、可编程化。2. 可编程协作协议的底层逻辑为什么协议比提示词更靠谱2.1 提示词的三个致命缺陷先说说为什么单纯堆提示词走不远。我踩过的坑里最典型的有三个第一上下文漂移。你写了一段很长的系统提示词前几轮对话效果很好但聊到第十轮AI 开始忘记前面的约束。这不是模型的问题而是提示词本质上是软约束它没有强制力。你没法像写代码那样用assert去校验 AI 有没有遵守规则。第二不可组合。你有一个代码审查的提示词一个单元测试生成的提示词想把它俩串起来做审查后自动补测试只能靠人手动复制粘贴。提示词之间没有接口没有输入输出契约组合起来全靠人肉。第三不可测试。你怎么知道你的提示词改了一版之后效果是变好了还是变差了没有回归测试没有基准用例全靠感觉。这在个人玩票时没问题但在团队协作里是灾难。2.2 协议化带来的三个改变Superpowers 强调的可编程协作协议本质上是给 AI 协作加上三层结构层次提示词模式协议模式定义自然语言描述结构化 DSL有明确字段执行单轮对话多阶段流程有检查点验证人工目测自动化断言 回归用例定义层用 DSL 把做什么、输入什么、输出什么、约束是什么写清楚。比如一个老系统重构的 skill它的定义可能长这样skill: legacy-refactor version: 1.2 input: - source_path: string - target_pattern: string - forbidden_apis: list output: - refactored_files: list - test_coverage_delta: float - risk_report: markdown constraints: - no_breaking_change: true - min_coverage: 0.8 stages: - analyze - plan - refactor - verify这不是我瞎编的格式而是这类工程化实践里最常见的表达方式——用 YAML 或 JSON 描述 skill 的契约。你可能会问为什么不直接用自然语言因为自然语言没法被程序解析没法做静态检查没法在 CI 里跑。执行层协议规定了阶段stage每个阶段有明确的进入条件和退出条件。比如analyze阶段必须产出依赖图plan阶段必须列出所有受影响的调用方refactor阶段每改一个文件就要跑一次测试。这些检查点是硬性的AI 不能跳过。验证层这是最容易被忽略但最重要的一层。协议化之后你可以为每个 skill 写回归用例——给定一组输入期望输出是什么。改了一版 skill跑一遍用例就知道有没有退化。这就是工程化和玩票的分水岭。2.3 一个生活化类比把提示词想象成口头交代任务把协议想象成书面 SOP。你让新同事把那个报告弄一下他大概率弄不对但你给他一份 SOP写明第一步拉数据、第二步核对口径、第三步按模板出图、第四步找张三复核他就能稳定产出。AI 也是一样协议就是给 AI 的 SOP而且是机器可读、可校验的 SOP。提示不要一上来就追求完美的协议。我建议从一个 skill 只做一件事开始先把最痛的那个场景协议化跑通了再扩展。贪多必翻车。3. Skill 工程化的四个关键动作从能用到可维护3.1 动作一把隐性知识显性化Skill 工程化最难的不是写代码而是把老员工脑子里的经验挖出来。比如你们团队做代码审查老员工一眼就能看出这个循环里查数据库会有性能问题但新人看不出来。这条经验如果不写进 skillAI 也学不会。我的做法是拿一个真实的历史 PR让老员工边审边说出声把每一句这里不对背后的判断依据记下来。比如这里不对背后的依据是循环内 IO 操作N1 查询风险。把这些依据整理成规则写进 skill 的 constraints 里。这个过程很枯燥但价值极高。因为一旦显性化它就不再依赖某个人的记忆而是变成了团队资产。3.2 动作二给 skill 设计清晰的边界一个常见的错误是一个 skill 管所有事。我见过有人写了一个万能代码助手skill结果它既想审查代码、又想生成测试、还想写文档最后哪个都做不好。正确的做法是单一职责。一个 skill 只解决一类问题边界清晰。比如code-review-skill只做审查输出问题列表不改代码test-gen-skill只生成测试输入是函数签名和覆盖率要求refactor-skill只做重构输入是目标模式输出是改动后的文件这样设计的好处是每个 skill 可以独立测试、独立迭代、独立复用。你想做审查补测试就把两个 skill 串起来而不是写一个巨无霸。3.3 动作三建立 skill 的版本管理Skill 是资产资产就要有版本。我建议用 Git 管理 skill 定义文件每次修改都走 PR 流程。为什么因为 skill 的改动会直接影响 AI 的输出质量改错了可能导致批量事故。版本管理还要配合变更日志。每次改 skill写清楚改了什么、为什么改、影响范围是什么。比如v1.2 把 min_coverage 从 0.7 提到 0.8因为上个季度线上事故都出在覆盖不足的模块。3.4 动作四给 skill 配回归测试这是工程化的核心。没有回归测试的 skill改起来就是赌博。回归测试怎么做准备一组输入-期望输出的用例每次改 skill 就跑一遍。对于代码类 skill用例可以是给定一段有 N1 问题的代码期望输出里包含 N1 警告。对于文档类 skill用例可以是给定一份需求文档期望输出的摘要包含三个关键点。# 一个简化的 skill 回归测试示例 def test_refactor_skill_detects_n_plus_one(): input_code for user in users: orders db.query(fSELECT * FROM orders WHERE user_id{user.id}) result run_skill(refactor-skill, input_code) assert N1 in result.risk_report assert result.test_coverage_delta 0.0这段代码不是让你照抄而是说明思路skill 的输出要可断言。如果输出是一大段自然语言没法断言那说明你的 skill 设计得还不够结构化。4. DSL 在 AI 协作里的角色为什么需要一门给 AI 看的语言4.1 DSL 不是噱头是刚需很多人一听DSL就觉得是过度设计觉得用自然语言写提示词就够了。但当你真正管理几十个 skill、上百个协作流程时自然语言的歧义性会把你逼疯。举个例子你写重构这个模块保持接口不变。AI 可能理解成函数签名不变也可能理解成HTTP 接口不变还可能理解成数据库表结构不变。三种理解对应三种完全不同的改法。DSL 的作用就是消除这种歧义——interface_stable: [function_signature, http_api]写得清清楚楚。4.2 一个可落地的 DSL 设计思路设计 DSL 不需要多复杂关键是覆盖你实际需要的维度。我总结了一个最小可用的 DSL 骨架包含五个部分元信息skill 名称、版本、作者、适用场景。输入契约需要哪些参数每个参数的类型和约束。输出契约产出什么格式是什么怎么校验。执行阶段分几步走每步的进入/退出条件。约束与护栏哪些事绝对不能做哪些指标必须达标。meta: name: legacy-refactor version: 1.2 scope: Java/Spring 老系统模块级重构 input: source_path: {type: path, required: true} target_pattern: {type: string, enum: [layered, hexagonal, ddd]} forbidden_apis: {type: list, default: []} output: refactored_files: {type: list, format: file_path} risk_report: {type: markdown, sections: [breaking, perf, security]} coverage_delta: {type: float, min: 0.0} stages: - name: analyze exit_when: dependency_graph_generated true - name: plan exit_when: affected_callers_listed true - name: refactor exit_when: all_tests_pass true - name: verify exit_when: coverage_delta 0.0 guardrails: - 禁止修改 public API 签名 - 禁止删除已有测试用例 - 单次改动文件数不超过 20这份 DSL 的价值在于它可以被程序解析可以在 CI 里做静态检查可以在执行时做动态校验。比如单次改动文件数不超过 20这条护栏如果 AI 想改 50 个文件协议层直接拦截要求它拆成多次。4.3 DSL 和自然语言的分工有人会问那自然语言还有用吗当然有用。DSL 负责骨架自然语言负责血肉。比如risk_report的具体内容还是让 AI 用自然语言写但它的结构必须有 breaking、perf、security 三节由 DSL 规定。这种分工的好处是结构化的部分可校验非结构化的部分保留灵活性。就像写代码函数签名是强类型的函数体内部可以自由发挥。注意DSL 设计要克制。我见过有人设计了一门图灵完备的 DSL结果没人会用。记住DSL 的目的是降低协作成本不是炫技。能用 YAML 解决就别上自定义语法。5. 老系统重构实战把 Superpowers 思路落到真实项目5.1 为什么老系统重构是 skill 的最佳试炼场热词里有一条superpowers 如何做老系统重构这其实点到了要害。老系统重构是 AI 协作里最难的场景之一因为它同时具备三个特征上下文大、约束多、风险高。上下文大一个跑了五年的系统代码几十万行依赖关系盘根错节AI 的上下文窗口根本装不下。约束多不能停机、不能改对外接口、不能动核心业务逻辑、测试覆盖率不能降。风险高改错一行可能影响几百万营收。正因为难它才最能体现协议化协作的价值。纯靠提示词你根本搞不定但用 skill 工程化的思路把大问题拆成小问题把隐性约束显性化就有解了。5.2 分阶段拆解一个真实的重构流程我把老系统重构拆成五个阶段每个阶段对应一个 skill阶段一依赖分析。输入是代码库路径输出是模块依赖图、循环依赖列表、高风险模块清单。这个阶段不改任何代码只做分析。为什么要单独成阶段因为分析结果要给人看、要评审确认无误才能进入下一步。阶段二重构规划。输入是依赖图输出是重构顺序、每步的预期影响、回滚方案。这个阶段的核心是排序——先改哪些、后改哪些。原则是从叶子节点往根节点改先改没有下游依赖的模块降低风险。阶段三单模块重构。输入是单个模块输出是重构后的代码 测试。这个阶段是真正动手的但范围被严格限制在单模块内。为什么要限制因为单模块改动可控出问题好回滚。阶段四集成验证。输入是重构后的多个模块输出是集成测试报告。这个阶段跑全量测试验证模块间协作没问题。阶段五灰度上线。输入是验证通过的代码输出是灰度计划。这个阶段其实已经超出 AI 的能力范围但 skill 可以生成灰度方案供人参考。5.3 每个阶段的护栏设计护栏是 skill 工程化的精髓。以单模块重构为例我设计的护栏包括改动文件数上限单次不超过 20 个文件禁止修改的 API 列表从配置里读硬性拦截测试覆盖率下限重构后覆盖率不能低于重构前回滚点每改 5 个文件打一个 git tag这些护栏不是摆设而是要在执行时真正生效。比如 AI 想改第 21 个文件协议层直接报错要求它先提交当前批次。# 护栏校验的伪代码逻辑 if [ $(git diff --name-only | wc -l) -gt 20 ]; then echo ERROR: 单次改动超过 20 个文件请拆分批次 exit 1 fi for api in $(cat forbidden_apis.txt); do if git diff | grep -q $api; then echo ERROR: 检测到禁止修改的 API: $api exit 1 fi done5.4 实测中的意外情况我在实际项目里踩过的坑分享几个坑一AI 会自作聪明地优化无关代码。你让它重构 A 模块它顺手把 B 模块的一个看起来不好的写法也改了。这在护栏里要明确禁止——只改指定范围内的代码。坑二依赖图不准。静态分析工具给出的依赖图往往漏掉反射调用、动态代理、配置文件里的依赖。所以依赖分析阶段的输出必须人工复核不能全信 AI。坑三测试用例本身有问题。老系统的测试用例可能写得很烂甚至断言是错的。重构后测试挂了不一定是重构错了可能是测试本身有问题。这时候要人工判断不能盲目回滚。坑四上下文丢失。分阶段执行时后一阶段可能忘记前一阶段的结论。解决办法是把前一阶段的输出作为后一阶段的输入显式传递而不是靠 AI 记忆。6. Skill 与 Agent 的边界别把两件事混为一谈6.1 一个常见的概念混淆热词里反复出现skill 和 agent 的区别agent 和 skill 的区别说明这是很多人的困惑点。我用一句话说清楚Agent 是谁来做Skill 是怎么做。Agent 是一个有自主性的执行者它能感知环境、做决策、调用工具。Skill 是一个被封装的能力单元它定义了给定输入产出什么输出。Agent 可以调用多个 SkillSkill 本身不关心是谁在调用它。打个比方Agent 是员工Skill 是操作手册。员工可以翻手册干活手册不知道也不关心是张三还是李四在翻。6.2 为什么这个区分很重要因为很多团队把两者混在一起设计结果做出来的东西既不像 Agent 也不像 Skill。比如有人写了一个自动修 bug 的 agent里面塞了几百行提示词既做决策又做执行最后没法测试、没法复用、没法维护。正确的做法是分层层职责例子Agent 层决策、调度、异常处理决定先审查还是先测试Skill 层单一能力封装代码审查、测试生成工具层底层操作读写文件、跑命令Agent 层可以很薄薄到只做读任务、选 skill、传参数、收结果。Skill 层要厚每个 skill 都要有完整的契约、护栏、测试。6.3 一个 Agent 调度多个 Skill 的例子假设你要做一个自动处理 issue的 Agent它可能这样调度读 issue 内容判断类型bug / feature / question如果是 bug调用repro-skill尝试复现复现成功调用locate-skill定位问题代码定位成功调用fix-skill生成修复修复完成调用test-skill补测试全部通过调用pr-skill生成 PR 描述每个 skill 都是独立的、可测试的、可替换的。Agent 只负责编排。这样设计你想换掉定位这个 skill不影响其他部分你想给修复skill 加个护栏也不影响 Agent 逻辑。提示如果你现在的 AI 协作代码里决策逻辑和执行逻辑混在一起那大概率是没分清 Agent 和 Skill。建议先做一次拆分把执行逻辑抽成独立 skill。7. 避坑指南Skill 工程化里最容易翻车的五个地方7.1 坑一Skill 粒度过细或过粗粒度过细一个 skill 只做读文件另一个只做写文件结果调度逻辑比业务逻辑还复杂。粒度过粗一个 skill 管从需求到上线全流程结果没法测试、没法复用。我的经验是一个 skill 对应一个可独立验证的产出。比如生成测试是一个 skill因为它的产出测试文件可以独立验证读文件不是一个 skill因为它没有独立价值。7.2 坑二护栏形同虚设很多团队写了护栏但执行时不检查。比如规定了不能改 public API但 AI 改了也没人拦。护栏必须在执行时强制校验不能只写在文档里。实现方式可以是在 skill 执行前后加 hookhook 里跑校验脚本。校验不过就中断让人介入。7.3 坑三没有回滚机制AI 改代码改错了怎么办必须有回滚机制。最简单的是 git tag每完成一个阶段打一个 tag出问题直接 reset。复杂一点的可以做影子环境改动先在影子环境验证通过了再合并。我强烈建议任何会修改代码的 skill都必须有回滚点。这是底线。7.4 坑四忽略成本AI 调用是有成本的尤其是大上下文场景。一个老系统重构如果每次都把整个代码库塞进上下文成本会高到离谱。解决办法是按需加载——分析阶段只加载依赖图重构阶段只加载单模块代码。7.5 坑五把 skill 当成一次性脚本Skill 是资产要长期维护。我见过有人写了个 skill 跑通一次就扔了下次遇到类似场景又重写一遍。这是巨大的浪费。正确的做法是每个 skill 都进版本库都写文档都配测试都有人负责维护。8. 从个人实践到团队资产Skill 库的运营思路8.1 建立 skill 库的三个阶段阶段一个人积累。先让团队里最活跃的几个人各自写 skill解决自己最痛的问题。这个阶段不追求规范追求跑通。阶段二团队共享。定期做 skill 分享会把好用的 skill 推广出去。同时开始制定规范——命名规范、目录结构、文档模板。阶段三平台化。建一个内部的 skill 仓库支持搜索、版本管理、依赖管理。新人入职第一件事就是学怎么用 skill 库。8.2 Skill 的命名与分类命名要见名知意。我推荐领域-动作-对象的格式比如java-refactor-module、python-gen-test、doc-summarize-pr。分类可以按领域前端/后端/数据、按动作分析/生成/验证、按场景开发/测试/运维。8.3 如何评估一个 skill 的质量我用的评估维度有四个可测试性有没有回归用例用例覆盖了多少场景可复用性被多少个不同项目调用过稳定性最近 30 天的失败率维护性有没有明确的负责人最近有没有更新一个 skill 如果三个月没人维护、失败率还高就该考虑下线或重写。8.4 一个真实的运营数据我在团队里推这套东西大概半年从最初的 3 个 skill 涨到 40 多个其中真正被高频使用的有 12 个。这 12 个 skill 覆盖了团队 70% 的日常 AI 协作场景。剩下的 28 个里有一半是写了但没人用后来被清理掉了。这个数据说明什么Skill 不在多在精。与其写 100 个没人用的 skill不如把 10 个核心 skill 打磨到极致。9. 我个人的几条实操心得最后分享几条踩坑踩出来的经验都是文档里不会写的。第一条先手动跑通再协议化。不要一上来就设计 DSL、写护栏。先用自然语言把流程跑通跑个三五次摸清楚哪些步骤是必须的、哪些约束是真正重要的再把它协议化。顺序反了你会设计出一堆用不上的字段。第二条护栏要少而硬。护栏不是越多越好。我见过有人写了 50 条护栏结果 AI 每做一步都被拦效率极低。真正重要的护栏就那么几条——不能改的 API、不能降的覆盖率、不能超的文件数。其他的用建议而不是强制。第三条给 AI 留求助的口子。协议再完善也会遇到 AI 搞不定的情况。这时候要让它能举手——输出我需要人工介入原因是 XXX而不是硬着头皮瞎改。我在每个 skill 里都加了escalate机制AI 觉得不确定就升级给人。第四条定期清理 skill 库。Skill 会腐烂。三个月不用的、失败率高的、被新 skill 替代的该删就删。库越干净维护成本越低。第五条别追求全自动。老系统重构这种高风险场景全自动是危险的。我的做法是AI 做 80%人做 20%——AI 负责分析、生成、验证人负责关键决策和最终把关。这个比例可以根据场景调整但永远不要追求 100% 自动。这套东西说到底核心就一句话把 AI 协作当成软件工程来做而不是当成聊天。有契约、有版本、有测试、有护栏、有回滚它才能从玩具变成生产力。至于 DSL 用什么语法、skill 怎么分类这些都是细节可以慢慢磨。方向对了剩下的都是时间问题。