起因:多个 AI agent 共用一个 GitHub 账号
很多开发者已经让对话式 AI 代跑开源贡献流程:建分支、写 commit、开 PR、回 issue。随着 AI 工具增多(豆包、atomcode、codex……),一个现实问题出现了:多个 AI agent 要共用你一个人的 GitHub 账号去操作。token 散落在各处、一个 token 干所有事,出了权限问题分不清是谁的责任,泄露了也不知道影响范围。
我们的做法:把 GitHub token 统一收进一个本地约定目录(~/.config/github/),按职责分文件,跨会话、跨工具共享同一份约定。
核心设计:按职责分文件,互不混用
一张 Mac 上目前维护三个 token,各管一摊:
只读 API token(fine-grained):跨项目查公共数据、提升 API 限流配额,不能写任何东西
玄铁上游一条龙 token(classic
public_repo):推 fork 分支 + 开上游 PR + issue / 追评,全部 API 自动化某个上游仓库的专用 PR token(fine-grained):只授权一个 fork 仓库,仅用于给那个项目交翻译 PR
原则三条:最小权限、单一职责、互不混用。用文件而不是环境变量,是因为多个会话、多个 agent 都要读同一份约定,文件路径可复用、可审计;环境变量只活在一个 shell 里,撑不起跨会话协作。
为什么玄铁仓的 token 用 Classic 而不是 Fine-grained
玄铁(XuanTie)是一门开源中文编程语言,我们作为贡献者要给它上游仓开 PR。踩过的坑:fine-grained token 的「Only select repositories」只能选自己拥有的仓库,选不到别人的上游仓库—— 开上游 PR 直接 403。classicpublic_repo覆盖所有公开仓库,推分支、开 PR、回 issue 一条龙都够。
还有一个隐蔽的坑:重 fork 之后,fine-grained 的授权列表会失效。授权列表挂的是旧仓库 ID,删库重 fork 后推新 fork 分支照样 403。所以我们后来把「推分支 + 开 PR + issue」合并进一个 classic token,单一职责,不再维护多个半残的 fine-grained。
workflow scope:推含 ci.yml 的分支被 GitHub 拒绝
上游仓库一旦引入 GitHub Actions 工作流文件(.github/workflows/ci.yml),基于最新 master 建分支再推送就可能被 GitHub 拦下:
refusing to allow a Personal Access Token to create or update workflow .github/workflows/ci.yml without 'workflow' scopeclassic token 的
workflowscope 只能在新建时勾选,已建 token 补不了fine-grained 需要加Workflows: Read and write
网页交互还有个坑:Settings 里的Generate new token 是下拉按钮,要再点一下(classic)才进 classic 配置页
提交约定:诚实标注人类参与程度
token 是基础设施,标注规范是行为准则—— 两者配套,才构成完整的协作约定。核心一条:诚实。
批准 ≠ 审阅:声明只写「人类已在 Agent 对话中批准提交」,不冒充「逐字审阅」
提交 vs 追评,两套标注:创建 issue/PR、提交 commit 用「人类已批准」;AI 自行追加的评论(补验证、补测试结果)用「AI 代理自行追加、未经人类逐字审阅」
红线:任何「人类已批准」的表述,必须以人类真实批准为前提
我们也犯过错:给 closed issue 追评验证结论时,尾巴误套了「人类已批准提交」—— 那条评论人类根本没批准。被指出后补上了「适用范围边界」:追评是 AI 自作主张,信息可以给,措辞必须诚实。
AI 自己查 CI:不依赖人类截图
协作里还有一个高频动作:挂完 PR 后确认 CI 结果。以前靠人截图 PR 列表的对号、展开 checks、copy Actions 链接喂给 AI;现在 agent 自己调 GitHub REST API:
GET /repos/{owner}/{repo}/pulls/{n}/commits?per_page=1 # 取最新 commit sha GET /repos/{owner}/{repo}/commits/{sha}/check-runs # 读 check runs解读规则:
check_runs为空 = CI 未触发(纯文档 PR,paths-ignore 生效 —— 没有对号是「跳过」不是失败)每条 run 的
conclusion:success = 绿勾,failure = 红叉html_url就是该 job 的 Actions 页面链接,省去手动 copy
安全红线
token 文件权限
600,仅本用户可读写严禁提交进任何 git 仓库、发到外部服务、贴公开渠道
过期后重新生成并覆盖对应文件,文件名保持不变(使用方无需改动)
落地效果
这套约定已经跨会话持续生效:多个豆包会话、其他 AI agent 都读同一份文档。玄铁语言的 macOS/arm64 自举 PR、历史 issue 的验证追评、CI paths-ignore 配置的实测确认 —— 都是这套「按职责分文件 + 诚实标注」支撑下来的。
可复用的一句话:token 按职责分文件是基础设施,标注规范是行为准则;基础设施管「能不能」,行为准则管「怎么诚实地用」。