Claude Code `run-<unit>` Skill 生成模板精读:为任何项目编写"Agent 可直接驱动"的运行技能
导读
本文聚焦 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 真的会打出来"的动词——start、run、build、test、screenshot。通用化描述(如 "helpful utilities for billing")无法命中请求意图,就不会被自动加载。
从 run/SKILL.md 可印证这套机制的上下游关系:当用户要求"运行/截图应用"时,/run 技能会先从项目目录向仓库根逐级探测已有的项目技能(探测命令见第 7 节),若发现某个技能的 description 覆盖"启动/驱动本应用",就逐字照做该技能;没有才回退到六类通用模式。而 run-skill-generator 的 disable-model-invocation: true 则说明生成器本身不参与自动匹配,只负责产出上述技能目录。
3. 模板正文的结构顺序:每一节解决一个明确问题
模板正文从一段一句话描述开始,然后按固定顺序排列各节。其顺序本身就有讲究:agent path 在前、human path 在后,可验证的在前、经验性的收尾。下面逐节拆解模板的设计意图与填写要求。
3.1 开头的一句话 handle 说明(第 6-10 行)
模板要求写一句话说明"这是什么、Agent 如何驱动它",并明确指出 handle(把手)在哪里:
- 桌面应用:写明 "drive it via
.claude/skills/run-<unit-name>/driver.mjsunder 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 最终整理的 launch、ss [name]、click <sel>、click-text <text>、type/press、wait、eval、text、windows、quit 等。这张表就是 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 在 --- 之后、--- > 之前有一大段"提交前务必阅读并删除"的注释,内容包括:
- frontmatter 备忘:
<unit-name>要同时替换进name:与description:;name:会成为斜杠命令且必须与目录名一致;description:决定 Claude 是否自动加载技能,务必保留那些请求方会输入的动词。 - driver 备忘:driver 脚本默认与本文档同目录,要在 Run 节引用它;Web 应用通常没有独立 driver 文件——Run 节里的
chromium-cliheredoc 就是 harness;若 driver 长大后项目测试套件想复用(共享 launch helper、真正的 e2e harness),把它迁到单元的scripts/或e2e/并更新这里的路径——skill 留在原地,driver 找到更好的家。 - 最后一句 "Delete everything from
---above onwards before committing"——意味着模板交付物是一份不含任何作者说明的干净技能文档,所有<...>占位符都必须被真实内容替换。
5. 模板背后的工作流:从"生成器规则"看它如何被使用
只看 template.md 还不能理解它为什么长这样,需要结合同一目录下的 SKILL.md 看产出链路:
定义完成(Definition of done)四条件是模板内容质量的验收标准:
- 你在本容器里启动过真实应用并与之交互过——带 GUI 的必须有落在磁盘上的截图;
- 交互 harness 已随技能提交(driver 脚本 / REPL 封装 / smoke 测试 / SKILL.md 内联的 chromium-cli heredoc);
- SKILL.md 把 harness 写成首要 Agent 路径(未来 Agent 先读到的是 "run this driver",而不是 "npm start 会弹窗");
- 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 容器里真去启动一次,缺 .so 就 apt-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 的自检清单
把模板与生成器规则对照,可提炼出交付前的自检问题(也即模板中每条 <注释> 的删除条件):
- 每个代码块是否都是本次会话、本容器真跑通的命令?有没有从 README 抄来的、从未执行过的路径?
- 应用是交互式的(GUI/TUI/服务器/REPL),技能里是否有 driver/smoke/内联 heredoc 可供未来 Agent 真正驱动它?
- 技能读起来是否像 README(同结构、同命令、同免责)?是的话你只是在转述文档,没有执行。
- 开头是否一句话说明了 handle 在哪(
driver.mjsunder xvfb /chromium-cli/curl)?路径是否相对<unit-dir>而非技能目录? - 环境变量是否区分必填/可选并给了默认值?Gotchas 是否充满"没人能猜到"的真踩坑?Troubleshooting 是否只收录真实错误?
- frontmatter 的
name:是否与目录名一致、description:是否带上了 Agent 会输入的动词? - 声明 "not supported on this platform" 前是否真的试过启动?(README 作者在 Mac 上,而你在 Linux 容器里——先试再说。)
- 交付前是否删除了
---之后的所有模板说明注释?
把这份清单走完,你就得到了一个与 README 有本质区别的项目运行技能:它不是"描述一个谁都无法触碰的窗口",而是让下一位 Agent(或同事)从零构建、启动并真正操作应用的可靠路径。更多可直接借鉴的完整填充样例,见 run-skill-generator 目录下的六个 examples 文档,以及消费这些技能的上层入口 run/SKILL.md。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0629
MiniCPM5-2BMiniCPM5-2B 是一款面向端侧、本地部署和资源受限场景的 2B 稠密 Transformer,能够达到同尺寸开源模型 SOTA 水平。Markdown00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
HivisionIDPhotos⚡️HivisionIDPhotos: a lightweight and efficient AI ID photos tools. 一个轻量级的AI证件照制作算法。Python07
DragonOSDragonOS is an operating system developed from scratch using Rust, with Linux compatibility. It is designed for **Serverless** scenarios. 使用Rust从0自研内核,具有Linux兼容性的操作系统,面向云计算Serverless场景而设计。Rust00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00