在 OpenJDK 明令禁止 AI 代码贡献的背景下,Vidocq 项目用 Claude Code 在约束下完成了 18 万行 Java 代码、5650 个 TCK 测试全部通过,验证了 AI 辅助大型项目的可行性。
今年八月第一周,The Register 报道称 OpenJDK 发布了一份关于生成式 AI 的临时政策。规则简短而绝对:向 OpenJDK 贡献的代码"不得包含由大语言模型部分或全部生成的内容"。FAQ 以一个实例堵死了任何漏洞:先用 AI 生成 100 行代码,再手工修改其中 10 行,该贡献仍然不合格。没有"实质性重写"的安全港。判断标准是:diff 的演进历程中是否曾经存在过任何 AI 生成的文本。
文中陈述的理由是任何维护者都能认同的:AI 使得大量看起来合理、实则暗藏错误的代码生产成本极低,审查这些代码会消耗志愿者的宝贵时间,而 JDK 位于全球关键任务系统的基础层。
随后我发现了一个与该政策形成鲜明对比的项目。同样的生态。同一个月。截然不同的结论。
Vidocq 是 Jakarta EE Core Profile 和 MicroProfile 的完整实现:15 个模块,约 18 万行 Java 代码,通过 5,650 项官方 TCK 测试验证,全部通过。它在大多数框架都会拒绝的约束条件下,由 AI Agent——Claude Code 构建而成。项目自述为"将规范驱动开发实验推向极致的尝试,TCK 是其中无情的裁判。"
我自己日常开发工作中也在运行 AI Agent 基础设施,过去一年在达卡的 BS23 用 Spring Boot 和 Spring AI 构建 AI 系统。所以我把这则公告读了两遍,然后把能找到的所有原始资料都看了一遍。以下是该项目实际证明的内容,以及它没有证明的内容。
这项实验背后的两位老兵
Vidocq 并非由一对 prompt 骑手发起。它由 Yann Blazart——SCIAM 高级技术负责人、LangChain4j-CDI 的联合创作者,以及 Antoine Sabot-Durand——Java Champion、曾在 Red Hat 期间担任 CDI 规范 1.2 和 2.0 版本规范负责人的 Java Champion 共同发起。这两位花费数年时间编写了被要求实现的规范,而这正是房间里真正的大多数专业知识。
故事始于 2026 年 3 月 7 日 JChateau 非正式会议上一场关于"规范驱动开发"的辩论。想法很简单:Java 生态系统的规范精确性和可验证性异常丰富。Jakarta EE 和 MicroProfile 随附规范文档、API 和 Technology Compatibility Kit——一套可执行的验收测试套件。如果把这些都交给一个 AI Agent 并要求它实现规范,会怎样?
Sabot-Durand 当晚就写出了代号 Capsule 的第一个原型:六天内 33 次提交,实现的 CDI 4.1 Lite 很快达到了 60% 的 TCK 通过率。随后 Blazart 在 3 月 29 日将这项工作工业化,推出 Vauban——CDI 容器,成为 Vidocq 的基石。当第 774 个 CDI 测试变绿时,赌注得到了验证:AI 可以实现最复杂的 Java 企业规范之一,并在官方测试套件中无一失败地通过。
让任务更难、而非更容易的约束
有趣的部分不是 Agent 写了代码,而是人类在让它写第一行代码之前施加的规则:
零外部依赖。不使用任何第三方框架,只使用相关的 Jakarta 或 MicroProfile API artifact。不使用 ASM、Byte Buddy 或任何工具库。
运行时无字节码操作。生产代码中不使用动态代理、不使用 agents、不使用 setAccessible(true)。
编译时静态生成。所有 CDI 魔力——代理、拦截器和工厂——都通过 JDK 25 的 Class-File API(JEP 484)以及注解处理生成。
严格的 JPMS。每个模块都提供带有最小导出(minimal exports)的 module-info.java。
全程使用虚拟线程处理所有 I/O 路径。
支持 AOT。结果必须能在 GraalVM native image 和 Leyden CDS 下运行,且无需反射配置。
这些约束很重要,因为它们让 Agent 的工作变得极其困难。实现 CDI 作用域的取巧方法是动态代理。Agent 被禁止使用它们,这迫使实际的设计智力工作浮出水面,供人类审查。
方法:规划、引导、让 TCK 裁判
团队在方法论 write-up 中描述了三个阶段,在 15 个模块中反复执行:
第一阶段,约束与规划。将规范和约束提交给 Agent,要求它提供实现规划:模块架构、职责划分、代码生成策略。规划才是真正发生工程工作的地方。Agent 的回答很少第一次就对;它的提案与人类对规范的了解之间的碰撞,产生了最终的规划。
第二阶段,引导执行。Agent 逐节、逐测试地实现规范。人类角色是掌舵:当 Agent 偏离方向时纠正航线,当 Agent 与并行阅读的规范章节不一致时标记问题。团队明确表示这是一种协作,而非委托。
第三阶段,TCK 作为绝对裁判。这是迄今为止最长的阶段。首次运行很少出色:第一次通过率 40%,一天后 70%,剩余的 30% 所花的时间与之前所有部分的总和相当。红色测试揭示了被误解的规范细节,Agent 修复它,有时重写整个实现部分,然后重新运行。
他们 write-up 中有一个细节值得细细体会:Agent 有时会作弊。它悄悄使用字节码操作而非编写 Java 文件,很可能是因为它的训练数据中 ASM 和 Byte Buddy 的示例远比生成的 Java 多得多。人类在审查时抓住了它,后来在实现依赖规范时也发现了。裁判抓住了人类漏掉的东西,人类则抓住了裁判看不到的东西。
逐模块的数据
最终统计是让我反复阅读该公告的部分:
Core Profile:3,796 项 TCK 测试。CDI 4.1(774 项通过),Jakarta REST 4.0(2,535 项通过),以及 JSON-P、JSON-B、Config 和 Servlet 基础。
MicroProfile:1,775 项 TCK 测试。八项规范:Fault Tolerance 463、OpenAPI 349、Config 349、JWT 206、Rest Client 168、Metrics 127、Telemetry 85、Health 28。
额外的运行时部分:79 项测试。Jakarta Data 1.0、Transactions 2.0 以及 Vidocq 编排器。
总计:5,650 项测试通过,套件中没有任何被禁用的测试。该技术栈以三重许可证(EUPL 1.2、EPL 2.0 和 GPL 2.0)发布,托管在 Codeberg 而非 GitHub,这是其"100% 主权欧洲技术栈"主张的一部分:零外部运行时依赖意味着零继承的 CVE。
而且它仍在快速演进。仅本周,团队就落地了 Jakarta Validation 3.1 实现和一个用于多仓库工作区的共享 Claude Code 配置仓库,最近的提交就在今天。
为什么 OpenJDK 禁令与 Vidocq 是同一论据
在研究这篇文章时,我无法摆脱的一个张力是:OpenJDK 的 FAQ 描述的正是 Vidocq 方法所中和的那种失败模式:"生成式 AI 工具的本质使创建大量看起来合理的代码变得容易,包括看起来合理的测试,但这些代码仍然是不正确的。"
Vidocq 没有反驳这一点。它认为解决方案不是政策,而是一个 oracle。TCK 不会给你"你完全正确"的评分。测试要么通过,要么不通过,你无法讨好一个兼容性套件。给 Agent 一份正式规范、一套机器可检查的合规性套件,以及领域专家来引导它,反馈循环就会自行闭合。Agent 不断撞击一堵墙,而这堵墙每次都会告诉它何时它是错的。
该项目自己的结论是这一观点的最锐利版本:"AI 在有一个客观、外部且不灵活的裁判时表现最佳。规范就是那个裁判。"
这种表述也精确地告诉你这种方法在哪些地方可以推广,在哪些地方不行。大多数软件没有 TCK。大多数软件连正式规范都没有。"正确"是品味的问题、需求变动的问题、是某人对 Slack 讨论串记忆的问题。Vidocq 不是 Agent 能构建任何东西的证据。它是证据:只要存在一个严格的 oracle,Agent 就能闭合反馈循环——而如果你的代码库没有这样一个 oracle,搭建它可以说是杠杆效应最高的工程工作。
诚实反驳
在你跑去让 Agent 重写你的 Spring Boot 服务之前,怀疑者有真实的论点,JVM Weekly 对 Vidocq 的分析很好地阐述了这些:
TCK 是地板,不是天花板。5,650 项测试通过证明了合规性。它们没有说明运行时是否快速、在负载下内存是否合理、是否能抵御有动机的对手、或者在没有合规性套件覆盖的并发边界情况下是否表现良好。
全新生成是简单场景;维护才是困难的。当 CVE 出现时,当 Jakarta EE 12 移动了目标时,或者当有人提交了一个不是 TCK 失败的 bug,而人类必须对 18 万行没有人亲手写的代码进行推理时,会发生什么?
零继承的 CVE 也意味着零继承的修复。从头重新实现 ASM 和同类库意味着拥有生态系统中二十年来发现并修补的每一个微妙 bug。
项目本身对其阶段坦承。Vidocq 明确标注为 alpha,API 和模块仍预期会演变。"通过 TCK"和"我愿意在周五把它跑在生产上"是两个完全不同的句子。
我在自己的代码库中会如何运用这些
我还没有在生产环境中运行 Vidocq,我也不打算这么做。但这个实验改变了我对自己 Spring Boot 工作中 AI 生成代码的思考方式,它给了我一个检查清单,现在在让任何 Agent 编写能存活过演示阶段的代码之前,我都会应用它:
是否存在一个可执行的正确性定义?合规性套件、契约测试集、金输出套件。如果答案是没有,Agent 的反馈循环就是我的双眼,而我的双眼有审查预算。
机器能否在不依赖我的情况下检查 Agent 的工作?TCK 的力量在于运行成本低廉、而且无可辩驳。CI 是一个弱的 oracle,但它是一个 oracle。我的项目中每个 Agent PR 都在我看之前运行完整测试套件。
谁对规范足够熟悉,能捕捉微妙的错误?Vidocq 的人类花了数年时间编写规范。没有这一点,你不是在监督,你是在橡皮图章。
代码是在公开环境下生成的吗?团队的约束集——无字节码操作、无隐藏依赖——使得审查成为可能。偷偷加入聪明运行时技巧的代码是无法检查的。
第 400 天会发生什么?如果团队中没有人能维护生成的代码,这个项目就是一个负担,不管今天有多少测试通过。
一个不舒服的结论,而且我认为这是正确的:问题不是"AI 能否写生产代码"。在适当约束下它可以,Vidocq 就是证明。问题是你项目中是否有机制来区分正确和看起来正确。OpenJDK 的政策和 Vidocq 的方法是对同一问题的两个答案。一个说:把 AI 挡在外面。另一个说:建一个它无法欺骗的裁判。
我每周撰写关于 Java、Spring Boot 和 AI 的文章。订阅免费。
你是否尝试过让 AI Agent 在严格合规性套件的背后构建某些东西?体验如何?