AI 辅助提交怎么标:Assisted-by、Co-authored-by 与签名别混

git log 末尾那一行,看起来像名牌,实际该干的是配料表的活:写清用了什么工具、哪个模型,把签名、签核和责任留给按合并键的人。

分享
AI 辅助提交怎么标:Assisted-by、Co-authored-by 与签名别混

一句话结论:提交末尾那一行不是"介绍一位新同事",而是配料表——它只回答"这次改动里有没有 AI、是哪个工具、哪个模型",不承担署名、签核、担保中的任何一项。而一旦这条标签变成"没人检查的可选规范",它就会退化成噪音:Linux 内核刚刚用 10% 的遵守率证明了这一点。

披露:本文编译自 Barista Labs(Sean McLellan)同一主题的两篇:主文《Assisted-by git trailer: provenance for AI-assisted commits》(2026-06-20 发布、2026-10-23 更新),以及同日发布的姊妹篇《Linux is dropping Assisted-by: what AI disclosure needs》(2026-10-23)。前者给概念与策略表,后者给内核时间线与可执行的强制方案,本文按顺序合并编译;第四节的各家政策表述另外参考 All Things Open 2026-05-11 的梳理。文中数字、引语与时间线均来自原文及其引述来源,我们未独立验证;标了"编者补充"的 git 命令不是原文内容。


一、早上你跑 git log 看到的那一行

最后一条提交的末尾写着:

Co-authored-by: Claude <noreply@anthropic.com>

再去 PR 页面上看,贡献者头像是两个——旁边多了一个,好像昨晚有位叫 Claude 的同事加入了这个项目,还和你一起交付了代码。

它没有。没人招过它,没人能把它排进 review 轮值,也没人能要求它证明"自己有权提交这次改动"。

这一行看起来是名牌,实际干的是溯源记录的活。 两者之间的落差,就是本文要处理的问题。

那个 footer 真正要回答的,不是"团队里还有谁",而是一个更窄但更有用的问题:这次改动里 AI 是否起了实质作用?这件事写在哪,能让下一个人不用猜?

二、一行小字,吵在明面上:Artsy 的 RFC

Artsy(艺术品交易平台)把这场争论放在公开流程里跑了一遍:

  • 2026-05-27 开 RFC,标题就是《disclose LLM usage in commits or PRs》(在提交或 PR 里披露 LLM 使用);
  • 2026-06-08 合并。

提案本身克制得出奇:采用一个轻量约定,给"有显著 LLM 参与"的提交或 PR 打标记,记录供应商,可选记录模型。

第一稿用的就是 Co-authored-by —— 因为这正是所有人都已经会用的那个 trailer。讨论把团队说服了,改成:

Assisted-by: Claude:Opus-4.5

Joey Aghion 在讨论里的理由很干脆:Assisted-by 之所以有说服力,是因为它让责任看得见、且排他地留在人类贡献者身上,哪怕 GitHub 的界面根本不把它算作一个贡献者。"最后那半句是特性,不是 bug"——重点就在于工具不该获得一个头像。

他还主张"先合了再说",好让团队真正看到这个约定到底带来多少麻烦、多少价值。这种诚实的采纳方式,比任何治理框架都少见。

讨论里没人假装这事很干净,团队自己戳了四个真实边缘:

  1. 提交级还是 PR 级? 每个提交一条精确但嘈杂;写在 PR 描述里省事,但模糊了"到底哪次改动被 AI 碰过"。
  2. Cursor 的 auto 模式怎么办? 工具自己选模型、且不告诉你是哪个 —— 你没法记录一个你从没拿到过的模型名。
  3. 大家会不会用 Claude hook 或 shell alias 自动化? 那样标签会不管有没有实质帮助都照常出现。
  4. 现在几乎所有提交都是 AI 辅助的吧? 如果标签永远亮着,它还意味着什么?

这几条不是"所以别做"的理由,它们就是这个设计问题本身,也是每个团队动手那一周都会撞上的同样四个问题。

三、为什么用 trailer,为什么偏偏是这一个

git 支持在提交消息末尾写结构化的 key: value 行,这是有意设计的,git 自己就文档化了怎么解析它。这就是"可 grep 的披露"和"写在 PR 描述里、没人会读第二遍的一句话"之间的区别。

半年后你想回答"这个版本里哪些提交有 AI 参与",trailer 能直接给你答案,而翻 review 线程不能。

Co-authored-by 之所以诱人,是因为 GitHub 已经为"多人协作提交"文档化了它——就在那儿、能用、还渲染得好看。但它是为人设计的,而且它做出的是一个人形的声明。Bence Ferdinandy 早在去年 12 月就说得直白:"别把 Co-authored-by 滥用来标记 AI 辅助。" 共同作者意味着这个实体共享著作权与问责;模型无法承担问责,所以这行字在你写下的那一刻就是假的。

还有一件事要说清楚:这不是签名那场讨论。GitHub 会在密码学签名校验通过时给提交打 verified 标记——它只说明"某个密钥为这次提交作了担保",对"有没有模型参与写作"一无所知。

签名是"谁为它站台",溯源是"它由什么做成的"。这两件事请分开放。

四、不只 Artsy 一家

这不是某家公司的内部风格。开源社区已经吵了好几个月:James Fredley 在 2026-05-11 的 All Things Open 那篇里梳理了从"完全禁止"到"强制披露"的光谱,并指出:选择"允许 AI + 定规则"的项目,最后都落在同一类 trailer 上。

当时已发布指引的名单并不边缘,各自的写法也不完全一样:

项目 / 基金会 要求什么
Fedora 推荐 Assisted-by:;当"贡献的显著部分未经修改地取自工具"时必须披露
Rocky Linux 明确以 Fedora 为模板,同样推荐 Assisted-by:
LLVM 推荐 Assisted-by: 做透明化,强制人在环,并禁止 agentic bot 未经人工批准在项目空间行动
OpenTelemetry 推荐 Assisted-by:,给的例子是 Assisted-by: Claude Opus 4.5
Apache ASF 建议用 Generated-by:,好让发布工具能把它抽进机器可读的 Tooling-Provenance 文件
OpenInfra 两个都用:一般辅助用 Assisted-by:,整块生成用 Generated-by:
Linux 内核 曾要求 Assisted-by: AGENT_NAME:MODEL_VERSION [TOOL1] [TOOL2],后简化为 Assisted-by: LLM [TOOL1] [TOOL2],2026-10 正在移除
QEMU / Gentoo / NetBSD 直接禁止 AI 生成内容(Gentoo 2024 年投票、NetBSD 视为"受污染"、QEMU 一律拒收)

内核的版本写得最细,也成了最好的反面教材。 它先要求写成 AGENT_NAME:MODEL_VERSION,后来简化成 LLM,然后:

  • 2026-10-09 Sasha Levin 提交补丁,从 coding-assistants.rst、submitting-patches.rst(含各语言译本)和 checkpatch.pl 里删掉 Assisted-by 相关内容;
  • 10-13 的 v2 带上 Kees Cook 与 Greg Kroah-Hartman 的 Reviewed-by、Lorenzo Stoakes 的 Acked-by;
  • 10-21 Christian Brauner 也加了自己的 Reviewed-by;
  • 截至 10-23,linux-next 文档里的那段已经没了,主线 7.3 文档里还在——所以准确的措辞是"正在移除",不是"已移除"。

把这几份读下来,共识其实很一致:写下 AI 帮了忙、点名工具、能点名就点名模型,然后把签名、认证、问责全部留在人身上。 内核的撤退并没有推翻这后半句,它推翻的是另一个假设——只管在文档里要求,大家就会写。

五、营养标签,不是名牌

这是原文最值得记住的一个比喻,它同时告诉你该写什么、更该不写什么。

类型 它声明的是 谁拥有它
名牌(Co-authored-by) "我是这个团队的一员" 这就是 AI 无意中做出的声明,连头像都给了
签名(verified 徽章) "我,一个有密钥的人,为这次提交担保" 永远属于人
配料表(Assisted-by) "里面有什么成分" 它不投票、不签名、不入伙,也不假装原料有主见

所以标签上该写:AI 对这次改动有实质帮助、是哪个工具、工具愿意说的时候是哪个模型。

不该做的是:把工具变成共同作者、代替你的签核、伪装成签名、或者索要一个工具拒绝暴露的模型名。

如果 Cursor 的 auto 模式不肯说它选了哪个模型,诚实的标签是"工具名 + auto",而不是猜一个。写着厨师从没见过的配料的配料表,比承认"这是商业机密配方"更糟。

六、一张能直接填的仓库策略表

你不需要一套治理程序,你需要仓库里半页纸:说清什么时候打标签、标签长什么样。这样它才是习惯,而不是每次提交都重新辩论一遍。

字段 它回答的问题 一个可用的起步答案
触发条件 什么时候打标签 AI 实质塑造了这次改动时:它写了或重写了真实逻辑;只是自动补全了一个变量名时不算
放哪里 提交还是 PR 单个提交明显是 AI 写的时候就打在该提交上;帮助分散在整个分支上时写在 PR 层
格式 那行长什么样 Assisted-by: TOOL:MODEL(Artsy 的例子是 Assisted-by: Claude:Opus-4.5);模型不可见时只写工具。别抄内核那个 AGENT_NAME:MODEL_VERSION —— 内核自己都放弃了
字段 记什么 工具必记;工具愿意说的时候记模型;不记任何假扮成人的东西
保持属于人 AI 永远不碰的东西 Signed-off-by、DCO 认证、签名、评审人的名字
诚实规则 auto 模式怎么记 记工具 + auto;永远不要编造你没拿到的模型字符串
强制执行 你怎么知道标签是真的 一个在每个 PR 上要求 yes/no 回答的 CI 检查;或者干脆不搞 trailer 规则,改成 PR 描述里几句话说清
红线 你不越过的那条线 不给工具用 Co-authored-by;不要自动盖到每个提交上,否则标签就不再有意义

这张表里只有三行是真正干活的,也正是大家会跳过的三行:

  • 触发条件——在周二为某次提交争论之前,先定义好什么叫"实质",否则标签会挂到每一件事上。
  • 保持属于人——这一行让整套东西保持诚实:trailer 只增加上下文,绝不把责任从人身上挪走。
  • 强制执行——这一行是内核用最难受的方式学到的。其余都只是格式问题。

一个顺带的好处:一旦标签稳定下来,git log --grep='Assisted-by' 就变成了一个真问题的真答案,评审人也能拿到一个可过滤的信号。

七、内核在 Assisted-by 上学到了什么

一句话版:一个没人检查的可选标签,会变成噪音。要么在 CI 里执行它,要么就在评审人本来就会读的地方写几句话。

让内核下决心的是数字。LWN 统计了 7.3 周期到 -rc7 的 18,533 个非合并 changeset,其中 1,884 个(本质上是 10%)带了 Assisted-by 标签。而同一次 Summit 上,LWN 记录 Dave Airlie 的估计:约 90% 的贡献者都在用 LLM。

Levin 的 v2 补丁把后果写得很直白:这个标签"不再提供它被保留下来时想要的那个信号——它的缺失并不能说明补丁是怎么做出来的"。补丁也把决定描述成一个二选一:"要么找到办法强制执行这条要求,要么放弃它",而"会场里有强烈(虽非一致)的共识:放弃"。关于工具如何被使用的信息,应该改放到补丁的 cover letter 里。

当初主张要标签的人,后来公开改了主意。曾经支持的 Greg Kroah-Hartman 在 10-13 写道:

"我现在改主意了,它完全没起作用,维护者们被它烦透了,所以我们干脆放弃,把注意力放回补丁本身。"

Kees Cook 回复 v1 更短:"它已经变得和我用什么编辑器一样冗余。"

但并非一致,而异议恰好点出了真正的开放问题:

  • Steven Rostedt 反对把理由只写在 LWN 文章里("这类改动不该依赖 LWN 文章"),并提出一个更强的标签 Vibe-coded-with:;
  • Laurent Pinchart(据 The Register 报道)表示"在没有加入另一种强制披露机制的情况下删掉标签,我不满意"。

如果不用标签,那用什么?——这正是下一节。

内核保住了什么

撤标签不等于撤披露,更不等于撤问责。三条都还在:

  1. DCO 规则:AI 代理永远不许加 Signed-off-by,因为只有人能合法认证开发者原产地证书;
  2. 提交者负责:发出补丁的人对补丁负责,不管用了什么工具;
  3. 文字披露:按 v2 补丁,工具使用信息放在补丁的 cover letter 里;另一份要求透明度的 generated-content.rst 指引不变。

这部分才是最该抄的:内核把披露从"没人检查的机器可读行"挪回了"评审人在读 diff 之前会读的那段文字"。

八、一条披露规则要过三道检验

这一节是 BaristaLabs 的判断,不是内核的决定。他们认为一条披露规则必须过三关:

  1. 有人真的会读它。说得出读者是谁、他会因此做什么不同的事。一个会因此更仔细看生成的测试的评审人,是读者;一个没人打开的看板,不是。
  2. 沉默本身有意义。如果"没有标签"既可能是"没有 AI"也可能是"懒得写",这个标签就零信息量——这正是内核的问题。
  3. 它待在评审本来就在的地方。提交 trailer 适合审计与 git log 查询;PR 描述与 cover letter 适合评审人。

据此只有两条可行路线,而它们共享一条硬线:

方案 你要什么 你怎么知道它是真的 适合谁
强制执行 每个 PR 强制回答 yes/no,回答 yes 时要求 trailer 没回答 → CI 失败;检测到 trailer → 自动打标 需要"哪些改动有 AI 参与"审计链的团队
要求散文 PR 描述或 cover letter 里几句话:用了哪些工具、用在哪 评审人带着 diff 一起读,可以追问 更在意评审质量而非计数的团队
两者共有 只有人才能加 Signed-off-by、只有人能批准合并 分支保护 + DCO 检查 所有人

要避开的正是内核刚退役的那一种:没有检查的可选 trailer。

九、三个可以直接抄的开源实现

你不需要自己造检查器,已经有人把零件开源了(原文列了三个,均于 2026-10-23 核对):

  • CHAOSS 的 disclosure:扫描一个提交区间,找 Co-Authored-By / Assisted-By trailer、已知 AI bot 的提交邮箱、以及 codex/、claude/ 这类 agent 分支名。disclosure scan --range=BASE..HEAD 无 AI 信号退 0、有则退 1,可直接当 CI 步骤;它的 GitHub Action 会给 PR 打标签,文本命令还能读 PR 描述里的勾选项。
  • Nextcloud 的 ai-policy.yml:发现助记 trailer 就给 PR 打 "AI assisted" 标签;当 coding agent 添加了 Signed-off-by 行时直接让检查失败。
  • HyperSpy 的 ci-check-ai-trailers.py:当提交在 Co-authored-by 里点名 AI 工具时让 CI 失败,并提示贡献者改用 Assisted-by。

但必须说清楚它们的边界:这三样都看不见"没人披露的 AI 使用"。检测能抓到 trailer、bot 邮箱、分支名,抓不到意图。所以原文的建议是把"回答"变成必答项——PR 模板里一个 yes/no 勾选框 + 一个"两个框都没勾就失败"的 CI 步骤;这时"没回答"是失败,而不是沉默。

如果强制执行的成本高于信息本身的价值,那就走内核那条路:要求散文。比如这两行:

"用 AI 助手起草了解析器测试;边界用例手工审阅并重写过。"

对评审人来说,这比一串 trailer 有用得多。

十、这个标签在整个体系里的位置

如果你用过原文作者的其他概念,这条 trailer 属于下游,不是又一道门:

  • AGENTOWNERS 是门:它决定一个 AI 写的改动能不能进入仓库,在任何人读 diff 之前。
  • review lanes 是车道:改动进来之后,谁来看、按什么顺序看。
  • work receipts 是收据:agent 在一个任务里到底做了什么。
  • Assisted-by trailer 是另一回事:它不是门,也不是另存一份的收据。它是跟着改动一起走、烤进历史的标签——PR 线程归档之后、记得上下文的人都走了之后,它还在那儿。
门决定改动能不能进来,车道决定谁来看,而 trailer 是这次改动对它自己的永久陈述。

十一、从一个仓库开始

别写"AI 披露框架"。先在一个仓库里加一条约定——那个"一年后你会真的想知道哪些改动有 AI 参与"的仓库。

原文的步骤,照抄即可:

  1. 写下谁会读这条披露、他会拿它做什么;
  2. 选"强制执行"或"散文",不要发布第三种"可选"方案;
  3. 定下什么算"实质";
  4. 选提交级还是 PR 级,然后认下来;
  5. 如果强制执行:加 PR 勾选框 + CI 步骤;如果选散文:在 PR 模板里加两个提示问题;
  6. 在仓库里放一个提交模板,让那行字是一次按键,而不是需要记住的事;
  7. 把 auto 模式的规则写下来,免得有人编造模型名;
  8. 把 Signed-off-by 和合并批准留给人,并在 CONTRIBUTING.md 里写明。
下一次你跑 git log、看到提交末尾那一行时,希望它读起来像一张配料表,而不是在介绍一位从未存在过的同事。

十二、编者补充:三条命令

原文是概念与政策层的,这里补最小可用的 git 操作(编者补充,非原文内容):

# 写(git 2.32+)
git commit -m "fix: handle empty case" --trailer "Assisted-by: Claude:Opus-4.5"

# 解析(懂块边界与多值,比 grep 可靠)
git log -1 --format='%(trailers:key=Assisted-by,valueonly)'

# 反查
git log --grep='Assisted-by'

要注意的是:trailer 是纯文本,谁都能写。所以它的可信度不来自格式,而来自谁写——这一点我们在 多 Agent 同机:Git 作者、凭据与提交归属怎么分 里拆过:归属信息最好由不参与推理的那一层写(引擎 / 包装层 / hook),而不是指望 agent 自己记得。

十三、边界

  • 本文为编译整理,未独立验证任何数字或时间线:18,533 / 1,884 / 90%、补丁日期与署名、RFC 时间点均来自原文及其引述来源。
  • 内核状态是"正在移除":linux-next 文档已删、主线 7.3 文档尚存(截至 2026-10-23),补丁仍可能改动。引用前请核对最新文档树。
  • LWN 对 Summit 的报道,作者 Jonathan Corbet 自己加了注:那是他对一场邀请制讨论的"完全个人解读";一手记录是补丁文本与邮件列表回复。
  • 各家政策会变(Fedora / Rocky / LLVM / OTel / ASF 都在更新),第四节的政策描述是 2026-05 至 2026-10 的快照。
  • 本文讨论的是"怎么记",不涉及"该不该允许 AI 参与"——后者各家分歧极大(QEMU / Gentoo / NetBSD 直接禁),本文不做价值判断。

相关阅读:AI 编程 / Vibe Coding 完全指南 | 多 Agent 同机:Git 作者、凭据与提交归属怎么分 | 1,866 个项目的 Agent 说明书实测 | Claude Code 团队怎么做代码评审:7 层防线 | Agent 审计日志:让篡改留下形状

Sources

本文由 hubwiz 编译整理,转载请注明出处。

这是「AI 编程 / Vibe Coding」专题的一部分。完整地图见:AI 编程 / Vibe Coding 完全指南