GitHub CLI 的 gh skill 命令实战:Agent Skills 的搜索、预览、安装、更新与发布
本文基于 GitHub CLI(cli/cli)仓库中的 skills/gh-skill/SKILL.md 展开,系统讲解 gh skill 命令族(search / preview / install / update / publish)的完整用法,并结合 pkg/cmd/skills/ 与 internal/skills/ 下的源码实现,说明版本解析顺序、技能发现约定、安装元数据注入与原子化更新等底层机制。读完后,你既能以开发者身份完成技能的安装维护与发布,也能让 Agent 自主管理其可用的技能集。
一、命令总览与定位
gh skill 用于从 GitHub 仓库安装、预览、搜索、更新和发布 Agent Skills。Agent 可以借助它把自己的技能集与一个或多个 GitHub 仓库保持同步。该命令也注册了复数别名 gh skills,在脚本与文档中推荐优先使用规范的单数形式 gh skill。
从顶层命令的源码 pkg/cmd/skills/skills.go 可以看到几个关键事实:
- 命令的 Short 描述标注为 "Install and manage agent skills (preview)",即技能管理功能处于预览状态,行为可能在不另行通知的情况下变化;
- 通过
Aliases: []string{"skills"}注册了复数别名; - 通过
cmd.AddCommand(...)挂载了六个子命令:install、list、preview、publish、search、update,分别实现在 pkg/cmd/skills/install/install.go、pkg/cmd/skills/list/list.go 等文件中; PersistentPreRunE中调用telemetry.SetSampleRate(ghtelemetry.SAMPLE_ALL),即技能类命令的遥测采样率为全量,这与其预览阶段的特性收集需求相呼应。
二、搜索:gh skill search
gh skill search <query> # 自由文本搜索
gh skill search <query> --owner <org> # 限定到某个 owner
gh skill search <query> --limit 20 --page 2
gh skill search <query> --json skillName,repo,description
gh skill search 会跨所有公开的 GitHub 仓库搜索名称或描述匹配查询词的技能,底层调用 GitHub Code Search API,以 filename:SKILL.md 为固定条件检索。实现位于 pkg/cmd/skills/search/search.go:
--limit(短参-L)默认 15,--page默认 1;--owner将结果限定到指定用户或组织(源码中以user:<owner>修饰查询);--json支持六个字段:repo、skillName、namespace、description、stars、path(见 SkillSearchFields)。
排序与去重的源码细节。搜索结果并非直接返回,而是经过多轮处理(searchRun):先按相关性预排序,再截断工作集、并发抓取每个技能的 frontmatter 描述与仓库 star 数做"富化",然后过滤、再排序,最后按技能名去重。评分函数 relevanceScore 的权重设计是:
| 信号 | 分值 |
|---|---|
| 技能名与查询词完全相等(含连字符归一化) | 3000 |
| 技能名包含查询词 | 1000 |
| namespace 包含查询词 | 500 |
| 描述包含查询词 | 100 |
| 仓库 star 数 | √n × 30 |
此外,deduplicateByName 对同名技能最多保留 3 条,防止聚合类仓库(照搬热门技能)刷屏。多词查询还会自动补发一次连字符形式的检索(如输入 "mcp apps" 时同时搜 "mcp-apps")。交互模式下,搜索结果会进入多选器,可直接选择技能并链式调用 gh skill install 完成安装。
三、安装前预览:gh skill preview
gh skill preview <owner>/<repo> <skill-name>
gh skill preview <owner>/<repo> <skill-name>@v1.2.0 # 固定某个版本
preview 从仓库拉取技能文件并在终端渲染 SKILL.md,不安装任何东西:先打印技能目录的文件树,再输出渲染后的正文(YAML frontmatter 会被剥离后按 Markdown 渲染)。交互运行时,若技能包含脚本、参考资料等附加文件,还会弹出文件选择器逐个浏览。
实现见 pkg/cmd/skills/preview/preview.go:
- 版本语法:在技能名后追加
@VERSION,版本可解析为 git tag、分支或 commit SHA(preview.go 文档说明); - 批量限制:非交互模式下额外文件最多渲染 20 个、总量 512KB,超出部分跳过(renderAllFiles);
- 与 install 相同,支持
--allow-hidden-dirs来纳入.claude/skills/等点目录中的技能。
四、安装:gh skill install
gh skill install <owner>/<repo> <skill-name>
gh skill install <owner>/<repo> <skill-name>@v1.2.0
gh skill install <owner>/<repo> skills/<scope>/<skill-name> # 精确路径,最快
gh skill install ./local-skills-repo --from-local
<owner>/<repo> 与 <skill-name> 都是必填项(交互模式下可改为提示选择)。核心参数(定义于 install.go):
| 参数 | 说明 |
|---|---|
--agent <id> |
目标 Agent 宿主,如 github-copilot、claude-code、cursor、codex、gemini-cli,可重复指定多个;非交互模式默认 github-copilot。作为 Agent 使用时应知道自己是哪个宿主,据此显式设置 |
--scope project|user |
project(默认)写入当前 git 仓库内;user 写入主目录、全局生效 |
--pin <ref> |
固定到 tag、分支或 commit SHA。与 --from-local 及内联 @version 语法互斥 |
--allow-hidden-dirs |
同时发现 .claude/skills/ 等点目录下的技能;有被他人内容污染的风险,非必要不用 |
--force(-f) |
覆盖已存在的安装 |
--dir |
指定自定义目录,覆盖 --agent 与 --scope |
--all |
安装仓库中发现的全部技能,不与技能名参数同用 |
--from-local |
把参数当作本地目录路径安装;文件被复制而非符号链接,并在 frontmatter 注入本地路径追踪元数据 |
版本解析顺序。当技能名不带版本时,CLI 按以下优先级解析(install.go 帮助文本 与 discovery.ResolveRef 一致):
- 仓库中最新的带 tag 的 release;
- 默认分支 HEAD。
需要特别注意的是:只有"确实没有 release(404)"才会回退到默认分支;403、500、网络错误等会直接报错,防止静默使用了意外的 ref。显式版本则先按分支、再按 tag、最后按 commit SHA 解析(resolveExplicitRef)。
路径式安装的加速原理。技能名既可以是名称、命名空间名(author/skill),也可以是仓库内精确路径(如 skills/author/skill、packages/agent-skills/code-review,或以 SKILL.md 结尾的任意路径)。当传入精确路径时,installRun 走 discovery.DiscoverSkillByPath 直接取单个 blob,避免对整个仓库 git tree 的完整遍历——在大仓库中这是显著的性能优化,源码注释中明确将其标注为 "Performance tip"。
多 Agent 共享目录。从 internal/skills/registry/registry.go 可以看到,DefaultAgentID 为 github-copilot,而 sharedProjectSkillsDir 为 .agents/skills。GitHub Copilot、Cursor、Codex、Gemini CLI、Antigravity、Amp、Cline、OpenCode、Warp 等多个宿主在 project 作用域下共用 .agents/skills 目录;如果一次选择多个解析到同一目标的宿主,每个技能只会写入一次(buildInstallPlans 按目标目录聚合安装计划)。各宿主的 project/user 目录映射表就维护在 Agents 变量中,例如 Claude Code 的 project 与 user 目录都是 .claude/skills。
安装后的元数据注入。安装完成后,CLI 会向 SKILL.md 的 frontmatter 注入来源追踪元数据,包括 metadata.github-repo、metadata.github-tree-sha(安装时的目录树 SHA)、metadata.github-pinned、metadata.github-path 等键。接受性测试 acceptance/testdata/skills/skills-install.txtar 验证了这一点:安装后文件里能 grep 到 github-repo 与 github-tree-sha,且锁文件 $HOME/.agents/.skill-lock.json 被写入并记录了技能条目。正是这些元数据让后续的 gh skill update 能够检测变更、完成自更新。
另外,源码中还实现了"上游溯源"机制:若被安装技能的 frontmatter 指向了另一个原始来源仓库(re-published 场景),CLI 会记录 skill_upstream_redirect 事件并自动改为从上游安装;--upstream 标志可显式启用该行为(installRun)。
五、更新:gh skill update
gh skill update --all # 更新所有已安装技能
gh skill update <skill> # 更新单个
gh skill update <skill> --force
gh skill update --unpin # 解除 pin 并移到最新版
实现见 pkg/cmd/skills/update/update.go,要点:
- 自动扫描所有已知 Agent 宿主目录(Copilot、Claude、Cursor、Gemini 等)的 project 与 user 两种作用域,共享目录只扫一次(scanAllAgents);
- 更新判据是目录树 SHA 对比:从本地
SKILL.mdfrontmatter 读出github-tree-sha,与远端重新发现的结果比较,不同才更新; - 以
--pin安装的技能默认跳过并打印提示,用--unpin清除 pin 值后才会参与更新; --force即使远端与本地 SHA 一致也强制重新下载,会用原始内容覆盖本地改动的文件,但不会删除本地额外新增的文件;--dry-run只报告可用更新,不修改任何文件。
原子化更新机制值得单独一提。updateSkillInPlace 先把新版本装到与技能目录同文件系统的 staging 临时目录,再通过 swapDirectoryContents 把旧内容移入备份目录、新内容原子 rename 进来;任一步失败则从备份还原,保证既有技能目录的 inode 不变(符号链接、挂载等外部引用持续有效),失败时原有内容也完整保留。
六、发布:gh skill publish
发布会把仓库变成一个可被搜索发现技能源。技能按以下约定被发现(与 install 完全一致,见 publish.go 帮助文本):
skills/<name>/SKILL.mdskills/<scope>/<name>/SKILL.md<name>/SKILL.md(仓库根级)plugins/<scope>/skills/<name>/SKILL.md
每个 SKILL.md 需要 YAML frontmatter:
---
name: my-skill # 必须等于目录名
description: One sentence... # 必填,推荐不超过 1024 字符
license: MIT # 可选但推荐
---
校验、然后发布:
gh skill publish --dry-run # 仅校验,不发布
gh skill publish --dry-run ./path/to/repo # 校验指定目录
gh skill publish --fix # 自动剥离安装元数据
gh skill publish --tag v1.0.0 # 非交互发布
gh skill publish # 交互式发布流程
--fix 与 --dry-run 互斥(publish.go 中的 MutuallyExclusive 校验)。--fix 只重写安装时注入的 metadata.github-* 键、不执行发布;修复后应提交结果并重新运行 publish。
源码中的校验清单(publishRun)比帮助文档更细:
name必填且必须与目录名一致;- 名称须符合 agentskills.io 严格命名规范——小写字母数字加连字符、不以连字符开头/结尾(正则见 discovery.go);
description必填,超过 1024 字符给出 warning;allowed-tools必须是空格分隔的字符串而非数组;- 存在未剥离的
metadata.github-*安装元数据时报 error 并提示用--fix; - 缺少推荐的
license字段、正文超过 500 行(影响 Agent 上下文效率)给出 warning; - 仓库中若存在已安装技能目录(如
.claude/)且未加入.gitignore,会警告"可能把他人内容一并发布出去"。
发布流程四步(对应 runPublishRelease):
- 为仓库添加
agent-skillstopic(搜索可发现的前提); - 使用
--tag指定的 tag,或在 TTY 下交互式询问(建议 semver,源码会用 suggestNextTag 基于最新 tag 自动递增 patch 版本); - 自动推送未推送的提交(与
gh pr create的行为一致,ensurePushed); - 创建带自动生成的 release notes 的 GitHub release。
脚本化使用时务必传 --tag,否则会落入交互流程而失败。源码中还内置了若干仓库安全体检(非阻塞的 warning/info):是否启用 immutable releases、tag 保护 ruleset 是否缺失、secret scanning 及其 push protection 是否开启、技能含代码/依赖清单时 code scanning 与 Dependabot 是否配置等(checkSecuritySettings、checkTagProtection)。
七、Agent 自我管理模式
对于让 Agent 自我管理技能的场景,skills/gh-skill/SKILL.md 给出的合理闭环是:
gh skill search <topic> --json skillName,repo,namespace发现候选技能(非交互、可解析输出);gh skill preview <repo> <skill>审查SKILL.md内容;gh skill install <repo> <skill> --agent <host> --pin <ref>做可复现安装——注意这里显式指定--agent(Agent 应知道自己是哪个宿主)并用--pin固定版本;- 定期执行
gh skill update --all保持技能集刷新。
配合第四节提到的元数据注入机制,这一闭环完全不需要人工维护:安装时写入的来源与 tree SHA 信息既是更新检测的依据,也是溯源审计的基础。
八、适用前提与限制
- 功能状态:
skill命令族整体标注 preview,帮助文本明确"可能在不另行通知的情况下变化"; - 主机限制:安装、搜索、预览路径都会先做
source.ValidateSupportedHost校验,远端操作面向受支持的 GitHub 主机(本地目录安装走--from-local,且--from-local与--pin、--upstream互斥); - 大仓库限制:当仓库 git tree 超过 GitHub API 截断上限时,完整发现会返回 TreeTooLarge 错误并提示改用路径式安装(install.go);
- 点目录技能:
.claude/skills/等隐藏目录中的技能默认被排除,且被提示可能是其他发布者的复制品,需--allow-hidden-dirs显式纳入; - 验证入口:仓库的 acceptance/testdata/skills/ 目录下有整套 txtar 验收测试(安装、预览、发布、更新等场景),可作为行为基线参考。
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