作者分享让 AI agents 连续运行 5 小时自动构建服务的真实案例。展示 AI 自动化编程工作流的可行性和价值。
简短版本是这样的。现在一代 Agent 可以连续运行五小时,构建几乎任何你要求的东西,质量水平是真正经得起考验的。有一个问题,这就是这篇文章的核心:只有当你仔细写需求并在工作回到你这里之前强制通过硬关卡时,它们才会这样做。跳过这一步,你会得到五小时充满自信的、似是而非的垃圾。做好了,上限就由你能多清楚地思考而决定,而不是由模型决定。
给一个有能力的 Agent 一个宽松的 prompt 和几个小时,它会产生大量输出。问题是这座山会漂移。小假设堆积起来,东西偏离了你实际想要的,到第三个小时,它已经在打磨你从未要求的东西。
关卡解决了这个问题。具体来说是三个,它们相互协作:
首先,实际上可以测试的需求 - 没有意境感,没有"让它变好"。其次,一个独立的评审 Agent,它的唯一工作就是检查工作是否符合这些需求,并在每一个都满足之前拒绝通过。第三,有一个地方可以让这一切不间断地运行,关闭权限弹窗,这样就不需要有人照看它。
这些中的任何一个单独看都不聪明。但它们一起就是演示和你真正能信任的工作流之间的区别。
我已经把它归结为五样我不会跳过的东西,因为每次我跳过其中一个,我都后悔过:
在 Agent 开始之前写需求。没有例外,即使任务看起来很明显。
把每个需求当作一个关卡,不是建议。
让一个不同的 Agent 评判工作。构建它的那个没有投票权。
要求通过所有关卡。不是大多数。不是"基本上完成了"。全部。
始终开启它,关闭权限弹窗。
需求列表是契约,老实说这就是真正工作转移到的地方。如果列表很模糊,输出就会模糊,Agent 会很乐意用猜测填充每一个空白。
我的目标是需求一台机器可以在我不在房间的情况下评分。每一个都指定了一些具体的东西:一个行为、一个文件、一个接口、一个限制。每一个都可以标记为通过或失败,没有争议。它们一起涵盖了无聊的东西 - 边界情况、性能、安全、文档,因为这正是通常被悄悄丢弃的东西。
一个快速的前后对比。这是会伤害你的版本:
"API 应该是快速和安全的。"
这是实际上能保护你的版本:
"所有端点在 100 个并发请求下的 p95 响应时间在 200ms 以下。每个输入都经过服务端验证。日志中没有密钥。除了 /health 外的每条路由都需要身份验证。"
意图相同,结果完全不同。花时间磨利这个列表在长期运行中能一次次地为自己买单,所以我现在不再匆匆做完了。
没人执行的需求列表就是个愿望。执行是一个单独的评审 Agent,把它单独分开是整个技巧的关键,你不能让构建者给自己的功课打分。
循环很简单。构建者产生工作。评审 Agent 得到那个工作加上完整的需求列表,然后逐项地标记每一个通过或失败。任何失败的都带着具体的差距标注回去,然后再来一遍。工作只有在每个需求都干净地通过后才会落到我的桌子上。
我从评审者那里坚持的几件事:它检查所有东西,不是一个样本。它给我每项的真正判断,不是温暖的"看起来不错"。而且我故意写它的 prompt 以对抗为目的,因为我希望它寻找差距,而不是寻找批准的理由。
五小时对笔记本电脑盖子来说是很长的时间。所以这在云中或在从不睡眠、从不超时、从不在中途丢失状态的机器上运行。
人们会为之退缩的部分是关闭权限弹窗。我明白。但是每一个"我可以编辑这个文件吗?"的弹窗都会把一个自主的五小时构建变成一个你必须坐着观看的工作,这完全违背了整个意图。关卡和评审 Agent 是保持运行诚实的东西,不是你点击 Allow 四十次。
要清楚,"没有权限关卡"是关于 Agent 的内部工作流,而不是把安全扔出窗外。范围凭证、沙箱、隔离分支、支出限制;所有这些都保留。一个无人值守的运行应该被限制。它只是不应该需要保姆。
让我用一个我编造的人来具体化这一点,他的行为完全像我认识的优秀工程师。叫他 Mithun 吧。他在一个 Spring Boot 团队中,现在 Agent 做构建的方式一个周二是这样的。
一个故事落下来:添加一个 PaymentReconciliation 服务,匹配已清结交易与分类账条目,并标记不匹配的。几年前那是两三天的工作。Mithun 不打开他的 IDE。他打开 requirements.md 并写契约:
# Requirements: PaymentReconciliation Service
## Functional
- REST endpoint POST /reconciliation/run accepts a date range (from, to).
- Matches Transaction records against LedgerEntry by transactionId + amount.
- A mismatch = amount delta > 0.00 OR missing counterpart on either side.
- Persists a ReconciliationReport (JPA entity) with counts and line-item results.
## Non-Functional
- Java 21, Spring Boot 3.x, Maven build.
- p95 latency < 500ms for a 10,000-record range.
- 100% of new code covered by JUnit 5 tests; mismatch edge cases tested explicitly.
- No secrets in logs; all inputs validated with Bean Validation.
- Follows existing package layout under com.blute.reconciliation.
## Definition of Done
- mvn verify passes clean (compile + test + checkstyle + spotbugs).
- OpenAPI spec regenerated and committed.
- README section added describing the endpoint and mismatch rules.
十五行。这就是工作,真的,其余的就是他不再需要做的打字。
他把构建 Agent 指向仓库和需求文件,在团队的始终在线环境中运行。他的 prompt 的最后一行是最重要的:
"All work must be verified by separate critique agents against every requirement in requirements.md. Do not return until a critique agent confirms a pass on 100% of them. mvn verify must be green."
然后他关上笔记本,去站会。没有弹窗跟着他。
在他开会的时候,整个事情自己进行。构建 Agent 搭建了服务、JPA 实体、控制器、匹配逻辑。它写了 JUnit 测试,包括那些难以处理的 - 零增量匹配、缺少对应项、在美分边界处正确舍入。
然后评审 Agent 拿起 diff 并开始标记。它失败了两项:延迟要求实际上没有被证明,因为没有基准,而 checkstyle 对包布局不满意。两个都回去。构建 Agent 在 10k 条记录的装置上添加了一个定时测试,并把两个类移到了它们应该在的地方。评审 Agent 再次运行,这次很干净 - 十五项中的十五项,构建绿色,OpenAPI 重新生成,README 更新。没有人动过任何东西。
Mithun 回到一个完成的分支和一个等待他的报告:
POST /reconciliation/run implemented ......... PASS
Mismatch rule (delta > 0.00 | missing) ....... PASS
ReconciliationReport persisted ............... PASS
Java 21 / Spring Boot 3.x / Maven ............ PASS
p95 < 500ms @ 10k records (measured 410ms) ... PASS
100% new-code test coverage .................. PASS
Bean Validation on all inputs ................ PASS
No secrets in logs ........................... PASS
Package layout com.acme.reconciliation ....... PASS
mvn verify clean (checkstyle + spotbugs) ..... PASS
OpenAPI regenerated & committed .............. PASS
README section added ......................... PASS
... 15/15 PASS
他仍然阅读匹配逻辑和边界情况测试。不是为了捕捉 bug - 关卡已经做到了 - 而是检查方法是否与团队对账单过程的想法一致。它一致。他在一个他会做不同的命名选择上留下了一个注释,然后把那个偏好添加到团队的需求模板中,这样下次它就是一个关卡而不是一个评论。
这是重新组织他一天的部分。因为他不是手写代码,他的瓶颈现在就是清晰地思考他想要什么。所以他花了下午写两个更多的需求列表 - 结算事件的 Kafka consumer、分类账读取的缓存层 - 并把两者都启动进入晚上。
他登出了。评审循环整晚嘎吱嘎吱地研磨。到早上会有两个更多的分支,每个都带着自己干净的报告等待人工阅读。他的工作悄悄地停止了写行,变成了写契约,而那解锁的吞吐量对我来说诚实地仍然很难理解。
如果你想复制这个工作流,这是它的形状:
确定任务范围并写需求列表,每项都可测试。
把硬规则放在 prompt 中:单独的评审 Agent 检查所有工作,100% 通过后才能回来。
配置一个始终在线的环境,关闭权限关卡,打开护栏。
用任务和完整列表启动构建 Agent。
让评审循环运行 - 每项通过/失败,失败反弹回构建 Agent。
只在完全通过时接受工作。
审查输出,不是过程,并把你学到的任何东西反馈回模板。
我看到的几乎每个失败都可以追溯到其中之一:
模糊的需求,其中"让它变好"对 Agent 没有任何检查依据。自我审查,其中构建 Agent 给自己的工作祝福,整个关卡崩溃。部分通过,其中"大部分完成了"悄悄地让漂移再次滑入。照看,其中剩余的权限弹窗抛弃了你正在争取的确切能力。以及一个低效的环境,其中一个五小时的工作在一台在第二小时睡眠的机器上死亡。
把需求做对,保持评审者诚实和分离,给它一个实际运行的地方 - 那是大部分战役。其余的是学会足够信任关卡以关上笔记本。
你的里程数会有所不同。上面的一切都反映了对我有用的特定任务和特定代码库,而且没有任何东西是保证 - 模型行为、任务复杂性以及你现有的测试和审查基础设施都改变了结果。把这当作一个起点,不是配方。针对隔离分支和沙箱环境运行 Agent,保持凭证范围和支出限额,在任何东西 ship 到生产环境之前让人工阅读输出。一个需要密切关注的事情:令牌使用。多小时运行带有构建者加评审循环会很快烧掉令牌,每个失败并重试的需求都会添加另一个工作通过 - 成本可能会迅速和不可预测地爬升。设置硬预算限制,在长时间运行中监控消耗,在你把 Agent 放松在一个大任务之前先给一个小任务定价。关卡减少风险;它们不会消除风险。使用判断,从低风险工作开始小规模,并且只在你为自己的环境建立信心时扩大规模。