Rust 语言项目为 rust-lang/rust 单一仓库通过了一项 LLM 使用政策。它没有简单禁止 AI 工具,而是划出了一条更具体的边界:LLM 可以帮助分析、提炼、审阅和提出建议,但不能被当作无需说明的代码作者。
这项规则目前由五个团队采纳,并不等于整个 Rust 项目对 LLM 的统一立场。不过,它提供了一种值得其他开源项目参考的治理思路:问题不只是“能不能用 AI”,而是贡献者能否解释代码来源、验证实现,并对提交内容承担责任。
“可以建议,不能代替创作”意味着什么
政策的核心可以理解为区分两类活动。
一类是辅助理解:让 LLM 解释错误信息、归纳讨论、寻找可能遗漏的测试场景、审阅补丁,或者提出若干实现方向。这些工作不会自动进入代码库,贡献者仍需判断建议是否正确。
另一类是直接创作:让模型生成一段实现,然后在没有明确说明来源的情况下把它包装成自己的代码。这里的风险不只在代码质量,还涉及作者身份、版权来源以及维护责任。
两者之间并非总有清晰的技术边界。例如,模型建议把一个锁换成原子操作,贡献者理解内存序后自行实现,这更接近建议;模型直接输出完整补丁,而贡献者只运行格式化工具后提交,则明显包含机器生成内容。
因此,判断时不能只问“有没有复制粘贴”,还要问三个更实际的问题:
- 关键实现决策是谁做出的?
- 贡献者能否逐行解释并修改这段代码?
- 提交记录是否准确披露了机器生成内容?
政策摘要明确表明,LLM 生成的代码并非绝对不能提交,但贡献者不能模糊其来源。披露不是一句笼统的“使用过 AI”,而应当让审阅者知道哪些内容受到影响,以及人工完成了哪些验证。
为什么开源项目在意作者身份
成熟项目接收的不是一次性代码片段,而是一项长期维护承诺。补丁合并后,维护者可能需要在数年后追查一个并发缺陷、平台兼容问题或未定义行为。如果原贡献者并不理解实现,审阅阶段建立的信任就会失效。
来源也是现实问题。LLM 输出可能复现训练材料中的表达,也可能生成看似合理但并不存在的 API。公开披露不能自动消除版权或许可证风险,却能让维护者决定是否需要重写、加强审查或拒绝该部分贡献。
Rust 代码还经常涉及 unsafe、生命周期、并发内存模型和编译器内部约束。模型能够生成语法正确的实现,并不意味着它证明了安全不变量。对于这类代码,“测试通过”通常只是最低门槛。
可以这样实践:把披露放进 PR 流程
下面不是 Rust 政策原文规定的固定模板,而是一种可直接改造的项目实践。可以在仓库中创建 .github/pull_request_template.md,要求贡献者标明 LLM 的使用范围:
## Change summary
Describe the behavior changed by this pull request.
## LLM usage
- [ ] No LLM was used for this contribution.
- [ ] An LLM was used only for analysis, summarization, or review.
- [ ] This contribution contains LLM-generated code or tests.
If an LLM was used, describe:
- affected files or functions:
- generated or suggested content:
- manual verification performed:
- tests added or executed:
## Verification
```text
cargo fmt --check
cargo clippy --all-targets --all-features -- -D warnings
cargo test --all-features
贡献者也可以在提交前运行一组可复制的 Rust 检查命令。根据仓库实际配置调整 feature 参数:
```bash
set -euo pipefail
cargo fmt --check
cargo clippy --all-targets --all-features -- -D warnings
cargo test --all-features
这些命令只能发现格式、静态检查和测试覆盖到的问题,不能证明模型生成代码的来源或语义正确。涉及 unsafe 时,可以进一步要求贡献者写出安全不变量。例如:
/// Returns a shared view into `ptr`.
///
/// # Safety
///
/// The caller must guarantee that:
/// - `ptr` is non-null and properly aligned;
/// - it points to an initialized `u32`;
/// - the value remains alive for `'a`;
/// - no mutable access occurs during `'a`.
pub unsafe fn view<'a>(ptr: *const u32) -> &'a u32 {
// SAFETY: The caller is required to uphold the invariants above.
unsafe { &*ptr }
}
fn main() {
let value = 42_u32;
let observed = unsafe { view(&value) };
assert_eq!(*observed, 42);
}
如果贡献者无法独立说明这些条件为什么充分,就不应仅凭模型的解释提交这类实现。
审阅者需要改变什么
披露 LLM 使用情况之后,审阅流程也要相应调整。审阅者可以要求贡献者解释关键约束,而不是只检查最终 diff 是否整洁。对于机器生成比例较高的补丁,应重点检查不存在的 API、过度泛化、遗漏的错误分支、无意义测试,以及与仓库既有抽象不一致的实现。
项目还需要避免把披露机制变成惩罚机制。如果承认使用 LLM 必然导致补丁被拒,贡献者会获得隐瞒的激励。更合理的处理方式是根据风险提高验证要求:文档措辞可以轻量审阅,普通业务逻辑需要测试,unsafe、密码学和并发代码则需要严格的人工论证。
采用这类政策前的检查清单
Rust 的做法说明,开源项目不必在“全面禁止”和“完全放开”之间二选一。团队可以先明确允许的辅助活动,再为机器生成内容建立披露和验证规则。
落地时至少需要回答以下问题:
- 政策适用于哪些仓库、团队和贡献类型?
- “建议”与“生成内容”如何区分?
- 贡献者应在 PR、提交信息还是单独文件中披露?
- 哪些高风险模块禁止或限制机器生成代码?
- 维护者发现未披露内容时如何处理?
- 谁对许可证、安全性、测试和后续维护负责?
LLM 可以缩短检索和分析时间,但它不会接管贡献者责任。对长期维护的开源项目而言,真正重要的不是工具是否出现过,而是代码来源是否透明、论证是否可复核,以及提交者是否真正理解自己交付的内容。