ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

QGIS 把 AI 贡献写进禁令:一份 140 行的政策被删到 15 行,人在回路为什么没守住

QGIS 把 AI 贡献写进禁令:一份 140 行的政策被删到 15 行,人在回路为什么没守住

一份一百四十行的政策,被删到只剩十五行

十月七日,QGIS 把一份只有十五行的政策文件合进了主干。

它删掉了原先一百四十行的 AI 工具使用政策,只留下一句式的禁令。

被替换的是同一年年初由 Even Rouault 起草的 QEP408,那版政策的核心是人在回路。

从人在回路到一律禁止,中间只隔了八个月。

新提案编号 QEP428,作者是 QGIS 核心贡献者 Nyall Dawson。

拉取请求号 387,改动统计是增加七行、删除一百四十行。

合入的时间戳落在十月七日晚上,随后源分支被删除。

十月十二日,这条消息被顶上 Hacker News 首页,拿下二百八十七分。

到当天下午,讨论串已经积累了二百九十五条评论。

一条十五行的政策能引发这种体量的讨论,说明争的从来不是 QGIS 本身。

QGIS 是一套开源地理信息系统,用 C++ 与 Python 写成,历史超过二十年。

它的贡献者里有大量来自测绘、遥感、城市规划与公共部门的工程师。

这类用户既是使用者也是回馈者,社区结构比纯互联网项目更紧密。

所以当它决定关门时,受到影响的是一整条职业化的贡献链路。

禁令的两句话写了什么

新政策的正文只有两句话,第一句划定范围,第二句写后果。

第一句说,qgis/qgis 仓库不接受任何由大模型、AI 或智能体协助产出的代码贡献。

第二句说,如果事后发现你用了 AI、LLM 或任何智能体工作流,代码会被回滚,贡献者权限会被制裁。

关键词是「事后发现」,它把举证责任放在维护者一侧,也把时间窗口拉到合入之后。

制裁手段写了两条:代码回滚,以及贡献者权限处置。

文件头部的版本号是 2.0,作者一栏从 Even Rouault 改成 QGIS 项目贡献者。

日期一栏保留了二零二六年九月二十四日,那是提案提交讨论的日子。

联系人一栏从个人邮箱换成了 qgis.org 这个组织地址。

这三处头部改动说明,它不再是一份个人提案,而是一份项目立场文件。

被删掉的旧政策不是敷衍之作,它有一百四十行,结构完整。

旧政策要求贡献者必须逐行读过并理解模型产出的代码,再请维护者评审。

它还要求贡献者能够在评审中回答关于自己改动的问题。

透明性方面,它要求用 Assisted-by 这类提交信息尾注标出工具使用情况。

它明确禁止了未经人类批准、在项目空间里自行行动的智能体,比如 GitHub 上的 @claude。

自动发布评论的评审机器人同样被禁,除非人类留在回路里。

旧政策甚至单列一节叫「提取性贡献」,专门描述只索取不回馈的行为。

那一节讨论了如何识别这类贡献,以及为什么它们会消耗维护者的时间。

它还建议新人从小改动起步,先建立对自己判断力的信心。

这些条款在文本层面几乎无懈可击,问题出在文本之外。

旧政策不是没写清楚,是没人执行

一位参与者在讨论里翻出了执行层面的账本。

他说,旧政策里设计的 extractive 标签从来没有被创建过。

与此同时,大约五十个拉取请求被打上了 AI Assisted 标记。

这五十个里面,约四十个最终没有合入主干就被关闭。

还有若干请求连标记都没有,直接在评审过程中被静默关掉。

这组数字说明一件事:标签体系先于流程崩溃了。

标记本身成了负担,而不是帮助评审者判断风险的工具。

分类要求假设了贡献者会主动披露、维护者会主动归类。

当提交量涨到某个阈值,这两个假设会同时失效。

Dawson 在回复里承认,旧政策的那套流程在现实中并没有发生。

他给出的理由是,机器产出的内容流量远超人类评审者能认真消化的上限。

这句话在另一位维护者 haubourg 的评论里被展开得更具体。

haubourg 说,来自外部贡献者的 AI 使用,给维护者的肩膀压上了难以承受的压力。

他描述了两个都不想要的结局:未评审请求越堆越长,或者代码在没被完整读懂的情况下合入。

他提醒,自由软件社区建立在人的网络之上。

机构信任 QGIS,是因为它们知道自己可以回馈,可以雇人做支持、培训和功能开发。

如果这个网络被稀释,项目会失去欢迎人类贡献者所需的带宽。

这段论证把禁令的动机从技术判断挪到了组织生存。

它也是整场讨论里被点赞最多的一条评论,四十五个赞成对四个反对。

一条自述:模型让我以为自己能修 QGIS

讨论串里最有分量的一段话,来自一位自称初级开发者的贡献者 Amalvir。

他说自己正是这条政策的直接影响对象,并且投了赞成票。

他此前提交过两个由 AI 协助的回归修复请求,用来定位缺陷原因并给出修复。

他说当时没有意识到,这样做会给本就脆弱的评审者社区造成伤害。

他承认自己还没有能力修复 QGIS 这种复杂度项目里的缺陷。

但模型给了他一种「这件事可以做」的错觉,几轮对话之后缺陷看起来就修好了。

他的原话是,这样做破坏了评审者与贡献者之间的信任契约。

那个契约的内容是:你在这个项目里提交改动,就说明你知道自己在做什么。

他补充了第二层影响,这一层很少有人讨论。

当贡献变得如此容易,使用 AI 的贡献者学到的东西很少甚至没有。

他们无法在项目里积累能力,也就永远没有希望成为评审者。

结果是社区停滞,维护者队伍得不到补充。

这段自述把一个抽象争论还原成一条具体的成长路径被截断。

它也让「禁止」这个动作有了可以辩护的动机。

一位核心贡献者随后引用了这段话,作为支持关门的关键理由。

值得注意的是,说这段话的人并不是被针对的对象,而是自愿放弃工具的人。

反对意见:边界在哪里,误伤有多大

反对的声音同样具体,而且大多不是关于要不要用 AI。

一位参与者 kannes 先讲清立场:他认为当前围绕 AI 的狂热在很多层面都是问题。

但他想指出一些技术上的好处,这些好处会被新政策一并禁掉。

他列举的第一项是用模型在代码库里发现不那么明显的上下文。

他强调模型经常出错,但结果可以被人用来理解代码,从而写出更好的贡献。

第二项是把模型当成一个模拟评审者。

把代码丢给它,拿到一份清单,丢掉无关部分,再看剩下的是否指出了真问题。

他把这种用法比作 IDE 里那个偶尔有用的助手,能减少错误并提高稳健性。

他担心「协助」和「使用」这两个词太宽,会把孩子和洗澡水一起倒掉。

他追问这份政策的意图到底是什么:是减少维护者压力,还是对 AI 表态。

如果是后者,他认为文本可以写得更清楚,立场也可以更强。

另一位参与者把边界问题问得更直接:这包括议题内容、评论和请求描述吗。

他得到的回答是,安全公告这一块过去几乎全部由 AI 撰写。

这说明同一条禁令在不同工作流上的实际边界并不一致。

Even Rouault 用一个小号回复了「倒掉孩子」的质疑,态度坦率。

他说他们清楚可能会倒掉孩子,但那个孩子可能本来就活不下来。

他把这份提案称为一个权宜之计。

他的理由是,两年前的世界虽然不算好,但至少没有今天这么糟。

在完全理解后果之前,没有理由放开。

他判断,也许要等这轮 AI 泡沫破裂,才能看清什么算是公平的 AI 使用。

另一条建议来自长期贡献者 adamjstewart,他谈的是范围。

他建议把文档、缺陷报告、讨论、请求描述和评论全部纳入管辖。

他的理由是,这些文字往往比代码本身更啰嗦,也更具提取性。

这条建议没有写进最终的两句话里,但它指出了政策执行的一个盲区。

Dawson 对范围的回答,是把这次改动定性为一道暂时关上的门。

他说这不会是一份刻在石头上的永久政策。

他用的措辞是:先关门,等时机安全、讨论充分时,再选择性地开一条缝。

他点名了两个可能的开口:把 AI 当作 IDE 自动补全的替代。

以及把 AI 用于语言翻译。

这两个场景都要按个案单独讨论,不会一次性放开。

他也解释了为什么要从最严格的一端起步。

旧政策的执行失败被摆出来之后,他的判断是项目已经因此失去至少一位价值极高的贡献者。

投票、数字与分歧的形状

提案在十月五日走完讨论期,进入投票阶段。

十月七日,标签从 Voting 换成 Accepted,随后合入主干。

讨论串里有三十条对话,参与者列表里出现十五个人。

投票结果用表情写在页面上:提案本身拿到六十九个赞成和十九个反对。

haubourg 那段解释维护者压力的评论,拿到四十五个赞成和四个反对。

Amalvir 那段自述拿到十三个赞成和两个心形。

赞成票里包括 Even Rouault 本人,也就是旧政策的作者。

他在投票评论里只写了一个加一。

这些数字不能直接等同于社区共识,但能说明分歧的形状。

赞成的一方集中在维护者负担和社区可持续性上。

反对的一方集中在边界模糊和技术好处被误伤上。

两边的共同前提是:评审者的注意力是稀缺资源。

分歧只在于,关门是不是保护这份注意力的正确手段。

两版政策并排看

把两版政策放在一起,差异会变得很直观。

下面这张表对比的是管辖对象、透明度要求和违规后果三个维度。

维度QEP408(旧,人在回路)QEP428(新,一律禁止)
管辖对象代码、提案、议题、安全漏洞、评论仓库内的代码贡献
允许的使用人工逐行复核后可以提交不允许任何协助式产出
透明度要求用 Assisted-by 尾注披露工具使用不再区分披露与不披露
智能体行为禁止未经人类批准自行行动禁止任何智能体工作流
违规后果评审阶段拒绝或要求重做代码回滚与贡献者权限处置
文本规模约一百四十行两句话

表格里最值得注意的一行是透明度要求。

旧政策把披露当作核心机制,新政策直接取消了这一层。

取消披露的理由很直接:如果使用本身就是违规,披露就只剩下自证其罪的功能。

把禁令写成钩子:一个真跑过的 commit-msg 检查

政策文本本身不执行任何检查,它需要落到工具链上才有牙齿。

最轻的一种落法,是在提交信息这一层加一道钩子。

下面这段 Python 脚本可以直接放进 .git/hooks/commit-msg。

它读取 Git 传进来的提交信息文件路径,逐行匹配被禁的尾注。

匹配目标是 Assisted-by 尾注。

它同时拦截把 Claude、Copilot、Codex、Gemini、Cursor 写进共同作者行的写法。

命中任意一条就打印拒绝理由并返回非零退出码,让这次提交失败。

这段代码在本机真实跑过两次,输出是确定的。

第一次喂进去带 Assisted-by 的提交信息,脚本打印拒绝行并返回退出码一。

第二次喂进去只带 Refs 的正常提交信息,脚本静默返回退出码零。

#!/usr/bin/env python3 # .git/hooks/commit-msg import re import sys BANNED = re.compile( r"assisted-by:|co-authored-by:\s*(claude|copilot|codex|gemini|cursor)", re.IGNORECASE, ) def main(path): text = open(path, encoding="utf-8", errors="replace").read() hits = [line.strip() for line in text.splitlines() if BANNED.search(line)] if not hits: return 0 print("QEP428: commit message carries an AI-assisted trailer, rejected") for line in hits: print(" -", line) return 1 if __name__ == "__main__": sys.exit(main(sys.argv[1]))

这段钩子只能拦住声明出来的工具使用,拦不住隐瞒。

它的价值在于把「必须披露」这条旧政策要求变成可执行的检查。

而新政策把披露这一层整个拿掉了,因为它不再区分披露与不披露。

在禁令之下,钩子的作用从确保透明变成提供事后追溯的线索。

这也解释了为什么新政策把后果写成回滚与权限处置,而不是要求补充说明。

如果项目愿意,还可以把检查扩展到共同作者行之外。

例如扫描请求描述模板里的固定段落,或者校验提交者签名与已知账号的对应关系。

但这些手段都只能降低噪声,不能替代评审者读懂代码这件事。

关门的代价与开源治理的下一步

把这件事只看成 QGIS 一家项目的选择,会漏掉它真正的位置。

过去一年里,已经有一批开源项目在收紧 AI 贡献的口子。

有的要求披露,有的要求人类逐行负责,有的直接禁止。

LLVM 的政策是人在回路的代表文本,要求贡献者对每一行负责并标注工具使用。

GDAL 的 RFC 111 走了同一路线,把披露与复核写进正式流程。

QGIS 的特殊之处在于,它先试过最温和的那一档,然后退回了最严格的那一档。

这条路径比单纯的禁令更有信息量,因为它包含一次失败实验的结果。

失败的关键指标不是有多少 AI 请求被提交,而是有多少被认真评审。

五十个标记、四十个关闭、一个从未创建的标签,三个数字指向同一件事。

流程设计假设了贡献者会主动披露、维护者会主动分类。

当提交量涨到某个阈值,两个假设同时失效。

于是政策被迫从管理使用切换到禁止使用,因为前者需要的人力更多。

这也意味着禁令的可持续性取决于同一件事:维护者的人力是否够用。

关门降低了分类成本,但把判断成本转移到了发现环节。

事后发现的机制要求有人持续怀疑、持续核查,这同样需要时间。

Dawson 承诺的按个案开口,是这个机制唯一的减压阀。

如果开口的节奏由维护者随意掌握,政策就会在边界上反复摇摆。

如果开口需要公开的判据,比如翻译场景与补全场景各自的门槛,争议会小得多。

对贡献者来说,可操作的建议反而变简单了。

在 QGIS 仓库里,不要提交任何由模型生成或改写的代码,包括看起来很小的修复。

不要用模型生成请求描述或评论,除非项目明确放开这一项。

如果确实用了模型做理解或验证,也把它留在本地,不要让它出现在提交物里。

把贡献规模压到自己能完全解释的程度,这是旧政策里唯一没有被争议的建议。

对维护者来说,这次讨论提供了一份现成的风险清单。

分类标签在提交量低的时候有效,在提交量高的时候会先崩。

更稳的做法是把披露要求绑在工具链上,而不是绑在人的自觉上。

提交信息钩子、签名验证、贡献者协议都可以承担一部分过滤。

这也是整场讨论里唯一没有分歧的结论。

模型的产出速度可以无限提升,人类评审的注意力不能。

所有治理设计最终都要回到这个不对称上。

QGIS 选择用关门来缩小输入,把不对称暂时拉回可控区间。

这个选择会付出代价,代价包括误伤那些只用模型做理解的贡献者。

代价还包括短期内失去一部分愿意尝试新工具的新人。

项目赌的是,保住评审者网络比留住这部分新人更重要。

这个赌注是否成立,要等下一年的贡献者数量才能验证。

在那之前,这份十五行的政策就是 QGIS 给出的答案。

它把问题从「怎么用好 AI」改写成「怎么保住人」。

这个改写本身就是本轮事件最值得记录的部分。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进