AI 輔助程式碼如何符合開源專案政策?
開源專案對 AI 輔助程式碼的規定並不一致,提交 PR 前先查閱政策,並在 commit trailer 揭露使用情況,避免修補程式被拒。
在將 AI 輔助程式碼提交至上游前應採取的措施
目前,開放原始碼專案會發布 AI 輔助程式碼政策,但各專案的政策並不一致。因此,應養成簡單的習慣:在撰寫修補程式前先查閱政策,提交時準確揭露使用情況。這些政策背後都有一項共同原則:絕對不要提交任何無法在程式碼審查中說明的程式碼。
即使修補程式本身正確,如果專案禁止產生式程式碼,或你隱瞞程式碼來源,仍可能被關閉。責任會落在你的名下,並且持續影響你的紀錄,因為維護者日後發現遺漏時,沒有理由再信任你過去的貢獻。先說明幾個政策中會使用的詞彙。LLM(large language model)是程式碼代理程式背後使用的模型。GitHub 上的 PR(pull request)在 GitLab 上稱為 MR(merge request),以下內容同樣適用於兩者。DCO(developer certificate of origin)是 commit message 底部的 sign-off 行,而它最後成為整個爭議的核心。
開源專案對 AI 產生程式碼的政策走向
各專案大致分成 4 類。以下每個例子都標註日期,因為這些文件仍會變動。
禁止。 Gentoo council 於 2024 年 4 月 14 日表決,明文規定「不得向 Gentoo 貢獻任何在 Natural Language Processing artificial intelligence tools 協助下產生的內容」。NetBSD 的 commit guidelines 將 LLM 產出的內容稱為「tainted code」,並規定「未事先取得 core 的書面核准,不得提交」。截至 2026 年 8 月,QEMU 的 code provenance 文件仍表示,專案將「拒絕任何被認為包含或源自 AI 產生內容的貢獻」。
僅限分析。 多數禁令的範圍比標題所暗示的更窄。QEMU 的文件指出,政策「不適用於其他 AI 用途,例如研究 API 或演算法、靜態分析或除錯,前提是其輸出不包含在貢獻中」。你可以使用 agent 閱讀程式碼,但不得提交它撰寫的內容。這項區分是多數限制較嚴格的專案實際採用的界線,也是人們最容易忽略的地方。
必須揭露。 Fedora council 於 2025 年 10 月核准 AI 輔助貢獻政策。政策允許使用相關工具,但責任由貢獻者承擔:貢獻者是作者,必須對整份貢獻負完全責任;若其中重要部分直接來自工具且未經修改,也必須揭露。Linux kernel 於 2025 年 12 月在 process documentation 中新增 coding assistants 頁面,提供記錄所用工具的 trailer,並明確規定誰可以 sign off。
沒有成文規定。 這仍是最常見的情況。2026 年 5 月的一份 preprint 調查 1,000 個熱門 GitHub repositories,發現只有 118 個具有任何書面的 AI 政策。保持沉默不代表允許。撰寫 patch 前,先在 issue tracker 用一句話詢問;這樣得到的答覆會成為公開紀錄,日後可以引用。
維護者制定這些規則的原因
第一個原因是審查負擔,而且成本差距只會朝單一方向擴大。代理程式可以在 1 分鐘內產生一份看似合理的 400 行合併請求。維護者要妥善審查這份請求,卻得花費一個下午,而且多數維護者都是志工。提交成本已降至接近 0。審查成本卻完全沒有下降。
curl 顯示了這條曲線的另一端。Daniel Stenberg 在 2025 年年中表示,透過該專案錯誤獎勵計畫收到的安全性報告中,約有 5 分之 1 屬於他所稱的 AI 垃圾:這些報告會提到真實的函式與真實的程式碼路徑,描述看似合理的攻擊,實際上卻毫無內容。該專案在 2026 年初結束獎勵計畫,不再持續為這股洪流提供資金。這些是報告而非修補程式,但讓維護者打開你的 PR 時已經感到疲憊的機制相同。
GNOME Calendar 將這個問題明確寫成標籤。2026 年 6 月,該專案為顯示「嚴重或完全依賴人工『智慧』產生程式碼」的合併請求引入「Probabilistically Automated」標籤,並精確指出其徵兆:「通常伴隨缺乏適當測試,以及根據理論上的預期行為而非程式碼正確性完成修補程式。」請把最後這句話讀 2 次。程式碼看起來應該能運作。卻沒有人確認它是否真的能運作。
第二個原因是來源,也就是程式碼來自何處,以及採用什麼授權條款。QEMU 清楚說明了這項衝突:簽署 sign-off 表示你「完全了解所貢獻內容的著作權與授權狀態」,但模型輸出的著作權狀態尚未確定。Gentoo 的委員會也提出相同原因,另外還包括品質與倫理。你不必同意這種法律解讀。但你必須注意,這是維護者要做的決定,不是由你決定。
如何找到專案的 AI 政策?
請依序查看以下位置。
- 儲存庫根目錄中的
CONTRIBUTING.md,接著查看.github/CONTRIBUTING.md,以及旁邊的任何DCO檔案。 - 開發人員文件。QEMU 將規則放在
docs/devel/code-provenance.rst。核心將規則放在Documentation/process/coding-assistants.rst。 - 專案網站或 wiki。Gentoo 的政策位於 council 的 wiki 頁面,NetBSD 的政策則位於提交指南中。
- issue tracker 與 mailing list archive。政策通常會先在這些地方存在數個月,之後才有人將其寫入儲存庫。
在 checkout 中執行以下 grep,即可涵蓋大部分內容:
grep -rniE '(llm|copilot|chatgpt|generative|ai-generated|ai-assisted)' CONTRIBUTING.md docs/ .github/ 2>/dev/null | head -20接著查看專案本身的歷史,因為已提交的慣例比任何摘要更具依據:
git log --format='%(trailers:key=Assisted-by,valueonly)' | grep . | sort | uniq -c
git log --format='%(trailers:key=AI-used-for,valueonly)' | grep . | sort | uniq -c數值旁的 trailer 值計數,可告訴你這個專案實際使用的格式。若結果為空,表示目前沒有人以該格式在此處揭露,這本身也是資訊。如果專案位於 GitHub,且你不熟悉這項工作流程,GitHub 上 pull request 與 fork 的運作方式涵蓋了本節所假設的操作細節。
在 commit trailer 中揭露,不要寫在註解中
Trailer 是 commit 訊息最後一段中的 Key: value 行。Git 已將此格式用於 Signed-off-by: 和 Co-authored-by:,各種工具也能解析,因此這是唯一會隨程式碼一同進入 tree 的揭露方式。
net: release the buffer on the error path
The error path returned before releasing the buffer, so every failed
setup leaked one page.
Assisted-by: Claude:claude-3-opus coccinelle sparse
Signed-off-by: Your Real Name <you@example.com>核心文件將此格式記載為 Assisted-by: AGENT_NAME:MODEL_VERSION [TOOL1] [TOOL2],並明確說明這一行的限制:「AI agents MUST NOT add Signed-off-by tags. Only humans can legally certify the Developer Certificate of Origin (DCO).」agent 的名稱放在 Assisted-by。你的名稱放在 Signed-off-by。絕對不要讓工具寫入第二個名稱,也不要讓工具捏造一個不屬於任何人的 Co-authored-by 位址。
名稱格式各不相同,因此請複製當地使用的格式,不要自行建立。2026 年 5 月,QEMU mailing list 上有人提議,針對機械式變更、測試、文件及 20 行以下的 bug fix,放寬該專案的禁令,並以類似 AI-used-for: tests, docs 的 trailer 記錄。截至 2026 年 8 月,這仍只是 mailing list 上的提案,而已提交的文件仍拒絕產生的內容。有一個專案在 2023 年至 2026 年間兩度改變立場。下一次變更不會等你,因此方法比清單更重要。
git commit -s --trailer "Assisted-by: Claude:claude-3-opus" -m "net: release the buffer on the error path"
git log -1 --format='%(trailers:key=Assisted-by,valueonly)'--trailer 需要 Git 2.32 或更新版本。第二個指令應直接回傳該值。若輸出空白行,表示 git 未解析 trailer;幾乎總是因為訊息底部的 trailer 區塊中間有空白行或一般句子。對於已經撰寫完成的一系列 commit,git rebase --signoff origin/main 會為每個 commit 加上 sign-off,而 git interpret-trailers --in-place --trailer "Assisted-by: Claude:claude-3-opus" msg.txt 會編輯訊息檔案。
有兩種失敗情況值得預先處理。Squash merge 會改寫 commit 訊息,因此對於採用 squash 的專案,請在 PR 描述中再次揭露,讓 maintainer 能夠讀到。review comment 不是正式紀錄,因為 comment 可以修改,而且永遠不會進入 git history。
準確性是雙向的。在你親自輸入的 commit 上加入 Assisted-by 是雜訊,也會降低真正揭露內容的可信度。若 agent 撰寫的 commit 沒有加入該標記,則會終止這段合作關係。
Signed-off-by 實際上代表什麼?
DCO 是一份簡短的文字,版本為 1.1,發布於 developercertificate.org,核心專案、QEMU 及許多其他專案都採用它。加入 Signed-off-by: Your Name <you@example.com> 表示你對其內容作出認證。請先閱讀你所認證的內容,因為多數人從未讀過就簽署了它。
條款 (a) 表示該貢獻「全部或部分由我建立,且我有權依檔案中指定的開放原始碼授權條款提交」。條款 (b) 涵蓋以較早的開放原始碼為基礎的工作,前提是你有權在修改後繼續提供這些內容。條款 (c) 涵蓋由已完成相同認證的人交給你的程式碼。條款 (d) 表示你了解該貢獻及簽署中的個人資訊會公開,且會永久保存。
請注意其中缺少的內容。DCO 從未表示每個字元都是由你輸入的。它表示你有權依此授權條款提交程式碼。因此,產生的程式碼在這裡會產生疑義:問題不在於作者身分,而在於你是否能交代程式碼的來源。大多數要求簽署的專案也要求使用真實姓名,因此化名會無法通過檢查。加入含有 git commit -s 的那一行;該行會從你的 git 設定讀取 user.name 和 user.email。當 DCO bot 讓你的 PR 檢查失敗,並指出缺少該行的 commit 時,執行 git rebase --signoff origin/main,再對你的分支執行 force push,即可修正問題。
簽署 commit 不等於簽署確認
git commit -s 會加入一行文字。git commit -S 則會使用您的 GPG 或 SSH 金鑰,對 commit 物件產生密碼編譯簽章。兩者回答的是不同問題。簽章證明此 commit 來自該金鑰的持有者,且自產生後未遭竄改。但簽章無法說明其中程式碼的來源。因此,包含未揭露產生程式碼的已簽署 commit,仍然可能違反政策。簽署確認是對來源的聲明。簽章是對身分的聲明。要求兩者的專案會同時要求簽署確認與簽章。
絕不要提交無法在審查中說明的程式碼
這項測試的重點其實不是誠實。請逐行回答:這行的用途是什麼?少了它會造成什麼問題?只要有一個問題答不出來,這個 patch 就還沒準備好,因為接下來一定會收到審查意見,而你的回答只會再觸發一輪生成。審查者看得出來。那一刻,貢獻者就會變成專案的成本。也請針對邊界情況、空輸入、失敗路徑及第二個呼叫端提出相同問題。
實際執行程式。建置它、執行專案的測試套件,並為你聲稱修正的錯誤撰寫重現程式。kernel 文件以直白的文字說明應有的處理方式:「如果修正無法建置或測試,或無法產生重現程式,請明確說明:維護者目前浪費太多時間分析未驗證的問題報告與未測試的修正。」寫下「我無法在實體硬體上測試」不會造成任何損失。暗示自己已經測試過,則會讓專案承擔代價。
請用自己的文字,並依照自己的時間表親自回覆審查意見。若在意見提出 30 秒後就回覆,卻用 5 個段落重述對方的內容,維護者就能確切看出發生了什麼事。也請維持 diff 精簡。你完全理解的 40 行程式碼,對專案的價值高於你監督完成、但有 400 行的重構。如果你的 agent 持續交回超出要求的內容,將變更限制在可運作的最小範圍內的技能 是控制 patch 大小、讓你仍能逐行辯護的方法之一。
將 agent 的指示保留在 repository 中
你提供給 agent 的指示是工具鏈的一部分,因此應像程式碼一樣管理。repository 根目錄中的檔案通常是 AGENTS.md,其中記錄 build command、test command、commit message 格式、sign-off 要求,以及專案已記載的 style rules。該檔案受版本控制且可供審查,今天與明天的內容也保持一致。每次工作階段憑記憶重新輸入指示,可能導致每次產生不同的 patch;你也無法知道遭拒的 patch 是在哪個工作階段產生的。撰寫 agent 與人員都能閱讀的 AGENTS.md 說明該檔案本身。
請注意其他人的 repository。不要把向不由你維護的專案新增 agent instruction file,當成你的第一個 PR。這會讓人覺得你試圖從外部制定專案的工具鏈政策,也很容易讓你的帳號與維護者早已厭倦的問題連結在一起。在有人要求之前,請將該檔案保留在你的 fork 中。
執行 agent 的位置也同樣重要。在你控制的 sandbox 中,若 agent 能夠建置專案並執行測試,你取得的 patch 就是實際驗證過的結果;這也是揭露曾獲得協助與揭露未經確認的猜測之間的差異。在自己的 VPS 上執行 coding agent 說明此設定,Claude Code、Cursor、Codex 與 Copilot 的實際差異 則說明這些工具在日常使用上的差異。
政策變更後的做法
- 撰寫任何內容前,先找出明確的政策:repository、開發者文件、網站或 issue tracker。
- 如果沒有政策,請在 issue 中用一句話詢問,並保留對方的答覆。
- 依專案使用的格式在表單中揭露,並寫入 commit trailer;如果專案會 squash,也要在 PR 內文中重複揭露。
- 使用真實姓名 sign off,並確認這行文字代表你有權提交該程式碼。
- 把自己的 patch 當成陌生人撰寫的內容來審查,因為它確實可能造成相同的問題。
等你讀到這一頁時,頁面上提到的每個專案都可能已經變更。這 5 個步驟不會變。
FAQ
我是否必須揭露自己使用了 AI coding agent?
請先確認專案規範,因為答案取決於各專案的本地政策。Fedora 要求在貢獻內容有相當大部分來自工具且未經修改時進行揭露。Linux kernel 要求加入 Assisted-by trailer。截至 2026 年 8 月,Gentoo 和 QEMU 完全不接受這類貢獻。如果沒有明文規定,仍應在 commit trailer 中揭露。維護者日後發現時,通常會針對隱瞞而不是工具本身作出反應,而這項反應也會影響你提交的其他內容。
哪些 open source project 禁止 AI 產生的程式碼?
以 2026 年 8 月為準,包含自 2024 年 4 月起適用此規定的 Gentoo、將 LLM 輸出視為必須經核心團隊核准之 tainted code 的 NetBSD、拒絕接受源自產生式內容之貢獻的 QEMU,以及 Loupe 和 Calendar 等數個 GNOME 應用程式。請以各專案自己的文字為準,不要只依賴這份清單,因為規範會隨時間變更。請注意,多數專案都有相同的例外:使用模型研究 API、執行 static analysis 或協助除錯通常沒有問題,前提是其輸出未出現在 patch 中。
Signed-off-by 與 signed commit 有何不同?
Signed-off-by 是由 git commit -s 加入的純文字行。它認證 developer certificate of origin,也就是你有權依專案授權條款提交這份程式碼。使用 git commit -S 建立的 signed commit,則是以你的 GPG 或 SSH key 對 commit object 產生的 cryptographic signature。它證明 commit 來自你的 key,且未遭到修改。來源與身分是兩項不同的聲明,因此 signed commit 仍可能違反 AI 政策。
我可以把揭露內容放在 pull request description,而不是 commit message 中嗎?
請將內容放在 commit message 中,因為該訊息會保留在 git history,並隨程式碼提供給之後 clone repository 的任何人。pull request description 之後可以被編輯,而且只存在於 hosting platform 上。當專案會執行 squash merge 時,也請將內容加入 PR body,因為 squash 會重寫你的 commit message,可能移除 trailer。
我的 pull request 因為是 AI 產生的而被關閉了。現在該怎麼辦?
不要在討論串中爭論政策,因為關閉請求的人並非唯一制定規則的人,而且討論串也不是修改規則的地方。先閱讀政策文字,再判斷自己是否能符合要求。如果專案禁止產生式 patch,仍然歡迎提交包含 reproducer 且不附 patch 的明確 bug report,這通常也是更有用的貢獻。如果要再次提交程式碼,請提交自己能逐行說明的小幅變更。