作者部署了一套夜间自动执行队列的系统,夜班agent正确完成了功能但有意停在发布前,白天作者却因信息不同步把功能重做了一遍。深刻揭示了人与AI agent共享状态的设计重要性。
我有一个队列,跨项目的工作都在那里排队等候。每晚有一个定时任务来清空这个队列,每个项目分配一个 headless agent,到处都是 rails——rails 指的是机械强制执行的护栏,在这类架构中代替信任而存在。
上周,队列里有一条待处理项:为自己的网站建一个写作板块。在一夜之间发生的事让我学到的关于运行 agent 的知识,比这个功能本身还多。
夜班运行时,它正常地取走了这条任务、修改了状态、在一个隔离的分支上构建了完整功能、记录了设计决策,然后在故意在差一步的地方停了下来。它的 rails 禁止在无人值守的情况下发布到线上。它在报告中写道,部署会绕过早晨的评审,并给我留了一行早晨的操作说明。到此为止,系统运行得完全符合设计。
日班是我,用一个交互式 agent 来工作。我们从头开始重新构建了同一个功能,在 main 分支上,然后部署了它。不是因为任何东西出了故障,而是因为我前一天读过那条队列条目——当时它还显示 pending——我把那个过时的印象记在了脑子里,而不是重新读一下那个花十秒就能打开的条目。状态文件显示 taken。我从来没去看。而夜班的那份报告——带着那一行操作说明的那份——在同一个早晨也没被处理,这件事我得自己承担。一份没有强制门禁强迫你看的报告,也不过是文字而已。
night shift, headless day shift, me with an agent
evening takes the entry: taken
builds on its own branch
stops before deploy, by rule
reports: deploy after review
morning reads my memory: still pending
rebuilds on main, deploys
later ── the two builds meet in review; the merge takes both ──
这是我觉得值得记下来的东西。每一条机械化 rail 都生效了。那些断言让两个构建永远碰不到同一个文件,drain 的 no-publish 规则让夜间的工作保持可审查,分支隔离让 main 分支保持干净。唯一失败的是那些跑在记忆而不是机制上的部分——我自己以为昨天的状态还是今天的。
我当然把那条规则写下来了。用文字写的规则也会衰减,这就是那个笑话,而这次它落在了我身上。所以那个比笑话更持久的修复是机械化的——它不得不如此。队列现在会从条目生成一页看板,taken 作为自己的 section 出现在那里,夜班的断言在日班开始工作前就在眼前。自然,这是在那天结束前就构建好的。
这次协调本身也有它的教训。一个功能的两套实现,一套出自无人值守的 agent,一套有我参与 loop 的 agent。当我并排 review 时,夜班版本更好。架构更清晰,sitemap 自己维护自己,server config 里的特殊 case 更少。但它也漏掉了一些只有线上部署才能暴露的东西,而日班版本已经踩过并解决了。所以这次合并拿了夜班的架构和日班来之不易的修复,两个构建最终都有了价值——这比那重复的小时数应得的结局更仁慈。
如果你也在夜里跑 agent,我的收获有三条。给夜班 rails,而不是信任——它会乐意遵守机械强制执行的规则。让早晨的 review 成为真实的一步,而不是形式主义——我的那个真的选出了赢家。而在开始任何工作之前,重新读一下队列,而不是你记忆中的队列。条目知道真相。你只是以为自己知道。