与 Agent 无关的 Java 质量护栏:用 AGENTS.md 与静态分析把标准写进仓库#
团队一旦在 GitHub Copilot、Windsurf、Cursor 之间轮换 coding agent,最先碎掉的不是模型能力,而是编码标准落在哪份 Markdown 里。Copilot 认 .github/copilot-instructions.md,Windsurf 主推 .windsurf/rules/*.md 并同时支持 AGENTS.md,Claude Code 默认读的是 CLAUDE.md——文件名各一套,同步成本落在开发者身上。
更稳妥的做法是把「给 agent 的 README」收敛到仓库内的 AGENTS.md 开放格式,再用 Maven verify 阶段的 Checkstyle、SpotBugs、ArchUnit 做可重复的验收轨。前者影响生成时的概率性合规;后者在构建失败时给出客观证据。下文按机制拆解,不依赖某次现场演示的违规条数作为行业基准(演讲者观点:双项目对比仅为说明性实验)。

Agent 不一致:问题不在模型,而在标准没有单一事实来源#
为什么#
Coding agent 输出非确定,同一 prompt 换版本或换厂商结果可能漂移;若规范只存在于聊天记忆或某 IDE 私有配置文件,PR 审查与 CI 都无法引用同一份约束。
机制与约束#
各产品在「持久化指令」上的路径不同,但方向一致:把跨会话规则从 prompt 里抽出来,放进仓库。演讲中将此概括为 agent churn 下的 instruction file 碎片化——痛点成立,但 Windsurf 官方路径是 .windsurf/rules/,而非口语里的根目录 rules.md;Codeium.md 在公开文档中未核实到同名约定,写稿应以各工具当前文档为准。
怎么做#
在版本库中选定 AGENTS.md 为跨 agent 主载体;对仍只认厂商文件的工具,用薄封装指向同一内容(见后文 Claude 互操作)。
常见误区#
- 以为「换更强的模型」就能替代团队标准文档。
- 把三套厂商 Markdown 手工复制粘贴当作长期方案——必然滞后于代码演进。

AGENTS.md:仓库绑定的开放约定,而非 IDE 附属品#
为什么#
标准应跟 Git 仓库走,而不是跟订阅或桌面客户端走;这样 Copilot agent、Windsurf Cascade、Cursor 等读取的是同一份 Markdown。
机制与约束#
agents.md 自述为 A simple, open format for guiding coding agents,FAQ 明确:无强制 schema,普通 Markdown 即可。2025-12-09 Linux Foundation 新闻稿 宣布 Agentic AI Foundation (AAIF) 成立,创始捐赠项目包含 MCP 与 AGENTS.md(OpenAI 于 2025-08 发布、12 月捐赠)。精确表述宜用「纳入 AAIF」,而非「与 MCP 合并为同一项目」。
GitHub Copilot 文档写明:多个 AGENTS.md 并存时,目录树中离编辑文件最近的一份优先;用户当前 chat 中的显式 prompt 仍可覆盖一切(agents.md FAQ)。
怎么做#
根目录放全局约定(构建命令、日志、横切架构);controller/、service/、repository/ 等再各放一层局部说明,避免单次把整库规范塞进 context。
repo/
AGENTS.md
src/main/java/.../controller/AGENTS.md
src/main/java/.../service/AGENTS.md
src/main/java/.../repository/AGENTS.md
常见误区#
- 把
AGENTS.md当成 Copilot 或某一家独有功能——多家已支持,Claude Code 例外见下节。 - 在根目录堆一份「万能圣经」——与「就近加载」机制背道而驰。

在 Spring Boot 分层项目里,可把「Controller 只调 Service」「@Service 类必须在 .service 包」写进各层 AGENTS.md,并在根文件用章节号索引(如 §2 架构、§3 包归属)。这样 agent 在编辑 BookService 时加载邻近说明,而不是整库规范。团队若维护 monorepo,agents.md 官方也建议 nested AGENTS.md——与 Copilot「最近文件优先」规则同构。

Context 里 AGENTS.md 只占一层:别把它当成全部上下文#
为什么#
Agent 实际「看见」的是多层信息的叠加:系统/厂商行为、自定义指令、会话历史、IDE 隐式上下文(打开文件、diff)、显式 @ 引用、终端与工具输出。演讲者观点:AGENTS.md 只是 custom instructions 层的一小块;若忽视其它层,仍会在中长会话里偏离标准。
机制与约束#

各产品对每层如何裁剪、计 token 实现各异,不存在跨厂商的「context engineering」统一规范——工程上应只注入与当前任务相关的标准(例如改 BookService 时优先加载 service/AGENTS.md)。
怎么做#
- 全局
AGENTS.md:< 2屏能读完的 build/test、DoD、ArchUnit 索引。 - 层内文件:只写该包 API/分层规则。
- 在 DoD 中写清「改完必须跑
./mvnw verify」,让工具输出进入反馈层。
常见误区#
- 认为写了
AGENTS.md就等于 100% 合规(演讲者经验估计约 80–90%,无官方统计)。 - 在 chat 里重复长篇规范,与文件内容双份占用 context。

编写 AGENTS.md:克制、可迭代,并把 DoD 写进 Definition of Done#
为什么#
无 schema 不等于可以无限堆砌。agents.md 允许任意标题,但过长或充满 agent 已知的常识会挤占有效 context(演讲者观点:引用近月论文称自动生成/冗长指令会降低生成质量——论文题名未在材料中给出,未独立核实)。
机制与约束#
建议章节(均非强制):项目概览、./mvnw verify 等构建与测试命令、代码风格指针(指向 Checkstyle 配置)、架构规则(与 ArchUnit 规则 人工对齐 章节号,工具不会解析 § 2)、安全要点。
怎么做#
## Definition of Done
- 代码变更后执行 `./mvnw verify`。
- 修复全部 Checkstyle、SpotBugs、ArchUnit 失败后再结束任务。
- 分层规则见 service/AGENTS.md;Controller 不得直连 Repository(AGENTS.md §2)。
Maven 官方说明:verify 阶段适合运行集成测试及额外检查(如绑定在此阶段的 Checkstyle)。
常见误区#
- 用表格复述 Java 命名惯例——Checkstyle 已覆盖的不要再写一遍。
- ArchUnit 与 Markdown 章节号「自动联动」——
because("… AGENTS.md §2")只是描述字符串,不会建立机器链接。

双轨护栏:指令左移 + 静态分析验收#
为什么#
文档标准若不能变成 BUILD FAILURE,仍会滑进 main;人工 review 慢且主观。幻灯片归纳:AGENTS.md 定义标准,静态工具执行标准。
机制与约束#

- 左轨(概率):agent 读
AGENTS.md/ 发现仓库里已有pom.xml插件后倾向按现有门禁生成(演讲者观点:「多数时候」即使用户未在 prompt 提 Checkstyle)。 - 右轨(确定):
maven-checkstyle-plugin的checkgoal 默认绑定verify,failOnViolation默认为true(check Mojo 文档)。
与 SonarQube 对比:定性成立——SonarScanner 需配置 SONAR_HOST_URL 等与 Server 通信;本地 Maven 插件路径更适合 agent 快速反馈循环。Sonar 亦有 Community Build 可本地部署,不宜简单说「Sonar 一定要外置 SaaS」。
怎么做#
pom.xml 片段(演示 OCR 为 3.3.1;插件站当前有更新版,坐标族一致即可):
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>3.3.1</version>
<executions>
<execution>
<id>checkstyle-validate</id>
<phase>verify</phase>
<goals><goal>check</goal></goals>
</execution>
</executions>
</plugin>
常见误区#
- 只跑
mvn compile——绑在verify的检查会被跳过。 - 指望 Sonar 与 Checkstyle 二选一即可覆盖架构分层——ArchUnit 表达力不同,见下节。

Checkstyle:把风格与 import 规则钉在构建期#
为什么#
无规范时 agent 生成代码常出现 tab、AvoidStarImport、缺少空行等——这些在 review 里烦,在 CI 里更应直接失败。
机制与约束#
Checkstyle 检查源码风格;常见模块包括 AvoidStarImport、FileTabCharacter、EmptyLineSeparator。
怎么做#
本地或 agent 执行:
./mvnw verify
失败时日志中出现 maven-checkstyle-plugin:check (checkstyle-validate) 及具体违规行号,可将输出贴回 agent 迭代。
常见误区#
- 认为「能编译」等于「符合团队风格」。
- 对历史项目事后才接入 Checkstyle 却期待零改动——演示中无
AGENTS.md的demo-projects在补插件后仍大量违规(现场构建输出,非通用基准)。



SpotBugs 与 ArchUnit:补足风格之外的缺陷与分层#
为什么#
Checkstyle 不管 NPE 风险、资源泄漏或并发问题;包结构与「Controller 不得直连 Repository」等架构约束也不是风格检查能表达的。演示路线图中将三者并列:Checkstyle 管「看起来对不对」,SpotBugs 管「跑起来会不会炸」,ArchUnit 管「结构允不允许」——分工是 演讲者归纳,但各工具官方定位支持这一拆分。

机制与约束#
- SpotBugs:在 字节码上查找 bug patterns;Maven
checkgoal 可使构建失败(SpotBugs Maven 文档)。与 Checkstyle 的checkgoal 同名不同插件,绑定同一verify阶段时需用不同 execution id 区分。 - ArchUnit:在
src/test用 JUnit 表达架构规则,@AnalyzeClasses+@ArchTest与 User Guide 中的resideInAPackage、layeredArchitecture等 API 一致。
怎么做#
SpotBugs 在 pom.xml 中通常与 spotbugs-maven-plugin 的 check goal 绑定 verify(细节见官方示例 POM)。本地验证:
./mvnw verify -DskipTests=false
ArchUnit 规则示例(与 OCR 中 ClassFileImporter、Service.class 语义一致):
@AnalyzeClasses(packages = "javaone.demo",
importOptions = ImportOption.DoNotIncludeTests.class)
class ArchitectureTest {
@ArchTest
static final ArchRule servicesInServicePkg = classes()
.that().areAnnotatedWith(Service.class)
.should().resideInAPackage("..service..");
@ArchTest
static final ArchRule noControllerToRepo = noClasses()
.that().resideInAPackage("..controller..")
.should().accessClassesThat().resideInAPackage("..repository..")
.because("Controllers must not access repositories directly (AGENTS.md § 2)");
}
OCR 可见 areAnnotatedWith(Service.class) 与 AGENTS.md § 交叉引用——需团队自行保持 Markdown 与测试同步。
常见误区#
- 在
AGENTS.md写「禁止 Controller 访问 Repository」却没有 ArchUnit——agent 仍可能生成跨层调用。 - 把 ArchUnit 当成运行时 AOP——它是测试阶段断言,默认 lifecycle 中随
verify里的test执行。

闭环:mvn verify 驱动 agent 自修复#
为什么#
标准写在 DoD 里却不执行命令,agent 仍可能提交红灯代码;IDE agent mode(Copilot agent、Windsurf Plan 等)若能跑终端,则 violations 可进入下一轮 prompt。
机制与约束#
mvn verify 执行至 verify 阶段,聚合 Checkstyle、SpotBugs、Surefire(含 ArchUnit 测试)。退出码非 0 即硬失败——与 agent 是否「理解」无关。
怎么做#
- 在根
AGENTS.md的 DoD 写明./mvnw verify。 - 让 agent 在任务末尾读取终端输出并修复,直至 green。
- 换 agent 时无需改标准文件——演示中 Windsurf Pre-Release 与 Copilot 均仍针对同一
BookService代码库工作(演讲者观点:Claude 原生不读AGENTS.md,需互操作)。
Claude Code 官方做法(优于非官方 hack):在 CLAUDE.md 中 @AGENTS.md import,或 ln -s AGENTS.md CLAUDE.md(Windows 建议 import)。
# CLAUDE.md
@AGENTS.md
常见误区#
- 假设 agent 一定会自动跑 Maven——取决于产品、权限与 DoD 是否足够明确(产品行为,非 Maven 规范)。
- 在 prompt 里写一遍 verify,却不在
AGENTS.md固化——换会话即丢失。

落地清单:从碎片化指令到可验证仓库#
| 步骤 | 动作 |
|---|---|
| 1 | 用根 AGENTS.md 替代多套厂商规则;Claude 用 @AGENTS.md |
| 2 | 按包分层嵌套 AGENTS.md,遵循 nearest wins |
| 3 | pom.xml 绑定 Checkstyle / SpotBugs / ArchUnit 至 verify |
| 4 | DoD 要求 ./mvnw verify + 修复全部失败 |
| 5 | ArchUnit because(...) 与 AGENTS.md 章节号人工对齐 |
| 6 | CI 与本地使用同一 verify,避免「本地绿、流水线红」 |
三条收益(演讲者归纳,与幻灯片一致):Agent Independence——换工具仍读同一标准;Build Accountability——未过门禁不可视为完成;Team Confidence——review 可聚焦业务逻辑。有护栏的 spring-boot-demo 在 agent 模式下会先读取各层 AGENTS.md 再生成,并出现 GlobalExceptionHandler 等横切结构;无 AGENTS.md 的 demo-projects 由 Junie 生成时则缺少统一异常处理与文档化注释——差异方向与机制一致,具体类名与违规数为演示现场结果,不宜外推为行业统计。

具体 checkstyle.xml、SpotBugs include 过滤器与演示仓库 URL 未在公开材料中给出完整正文;落地时应从团队现有 Checkstyle 配置或 Google/Java 社区规则集 起步,再逐步收紧。
参考与延伸阅读#
- agents.md — 面向 coding agent 的开放 Markdown 格式
- agentsmd/agents.md — 规范与示例仓库
- Linux Foundation — Agentic AI Foundation 成立新闻稿(含 AGENTS.md、MCP)
- GitHub Copilot — 仓库自定义说明(copilot-instructions.md、AGENTS.md、路径级 instructions)
- Cursor — Rules 与嵌套 AGENTS.md
- Windsurf — AGENTS.md 与 Rules 引擎
- Windsurf — Cascade Memories 与 .windsurf/rules
- Claude Code — Memory、CLAUDE.md 与 @AGENTS.md 互操作
- Apache Maven — 生命周期与 verify 阶段
- maven-checkstyle-plugin — check goal 与 failOnViolation
- Checkstyle — 检查模块索引
- SpotBugs — 介绍(字节码 bug patterns)
- SpotBugs Maven Plugin — check goal
- ArchUnit — User Guide(@AnalyzeClasses、layeredArchitecture)
- SonarScanner CLI — 与 SonarQube Server 通信要求



