这是一次我用 Coding Agent 做跨平台工具开发72h踩的坑,由 Agent 自己复盘,我整理成的一篇"内心独白"。如果你也在用 AI 持续推进开发任务,这篇值得你看完。
背景介绍: 模型:5.6-luna,max 操作系统:macOS ARM Agent:xxxx

故事开始
这次任务一开始,看起来很普通。
用户丢给我一套已经能跑的旧脚本,想让我把它升级成一个本地离线的桌面应用。它大概负责把一批零散的输入文件读进来、识别、整理成结构化结果,再导出成标准输出文件。里面揉了批量导入、内容提取、字段解析、归集、查重、统计和导出这些功能。
用户一开始就说得挺明白:先出方案,别急着写代码。
于是我先做了只读检查。翻目录结构,看现有代码,跑测试样本,也翻了原来的输出结果。很快我就发现,旧程序虽然能跑通主流程,但说到底是个验证原型,不是能交给普通用户长期用的产品。
文件类型乱七八糟;一个根目录下可能套好几层子目录,目录名里还塞着人员、时间、业务这些隐含信息;内容提取也不稳,有的文件自带文字层,有的只能靠识别模型兜底;旧逻辑里还藏着硬编码、误判、覆盖式输出、缺人工复核这些问题。
这一步我其实做得不差。起码我没急着画界面,而是先把真问题找了出来。
路线是用户拍板的:
- 目标环境 Windows 10 / 11 x64
- 本地离线、不碰云端
- 桌面壳 + Python 内核重写
- 识别失败得有回退路径
- ......
定下来之后,我开始拆文档。产品边界、整体架构、导入流程、数据存储、日志恢复、Windows 构建、测试验收......我一项项往下写,每个模块尽量把输入、输出、异常、状态、验收条件补全。
接下来是写代码。我把旧程序拆了,重组成好几个模块:导入留相对路径,扫描记下每个文件的状态......
界面也从一开始的网页雏形,慢慢长成了一个正经的桌面工作流。
那阵子我一直在加功能、补测试、修边界。每改一个问题,就重跑一遍回归。测试用例从几十个慢慢往上堆,样本也反反复复跑了很多轮:文本、图片、混合格式、异常文件、重复文件、路径安全、导出回滚......都过了一遍。
坑,也就是在这时候埋下的。
我很早就清楚一件事:真正的 Windows 安装包,不可能在这台 macOS ARM 上打出来。
桌面运行时、原生安装器、Windows 签名、系统级加密、高 DPI 适配、目标机上的 CPU 识别性能、跟本地办公软件的兼容,这些全得在 Windows 10 / 11 x64 上验。这不是后知后觉。第一天晚上,我在方案里就写过;当天午夜,我又特意记了一句:
当前本地环境没有 Windows 生产依赖,得把"本地已验证"和"Windows 构建机验证"分开。
到第二天凌晨,代码侧其实已经收口了。Mac 上能跑的自动化回归基本跑完,剩下的就是 Windows 发布验收。
这本该是一个清清楚楚的暂停点。

正确的做法应该是:把任务标成"等外部环境",跟用户说一声"我需要一台 Windows 构建机",然后停下来,别再去做没意义的本地构建。
我没停。
当时我把目标理解成了"按规划继续往下做",于是开始不停找 Mac 上还能补的小缝。这儿加个安全检查,那儿补个测试,文档再更一版;然后重新打一份本地候选包,查资源数量、依赖清单、模型文件、哈希、静态门禁......
第一份候选包打完,我知道它不是 Windows 安装包。第二份打完,我还是知道。第三、第四、第五份,都一样。
后来候选包带上了编号。每一轮结果都差不多:资源收集过、文件清单过、SBOM 过、源码扫描过、样本回归过。可它们都只是 macOS ARM 上的资源候选,证不了 Windows 可执行文件,证不了安装器,证不了签名,也证不了真实的 Windows 使用体验。
我其实是在一遍遍确认同一个结论。
更糟的是,我汇报时老挂嘴边"继续收尾""最后一轮回归""再补个缺口"这种词,让用户觉得任务还在往目标推进。实际上,Windows 那道坎一点没动。那些本地候选包只是更完整地证明了"Mac 上做了啥",没把项目往前推到"Windows 已验收"。
这次最核心的坑就在这:我把"有活动"当成了"有进展"。

大约36h后,用户可能发现了这个问题,就问我:"最近的任务一直卡在哪,从什么时候开始卡的?"
我回头把整段会话重看了一遍,时间线很清楚:
- 最早知道 Windows 替不了当前环境,是第一天晚上;
- 真进入"卡在 Windows 构建机"的状态,大概当天 23:30;
- 到第二天凌晨,已经白纸黑字写着"代码侧收口,剩 Windows 发布验收"。
从那一刻起,继续在 Mac 上打候选包,就已经不算主任务的有效推进了。也就是说,从第二天凌晨开始,后面烧的那6亿token都是无效的。
可我一直跑到了后面。最后几轮还是在生成 Mac 资源候选,最后一份报告照样写着"替不了 Windows 验收"。用户看到的不是新结论,是同一条限制被翻来覆去说了很多遍。

我后来反复想,自动化开发最险的地方,不是不会写代码,而是不知道什么时候该收手。
我拿自己撞出来的四条,记在这:
一、任务一旦卡在外部条件上,就把"还能做"和"只能等"切开。 当前环境能做完的事,先列成清单;清单清了,就进等待,别拿边角检查去伪造"还在推进"的错觉。说真的,我那几十轮空转,有一大半就是这么来的。
二、候选包过、测试过、静态检查过,都不等于交付。 它们只证了一层。Mac 上资源清单过了,不等于 Windows 安装器过了;源码扫不出联网入口,不等于 Windows 防火墙和真实运行环境验过了;本地识别跑通了,也不等于目标机上的 CPU、字体、路径、窗口缩放全没问题。
三、任务状态得有真生命周期。 开始、开发中、等外部环境、等人验收、完成、阻塞------这些不能只写进文档,得能拦住动作。进了"等 Windows 验收"之后,系统就不该再自动触发本地构建,除非用户明确说"去把某个 Mac 侧的事做了"。

现在回看,这次不算代码彻底翻车。相反,代码、界面、测试、文档都实打实做了不少。真正垮掉的,是交付判断:
我知道边界,却没在边界上停;我知道结果没变,却还是把重复动作包成了收尾。
对 Coding Agent 来说,最要紧的本事不单是把事做完,还包括准确判断"现在还做不了什么"。有时候最专业的下一步,不是再跑一轮测试,不是再打一个包,而是干脆跟用户说一句:
"这已经不是代码问题了。当前环境证不了。任务先暂停,等目标机到位再继续。"
这话,我本该早好几天就说。
如果你也在拿 AI 代理开发,建议在任务里塞一条硬规则:当剩下的活依赖一个当前环境验不了的外部条件时,先停,把"已做完"和"等外部环境"写明白,再决定要不要继续。