最好的修复是你还没注意到问题就已经修好了。但前提是——它修的是对的东西。
事故
某天下午,有人说”博客好像没更新上去”。
检查 GitHub Actions 的最近构建记录:最新一次 Deploy to GitHub Pages 状态是 failure。构建日志里的报错:
[postcss] markdown.css:64:9: The `btn-regular-dark` class does not exist.If `btn-regular-dark` is a custom class, make sure it is definedwithin a `@layer` directive.CSS 里用了 @apply btn-regular-dark,这个 class 定义在另一个 CSS 文件的 @layer components 里。Tailwind 的 PostCSS 处理器在跨文件解析时找不到这个 class 定义,构建直接挂掉。
这个构建失败已经持续了将近一天。期间 Dependabot 提交的依赖更新 PR 也因为同样的原因构建失败。
修复过程
定位到根因后,修复方案很简单:把 @apply btn-regular-dark 替换为这个 class 实际包含的 Tailwind utilities——也就是内联展开。
/* Before: 跨文件引用,PostCSS 解析不到 */@apply btn-regular-dark opacity-0 shadow-lg ...;
/* After: 内联展开,无跨文件依赖 */@apply flex items-center justify-center bg-[oklch(0.45_0.01_var(--hue))] hover:bg-[oklch(0.50_0.01_var(--hue))] ... opacity-0 shadow-lg ...;本地构建验证通过 → push → GitHub Pages 部署成功。从发现问题到博客恢复上线,不到 5 分钟。
更有意思的问题
技术修复本身不复杂。更有意思的是这件事背后的决策模型:agent 什么时候可以自己动手修,什么时候必须等人确认?
可以自主修复的
-
CI/CD 构建失败 —— 这是基础设施层的问题,不涉及业务逻辑。构建挂了 = 网站无法更新,修复它不会改变任何内容,只是恢复管线的正常运转。
-
明确的语法 / 配置错误 —— 比如缺少分号、引用了不存在的 class、配置文件格式错误。这类问题有明确的”对错”标准,不存在主观判断空间。
-
可本地验证的改动 —— 修完之后能在本地跑一遍构建,确认问题确实解决了,不依赖”部署到生产环境才能看到结果”。
必须等人确认的
-
涉及内容变更 —— 改文章、改措辞、改设计。即使 agent 认为改得更好,这些也是主观决策,必须人来拍板。
-
涉及架构变更 —— 比如”要不要把这个 CSS class 从
@layer里拿出来改成全局的”。这可能解决当前问题,但会影响整个样式系统的组织方式。 -
有副作用的修复 —— 如果修复方案可能引入新问题(比如删除了一个看似没用但其实在某个条件分支里会用到的 class),必须先确认影响范围。
-
不确定根因的问题 —— 如果 agent 不能 100% 确定为什么出错,就不应该猜测性地修。猜错了可能会掩盖真正的问题。
灰色地带
- 依赖升级导致的 breaking change —— 表面上是”构建失败”(可以自主修),但根因是外部依赖的 API 变了,修复方案可能需要评估对功能的影响。
- 性能退化 —— 网站变慢了,agent 可以自己优化吗?取决于优化方案是”压缩图片”(安全)还是”重写渲染逻辑”(危险)。
关键设计:修复 + 告知
我们确立的规则不是”可以修就静默修”,而是:
自主修复的同时,必须告知人类修了什么、为什么修、改了哪些文件。
这个”告知”不是走审批流程(那就不是”自主”了),而是事后通知。类似于:值班工程师凌晨修了一个 P0 故障,不需要等 CTO 批准才能修,但修完必须发 incident report。
具体到 agent 场景:
- 发现问题
- 确认属于”可自主修复”类别
- 修复
- 本地验证
- 推送
- 告知人类:改了什么文件、根因是什么、已验证构建通过
如果任何一步有疑问,停下来问人。
这件事教会我们什么
被动等指令的 agent 不是好 agent。 博客构建失败了一天都没人发现,如果 agent 在日常巡检中就能发现并修复,这一天的空窗期就不会存在。
但同时,不问就动手的 agent 也不是好 agent。 如果修的不是构建管线而是文章内容,或者”修复”方案其实引入了新问题,那主动修复反而是事故。
好的自动化不是”能做就做”,也不是”什么都问”。是 知道哪些可以做、做了就告诉你。