首页
/ Claude Code `run-<unit>` Skill 生成模板精读:为任何项目编写"Agent 可直接驱动"的运行技能

Claude Code `run-<unit>` Skill 生成模板精读:为任何项目编写"Agent 可直接驱动"的运行技能

2026-09-08 23:57:42作者:龚格成

导读

本文聚焦 run-skill-generator 中提供的 run-<unit-name> 技能模板(template.md),并辅以同目录下的生成器规则(SKILL.md)、六个项目类型示例(examples/)以及上层 /run 技能的兜底逻辑进行印证。该模板定义了 Claude Code 中"项目专属运行技能"的标准写法——让未来任意 Agent 能在全新 Linux 容器里把一个项目构建起来、启动它、并真正驱动它(点击按钮、发请求、按键盘),而非仅仅"读一份 README"。读完本文,你将掌握这套模板的每个字段与每个章节的设计意图、frontmatter 的自动加载约定、driver 与 SKILL.md 的协作边界,以及如何针对 CLI、Web、桌面 GUI、TUI、服务器、库六类项目落地成可直接复用的技能目录。


1. 模板是什么:一份"交付物是代码 + 文档"的成文骨架

在 Claude Code 的技能体系里,一个可运行的"run-* 技能"包含两部分、放在同一目录下:

<unit>/.claude/skills/run-<unit-name>/
  SKILL.md      <- 面向 Agent 的说明,SHORT,指向 driver
  driver.mjs    <- (或 driver.py、smoke.sh……或没有:Web 应用直接
                   用 chromium-cli,其 heredoc 内联在 SKILL.md 里就是脚本)

配套的 run-skill-generator/SKILL.md 把这条原则概括为一句:"the driver is the deliverable. The SKILL.md is its man page"(driver 才是交付物,SKILL.md 只是它的手册)。纯 markdown 文件无法点击按钮,因此只要应用有任何交互面(GUI、TUI、常驻服务器、REPL),未来 Agent 就需要一个编程式的"把手"——你写出的那份 driver 脚本或 smoke 脚本必须随技能一起提交。

template.md 正是上面这份 SKILL.md 正文的标准模板:它把一节节的占位符、注释、示例命令按固定顺序排好,作者只需把"自己真实跑通的命令"填入对应位置,交付前再删掉所有说明注释。生成器 SKILL.md 第 3 步明确要求 "Use template.md as the starting structure - it has the frontmatter shape"。

2. 模板头部:YAML frontmatter 决定"斜杠命令"与"自动加载"

模板开头是两行 YAML:

---
name: run-<unit-name>
description: Build, run, and drive <unit-name>. Use when asked to start <unit-name>, run its tests, build it, take a screenshot of its UI, or interact with the running app.
---

模板文件末尾的注释对这两行做了权威解释,是所有作者必须遵守的规则:

  • name: 要替换 <unit-name> 并变成斜杠命令(slash command),例如 run-billing。它必须与技能所在目录名一致——目录是 run-<unit-name>,name 就是 /run-<unit-name>。生成器 SKILL.md 还补充了目录名的 slugify 规则:全小写、空格转短横线、禁止斜杠run-billing-api 合法,run-billing/api 不合法)。
  • description: 是 Claude 扫描来决定是否自动加载该技能的字段。模板特意提示:保留那些"请求方 Agent 真的会打出来"的动词——startrunbuildtestscreenshot。通用化描述(如 "helpful utilities for billing")无法命中请求意图,就不会被自动加载。

run/SKILL.md 可印证这套机制的上下游关系:当用户要求"运行/截图应用"时,/run 技能会先从项目目录向仓库根逐级探测已有的项目技能(探测命令见第 7 节),若发现某个技能的 description 覆盖"启动/驱动本应用",就逐字照做该技能;没有才回退到六类通用模式。而 run-skill-generatordisable-model-invocation: true 则说明生成器本身不参与自动匹配,只负责产出上述技能目录。

3. 模板正文的结构顺序:每一节解决一个明确问题

模板正文从一段一句话描述开始,然后按固定顺序排列各节。其顺序本身就有讲究:agent path 在前、human path 在后,可验证的在前、经验性的收尾。下面逐节拆解模板的设计意图与填写要求。

3.1 开头的一句话 handle 说明(第 6-10 行)

模板要求写一句话说明"这是什么、Agent 如何驱动它",并明确指出 handle(把手)在哪里

  • 桌面应用:写明 "drive it via .claude/skills/run-<unit-name>/driver.mjs under xvfb"——让未来 Agent 知道第一步该看哪;
  • Web 应用:写明 "start the dev server then drive it via chromium-cli"。

如果应用不在仓库根目录,还需加一句 "All paths below are relative to <unit-dir>/"(下文所有路径相对于单元目录)。

3.2 Prerequisites:不是通用清单,是你真跑过的那行 apt-get

模板强调:给出你实际执行的 apt-get install 那行命令,而不是一份泛泛的包清单;目标平台为 Ubuntu

sudo apt-get update
sudo apt-get install -y <packages-you-actually-installed>

这背后是对"全新机器冷启动"的承诺——比如 examples/electron.md 里为桌面 GUI 记录的是:xvfb libnss3 libgbm1 libasound2t64 libgtk-3-0 libxss1 libxkbcommon0 libatk-bridge2.0-0 libcups2 libdrm2,其中每个 lib* 都对应一次"缺 .so → 补装"的实战。如果运行时版本有要求(如 Node 20 via nvm、Python 3.12 via uv),也在此注明。

3.3 Setup:一次性初始化 + 环境变量(必填/可选带默认值)

模板要求给出 clone 后的一次性设置命令:装依赖、做配置、用精确命令应用任何补丁(feature-gate 覆盖、配置 stub 等)。随后列出环境变量,区分必填与可选并给出合理默认:

export FOO_API_KEY=...   # required - get from <where>
export BAR_MODE=dev      # optional - default is prod

3.4 Build:没有独立构建步骤就整节省略

模板明确 "Skip if no separate build step. Otherwise the exact command"。生成器 SKILL.md 补充:若你打过补丁(改 feature gate、覆盖配置),要把精确的 sed 或编辑写进 Build 节——比如 examples/electron.md 中提到先 npx electron-forge start 产出 .vite/build/ 再用 Ctrl-C 停掉,只要构建产物、不要它顺便打开的窗口。

3.5 Run(agent path):未来 Agent 真正会读的一节

模板指出 "这是未来 Agent 实际使用的章节"。若你写了 driver/REPL/smoke 脚本,这里记录如何启动它、它做什么;若应用简单到一条 curl 或单行命令就够,这条单行命令就写在这里。

针对 REPL 型 driver,模板给了完整的 tmux 封装 + 就绪标记轮询范式,并解释了为什么不建议固定 sleep:轮询比固定 sleep 更快(应用一就绪立即返回),且应用没起来时会响亮地失败,而不是截到一张渲染到一半的屏幕:

tmux new-session -d -s app -x 200 -y 50
tmux send-keys -t app '<launch command>' Enter
timeout 30 bash -c 'until tmux capture-pane -t app -p | grep -q "<ready-marker>"; do sleep 0.2; done'
tmux send-keys -t app '<first driver command>' Enter
tmux capture-pane -t app -p

这套 new-session → send-keys → until capture-pane | grep → capture-pane 序列在 examples/tui.md(TUI)与 examples/electron.md(GUI)中反复出现,是全文最核心的"Agent 驱动交互应用"手法。模板建议捕获 pane 时若输出难读可考虑 -e(保留转义序列)与 -J(合并折行)。

3.6 产物落地与 driver 命令表

模板要求写明产物落地的绝对路径,例如 "Screenshots -> /tmp/shots/. Logs -> /tmp/<app>.log"(截图/日志的绝对路径);若 driver 有命令,用一张两列表格记录(command / what it does),例如 examples/electron.md 最终整理的 launchss [name]click <sel>click-text <text>type/presswaitevaltextwindowsquit 等。这张表就是 driver 暴露给 Agent 的"API"。

3.7 Run(human path):与 agent path 明显不同才写,简短

模板提示 "If meaningfully different from the agent path. Brief - agents won't use this, humans can figure it out"。典型就是 examples 中反复出现的对比:

npm start   # opens a window; useless headless. Ctrl-C to quit.

"人类路径"往往是阻塞式、会弹窗的(npm start./myapp),对无头 Agent 无价值,所以放在第二、且一句话带过(如何停止也要写明)。

3.8 Test:命令 + 预期结果

<command>

模板要求写下预期结果——"N suites pass",或列出已知 flaky 的测试。这与生成器的"定义完成"标准一致:测试套件只是 sanity check,不是主菜,真正的验收是你已经启动并驱动过真实应用(详见第 6 节)。

3.9 可选章节:Gotchas 与 Troubleshooting

模板标注这两节"只在有真实内容时才写,不要写通用建议":

  • Gotchas:那些"看着应该能行、实际不行"的非显然陷阱及其绕过方案。examples/electron.md 列了一组真实模式:firstWindow() 给的可能是启动屏;真实 UI 在 BrowserView 而不是 BrowserWindow 里;locator.click() 因坐标计算会点到下层窗口(所以 driver 骨架用 page.evaluate(el => el.click()) 走 DOM 事件);contentEditable 输入框 fill() 无效要用 keyboard.type();Electron 会抢 stdin(需要 fs.openSync('/dev/stdin','r') + createReadStream 技巧)。
  • Troubleshooting:症状 → 修复,只写你真遇到的错误。examples/electron.md 的示例格式为 "Launch timeout (30s): build output missing? -> re-run the build step",并提醒容器内几乎总要 --no-sandbox

4. 模板末尾的 "DELETE" 注释:交付前必须删掉的作者备忘

template.md 在 --- 之后、--- > 之前有一大段"提交前务必阅读并删除"的注释,内容包括:

  1. frontmatter 备忘<unit-name> 要同时替换进 name:description:name: 会成为斜杠命令且必须与目录名一致;description: 决定 Claude 是否自动加载技能,务必保留那些请求方会输入的动词。
  2. driver 备忘:driver 脚本默认与本文档同目录,要在 Run 节引用它;Web 应用通常没有独立 driver 文件——Run 节里的 chromium-cli heredoc 就是 harness;若 driver 长大后项目测试套件想复用(共享 launch helper、真正的 e2e harness),把它迁到单元的 scripts/e2e/ 并更新这里的路径——skill 留在原地,driver 找到更好的家
  3. 最后一句 "Delete everything from --- above onwards before committing"——意味着模板交付物是一份不含任何作者说明的干净技能文档,所有 <...> 占位符都必须被真实内容替换。

5. 模板背后的工作流:从"生成器规则"看它如何被使用

只看 template.md 还不能理解它为什么长这样,需要结合同一目录下的 SKILL.md 看产出链路:

定义完成(Definition of done)四条件是模板内容质量的验收标准:

  1. 在本容器里启动过真实应用并与之交互过——带 GUI 的必须有落在磁盘上的截图;
  2. 交互 harness 已随技能提交(driver 脚本 / REPL 封装 / smoke 测试 / SKILL.md 内联的 chromium-cli heredoc);
  3. SKILL.md 把 harness 写成首要 Agent 路径(未来 Agent 先读到的是 "run this driver",而不是 "npm start 会弹窗");
  4. SKILL.md 里每个代码块都是你本次会话、本容器里真跑通的命令——不抄 README、不推断。

所以模板正文里每一个代码块都隐含"已验证"承诺,这正是第 3 节各节"用真实命令、删通用建议"要求的来源。生成器还给了反例警示(Red flags):没有 GUI 截图 = 你没运行它;技能长得像 README = 你在转述已有文档;Troubleshooting 太通用 = 你没真正执行过;"everything worked first try" = 你八成只跑了测试套件就当完成了。

方法论主线("every claim is a hypothesis")也解释了模板为何要求写得如此具体:README 里 "Requires macOS/Windows"、"Requires a GPU"、"Requires a paid account" 这类结论都被当成可证伪的假设——在无头 Linux 容器里真去启动一次,缺 .soapt-get 补,GPU 就走 --disable-gpu 软渲染,付费门禁只是代码里可读的门(env var?构建宏?SSR 内嵌 JSON?)找到并本地打补丁即可,而这条补丁路径要如实写进技能。障碍即内容:真实执行中遇到的怪问题,正是 Gotchas 节的金矿。

6. 模板中的目录与 driver 形态:按项目类型对号入座

模板本身刻意保持项目类型无关,真正的"driver 形状"由 examples/ 目录按类型给出(生成器把它整理成一张表,六个示例与 /run 技能的兜底模式共享):

项目类型 driver 形态 示例
Web 服务器 / API 后台启动 + 基于 curl 的 smoke 脚本 examples/server.md
CLI 工具 代表性参数 smoke 脚本,校验退出码与输出 examples/cli.md
TUI / 交互终端 tmux 封装:send-keys / capture-pane examples/tui.md
Electron / 桌面 GUI Playwright _electron REPL driver,xvfb 下运行,支持截图,tmux 包裹 examples/electron.md
浏览器驱动 Web 应用 dev server + chromium-cli 脚本 examples/playwright.md
库 / SDK import-and-call 的 smoke 脚本 examples/library.md

几个与模板配套的要点值得注意:

  • Web 应用通常没有 driver 文件,Run 节里内联的 chromium-cli heredoc(nav → wait-for → click/fill/press → screenshot → console --errors 循环)就是 harness;
  • Electron/桌面应用的 driver 默认就住在技能目录内.claude/skills/run-<name>/driver.mjs),模板的 Run 节要给出它的启动命令;
  • 覆盖 PR 真正触碰的层:若项目大多数 PR 改的是内部函数而非 UI,driver 的主入口应是"直接 import 并调用"路径(如 NODE_ENV=test bun run script.ts),tmux 启动退居其次;
  • driver 的"毕业"路径:被项目真实测试套件需要时迁到 scripts/e2e/,SKILL.md 更新指向,技能本身不动。

7. 模板使用前的探测:先找已有技能,而不是重写

run/SKILL.md 与 run-skill-generator 的第 0 步给出了同一段 shell 探测脚本——从当前目录向上逐级扫描 .claude/skills/*/SKILL.md 里的 description(用户命名五花八门,要按描述匹配而非名字):

d=$PWD; while :; do
  grep -Hm1 '^description:' "$d"/.claude/skills/*/SKILL.md 2>/dev/null
  [ -e "$d/.git" ] || [ "$d" = / ] && break
  d=$(dirname "$d")
done

若已存在覆盖"启动/驱动本应用"的技能(无论叫什么名字),精炼它而不是重写:验证其断言、修正错误、补缺漏、保留有效的部分,有 driver 就重跑一遍 driver,且沿用其现有名字。若发现旧版产物 .claude/run.md(早期工具生成的),执行迁移:正文变为新技能的 SKILL.md 内容、引用的脚本移入技能目录、删除旧文件。只有确认没有现成技能,才决定新建位置并套用 template.md

8. 模板的放置位置与粒度约定

结合生成器规则,模板产物的落点有三种典型情形:

  • 单项目仓库:放在仓库根 .claude/skills/run-<repo-name>/
  • 多应用大仓库:每个可部署单元一个,就近共置,例如 apps/billing/.claude/skills/run-billing/apps/desktop/.claude/skills/run-desktop/
  • 一个应用含多个二进制:仍在应用根建一个技能,为每个二进制加一节 ## Run: <name>(它们共享 Setup),从最接近的单二进制示例起步再扩展。

若不确定单元边界,生成器明确要求问用户,并把候选列出来让用户选择(mega-repo 根出现 apps//packages//services/ 时尤其如此)。Claude Code 会原生发现嵌套的 .claude/skills/ 目录——只要 Agent 在 <unit> 内任意位置工作,/run-<unit-name> 就能作为可用技能出现,并在请求命中其 description 时自动加载(例如 "run the desktop app"、"take a screenshot of billing")。

9. 写在最后:一份合格 run-skill 的自检清单

把模板与生成器规则对照,可提炼出交付前的自检问题(也即模板中每条 <注释> 的删除条件):

  1. 每个代码块是否都是本次会话、本容器真跑通的命令?有没有从 README 抄来的、从未执行过的路径?
  2. 应用是交互式的(GUI/TUI/服务器/REPL),技能里是否有 driver/smoke/内联 heredoc 可供未来 Agent 真正驱动它?
  3. 技能读起来是否像 README(同结构、同命令、同免责)?是的话你只是在转述文档,没有执行。
  4. 开头是否一句话说明了 handle 在哪(driver.mjs under xvfb / chromium-cli / curl)?路径是否相对 <unit-dir> 而非技能目录?
  5. 环境变量是否区分必填/可选并给了默认值?Gotchas 是否充满"没人能猜到"的真踩坑?Troubleshooting 是否只收录真实错误?
  6. frontmatter 的 name: 是否与目录名一致、description: 是否带上了 Agent 会输入的动词?
  7. 声明 "not supported on this platform" 前是否真的试过启动?(README 作者在 Mac 上,而你在 Linux 容器里——先试再说。)
  8. 交付前是否删除了 --- 之后的所有模板说明注释?

把这份清单走完,你就得到了一个与 README 有本质区别的项目运行技能:它不是"描述一个谁都无法触碰的窗口",而是让下一位 Agent(或同事)从零构建、启动并真正操作应用的可靠路径。更多可直接借鉴的完整填充样例,见 run-skill-generator 目录下的六个 examples 文档,以及消费这些技能的上层入口 run/SKILL.md

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
898
5.82 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
921
1.84 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.8 K
1.02 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
531
596
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.02 K
519
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.36 K
1.46 K
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
548
391