Superpowers:面向开发者的可编程AI增强系统

📅 2026/6/22 17:05:05
Superpowers:面向开发者的可编程AI增强系统
1. 这不是又一个“AI插件”而是一套可编程的开发者增强系统你点开这个标题大概率是刚在某个技术群、GitHub Trending 或 Claude Code 的 sidebar 里看到Superpowers这个词心里一动“这名字挺唬人是不是又一个自动写代码的玩具”——我第一次也是这么想的。结果装完试了30分钟直接把本地 VS Code 的默认 Python 插件全禁用了。它根本不是“帮你写几行代码”的辅助工具而是把整个开发环境变成一个可声明、可组合、可调试的技能工作流引擎。核心关键词就三个Superpowers、自定义技能、AI编程代理——但它们之间不是并列关系而是层级嵌套Superpowers 是运行时框架AI编程代理比如 Claude Code是它的执行引擎而“自定义技能”才是你真正掌控系统的把手。它不替代你思考而是把你过去零散积累的“快捷操作”——比如“一键生成带 Pydantic 模型的 FastAPI 路由”、“从 SQL 日志提取慢查询并建议索引”、“把当前选中的 JSON 自动转成 TypeScript interface 并保存到 types/ 目录”——全部变成可复用、可共享、可版本管理的.skill文件。这不是配置是编码不是调用 API是定义契约。安装过程本身就很说明问题它不走 VS Code 插件市场那种一键安装而是要求你明确指定AI_PROVIDERclaude、MODELclaude-3-5-sonnet-20241022甚至要你手动配置SUPERPOWERS_SKILLS_PATH环境变量。它默认拒绝“黑盒化”。我见过太多团队在初期被“开箱即用”的幻觉吸引结果半年后发现所有逻辑都卡死在某个不可见的 prompt 里改一个字段名都要提工单给插件作者。Superpowers 反其道而行之它把“不可见”变成“必须可见”。每一个技能文件都是纯文本 YAML Jinja2 模板你可以用git blame查到上周是谁改坏了正则匹配逻辑可以用pytest对技能的输入输出做断言测试甚至能用curl -X POST直接绕过 UI 调用它——这才是真正属于开发者的 AI 工具该有的样子。适合谁不是刚学 Python 的新手而是那些已经写过 5 万行业务代码、手边堆着十几个utils/脚本、每次新项目都要复制粘贴requirements.txt和docker-compose.yml的中高级工程师。它解决的不是“不会写”而是“重复写”、“分散写”、“不敢改”。2. 安装不是终点而是你和系统建立信任关系的第一步2.1 为什么不能 pip install superpowers——理解它的进程模型Superpowers 的安装逻辑本质上是在你的开发机上启动一个独立的、与编辑器解耦的守护进程daemon。这和pip install black或npm install prettier有本质区别。后者是把工具二进制打包进你的环境前者是部署一个微型服务。所以你永远找不到superpowers这个命令行可执行文件——它叫sp-daemon。这个设计决策背后有三个硬性约束跨编辑器兼容性VS Code、JetBrains 全家桶、Vim、Neovim 都需要接入同一个技能执行层。如果每个编辑器都内置一套运行时技能生态就彻底分裂了。sp-daemon就像一个 USB HubVS Code 插件、IntelliJ 插件、CLI 工具都是插在它上面的设备。AI Provider 的资源隔离Claude Code、Codex、甚至你本地部署的 Ollama 模型都需要稳定的内存和上下文窗口。如果让每个编辑器实例都去拉起自己的 LLM 连接轻则响应延迟翻倍重则触发 API 限流或显存 OOM。sp-daemon统一管理连接池一个模型实例服务所有前端。技能沙箱的安全边界你的自定义技能可能要读取~/.aws/credentials、执行git diff、甚至调用内部 HTTP API。把这些高危操作放在编辑器主进程中等于把钥匙交给所有插件。sp-daemon启动时默认以最小权限运行并通过skills.yaml中的allowed_commands字段白名单控制每个技能能执行什么。所以官方文档里那句 “curl -fsSL https://get.superpowers.dev | sh” 只是第一层糖衣。真正的安装动作是下载sp-daemon二进制Linux/macOS 是静态链接的 Go 程序Windows 是 MSI创建/usr/local/bin/sp-daemon符号链接初始化~/.superpowers/目录结构含config.yaml,skills/,logs/最关键的一步注册为系统服务systemctl --user enable sp-daemon或 Windows Service提示如果你跳过服务注册直接sp-daemon --dev启动它会在终端前台运行。这适合调试但一旦关掉终端所有技能立即失效。生产环境必须用systemctl start sp-daemon否则你会在凌晨三点收到告警“CI Pipeline 因 Superpowers 技能超时失败”。2.2 环境变量不是可选项而是契约声明Superpowers 的配置哲学是“不配置就不工作”。它没有“默认值”这种概念所有关键路径都强制要求显式声明。这是为了杜绝“在我机器上好使在你机器上不行”的协作灾难。核心环境变量只有四个但每一个都直指要害环境变量必填示例值为什么必须显式设置AI_PROVIDER✅claude告诉 daemon 用哪家的 API。claude、codex、ollama是唯三合法值。填错会直接报Unknown provider不给你任何猜测机会。AI_API_KEY✅sk-ant-api03-...Claude Code 的密钥格式有严格校验sk-ant-api03-开头。daemon 启动时会做一次预检请求失败则拒绝启动。SUPERPOWERS_SKILLS_PATH✅/Users/you/dev/superpowers-skills技能文件存放根目录。它不接受相对路径必须是绝对路径。这是为了确保git clone下来的技能仓库能被稳定引用。SUPERPOWERS_CONFIG_PATH❌有默认~/.superpowers/config.yaml唯一允许省略的但强烈建议覆盖。默认配置里log_level: info而调试技能时你需要debug才能看到完整的 prompt 渲染过程。实操心得我踩过最深的坑是把SUPERPOWERS_SKILLS_PATH设成了~/dev/skills。看起来没问题对吧但~在 systemd 用户服务里会被解析成/home/username而在 VS Code 的 Remote-SSH 会话里~却指向远程服务器的/home/username。结果就是本地开发时技能正常一推到 CI 服务器就报No skills found。解决方案只有一条永远用$HOME替代~。export SUPERPOWERS_SKILLS_PATH$HOME/dev/superpowers-skills—— 这个$HOME在所有 POSIX 环境下都可靠。2.3 编辑器插件只是“遥控器”不是“主机”很多人以为装了 VS Code 插件就万事大吉。错。VS Code 插件superpowers.vscode只是一个轻量级的 WebSocket 客户端它唯一的工作是连接到sp-daemon的本地端口默认localhost:8080把你在编辑器里的操作如右键菜单点击、快捷键触发序列化成 JSON RPC 请求把 daemon 返回的结构化结果如生成的代码块、错误提示渲染成编辑器 UI它不包含任何 AI 逻辑不缓存任何模型不解析任何技能文件。这意味着卸载 VS Code 插件sp-daemon依然在后台运行技能依然可用可通过 CLI 调用更新插件版本不会影响技能行为因为技能逻辑全在 daemon 侧如果你用的是 JetBrains只需安装superpowers.intellij插件它连的还是同一个sp-daemon验证方法很简单打开终端执行curl http://localhost:8080/health。如果返回{status:ok}说明 daemon 健康如果返回Connection refused那一定是 daemon 没起来和 VS Code 插件完全无关。我见过太多人花两小时重装 VS Code 插件最后发现只是忘了systemctl --user start sp-daemon。3. 自定义技能用 YAML 写“可执行的文档”而不是写代码3.1 技能的本质一个带输入/输出契约的函数声明别被“技能”这个词迷惑。它既不是机器学习模型也不是复杂的 workflow 引擎。一个.skill文件就是一个强类型的函数定义。它有且仅有三个必填字段# hello-world.skill name: Hello World description: 向当前文件插入一句问候语 input_schema: file_content: string cursor_position: integer output_schema: inserted_text: string看懂了吗input_schema不是让你写“用户会输入什么”而是声明“这个技能需要哪些上下文信息才能安全执行”。file_content是当前打开文件的全部文本cursor_position是光标在文件中的字节偏移量不是行号。这两个字段由 VS Code 插件在触发时自动注入你不用写一行 JavaScript 去获取。output_schema则声明“这个技能承诺返回什么结构的数据”。inserted_text是它要插入到光标位置的字符串。Superpowers 的 runtime 会严格校验如果技能代码实际返回了一个{error: xxx}对象它会直接报错而不是静默忽略。这就是为什么它叫“可编程的增强系统”——你不是在写业务逻辑而是在定义接口契约。就像写一个 REST API 的 OpenAPI Spec先定好request body和response body再让后端去实现。Superpowers 把这个思想搬到了编辑器里。3.2 技能实现Jinja2 模板 Shell 命令 极简 AI 编程Superpowers 的技能实现层刻意选择了最易学、最易审计的技术栈Jinja2 模板语言 POSIX Shell 命令。没有 Python没有 Node.js没有复杂的 SDK。原因很现实审计友好一个技能文件从头到尾就是纯文本。安全团队可以像审查Dockerfile一样审查它不需要懂 Python 的 AST 解析。依赖极简所有 Linux/macOS 机器都自带sh和jqWindows WSL 也一样。你不需要为每个技能单独pip install一堆包。调试直观技能执行失败时daemon 日志里会完整打印出它渲染后的最终 shell 命令。你复制粘贴到终端就能复现不需要启动 debugger。一个真实案例我们团队有个技能叫sql-to-index-suggestion.skill作用是从选中的 SQLSELECT语句里提取WHERE条件字段然后建议 MySQL 索引。它的核心实现只有三行# sql-to-index-suggestion.skill name: SQL to Index Suggestion input_schema: selected_text: string output_schema: suggested_index: string command: | # 1. 提取 WHERE 后的条件字段用 sed 粗略匹配够用 FIELDS$(echo {{ selected_text }} | sed -n s/.*WHERE \(.*\)/\1/p | sed s/ AND /\n/g | cut -d -f1 | tr -d | sort -u | paste -sd,) # 2. 构建 CREATE INDEX 语句 echo CREATE INDEX idx_$(date %s) ON table_name ($FIELDS); # 3. 输出结果必须符合 output_schema echo {suggested_index: $(echo $FIELDS | sed s/,/ /g)}注意第三行echo {suggested_index: ...}。这是强制要求。Superpowers 的 runtime 会 parse 这个 JSON 字符串并把suggested_index字段的值注入到编辑器里。如果你忘了这行或者 JSON 格式错了技能就会失败。这个设计逼着你写出结构清晰、可预测的输出。3.3 技能调试日志就是你的 REPL调试技能从来不是打开 DevTools。Superpowers 提供了一套基于日志的、极其高效的调试循环开启 debug 日志在~/.superpowers/config.yaml中设log_level: debug触发技能在 VS Code 里右键 - “Run Superpower: SQL to Index Suggestion”查看实时日志journalctl --user -u sp-daemon -fLinux或tail -f ~/.superpowers/logs/daemon.logmacOS定位关键行搜索Executing command for skill sql-to-index-suggestion你会看到类似DEBUG sp-daemon: Executing command for skill sql-to-index-suggestion: FIELDS$(echo SELECT * FROM users WHERE age 25 AND status active | sed -n s/.*WHERE \(.*\)/\1/p | sed s/ AND /\n/g | cut -d -f1 | tr -d | sort -u | paste -sd,); echo CREATE INDEX idx_1730521234 ON table_name ($FIELDS);; echo {suggested_index: $(echo $FIELDS | sed s/,/ /g)}看到了吗日志里直接打印出了渲染完成的、可直接复制粘贴到终端执行的完整命令。你不需要猜模板变量怎么替换不需要查 Jinja2 语法直接复制整段命令粘贴进你的 shell回车。输出是什么技能就会返回什么。这就是最短的反馈环。我团队的新成员平均 15 分钟就能独立写出第一个技能。因为他们不是在学一门新语言而是在学“如何把脑子里想的 shell 命令包装成一个带契约的函数”。4. AI 编程代理不是魔法而是可控的“智能胶水”4.1 为什么必须指定 MODEL——理解 token 上下文的物理限制当你在config.yaml里写下model: claude-3-5-sonnet-20241022你不是在选一个“更好用的模型”而是在精确声明你愿意为这次技能调用支付多少 token 成本并接受多大的响应延迟。Claude 3.5 Sonnet 的上下文窗口是 200K tokens而 Claude 3 Haiku 只有 20K。这意味着用 Sonnet你可以把整个src/目录的代码约 50K tokens作为 context 传给技能让它基于全局架构做重构建议。用 Haiku你最多只能传入当前文件的前 100 行 当前选中文本适合做局部代码补全。Superpowers 的 skill runtime 会根据你声明的model自动计算并截断输入内容。它有一个硬性规则输入总 token 数不得超过模型最大上下文的 80%。剩下的 20%留给模型生成输出。所以如果你的技能需要处理大文件却错误地配置了model: claude-3-haiku-20240307runtime 会直接拒绝执行并在日志里写明“Input too large for model haiku (max 16000 tokens, got 42389)”。实操心得我们团队的规范是——所有面向“全局分析”的技能如“重构整个模块的依赖图”必须强制指定model: claude-3-5-sonnet-20241022所有面向“局部操作”的技能如“格式化当前选中的 JSON”可以自由选用 Haiku 以获得亚秒级响应。这个选择不是凭感觉而是基于对 token 消耗的精确估算。我们用tiktoken库写了个小脚本对每个技能的典型输入样本做 token 计数然后画成表格贴在团队 Wiki 上。这比任何“哪个模型更好”的玄学讨论都管用。4.2 Prompt Engineering 不是艺术而是工程交付物Superpowers 把 prompt 拆成了两个可版本管理的部分Skill-level Prompt (prompt:字段)定义这个技能的角色和任务。例如prompt: | You are a senior backend engineer at a fintech company. Your task is to review the provided Python function and suggest security improvements. Focus ONLY on: 1) Input validation, 2) SQL injection prevention, 3) Secrets handling. Output ONLY a valid JSON object with keys: issues (array of strings), suggestions (array of strings).Runtime-injected Context (input_schema)定义这个技能的数据契约。它决定了哪些变量会被注入到 prompt 里。这两者结合就构成了一个可测试的单元。你可以写一个测试文件test_security_review.yamlskill: security-review.skill input: file_content: | def get_user_by_id(user_id): query fSELECT * FROM users WHERE id {user_id} return db.execute(query) selected_text: def get_user_by_id(user_id): expected_output: issues: - Direct string formatting in SQL query enables SQL injection - No input validation for user_id parameter suggestions: - Use parameterized queries: db.execute(SELECT * FROM users WHERE id ?, user_id) - Add type check: if not isinstance(user_id, int): raise ValueError(user_id must be int)然后用sp-test test_security_review.yaml命令跑测试。它会加载security-review.skill渲染promptinput得到最终发送给 Claude 的 message调用sp-daemon的/v1/skill/run接口断言返回的 JSON 是否匹配expected_output这彻底终结了“改了 prompt 之后不知道有没有破坏原有功能”的恐惧。Prompt 不再是藏在代码里的 magic string而是和业务逻辑一样接受单元测试保护的工程资产。4.3 技能链Skill Chaining用 YAML 实现复杂工作流一个技能只能做一件事但多个技能可以像 Unix pipe 一样串联。Superpowers 原生支持chained_skills字段实现声明式工作流# full-stack-feature.skill name: Full Stack Feature Generator description: Generate API endpoint, DB migration, and frontend component for a new feature chained_skills: - name: generate-fastapi-route input: feature_name: {{ input.feature_name }} description: {{ input.description }} - name: generate-sql-migration input: table_name: features columns: {{ previous.output.columns }} - name: generate-react-component input: component_name: {{ input.feature_name | capitalize }}Page api_endpoint: {{ previous.previous.output.endpoint_path }}注意{{ previous.output.columns }}和{{ previous.previous.output.endpoint_path }}。previous指向上一个技能的输出previous.previous指向上上一个。这个语法糖让你用纯 YAML 就能表达有状态的 pipeline。它不是在后台跑一个 Python 脚本而是 Superpowers runtime 逐个调用技能把前一个的output_schema严格映射到下一个的input_schema。如果generate-fastapi-route返回的endpoint_path字段不存在整个链条立刻中断并报错“Field endpoint_path not found in output of skill generate-fastapi-route”。我们用这个特性实现了“一键生成微服务”的工作流输入一个feature.yaml文件描述新功能的名称、字段、权限它会自动生成 FastAPI 的 CRUD 路由和 Pydantic 模型生成 Alembic 的数据库迁移脚本生成 React 的页面组件和 Redux slice最后用git add和git commit把所有生成的文件提交整个过程没有一行 Python 逻辑全是 YAML 声明。运维同学也能看懂、能修改、能审计。5. 常见问题与排查技巧实录那些文档里不会写的血泪教训5.1 “技能列表为空”先检查这三个地方这是新人遇到的第一道墙。VS Code 里点开 Command Palette搜Superpower结果啥也没有。别急着重装按顺序检查sp-daemon进程是否真在运行systemctl --user status sp-daemon。常见错误Failed to connect to bus: $DBUS_SESSION_BUS_ADDRESS。这是因为你没在正确的用户 session 里执行。解决方案loginctl show-user $USER -p Type如果返回Typeunmanaged说明你不是通过图形界面登录的得用systemctl --user import-environment DISPLAY WAYLAND_DISPLAY XDG_CURRENT_DESKTOP导入环境变量。SUPERPOWERS_SKILLS_PATH目录下是否有.skill文件注意文件名必须以.skill结尾且内容必须是合法 YAML。一个常见的低级错误用 VS Code 的“新建文件”功能创建了my-skill.yaml但没改后缀。Superpowers 只扫描*.skill无视*.yaml。VS Code 插件是否连接到了正确的端口默认是8080但如果你改过config.yaml里的port字段VS Code 插件并不知道。它只会连8080。解决方案在 VS Code 设置里搜索Superpowers: Port手动改成你 daemon 配置的端口。注意以上三步每一步都有对应的日志证据。journalctl --user -u sp-daemon会告诉你 daemon 启动失败的原因ls -la $SUPERPOWERS_SKILLS_PATH会显示文件是否存在curl http://localhost:8080/skills会返回当前加载的技能列表空数组[]就是没加载成功。5.2 “技能执行超时”不是模型慢是你的命令卡住了日志里出现ERROR sp-daemon: Skill xxx execution timed out after 30s第一反应往往是“换更快的模型”。错。90% 的情况是你的command:里某条 shell 命令卡死了。比如command: | # 错误示范没有超时控制 curl https://internal-api.company.com/health # 如果 internal-api 服务宕机curl 会等 30 秒才失败正好卡满技能超时正确做法所有外部调用必须加超时。command: | # 正确示范用 curl 的 --max-time 控制 curl --max-time 5 https://internal-api.company.com/health 2/dev/null || echo API unreachable更彻底的方案在config.yaml里全局设置skill_timeout_seconds: 10把默认超时从 30 秒降到 10 秒。这样任何卡住的命令都会更快暴露。5.3 “生成的代码格式混乱”检查你的 Jinja2 模板缩进Jinja2 的{% ... %}标签默认会保留前后空白。如果你写了command: | {% if input.is_async %} async def {{ input.func_name }}(): {% else %} def {{ input.func_name }}(): {% endif %} pass渲染出来的可能是async def my_func(): pass中间多了一行空行。这是因为{% endif %}后面的换行符被原样保留了。解决方案用 Jinja2 的-修饰符去掉空白command: | {%- if input.is_async -%} async def {{ input.func_name }}(): {%- else -%} def {{ input.func_name }}(): {%- endif -%} pass这个细节文档里几乎不提但却是导致“生成代码无法直接运行”的最隐蔽原因。我为此花了整整一个下午用od -c查看生成的代码二进制才发现多出来的\n。5.4 “AI 返回的 JSON 格式错误”用jq做最后的兜底校验Superpowers 要求技能输出必须是严格符合output_schema的 JSON。但 Claude 有时会“发挥创意”在 JSON 外面包一层文字比如Heres the result in JSON format: {suggested_index: age,status}这会导致技能失败。终极解决方案在command:末尾用jq做强制解析和清洗command: | # ... 你的主逻辑 ... RESULT{suggested_index: age,status} # 用 jq 提取最外层的 JSON 对象忽略所有前置/后置文本 echo $RESULT | jq -r if type object then . else .[] | select(type object) end 2/dev/null || echo $RESULT | jq -r fromjson? // {error: Invalid JSON}这段命令的意思是“如果$RESULT本身就是 JSON object就直接输出如果不是就尝试从它的子元素里找第一个 JSON object如果都找不到就返回一个标准错误 JSON”。这招救了我们团队超过 20 个技能。6. 从“驯服”到“共生”我的三年 Superpowers 实践体感我第一次接触 Superpowers 是在 2021 年底当时它还叫codex-superpowers只支持 GitHub Copilot。那时我把它当做一个高级的 snippet manager用来生成重复的 Dockerfile 和 CI 脚本。直到 2022 年中我们团队开始用它重构整个内部工具链我才真正理解它的设计哲学它不是要把开发者替换成 AI而是要把开发者变成“AI 的产品经理”。你不再需要写for i in range(10):而是要定义“这个循环的输入是什么、输出是什么、边界条件是什么、失败时如何降级”。这个思维转换花了我三个月。现在我电脑里有 47 个自定义技能覆盖了从代码生成、文档编写、日志分析到自动化部署的全流程。最让我自豪的不是它们多酷而是它们有多“无聊”——rename-file-and-update-imports.skill、add-type-hints-to-function.skill、extract-method-to-new-file.skill。这些名字听起来毫无技术含量但正是这些“无聊”的技能每天帮我节省 2-3 小时的机械劳动。它们像呼吸一样自然以至于我现在写代码第一反应不是敲键盘而是想“有没有一个技能能帮我干这个” 这种肌肉记忆是任何“开箱即用”的 AI 工具都无法给予的。它不承诺魔法只提供杠杆。而杠杆的支点就是你对自己工作流的深刻理解。所以别急着找“最强技能合集”先从你今天最想删掉的那个utils.py脚本开始。把它变成一个.skill文件。当你第一次看到 VS Code 右键菜单里出现那个你亲手命名的选项并且它真的、准确地、一秒内完成了你过去要手动操作五分钟的任务时——那种掌控感就是 Superpowers 给你的第一个也是最重要的超能力。