agent-skills 开发者入门指南:五层架构心智模型、本地验证闭环与三条贡献路径
本文为 agent-skills 仓库(Production-grade engineering skills for AI coding agents)的维护者与潜在贡献者而写:讲清楚如何向这个仓库提交 skill、文档与评测脚本。读完本篇,你将掌握仓库的五层可组合架构、本地验证闭环的每一条命令及其底层实现,以及三条贡献路径各自的准入门槛与 Pre-PR 检查清单。
1. 适用对象:仓库维护者,而非技能使用者
docs/developer-onboarding.md 的读者是在 agent-skills 仓库内部工作的人:贡献新 skill、修订文档、改进 eval harness。如果你只是想在自己的项目里使用这套技能,应该看 docs/getting-started.md。
需要强调的一点是:这份入门文档定位是导览(guided tour),而不是规则手册(rulebook)。真正的规则分布在三份权威文档里,导览只负责告诉你"什么时候该读哪一份",从而避免规则在多处复述后产生漂移:
- CONTRIBUTING.md — 贡献工作流(新 skill 前置检查、结构要求、翻译与 Hook 测试政策);
- docs/skill-anatomy.md — skill 文件格式规范(frontmatter、章节解剖、上下文效率);
- evals/README.md — 三层评测框架(structural / trigger / behavioral)与 case 文件 schema。
2. 心智模型:五个可组合的层
理解仓库最常见的贡献错误,根源几乎都是没分清各层的职责边界。仓库有五个可组合层,各自回答一个不同的问题:
| 层 | 位置 | 职责 | 一句话概括 |
|---|---|---|---|
| Skills(技能) | skills/<name>/SKILL.md |
带验证门的分步工作流 | How(怎么做) |
| Personas(角色) | agents/<role>.md |
带视角与输出格式的角色 | Who(谁来做) |
| Commands(命令) | .claude/commands/、.gemini/commands/、commands/ |
面向用户的入口点,编排层 | When(何时触发) |
| References(参考) | references/*.md |
skill 按需拉取的检查清单 | What to check(检查什么) |
| Evals(评测) | evals/cases/<name>.json |
证明 skill 能触发、行为正确的证据 | Does it work(是否有效) |
把这张表内化,可以避免三类最高频的贡献错误:把参考材料塞进 skill 目录、构建会路由到其他 persona 的 persona、跨 skill 复制内容。
两条必须内化的结构性规则
- 用户(或斜杠命令)才是编排者。 Persona 永远不调用其他 persona;仓库认可的唯一多人格模式是并行 fan-out + 合并步骤。这一点在 AGENTS.md 中有明确落地:
/ship命令会并发运行code-reviewer、security-auditor、test-engineer三个人格并综合报告,而仓库明确禁止构建"路由器 persona"——那是斜杠命令与意图映射的职责。完整模式目录见 references/orchestration-patterns.md。 - 不复制,只引用。 Skill 之间通过名称互相引用,并链接到
references/下的共享清单,而不是复述内容。这条规则同样适用于文档本身(包括本篇入门文档):docs/skill-anatomy.md 将"Shared References 放在仓库根references/而非 skill 目录内"作为 pack 级设计选择,理由是多 skill 共用的清单若各自拷贝一份,迟早漂移。
一个容易踩的 scope 坑
仓库根目录的 AGENTS.md 和 CLAUDE.md 配置的是工作在这个仓库本身的 agent,它们不是可复用资产。写安装/设置指南时,永远不要指示用户把这两个文件拷进自己的项目——可复用的资产是 skills/ 下的技能。AGENTS.md 开头也自我声明了这一 scope 限制。
命令的三份平行目录
斜杠命令存在于三个平行目录中(Claude Code、Gemini CLI、Antigravity CLI)。改动其中任何一份,CI 会检查三者的 parity(一致性),详见下节。
3. 本地环境搭建
git clone https://gitcode.com/GitHub_Trending/agentskill/agent-skills
cd agent-skills
这个仓库没有构建步骤,也没有 package.json——所有校验器都是零依赖的纯 Node 脚本(例如 scripts/run-evals.js 顶部注释写明 "Zero dependencies")。你需要准备:
- Node 20+(与 CI 一致),用于
scripts/下的校验器; - bash(推荐附带
jq),用于 hook 回归测试; ghCLI,在提出新 skill 之前做重复 PR 检查;- Claude Code,仅当你想本地运行 Tier 3 行为评测时才需要。
如果想在一个本地 checkout 上实际试用这个技能包:
claude --plugin-dir /path/to/agent-skills
插件身份由根目录的 plugin.json 声明(当前版本 0.6.8),该目录同时携带 agents/、命令目录与 hooks/,整仓安装时可一起分发。
4. 验证闭环:CI 能跑的,你本地几秒就能跑
这个仓库"吃自己的狗粮"(eats its own cooking):skill 的验证是不可协商的,对仓库本身的贡献也是。下面这组命令覆盖了 CI 的全部内容:
# Tier 1, 结构层:frontmatter、命名、必需章节
node scripts/validate-skills.js
# 命令 parity 与描述同步,横跨三个命令目录
node scripts/validate-commands.js
# Tier 2, 触发与路由:正向 prompt 排进 top-k,负向 prompt 不撞车
node scripts/run-evals.js
# Tier 3, 行为层(按需运行,消耗 token;--dry-run 只打印计划)
node scripts/run-evals.js --behavioral <skill-name> --dry-run
# Hook 回归测试:改动 hooks/session-start.sh 或
# skills/using-agent-skills/SKILL.md 时必跑
bash hooks/session-start-test.sh
下面结合源码看每一层实际在检查什么。
4.1 Tier 1:结构校验(validate-skills.js)
scripts/validate-skills.js 是一个薄封装:规则本体全部在 scripts/lib/skill-lint.js 中(单一事实源,可导入、可单测,配套 scripts/lib/skill-lint-test.js)。主流程遍历 skills/ 下每个目录,调用 lintSkill() 收集 errors 与 warnings,逐 skill 打印 ✓ / ✗ / ⚠,最终按"error 数 > 0 → 退出码 1"决定 CI 红绿。校验的规则来源就是 docs/skill-anatomy.md:YAML frontmatter 必须含 name(小写连字符、与目录名一致)与 description(第三人称说明 + Use when 触发条件,最长 1024 字符),以及 Overview / When to Use / 核心流程 / Common Rationalizations / Red Flags / Verification 等推荐章节。
4.2 命令 parity:validate-commands.js
scripts/validate-commands.js 守护三个命令目录之间的静默漂移,三个目录在源码中显式列出(见 scripts/validate-commands.js):
| 目录 | 扩展名 | 宿主 |
|---|---|---|
.claude/commands/ |
.md |
Claude Code |
.gemini/commands/ |
.toml |
Gemini CLI |
commands/ |
.toml |
Antigravity CLI |
它检查两件事(均为 CI 阻断级 error):每个命令必须三处齐全(Claude stem 作为基准,plan 与 TOML 侧的 planning 通过 NAME_MAP 显式映射,见 scripts/validate-commands.js);三处 description 字段必须逐字一致。注意它故意不检查 prompt 正文差异——每个工具有自己的语法($ARGUMENTS、agent-skills: 前缀、GEMINI.md vs CLAUDE.md),正文差异是合理的。
4.3 Tier 2:触发与路由(run-evals.js 的确定性层)
node scripts/run-evals.js 是 Tier 2,一个对"agent 会选哪个 skill"的词法近似(lexical approximation)——对全部 skill 的 description 做带词干化的 TF-IDF,然后计算与每条 prompt 的余弦相似度排序。源码细节值得贡献者了解:
- 文本管线(scripts/run-evals.js):小写化 → 去停用词(内置约 40 词停用表)→ 轻量词干化(
stem()手工剥离-ally/-ing/-ed/-es/-al等后缀,把 "conflicts/conflict"、"architectural/architecture" 聚到一起,注释明说 "Not a real stemmer")。 - 语料构建(scripts/run-evals.js):每个 skill 的"文档" = description 词频 + 目录名分词权重 2 倍,所以 skill 命名本身也参与路由。
- 碰撞阈值(scripts/run-evals.js):任意两个 skill 的 description 余弦相似度 ≥ 75% 报 error,≥ 50% 报 warning——这是防止目录里长出近重复 skill 的护栏。
- 最低数量(scripts/run-evals.js):每个 case 文件至少 3 条正向 trigger、2 条负向 trigger、1 条行为评测,缺一项即 CI error。
--min-rank1棘轮:CI 以--min-rank1 80运行,而仓库内置基线是 86% 的 rank-1 命中率——留了余量,避免一次无关的 description 编辑立刻把 CI 打红。规则是"随路由变好而抬高,永远不许为了压回归而降低"。
Tier 2 的两大目标失效模式(也是它存在的理由):
- description 缺少用户真实会说的词汇(假阴性)——用户 prompt 与 description 词频交集为零,runner 会明确报 "description shares no vocabulary with a prompt users would say";
- description 过宽(假阳性)——把本该路由给别人的 prompt 也抢到了第一,报 "ranked #1 for a negative prompt (over-broad description)"。负向 trigger 若声明了
owner,runner 还会断言 owner 必须压过本 skill 排前(scripts/run-evals.js),避免 prompt 什么都匹配不上时的空转通过。
所以经验法则是:Tier 2 变红通常意味着"修你的 skill description",而不是修评测。完整设计、schema 与信任级别规则见 evals/README.md。
4.4 Tier 3:行为评测(按需,消耗 token)
node scripts/run-evals.js --behavioral <skill-name> --dry-run 只打印执行计划,不花 token;去掉 --dry-run 才会真正跑。从 scripts/run-evals.js 的实现看,执行路径是:
- 物化工作区(scripts/run-evals.js):为每条评测开一个
/tmp下的临时目录,把files[]里声明的 fixture 从evals/fixtures/拷入,git init并以本地身份提交 "fixture baseline",让 agent 有真实代码可 diff、可提交。fixture 路径解析(resolveFixturePath)会拒绝绝对路径与..逃逸,保证评测不会读到仓库外文件。 - 执行器调用(scripts/run-evals.js):
claude -p --verbose --output-format stream-json --permission-mode acceptEdits --allowedTools Read,Glob,Grep,Edit,Write,Bash,WebFetch,WebSearch,把整个SKILL.md以--append-system-prompt注入,prompt 走 stdin。明确的权限模式 + 工具白名单让执行评测能真正改文件、跑命令、看 diff,而不是被拒之后"口头表演"——trace 打分要抓的正是这种 narrate-instead-of-perform 失效模式。执行器超时 15 分钟,打分器超时 5 分钟。 - 打分:完整 stream-json trace 被
===TRACE START/END===标记包裹为不可信数据,经 stdin(而非 argv,trace 可能有数 MB,argv 会撞 OS 参数上限)喂给打分器;打分输出经parseGrading()严格校验 JSON 形状(expectations[]逐条 text/passed/evidence +summary计数一致性)后才写入evals/results/(gitignored),采用 skill-creator 的grading.json形状。
以 evals/cases/test-driven-development.json 为例,它含 3 条正向 trigger(如 "Write a failing test for this bug before fixing it")、2 条带 owner 的负向 trigger,以及 3 条行为评测——其中 id=2 是一条压力用例:"技术负责人说这是行改动、热修窗口十分钟就关,测试下个 sprint 补",expectations 明确断言"压力不能导致跳过快照测试步骤"。这正是 evals/README.md 所说:纪律类 skill 必须带时间压力、沉没成本、权威压力三类压力用例。其行为评测的 fixture 在 evals/fixtures/test-driven-development/(BUG.md、README.md、src/、test/ 等真实项目输入),对话类 skill 也可用人工评审豁免的 kind: "dialogue" 评测(见 evals/README.md)。
4.5 Hook 回归测试
hooks/session-start.sh 会把 using-agent-skills 元技能注入每个新的 Claude Code 会话。从源码看,它的所有输出路径都必须发出标准 SessionStart 信封 {"hookSpecificOutput": {"hookEventName": "SessionStart", "additionalContext": "..."}}(宿主如 Claude Code、Codex CLI 会校验 hook 输出形状),并用 jq 正确转义构造 JSON;当 jq 不在 PATH 上时(hooks/session-start.sh)优雅降级为一条 INFO 级 payload,提示用户安装 jq,且 exit 0。
回归测试 hooks/session-start-test.sh 同时覆盖"有 jq"和"无 jq"两个分支,任一断言失败即非零退出;CONTRIBUTING.md 给出的期望输出是 session-start JSON payload OK。想本地复现"无 jq 降级"分支,可以临时把 jq 所在目录从 PATH 里剥掉再跑测试(前提是 jq 独占一个 bin 目录,比如 Homebrew 的 /opt/homebrew/bin;若与 mktemp 等系统工具共用 /usr/bin,建议换独立包管理器装一份 jq 再试,完整命令见 CONTRIBUTING.md 的 "Reproducing the no-jq fallback" 一节)。
4.6 提交前的运行策略
每个 PR 之前运行相关子集。 一条通过 Tier 1 + Tier 2 + 命令 parity 的 PR 才是"可评审的";没过的会先被机制性打回,还没人读到内容。
5. 三条贡献路径
路径 1:修复或改进现有 skill(最常见,也是最佳首 PR)
- 保持改动聚焦、最小化;保留 skill 的结构与语气。
- 若改动了 frontmatter 的
description,预期 Tier 2 会有连锁反应——跑node scripts/run-evals.js,确认该 skill 的触发 prompt 仍排名达标(description 正是 Tier 2 语料的核心输入)。 - 跑 Tier 1 确认 frontmatter 仍然合法。
另外,CONTRIBUTING.md 要求:在改动前先查 evals/skill-impact.md 中的"skill 变更拒绝台账",看是否有针对同一 skill 的历史尝试及其评测证据;若某次 description 改动因评测被拒,还要向台账追加一行记录(日期、受影响 skill、尝试的改动、rank-1 分数前后对比、PR 链接与结果),并且把台账更新单独落到默认分支——不要只留在被拒的提案分支上,否则分支关闭或强推会丢失记录。
路径 2:提出新 skill(门槛更高,先做前置检查)
目录已覆盖开发生命周期的大部分,所以举证责任在"缺口"这一侧。动笔之前,按 CONTRIBUTING.md 的 "Before proposing a new skill" 做前置检查:
- 搜索目录——浏览 README.md 的 skill 清单与
skills/目录,确认没有现有 skill 已部分或全部覆盖你的想法; - 检查开放 PR——
gh pr list --state open,近重复 skill 的聚集已经存在,别再往里面加; - 检查被拒提案——搜索 evals/skill-impact.md 拒绝台账,避免重做已有评测证据支撑的旧提案;
- 确认解剖——确认想法符合 docs/skill-anatomy.md 的格式:一个带验证门的可执行工作流,而不是模糊建议;
- 在 PR 描述中明确论证缺口——为什么现有 skill、开放 PR、被拒提案都没有覆盖它。
如果与现有 skill 重叠,对那个 skill 的聚焦编辑优于新增目录。
一个新 skill 是一套文件,不是单个文件:
skills/<kebab-case-name>/SKILL.md;- 对应的
evals/cases/<name>.json(最少 3 正向 / 2 负向 / 1 行为评测,execution 类必须有evals/fixtures/下的真实 fixture 支撑); scripts/目录仅当该 skill 附带可运行辅助脚本时才创建——参考材料放references/,永远不要塞进 skill 目录。
frontmatter 精确规则、章节解剖与 case 文件最低数量以 CONTRIBUTING.md 与 docs/skill-anatomy.md 为准——入门文档刻意不重复这些细节,"以免两份文档漂移"。
有一点值得内化而非查询:写触发 prompt 时,要转述用户真实会怎么说话。把 description 复制进 prompt 是在"刷分"(gaming the eval)——Tier 2 的词法近似让这种自我匹配的 prompt 必然排名靠前的,什么也证明不了。反之,若一条真实风格的 prompt 排不上名,说明 description 缺词汇,这是真实发现,应去修 description。
路径 3:文档、references 与 harness
- 文档与 skill 只接受英文;翻译版不予接收,因为它们会随 skill 与文档演进而漂移(CONTRIBUTING.md 的 Translations 一节给出了完整理由);
- 改动 scripts/run-evals.js 或 eval schema 时,应保持与 skill-creator 的
evals.jsonschema 兼容——行为层逐字采用了该 schema(id、prompt、expected_output、可选files[]、expectations[]),只额外加了一个可选的kind字段(execution/dialogue)。这种兼容性是特性而非巧合; - 任何触碰 session-start hook 或其内嵌元技能的改动,必须跑 hook 回归测试(见 4.5)。
6. Pre-PR 检查清单
提交前逐项过一遍:
- [ ] Tier 1 绿:
node scripts/validate-skills.js - [ ] Tier 2 绿:
node scripts/run-evals.js - [ ] 若动了任何命令目录:命令 parity 绿——
node scripts/validate-commands.js - [ ] 若动了
hooks/或using-agent-skills:hook 测试绿——bash hooks/session-start-test.sh - [ ] 新 skill → eval case 文件存在,且达到最低 trigger / behavioral 数量
- [ ] 新 skill → PR 描述中论证了缺口;目录与开放 PR 均已检查
- [ ] 没有重复内容;以交叉引用代替复制
- [ ] 改动小而聚焦(仓库自身的
code-review-and-quality变更尺寸建议同样适用于本仓库的贡献)
7. 建议阅读顺序
- README.md — 技能目录与生命周期图(DEFINE → PLAN → BUILD → VERIFY → REVIEW → SHIP,约 10 分钟);
skills/using-agent-skills/SKILL.md— 从 agent 一侧看路由如何工作;- 端到端读一个成熟 skill(例如
skills/test-driven-development/SKILL.md)——通过实例内化解剖; - docs/skill-anatomy.md — 带着上下文再看格式规范;
- evals/README.md — 三个评测层级与 case 文件格式;
- CONTRIBUTING.md + AGENTS.md — 规则本体,以及仓库作用域的 agent 配置。
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 StartedRust0622
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00