Hurl阻止Vibe Coding的漂移

3个月的墙


如果你用vibe coding做的应用3个月就崩了,如果你正在经历AI覆盖已有逻辑的漂移问题,如果你想保护API契约不被代码变更破坏——Hurl和棘轮就是解决方案。

用vibe coding做SaaS。开始很快。“做登录”——30秒。“加支付”——2分钟。3周出MVP。

3个月后,奇怪的事情发生了。AI"整理"支付逻辑时悄悄改了折扣计算。加了新端点,现有认证就坏了。让它重构,公开API的字段名变了,所有客户端全挂。

这叫逻辑漂移——AI无意中修改了现有业务逻辑。回归bug在传统开发中也有。但逻辑漂移不同。开发者没有意图的更改,在开发者没有察觉的情况下,发生在整个代码库中。因为每个prompt都在新的上下文窗口中开始。


数据说话

这不是感受。有数据。

速度的代价是复杂度。 Carnegie Mellon研究团队比较了807个GitHub仓库在引入Cursor前后的变化(MSR 2026)。引入第一个月,代码增量增加了3-5倍。2个月后速度优势消失。留下的是静态分析告警增加30%,代码复杂度永久增加41%。这一发现被独立验证。Liu et al.(2026)分析了6,299个GitHub仓库中302,600次AI提交,发现未解决的技术债务从2025年初的几百件激增至2026年2月的110,000件以上。

不是变快了,而是变慢了。 非营利AI研究机构METR对16名熟练的开源开发者进行了随机对照实验(2025)。在自己熟悉的项目中,使用AI工具的组完成任务多花了19%的时间。但开发者本人认为自己快了20%。认知与现实的差距为39pp。新项目可能不同,但"AI=一定更快"的假设被打破了。

规模上去了,稳定性就崩了。 Google DORA报告(2025)显示,AI采用率每增加25%,软件交付稳定性下降7.2%。

确实崩了。 Amazon在2025年全公司强制使用AI编码工具,部署了21,000个AI代理。同期约30,000人被裁,审查人力骤降。AI快速生成代码与审查人力削减的结合,导致90天内发生4起Sev-1事故。2026年3月5日,6小时故障造成约630万笔订单损失。内部文件写道:“GenAI的快速代码生成正在无意中暴露漏洞,目前的安全措施完全不足。”


“做TDD"不是答案

对vibe coding漂移的常见建议是"写测试”。方向对,但怎么给测试决定了结果。

TDAD研究(arxiv 2026)精确测试了这一点。让Qwen3-Coder 30B解决100个SWE-bench Verified实例。

条件回归率
基线(无测试指示)6.08%
“做TDD"程序性指示9.94%(恶化)
将受影响的测试文件作为上下文提供1.82%(减少70%)

让它"做TDD"反而更糟。代理试图遵循程序性指示而偏离了本来的任务。但给出"这些测试文件必须通过"的具体上下文,回归减少了70%。

差异明确。不是"如何测试"的指示,而是"什么必须通过"的契约。


Hurl:用纯文本写契约

软件中的"契约"概念由Bertrand Meyer(1992)确立——前置条件、后置条件、不变量的三位一体,明确模块间的义务。Hurl将这一原理应用于HTTP边界。它是一个用纯文本声明HTTP请求和预期响应的测试工具。由Orange(法国电信)维护,是零运行时依赖的Rust二进制文件,GitHub 18.7k星。快到可以在CI中每次提交都运行。

# 登录成功
POST http://localhost:8080/api/auth/login
{
  "email": "test@example.com",
  "password": "secret123"
}
HTTP 200
[Asserts]
jsonpath "$.token" exists
jsonpath "$.user.email" == "test@example.com"

# 未认证访问返回401
GET http://localhost:8080/api/pages
HTTP 401

两个契约。登录必须返回200和token,未认证访问必须返回401。

这个文件被提交到git,在CI中每次提交都执行——AI一"整理"认证逻辑让401变成200,提交就被拒绝。漂移在到达生产环境之前就被捕获。


为什么是Hurl

单元测试也能捕获漂移——如果你不给AI修改测试文件的权限。但单元测试验证的是代码内部的函数,因此与实现结构性耦合。函数名一改测试也坏,每次重构都得一起改测试。

Hurl在HTTP边界上。它只声明请求和响应。它不知道代码的内部结构。AI怎么改代码都行,只要外部可观察的行为一样就通过,不一样就失败。它天然独立于实现,而非行为。

单元测试Hurl
验证对象函数内部HTTP契约
AI重构时一起变不变
漂移检测有条件(禁止修改时)天然
代码结构依赖
人类可读性代码级纯文本
LLM生成难度需要理解代码结构只需HTTP知识

Hurl验证的不是代码而是行为。代码AI可以自由改。行为不能变。这个区分是捕获漂移的关键。


棘轮锁定

Hurl测试通过后就锁定。这就是棘轮。被锁定的Hurl测试就是 ratchet code——使已通过的API契约不可逆的确定性代码。

1. 为当前API编写Hurl测试(或自动提取)
2. CI中每次提交都运行
3. 通过的测试禁止删除/修改
4. 新功能添加时添加新Hurl测试
5. 所有现有测试+所有新测试全部通过才能合并

让代理"重构代码”,它自由地改代码。但Hurl测试一坏,提交就被拒绝。代理必须在保留所有现有行为的前提下重构。Hurl未覆盖的边缘情况仍可能漂移,但已覆盖的行为,漂移被结构性地抑制。

与TDAD研究的发现完全一致。不是"写测试"的程序性指示,而是"这些Hurl文件必须通过"的具体契约。代理可以选择方法,但不能违反契约。


对遗留系统也适用

已经在用vibe coding运行生产环境?不需要从头开始。

第1步:用Hurl捕获当前行为。

有API文档就直接转成Hurl。没有就让代理读现有代码来写Hurl测试。目标是对所有端点用纯文本声明"这是它现在的工作方式"。

第2步:挂到CI上。

确认所有Hurl测试通过,加到合并条件中。

第3步:从此安全。

让AI重构也好,加新功能也好,Hurl保护现有行为。漂移一发生CI就立刻捕获。

不是基础施工而是抗震加固。不关门就加固建筑。


不是Vibe Coding的终结,而是进化

创造vibe coding的Andrej Karpathy本人在2026年2月——正好一年后——宣布"vibe coding时代结束了"。新范式是代理工程——人类不写代码,而是编排代理自主地规划、实现、测试。

Thoughtworks Technology Radar(2025)将Spec-Driven Development列为"Assess"等级。Martin Fowler团队发布了SDD工具分析。行业在向同一方向收敛。

Storey(2026)将漂移的根本原因理论化为两个新的债务概念。认知债务——团队共享理解的侵蚀,以及意图债务——“为什么这样做"的依据未被外部化。Hurl文件正是意图的外部化。“这个端点必须这样工作"的声明与代码分离,留在git中。

Hurl测试是这个转变的最小单元。不需要写10个规范。不需要学OpenAPI。一个Hurl文件就是一个契约。 而这个契约在不限制代理自由的前提下,结构性地阻止漂移。

不要换模型,加契约。


相关文章


参考文献

变更历史

  • 2026-05-22: 初版