作者构建了一套自动化框架,让多个AI智能体在无人的夜间自主完成代码仓库巡检、问题分类、任务入队,全部自动化流转无需人工干预。
队列现在自己清空,早晨的 note 一分钟就能看完
一个目录是我那些 agents 共享的任务管理器,这是我发布过的阅读量最高的东西,但它遗漏了最重要的部分:谁来处理这个队列。头一个月,诚实的答案是大部分都是我。夜间运行会清掉几个条目,但每一个机械性的发现——一个偏离的 git hook、一条依赖建议、一个过期路径——仍然等着我去注意到它并路由它。我统计了一天的提交:八个仓库 68 次提交,大约 48 次是 fleet 在自我维护,而我是那个路由器。队列路由了工作。但没有任何东西路由时间。
所以现在 fleet 在四个动作中自我维护。
检测自行提交工作。每个夜晚,确定性的 lenses 扫描每一个仓库,并通过会话使用的同一个原子门,将允许列表中的一类发现直接写入队列。允许列表是整个设计的核心:过期的 gate、只在 CI 中运行的测试、死的路径、落后于其 pack 的工具。判断类留在外面。超出预算的文件是编辑决定,缺失的 contract 会被创建,任何被扫描标记为风险的都是裁定。一个错误的工作单比一条报告行的代价更高。
进度以契约为准,从不以提交为准。夜间循环的第一个版本,在子进程提交时计算一轮为有效的。基准之夜说明了为什么这是错误的 delta:十五个 spawn 中有十一个提交了,其中六个是相同的追加段落,而每个被 spawn 的条目从未移动过。现在每条目一轮无效的判定标准是:子进程启动时可工作,退出时仍待处理且可工作。在三个不同夜晚都无效的条目会被标记为需要我,通过门自身的动词留下一条注释。死子进程留下的 lease 在下一次运行开始时被回收。夜晚收敛于队列状态而非在其上空转。
night 1 pending ──child──▶ pending fruitless: 1
night 2 pending ──child──▶ pending fruitless: 2
night 3 pending ──child──▶ pending fruitless: 3 ──▶ needs: owner
one line in the brief,
one batched decision
早晨的报告是 PA 的便条。我过去收到的每一份报告都是准确的,但没有一份曾经可操作:十五行按时间顺序排列的"Started work",同样的错误一次又一次。我用一句话写了 spec:PA 第二天早晨向老板汇报,在喝咖啡前用手机阅读。简报从运行的单一事实流编译而来,每条 producer 写入一条 JSON-lines 追踪,所以夜晚只有一份记录,而非没有人去协调的三份。它以夜晚的形态开头,区分四种状态(自己修复了、已处理、需要你、仍然卡住),通过 URL 链接合并请求,并根据条目自身尝试行计算夜间复发次数。声音测试支配一切:如果不能在不到一分钟内大声读出来,那就是错的。基准之夜的 4.6 KB 消息变成了 680 个字符。
Morning. The night worked 4 projects; 3 merge requests are ready
for your review.
Needs you:
* tooling: merge request ready to review (link)
* site: merge request ready to review (link)
* 3 decisions waiting in the queue (oldest 14 days); your next
sitting presents them in one batch.
* 6 entries have sat "in progress" for over a week, likely
orphaned by closed sessions; the board lists them.
Full detail: the dated report, one step down.
那是一份真实的报告,名字已改。没有模型写它。在那个以真实性为产品的单一表面上用一个模型是一种新的犯错方式,而简报本身的框架是:模型是优化手段,不是主题。
第四个动作来自本周的一次失败。drain 提交了一份提案,在卡住时升级给我,而提交 gate 拒绝了整晚的批次,因为提案不应该停在我这里:它的唯一出口是 board 上的一个 rank。十六个状态翻转坐在 staged 中,而简报什么都没说,因为提交的输出进了 /dev/null。现在任何 job 做出而被 gate 拒绝的写入都会成为"需要你"下的一行,带上 gate 的理由,而 escalate 动词在门口拒绝提案。
同一条给人类的规则,来自同一周。在一个 session 为另一个项目提交队列条目之前,它检查那个项目是否有活跃的 session,如果有就直接把请求连同验收测试发送过去,请求回复。队列的存在是为了碰撞安全和持久性,不是为了延迟,而活跃的 session 已经持有目标的 claim。任务结束时无人应答会变成一个条目,所以不会因为没人读的消息而丢失任何东西。第一次运行时,一条直接消息在几分钟内解决了一个被废弃的合并请求,而队列本来会等到夜里。
三周的数据:54 个条目被标记为需要我。其中 29 个是我每次都以相同方式解决的重复类。这个数字是我接下来要解决的目标。
队列仍然没有数据库。它只是不再需要我来充当一个。