你有没有算过这样一笔账:让 AI 帮你「看看某个开源库最近在忙啥」,它老老实实跑了一条 `gh api repos/xxx/yyy`,返回一大坨 JSON,光那一次调用的原始输出就够你写三篇小作文。
更离谱的是,它顺手还想帮你「优化」一下——`gh pr create`、`gh issue close`、`gh api -X DELETE` 全给你安排上。你只是想看一眼,它想给你改个仓库。
SkillHub 上的 `gh-cli-readonly-agent`(GitHub CLI 省 Token 只读工具集),就是来管这俩毛病的。一句话概括:给 AI Agent 配一套「只能看、不能动、还特别省」的 GitHub CLI 使用规范。目前下载量已经过了 510 万。
它不是工具,是一本「使用说明书 + 护栏」先说清楚定位,免得你误会。
这个 Skill 本身不装什么新二进制,它是一份写给 Agent 的行为契约。核心就四条硬规矩(原文叫 HARD RULES):
只读:任何写入、创建、合并、评论、删除操作,一律禁止省 Token:`gh` 命令必带 `--json` 裁剪字段,必带 `--limit`(默认不超过 10),必用 `| jq -c` 输出紧凑格式超时:所有 `gh api` 调用必须走预置函数 `gh_timed`缓存:高频查询必须走 `gh_cached`翻译成人话就是:能少要字段就少要,能少要几条就少要几条,能缓存就别重复问,能超时就别干等。
你可能觉得这不就是常识吗?问题在于,Agent 恰恰最容易在这几件事上「没常识」——它默认拉全量、默认不裁剪、默认不缓存。你把规矩写死,它才老实。
七个预置函数,把「省」做成肌肉记忆真正让我眼前一亮的是这一层:这个 Skill 假设运行环境里已经预置好 7 个函数,让 Agent 直接调用,而不是每次现场手搓。
| 函数 | 作用 |
|------|------|
| `gh_timed ` | 带 30 秒超时保护的 gh 调用 |
| `gh_cached ` | 带 30 分钟 TTL 的脚本层缓存 |
| `retry ` | 指数退避重试(最多 3 次) |
| `gh_read O/R path [ref]` | 读取文件内容并自动 base64 解码 |
| `gh_tree O/R [depth]` | 获取目录树,默认限深 3 层,输出去重路径 |
| `truncate_by_quota O/R path` | 按剩余 Token 配额自适应截断大文件 |
| `gh_default_branch O/R` | 探测默认分支(main → master → API 兜底) |
别小看这几个封装。`gh_read` 顺手帮你把 GitHub Contents API 那层 base64 解码处理掉了——就是那个每次都要 `jq -r '.content | @base64d'`、不写就返回一堆乱码的经典坑。`truncate_by_quota` 更有意思,它根据 `TOKEN_QUOTA` 环境变量动态决定读多少行,配额紧就少读点,配额松就多读点,让截断这件事变得自适应。
`gh_default_branch` 则是专治 404 的。很多仓库默认分支不叫 `main` 而叫 `master`,硬编码 `main` 就会扑空;这个函数把「先猜 main、再试 master、最后查 API」的兜底逻辑包好了。
省 Token 的实战姿势规矩立完了,具体怎么省?看几个原文里的典型写法。
读单个文件,推荐直接用预置函数:
gh_read O/R src/utils/parser.rs
gh_read O/R config.yaml v2.1.0 # 指定 tag 或 branch
读大文件就截断,别整份往上下文里灌:
gh_read O/R large_file.py | head -200
gh_read O/R large_file.py | sed -n '50,150p'
truncate_by_quota O/R large_file.py # 按配额动态截断
搜索仓库时,`--json` 只留你真正要的字段:
gh search repos --stars:>500 --language=python --sort=stars \
--limit 10 --json fullName,description,stargazersCount | jq -c '.'
这里有个很细节的提醒值得单独拎出来:Search API 限流是每分钟 10 次。所以高频搜索必须套 `gh_cached`,否则你会发现自己被 GitHub 礼貌地请去喝茶。
还有一个容易被忽略的安全细节——读取配置类文件后,可以顺手做一次脱敏:
gh_read O/R config.py | sed -E 's/(api[_-]?key|token|secret|password)\s*[=:]\s*["\x27][^"\x27]+["\x27]/\1="***"/gi'
Agent 读到了密钥,不代表它该把密钥写进聊天记录里。
写操作黑名单:正则拦得死死的只读不是靠自觉,是靠拦截。Skill 里明确列了一份黑名单:
正则拦截:`gh (pr|issue|repo|release|workflow|gist) (create|merge|comment|edit|close|delete|fork|run|disable|review)`API 拦截:`gh api -X (POST|PUT|DELETE|PATCH)`文件写入:对 `contents/PATH` 的 PUT / POST / DELETE有意思的是它还很贴心地澄清了一句:`gh run list`、`gh run view`、`gh pr checks`、`gh pr diff` 都属于只读,黑名单正则只拦「第二组动词」,不会误伤这些查询命令。
这个细节说明作者是真踩过坑的——拦得太粗,会把正常的「看 CI 日志」也给拦了。
出错会自愈,不会一路错到底Agent 跑命令最怕的不是报错,是报错之后还硬着头皮往下跑。这个 Skill 内置了一张错误自愈与熔断表:
| 错误码 / 条件 | 自动动作 |
|------|------|
| 401 | 触发 `gh auth login` 重新认证 |
| 403(限流) | `retry` 指数退避,连续 3 次则暂停 5 分钟 |
| 404 | 检查仓库名拼写、可见性,以及认证 scope |
| 5xx | 指数退避,连续 5 次暂停 10 分钟并告警 |
| 返回文本 > 5000 字符 | 自动截断并标注 `[已截断]` |
| 单轮工具调用 > 20 条 | 暂停 30 秒,防 Token 爆炸 |
其中有一句特别值得玩味:404 场景下明确写着「勿主动 `gh auth refresh --scopes repo`」,理由是避免给只读的 Agent 授予写权限。
这就是安全设计的克制感——宁可让你重新登录,也不为了图方便把写权限塞给一个本该只读的角色。
跨平台这件事,它是认真的很多 Skill 在 macOS / Linux 上写得好好的,一到 Windows 就翻车。这个 Skill 少见地给了三套适配:
bash:标准写法,`jq` 用单引号包裹表达式Windows CMD:`jq` 表达式改双引号,且 `|`、`>` 等特殊符号要用 `^` 转义PowerShell(pwsh 7):推荐单引号包裹 `jq` 表达式,里面可直接写双引号无需转义连「`date` 在 Windows 上是 `Get-Date` 的别名,取近一年要用 `(Get-Date).AddYears(-1).ToString('yyyy-MM-dd')`」这种细节都写进去了。写过多平台脚本的人看到这里应该会心一笑——这些坑,一个都躲不掉。
连自检脚本都给了最让我觉得「这作者是真干活的人」的地方,是第 10 节:一套纯静态的验证测试。
九个测试项 T1 到 T9,覆盖写操作拦截、认证状态、超时机制、读文件解码、目录树限深、动态截断、curl 降级、PowerShell 可用性、函数加载。全部只读断言,零写风险,`exit 0` 即通过。原文还给了一键自检脚本:
t() { eval "$1" >/dev/null 2>&1 && echo "PASS $2" || echo "FAIL $2"; }
t 'echo "gh pr create" | grep -Eq "gh (pr|issue|repo|release|workflow|gist) (create|merge|comment|edit|close|delete|fork|run|disable|review)"' T1_blacklist
t 'gh auth status' T2_auth
t 'timeout 1 sleep 2; test $? -eq 124' T3_timeout
t 'gh_read cli/cli README.md | grep -q "GitHub CLI"' T4_read
# …… 其余见原文
一个「用说明书」级别的 Skill,还自带验收标准——这在开源生态里并不常见。
gh 彻底不可用怎么办?还有降级方案。当 `gh` 命令本身不可用时,回退到 `curl` 直连 GitHub REST API:
curl -s --max-time 30 -H "Authorization: token $GITHUB_TOKEN" \
-H "Accept: application/vnd.github.v3+json" \
"https://api.github.com/repos/O/R/contents/README.md" \
| jq -c '.content | @base64d'
永远留一条退路,是工程靠谱的标志。
它适合谁如果你符合下面任意一条,这个 Skill 基本就是为你准备的:
经常让 AI 帮你看开源仓库、读源码、翻 PR 和 Issue被 Agent 的 Token 账单吓到过担心 Agent 手滑对仓库做出写操作在 Windows 和 macOS 之间来回横跳,受够了脚本不通用项目信息SkillHub:skillhub.cn/skills/indiv-yaoyao/gh-cli-readonly-agent作者:@indiv-yaoyao分类:开发编程下载量:510 万+依赖:`gh`(GitHub CLI)+ `jq`最后说句实在话:这个 Skill 最打动我的地方,不是它省了多少 Token,而是它把「Agent 该有什么样的边界感」这件事,写成了一套可执行的规范。只读、限流、脱敏、熔断、降级、自检——每一条都在告诉你:一个靠谱的智能体,不是能力越大越好,而是知道什么时候该停手。
在这个人人都想给 AI 更大权限的年代,愿意花力气教它「少动手」的工具,反而显得格外清醒。