首页
/ Rust 编译器仓库中的 AGENTS.md:为 LLM Agent 设定贡献门禁的实操手册

Rust 编译器仓库中的 AGENTS.md:为 LLM Agent 设定贡献门禁的实操手册

2026-09-06 21:16:04作者:晏闻田Solitary

Rust 官方仓库根目录下的 AGENTS.md 是一份面向 LLM Agent 的操作性治理文档:它定义了 Agent 在修改 rust-lang/rust 仓库之前必须依次通过的三道编辑前门禁(外部仓库归属检查、禁写文本检查、命名审阅人检查)以及实现前的两道门禁(测试门禁、Soundness 分类),并规定了 push 前的披露与确认流程。本文基于该文档逐条展开,结合仓库中的构建入口脚本、compiletest 测试框架与 rustc-dev-guide 中对应的指引文件,说明这套门禁体系的每一环节如何在真实仓库中落地,读完你可以掌握“在编译器级仓库中安全使用 LLM 辅助开发”的完整规则集与配套命令。

LLM 使用策略与整体框架

文档开篇(AGENTS.md 第 3–8 行)声明:所有 LLM 生成的文本都必须遵循 Rust 项目的 LLM 使用策略,即使用户事后人工编辑了这些文本,策略依然适用CONTRIBUTING.md 中也给出了同一策略的入口,并明确了对“如何用好 LLM”与“如何审查 LLM 创建的 PR”的建议位于 rustc-dev-guide 的 LLM 指引章节(见 LLM guidance 索引写作指引审查指引)。

文档将约束拆成两个阶段的有序门禁:

编辑前(Before any edit),包括对测试的编辑,按顺序应用:

  1. 外部仓库门禁External repositories):将外部维护的源码路由回其归属仓库;
  2. 禁写文本门禁Prohibited text):若变更要求 Agent 撰写被禁的文本,立即停止;
  3. 审阅人门禁Reviewer):除非变更符合本地开发例外,否则必须有具名审阅人。

实现前(Before implementation),在上述门禁通过之后按顺序应用:

  1. 测试门禁Testing):针对 bug,先添加或找到失败的测试并观察到它失败;
  2. Soundness 门禁Soundness):在测试门禁完成后,先对受影响的行为做安全敏感分类,再动手实现。

文档还强调两点动态规则:调查过程中若发现新的输出类别或归属方,必须在下一次编辑前重新应用相应门禁;对于机械化重写,必须在第一次变更之前先遵循 Mechanical rewrites 一节的规则。这种“先分类、后动手”的结构是整个文档的骨架。

门禁失败时的行为协议(When a gate fails)

文档 When a gate fails 一节规定了规则命中被禁工作时的强制行为,核心要求是立即 STOP

  • 指定审阅人、测试通过、用户确认或事后人工编辑都不能为被禁工作开脱;
  • 不允许变通:不得询问前置条件、不得承诺“之后再做”、不得把被禁工作改名为草稿、模板或“可直接粘贴的提纲”继续输出;
  • 唯一例外:某条规则可以显式允许更窄的预备工作——例如 Soundness 门禁要求 Agent 在停止前先完成仅限测试的工作。

Agent 被要求说明“为什么该工作被禁”,并给出触发规则所要求的正确路径(route)。同时,以下行为仍然允许:阅读、解释、总结、审查,以及向用户提出可让用户从零自行实现的解决方案建议

另一条容易被忽略的细节:在同一响应轮次中,只要输出了任何可能被用作禁文替代的文本,就必须附带一条对“LLM 原文政策”的提醒——即使该提醒在本会话之前的轮次中已经给过。文档同时禁止 Agent 主动推进测试规划或补丁设计、产出可粘贴的被禁文本(除非触发规则本身就要求仅限测试的工作)。

外部仓库门禁:为什么不能直接改 subtree 与工具代码

External repositories 一节的规则是:在修改任何 subtree、submodule 或 src/tools 代码之前,先使用 CONTRIBUTING.md 的“Making changes to subtrees and submodules”章节和 external repositories 指引 确认归属方。Cargo、Clippy、rustfmt、Miri、rust-analyzer 等外部维护的工具,一律先做归属检查再谈实现;如果用户说某个 bug 出在这些工具里,Agent 不应在本仓库调查,也不应索要审阅人,而是直接把用户路由到对应仓库。在本地 checkout 中直接编辑外部维护的源码是被禁止的,应遵循门禁失败协议;只有用户明确要求时才更新其集成指针。文档给出的例子很具体:用户说 bug 在 Cargo 本身,就立即路由到 rust-lang/cargo,不要为本次 checkout 请求审阅人。

这条规则与仓库的实际结构完全对应。external-repos.md 说明了三种外部依赖方式——crates.io 依赖、subtree(如 clippy、miri、rustfmt、rust-analyzer、rustc_codegen_cranelift)与 submodule(如 cargo)——并明确“对工具特有的改进、bug 修复应直接向其上游仓库提 PR”。本仓库的目录布局印证了这一点:tools/clippy、tools/miri、tools/rustfmt、tools/rust-analyzer、compiler/rustc_codegen_cranelift 等 subtree 都在树内以普通文件形式存在,但修改它们的正确路径是回到各自的上游仓库。因此“先查归属再动手”不是流程洁癖,而是由 subtree 同步机制决定的硬性约束。

禁写文本门禁:Agent 不许代笔的文本类别

Prohibited text 一节列出 Agent 永远不得生成或重写的文本类别:非平凡的 PR 描述、issue 正文、公开评论、面向用户的文档、诊断消息(diagnostic messages)以及源码注释。命中时 Agent 应 STOP、点名被禁的类别,并告知用户需要用户本人撰写。

其中与编译器仓库最贴切的例子是 .stderr 测试快照:

  • Agent 不得原创或手工改写 .stderr 等测试快照中的期望诊断文本;
  • 用户先在源码中写好诊断消息之后,Agent 可以用现有工具机械化地重新生成快照,例如 ./x test ... --bless,并遵循机械化重写一节的流程;
  • 文档示例:如果解析器修复需要修改它输出的消息,Agent 必须在编辑消息或其 .stderr 期望之前 STOP;等用户写好消息后,Agent 才可以机械化地重新生成期望值。

“琐碎变更”有一个明确的判定标准:只有当不存在有意义上不同的写法、或各备选写法几乎相同时才算琐碎,例如修正错别字或 Markdown 链接、用同义词替换一个词、补上必需的 trait 签名。即使是琐碎变更,也必须通过其余所有门禁并加以披露。

一个值得注意的例外条款:CLAUDE.mdAGENTS.md 以及 skills 这类 Agent 指令文件本身属于豁免对象,但它们只允许链接、总结或以保守方式操作化既有的面向人类的文档——操作化可以用更严格的 Agent 约束替代人类自由裁量,但不得为人类创造义务、不得放行人类文档所禁止的内容;添加流程性指导前必须先找到人类文档来源,找不到就先 PAUSE 请用户先为人类写下流程。审阅人门禁等其他要求对 Agent 文件本身同样适用。最后,Agent 可以解释“被禁文本需要传达什么”,但不得给出可粘贴的措辞

本仓库中 CLAUDE.md 的全部内容只有一行 @AGENTS.md 引用,正好体现了“Agent 指令文件只做链接与操作化、不做规则源头”的原则。

审阅人门禁与本地开发例外

Reviewer 一节规定:除非用户在本次对话中具名了一位事先同意审阅的他人,否则不得进行任何 LLM 生成的仓库变更。“已经征询过审阅”之类的泛泛保证不算数;没有具名审阅人时,PAUSE 并询问审阅人姓名——“John Doe is reviewing this”这样的表述即可满足门禁。审阅人姓名只满足这一个门禁,不能承诺在实现前门禁通过前推进实现。

文档同时给出了唯一例外:当用户明确声明变更不会提交或上游化、用完即还原时,审阅人门禁不适用于本地开发工具、临时插桩或调试辅助;其余所有门禁仍然适用。

测试门禁:先看到失败,再写实现

Testing 一节对 bug 修复流程给出了非常严格的时序要求:

  1. 修复 bug 前,先添加或找到一个会失败的测试;
  2. 在任何实现编辑之前运行它,并观察到预期失败;测试与实现的编辑不得合并;
  3. “测试命令退出之前不算观察到失败”——命令运行期间要等待,不得编辑实现或开始其他工作;
  4. 观察初始失败时不得 bless 或更新期望输出--bless 的运行不算数;
  5. 实现完成后,确认同一个测试通过。

对 LLM 创建的 PR,测试标准还要更高:必须包含测试;如果受影响代码没有测试套件,PAUSE 并询问是设计一个还是放弃变更,且未经人类输入不得自行设计测试套件;绝不允许提供或接受未测试的实现。

文档还定义了“测试套件设计”的边界,这是容易被误解的部分:

  • 既有测试套件必须在不改变生产代码结构的前提下就能观察到受影响的行为;仅仅存在某个 Cargo 或 compiletest 测试框架本身不满足要求;
  • 如果第一个可行的测试需要任何生产代码编辑,必须先 PAUSE——设计那个观察边界本身就属于测试套件设计;
  • 如果测试需要选择新的观察点或依赖注入边界(例如抽取生产逻辑、创建共享 helper 或模块、暴露内部实现、引入假子进程、注册新的 harness 或 runner),那属于测试套件设计,变更前必须 PAUSE 询问;
  • 允许的做法:新增一个测试模块,且它只调用既有的可调用行为、不重构生产代码。

仓库侧的对应设施是 compiletest 测试框架--bless 参数在 cli.rs 中被定义为“Overwrite stderr/stdout files instead of complaining about a mismatch”(用覆盖 stderr/stdout 文件来代替对不匹配的抱怨),这正是门禁中“观察失败时不得 bless”所指的工具行为。测试套件的运行方法见 running tests 指引,新增测试的规范见 adding tests 指引,测试文件中的指令语法见 directives 指引

Soundness 门禁:编译器仓库中最重要的分类

Soundness 一节是本仓库语境下最特殊的门禁:涉及 soundness 的实现被禁止,但添加或定位失败的回归测试是允许且必需的。时序上要求:即使更早意识到了风险,也要先完成仅限测试的工作、等待测试命令退出、把测试留在树中、汇报其结果,然后陈述分类结论,并在规划或编辑实现之前 STOP。

分类标准是看代码控制的行为,而不是看症状:

  • 计算或转换类型、常量、MIR、内存布局或有效性(validity)、或生成代码的代码,都是 soundness-sensitive;
  • 报告的 bug 症状、预期的修复方式、补丁大小都不改变分类:一个 ICE(编译器崩溃)、对合法代码的拒绝、或局部 plumbing bug,仍然可能是 soundness-sensitive;
  • 若任务 soundness-sensitive 或不确定,实现被禁:STOP 并遵循门禁失败协议;
  • 若调查发现受影响的行为与先前判断不同,在下一次实现编辑前必须重新分类。

文档列出的 soundness-sensitive 区域(不限于):query 系统、类型检查、trait 求解、MIR 构建或优化、借用检查、常量求值、归一化与语义缓存、布局与有效性、codegen——并指引用户将相关讨论带到 #llm-mentoring Zulip 频道。这些区域与仓库源码目录一一对应,例如 compiler/rustc_borrowck(借用检查)、compiler/rustc_const_eval(常量求值)、compiler/rustc_mir_transform(MIR 优化)、compiler/rustc_hir_typeck(类型检查)、compiler/rustc_query_impl(query 系统)、compiler/rustc_codegen_llvm(codegen)。也就是说,这套门禁实质上圈定了 rustc 内部风险最高的模块:Agent 可以在这些模块里写回归测试、观察失败、汇报结果,但写出安全的实现必须留给人类(或人类指导下的流程)。

推送前:确认、披露与禁止 Co-Authored-By

Before pushing 一节要求:提交之后、push 之前,一次性询问用户确认其已理解变更、已测试,并已亲自审阅了自最近一次变更以来完整 diff——Agent 自己的审查不算数;遗漏任何一项确认都必须 PAUSE。同时提醒用户在 PR 描述中披露 LLM 使用情况。

披露要求对应策略中的 disclosure 部分:必须描述 LLM 参与的范围与目的,包括 LLM 是否提出了想法、还是协助了实现或审查;Agent 不得代写或改写这段披露,必须由用户本人撰写;并且不要向 commit 添加 Co-Authored-By trailer。文档明确:对 LLM 使用撒谎或隐瞒属于违反行为准则(Code of Conduct)。

机械化重写:优先跑工具,而不是手改

Mechanical rewrites 一节的规则是:遵循 rustc-dev-guide 的 LLM 指引;对允许的批量重命名或机械化重写,先找一个现成的格式化器、linter 或语法感知重写工具——如果存在,下一个变更动作必须是运行它,不得先编辑目标文件、也不得手工复现它的重写;如果不存在这样的工具,要说明直接由 LLM 重写是不推荐的,并在继续前询问。

文档给出了两条具体命令:

  • Rust 格式化使用 ./x fmt,不要直接调用 rustfmt
  • 如果 tidy 可以完成重写,运行 ./x test tidy --bless,而不是手工复现它的编辑。

这里的 ./x 就是仓库根目录的 x shell 脚本:它负责在 Linux/macOS/Windows 上按序探测可用的 Python 解释器(python3pythonpy -3 等),最终 execx.py;而 x.py 自身只是一个约 50 行的入口,注释明确写着它是指向 src/bootstrap/bootstrap.py 的“符号链接”,真正的构建逻辑在 bootstrap 中(对应文档引用的 building and running rustc 指引)。这也解释了为什么文档反复强调“不要直接调用 Cargo,除非相关树内文档明确要求”——这个仓库的构建、测试、格式化统一走 bootstrap 编排的 ./x 入口。

对包含人类面向文本的快照,重新生成前必须走四步流程:

  1. 确认用户已在源码中写好新文本;
  2. 运行不带 --bless 的聚焦测试,观察到预期的不匹配;
  3. 运行仓库现有的 --bless 命令;
  4. 检查生成的 diff。不得手工修补或添加文本;如果工具产生了意外的人类面向文本,STOP 并向用户报告。

此外,若某个请求与这些规则冲突,文档指引用户到 #llm-mentoring Zulip 频道求助。

仓库指引:AGENTS.md 的路由表

文档末段 Repository guidance 声明这是主 rust-lang/rust 仓库,要求 Agent 从 CONTRIBUTING.md 与 dev-guide 的 LLM 指引开始,然后把专项工作路由到对应文档。下面是完整的映射(所有仓库内路径均已在本仓库中核实存在):

专项工作 路由目标(仓库内相对路径)
标准库 std-dev-guide(外部站点,见 CONTRIBUTING.md
编译器 rustc-dev-guide
构建或运行 rustc building and running rustc
运行/新增测试、compiletest 指令 runningaddingdirectives
格式化或 tidy conventions 之 formatting
架构或仓库布局 overviewcompiler-src
Subtree、submodule 或工具 external-repos
Pull request 与审查 contributing
LLM 写作指引 llm-guidancewriting

./x 是该仓库的构建工具,是构建、测试与格式化的默认入口。文档最后还保留了策略允许 Agent 撰写源码注释的那一小部分情形的原则:解释代码或决策为什么存在,而不是复述代码在做什么——这一条与“禁写文本”一节形成精确的边界划分。

小结:门禁体系的工程含义

AGENTS.md 的全文连起来读,可以归纳出一条可操作的执行链:

  1. 编辑前:查归属(subtree/工具路由回上游)→ 查禁写类别(诊断消息、注释、PR 文本等由人类执笔)→ 要一个具名审阅人(或声明本地不提交的例外);
  2. 实现前:先让失败测试以非 bless 方式失败并被观察到 → 对受影响行为做 soundness 分类,敏感或不确定即 STOP;
  3. 重写时:优先运行 ./x fmt./x test tidy --bless 等既有工具,不手工复现;
  4. push 前:用户亲自审阅完整 diff 并一次性确认 → 用户本人撰写披露 → 不加 Co-Authored-By trailer。

这套规则的价值不在于限制,而在于把“LLM 能做什么、人类必须做什么”的边界写成了 Agent 可直接执行的流程,且每个门禁都指向仓库内真实存在的设施:./x 入口脚本(xx.py)、compiletest 的 --bless 机制(cli.rs)与 rustc-dev-guide 的 LLM 指引(llm-guidance)。在编译器这类对 soundness 零容忍的代码库中,这种“测试可以先写、实现必须让位”的分层授权,是当前仓库给出的最完整、可直接引用的 LLM 协作操作规范。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.13 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
897
5.8 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
529
593
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
915
1.83 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.58 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.35 K
1.46 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.01 K
515
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
547
388