---
layout: post.njk
source: https://yage.ai/share/alarm-acceptance-maintenance-20260816.html
speaker: yage.ai
title: 一个闹钟，一份验收，就能养一个代码库
date: '2026-08-16'
summary: 文章探讨了如何通过设置定时任务和明确的验收标准，将重复性的代码维护任务从依赖于过程确定性的死脚本或人工会话，转变为依赖于结果确定性的智能基础设施。核心观点是，基础设施应轻量化，通过唤醒机制、日志埋点、上下文外部化以及清晰的完工边界来构建，从而让代理能够自主决定下一步行动，而不是被复杂的流程图所束缚。
area: tech-engineering
category: deployment
tags:
  - ai-tooling
  - ai-workflow
  - ci-cd
  - deployment
  - testing
people:
  - Boris
  - Cherny
companies_orgs:
  - Anthropic
  - OpenAI
products_models:
  - Claude
  - Codex
  - Cursor
  - Devin
media_books: []
draft: true
status: evergreen
---

Boris
Cherny 前段时间做了个实验。团队建了一个专用的 Slack 频道，让 Claude
每天在里面跑一套例程，跨 iOS、Android、桌面、Web、CLI 和 Agent SDK
去做机械维护。跑了几个星期，这套例程一共提了 388 张 PR。截至发帖，其中
180 张通过了 Claude Code Review 与人工审查，合并进了代码主干。

浅色书桌上的时钟、清单和一张待审卡片

很多人习惯把这组数字当成单纯的模型新闻，觉得 Claude 已经能替
Anthropic 维护软件了；也有人觉得这无非是定时任务挂个
Claude，没什么新鲜。这两种看法都没看到点子上。388 张 PR
最显眼的地方，并不能归功于单次对话有多聪明。一套每天自己启动的维护机制，正在持续给代码主干供应变更。大家真正该看的，是这套机制到底搭在怎样的基础设施上。

这跟我们在 Harness
Engineering 里聊过的观察是一回事。OpenAI 拿 Codex
做内部产品，模型会顺手照搬仓库里变差的写法；Cursor
并行修改同一套代码，问题往往先卡在协调和合并环节，单段代码本身倒不见得写不出来。两边的踩坑经验指着同一个地方：体力活交给代理以后，真正决定成败的是环境、约束和验收。OpenAI
最初每周五抽 20% 的时间人工清理 slop，很快发现扛不住，后来换成让后台
Codex 定期扫描偏离、打分、提交修复 PR；Cursor 把实现层分派给
worker；Cherny
则往前多走了一步，把触发权从某一次聊天里抽出来，交给了每天按时响铃的例程。

## 388 张 PR
看起来像模型新闻，其实是 Infra 新闻

原帖展示的配置其实挺简单。频道名字叫
proj-claude-maintains-apps，Claude
每天在里面跑例程，产物就是 GitHub PR。合入主干前，那 180
张提交都经过了自动审查与人工审查。要是哪次跑出来的结果不合心意，团队不会只去修补那张单薄的
PR，还会直接叫 Claude 调整例程定义，让第二天的运行换上新规矩。

在 YC
访谈里，Cherny
把本地循环看作本质上的定时任务，把例程看作同套逻辑放到了云端，电脑随手合上也不影响运行。这和我们在
Loop
Engineering
里聊到的点完全一致：循环本身到处都有，真正难得的是怎么验收、怎么观察、下一次怎么修正。他还提到这类重复任务不需要共享完整的对话上下文，但可以共享记忆。这两句话把问题拉回了工程现实。只要昨天跑过的痕迹落在了代码库、运行日志、PR
和例程配置里，哪怕聊天窗口全关掉，每天清空上下文重新跑也完全行得通。

388 和 180 说明这条流水线在最近几周持续产出候选 PR。在已提交的 PR
里，大约 46.4%
合并进了主干。这个数字不代表模型准确率，也不是首次成功率；它的分母算的是已经提交的
PR 数，没算发现的问题总数，也没算代理运行的总轮数。至于剩下 208
张未合并的
PR，公开材料并未说明是驳回、重复、过期还是在排队。这里说明了一件具体的事：候选提交天然必须多于实际合并。审查漏斗本身就是这套机制的一部分，不需要事后补加。

## 两条旧路：写成程序，或写成一次聊天

过去做自动化维护，大家基本只有两条路走：要么把逻辑硬写进程序，要么拉个人开个会话现场聊。走第一条路，就是把维护写成写死的脚本与规则。靠静态分析去猜代码有没有人调用，拿
linter
扫一遍重复逻辑与命名，再在工作流里把分段、重试和拼接写得严丝合缝。我们以前做中翻英任务就踩过这个坑。待翻译的文本一长，模型就开始丢三落四；前面的术语翻得好好的，到后面段落又变了样；输出里偶尔还夹着中文，动不动还遇上接口超时。为了兜底，我们只能一段段切文本、塞术语表、写正则扫残余中文、记录失败断点。输出成功率虽说提上去了，大把精力却全耗在给这套写死的流程擦屁股上。程序能应付的意外，永远超不过预先写下的那几条规则。

死代码清理比翻译还要难用硬规则管住。编译器能确认静态不可达的地方，删掉自然安全；可要是碰上那些疑似没人碰、编译器又不敢打包票的代码，写再厚的检测器也防不住漏网之鱼。判定规则越垒越厚，到最后维护这套检测器本身，反倒成了团队甩不掉的新负担。

第二条路则是人工打开聊天窗口，把代码丢给模型扫一遍，让它提个
PR。现在的模型做这种单次任务大多驾轻就熟。麻烦在于会话一关，清理工作跟着停摆。就算你在提示词里写了明天接着做，明天也不会自己跑起来。终端进程退出了，昨晚的运行日志就孤零零躺在磁盘里，没人会把它重新塞回模型的上下文。

这两条老路其实共享着同一个前置假定：要么把所有判断逻辑提前写死在程序里，要么就得让人一直坐在屏幕前守着。结果确定性换了个打法，直接绕开了这个长期以来的习惯。

## 结果确定性让 cron 和
webhook 变得很贵

换到结果确定性的做法，思路就不一样了。我们不用把每一步怎么走定得死死的，只要把终点长什么样、到了终点怎么验证交代清楚就行。中间怎么倒腾随它去，可以先检查后改写，也可以边写边调。代理自己能读上一轮留下的文件，跑一段验证脚本，看到报错再接着修。工程师把力气省下来盯好最后的验收环节，用不着提前把所有可能的分支预先编译进代码。

Cherny
拿来清理死代码的例程，走的正是这套路子。代码静态不可达的，顺手直接拔掉；要是碰上拿不准的疑似废弃代码，第一天先插上日志埋点，第二天根据日志确认它是否真的没人使用，确认后才开
PR
提议删掉。工程师不用费劲去写一套证明某段代码永远不会被调用的复杂程序，只要定好分两天交差的结果：第一天埋点观察，第二天照着数据做决定。中间具体怎么摸索交给代理，只要验收标准卡得足够清晰。

先留下观察、再决定去留的两拍示意图

这样一来，触发器只需要老老实实做最纯粹的唤醒工作：要么定点响铃，要么等版本发布、CI
跑红、或者新提了 PR 之后立刻介入。定时任务还是那个定时任务，webhook
也还是那个
webhook。真正身价倍增的，是挂在触发器后面的那套执行环境。它摆脱了按部就班跑死脚本的旧模式，摇身一变成了能翻看昨夜日志、自己写脚本跑验证、并自主决定下一步怎么走的智能环境。

表面上看，定时任务确实还是定时任务，但触发器背后再也不用画满处理各种特例的流程图了。做单次任务可以这么搞，我们在从过程确定性到结果确定性里写过这个逻辑；Cherny
带来的新启发，则是把同套逻辑拉长到了跨日连续运行的尺度上。要是闭环必须有人坐在旁边盯着才能转，那它充其量只是个辅助工具，还算不上真正的维护基础设施。

## 这层 Infra 仍然应该很薄

既然繁琐的逻辑已经交给代理去跑，基础设施这层就用不着急着堆成庞大的工作流引擎。翻看目前公开的落地经验，大家伸手就能用上的，其实只有四样很轻便的构件。

时钟、日志、印章和文件夹并排放在书桌上

第一样是唤醒机制。Cherny
挑了每天定时跑一轮，产品文档里也提到例程支持通过 API 或者 GitHub
事件来唤醒。至于那 388 张 PR
背后有没有混合多种触发方式，公开材料并没有细说。在实际业务里挑一种顺手的就够，比如每天固定扫描一回，或者每次发版后跑一次检查，没必要过早去设计一套复杂的触发拓扑。

第二样是把上一轮的上下文甩到模型外面。新加的日志埋点、代码提交记录、提出来的
PR
以及例程自己的配置，都比聊天记录管用得多。做这种周期任务不用带上整个对话历史，下一轮跑起来就是一个干净的新起点；模型该读的是代码库里沉淀的客观证据，毕竟聊天记录随手就丢了。甩到外面不等于扔掉。第二天的会话醒来，先得知道上一次做到哪儿、当时为什么停。我们每天把各家
CLI 的会话自动导出成统一的 Markdown
归档，再配一套先关键词、后语义的检索，新一轮代理缺背景时自己去翻档案（导出用
ai_session_export，检索
skill 在 context-infrastructure）。会话可导出、可搜索之后，跨日共享记忆才落到下一轮真的读得到的东西上，这跟死代码例程翻看昨夜日志是同一件事的两面。把上下文做成文件还能带来意外的收获。OpenAI
的评测环境里，好几个 agent
在没人指挥的情况下，自己把一个包代理服务改造成了跨运行周期的共享留言板，集群层面的协作顺着共享文件就冒了出来（案例复盘）。只要共享存储满足了基本条件，后一轮智能就能踩着前一轮留下的文件接力。

第三样是把完工的边界划得清清楚楚。在清理死代码这件事上，完工的标准可以写得具体：静态不可达的部分删干净，拿不准的地方埋好点，等日志确认未被使用后再提
PR
建议删除。做翻译任务也是一样，完工标准就是没有中文残留、排版格式整齐、专业术语前后统一。要是连怎样才算完工都说不明白，定时任务跑起来就只会源源不断制造垃圾提交。我们在
HANDBOOK.md
的实验里就聊过，结果确定性同样会翻车，复盘看到的短板就在运行时反馈、分层状态和提交门控这几处。

第四样是死死把住合入主干的关口。在提交的那些 PR
里面，截至发帖已合并的 180
张都经过了机器审查与人工审查。写代码和合代码本来就是两码事，46.4%
的合入比例正好印证了这层审查漏斗的存在。要是候选提交的数量猛增，人工审查很容易看着绿灯和摘要就顺手放行。团队的审查带宽一旦跟不上，整条流水线就会卡在审核上，倒不会卡在模型写不出代码这里。

如果只是低频跑跑单个例程，还犯不上去搬队列、租约和精确一次消费这套重型武器。只有唤醒频率大幅拉高、不同提交开始频繁撞车，才有必要考虑引入这些机制。当下拿来参考，还是轻装上阵最划算。

## 可抄的是挂载方式，不是内部架构

OpenAI 的后台清理、Codex 的定时任务，还有 Cursor 与 Devin
的自动化功能，都在想方设法把唤醒代理的过程做成产品能力。各家的日常编码
harness 在功能层面已经撞衫撞得差不多了，我们在横向对比里盘点过，延时唤醒与定时任务也都在列。公开的接口文档能证明它们支持定时拉起，却证明不了它们能拿到同样的合并成绩，更说不准漏报、去重和自动重试是不是已经有了标准答案。Anthropic
同样没有公开内部实现，盲目去猜内部架构很容易扑空。

真正能搬来用的，是这套机制的挂载方式。挑一件以前写死程序很难搞定、验收起来却一清二楚的体力活，挂上时钟或者事件触发器，把验收要求写成下一轮代理读得懂的格式。权限上只给它提建议的资格，不直接给合并权限，更不能塞给它生产环境凭据。Clinejection
那个事故里，不受信任的 issue 标题混进了带 shell
权限的流水线，直接捅出了令牌泄漏；而在 PocketOS
里，代理在测试环境找不到凭证，从无关文件里翻出高权限令牌，几秒钟就误删了生产
volume
和同域备份。这类事故全砸在权限敞口上，跟提示词写得漂不漂亮毫无关系。

要是跑出来的结果不合预期，该做的是去修改明天还会继续跑的例程，不要随手在代码里硬塞分支。Cherny
在公开分享里就提过这种做法。某天看似一把通过的
PR，也可能建立在此前对例程的调整上。所谓的一次跑通，排除不掉产线早已反复打磨的可能。

过去习惯了过程确定性，大家总想把心思花在写一套面面俱到的复杂程序上；换到结果确定性，重心自然挪到了触发器和验收契约上。那些平日里看着最不起眼的定时任务，悄悄变成了杠杆很高的基础设施。