AI 写代码,工程师画边界
我让 AI 建了一条视频产线。每天 12 期竖版短视频,覆盖选题、文案、配音、GPU 配图、渲染、发行。三天跑通,全程无人值守。
然后 48 小时内连出三次事故。每次事故都指向同一个缺失:AI 在写代码,但没有人在画边界。
三次事故,三堂课。讲完了你会发现,它们的底层是同一件事:AI 是代码生成器,但系统设计的责任没法外包。
事故一:8.18GB 的音频文件,与开环控制
给视频加背景音乐。一行 ffmpeg 命令:人声轨和循环 BGM 轨做混音。
混音逻辑:amix 的 duration 参数设为 first,以第一个输入的长度为准。
我把无限循环的 BGM 放在了第一个输入。
amix 的 first 指第一个输入的时长。BGM 被 -stream_loop -1 标记为无限循环。永无止境。
一个孤儿进程跑了 24 小时,往一个文件里持续写入 AAC 数据。最终大小:8,184,660,012 字节。68 秒的视频,配了一个 8.18GB 的音频文件。
从控制论的角度看,这是一个典型的开环系统失效:系统没有反馈回路,没有输出边界检测,没有异常终止机制。它在无限循环地做一件事,没有任何组件告诉它"你已经超越了合理范围,应该停止"。
工程控制论里有个基本原则:任何持续输出的系统,必须有对输出的度量和基于度量的终止条件。我用 ffmpeg 做混音的时候,只定义了"做什么",没定义"什么时候停"。
修复:在产线脚本里加了输出文件大小检查。更重要的是,把 ffprobe 的时长校验从"可选步骤"改成了"必要步骤"——合成完之后立刻验证音视频时长一致性,不匹配就终止。
但这只是补了一个特定场景的洞。系统性的修法是给整条产线加可观测性:每个阶段的输出都要有元数据校验(文件大小、时长、格式),超出阈值就中断并告警。这不是某个 bug 的 patch,是 Harness 的基础能力。
事故二:你配了最强模型,跑的是最弱版本
黑榜系统有一个负面词库,用来检测负面舆情信号。这个词库有一个动态覆盖机制:如果存在外置 JSON 词表文件,它整个替换内置词库。
我发现黑榜漏抓了"泡沫退去""被指虚假繁荣"这类负面信号,就在内置词表里补了十几个新词。改完一跑——没变化。
翻代码才发现:外置 JSON 词表把我的内置新词整个覆盖了。我改的是死代码。
这不是第一次遇到。之前写过一篇文章("你的 AI 悄悄换了个人"),讲的是配置文件里写了最强模型,实际因为代理链路挂掉,请求全部静默切换到了廉价模型。
这两件事的底层是同一个问题:模型工程里的配置漂移(Configuration Drift)。
配置漂移不只是"配置文件被改了"——它包括三种形态:一是配置与运行时不一致(文件里写 A,跑的是 B);二是多来源配置的优先级冲突(外置覆盖内置,但没人告诉你);三是配置变更后的效果验证缺失(改了配置,但没验证它真的生效了)。
修复方式不是"下次记得检查"——那不叫工程实践。我在配置加载的地方加了来源标记:每次加载配置,记录它来自哪个文件、哪个来源,并且在日志里显式输出"当前生效的配置来源: xxx"。这样配置漂移从静默变成显式。
更系统性的做法是给关键配置加运行时断言:配置加载后立刻校验关键值是否在预期范围内,不在就直接终止而不是带着错误配置继续跑。
事故三:一个字符覆盖了整个首页
给工厂监控页分配新目录,在发行脚本里加了一行 rsync 推送。源路径写的是 $SRC/pulse/——带尾斜杠。
rsync 的尾斜杠语义:带斜杠拷贝目录的内容,不带斜杠拷贝目录本身。一字符之差。
我的工厂页 index.html 被直接拷进了网站根目录,覆盖了整个站点的首页。发行脚本每分钟跑一次,所以每分钟覆盖一次。
从覆盖到发现,隔了八小时。发现方式:用户打开首页看到了流水线页面。
这就是 Harness 边界失效。Agent Harness 不只是"把各个步骤串起来的管道"——它是 AI 与真实系统之间的安全边界。这条边界需要三样东西:
前置验证:每次状态变更之前,校验目标状态的合法性。比如 rsync 推送到根目录之前,检查"这次推送会不会覆盖根目录的 index.html"。答案如果是"会",就拒绝执行或改写到子目录。
回滚能力:每次状态变更之前,保存变更前的状态快照。出问题的时候能一步恢复。我用 fnos 镜像做备份,但那是"每天备份一次"的粒度——对于每分钟跑一次的发行脚本来说太粗了。
最小权限:发行脚本的运行用户,应该只有它需要的目录的写权限,不应该有根目录的写权限。如果发行用户写不了根目录的 index.html,这个覆盖事故就从根上不会发生。
这三样加在一起,就是 Harness 的安全层。缺了任何一层,AI 的输出质量再高,系统也会因为一个边界条件被击穿。
从去重到编辑判断
技术事故之外,还有一个产品层面的教训。
最初的选稿逻辑很机械:每天 12 期,每期选没报道过的事件,跨期去重。跑了一天就出了问题——具身智能赛道每天只产出 10~20 条独立故事,但 12 期消耗 24~48 条。到第三天事件池就干了。
更根本的问题是:去重本身不是编辑思路。真正的新闻频道不是"每天覆盖不同事件"——同一事件随着进展,从不同角度反复报道,才是新闻。
所以我把选稿改成了每期独立编辑:把当日全部资讯交给大模型,让它判断传播价值、确定主题、选事件、写文案。同一事件可以在不同期里出现——但每期的角度不同。
这个转变的本质:从"规则驱动的机械去重"变成"语义驱动的编辑判断"。规则可以保证不重复,但不能保证有价值——价值需要理解内容之后做出判断,这恰恰是大模型擅长的。
改完之后每期的信息密度明显提升:同一事件在早间和晚间可以从不同角度覆盖(融资角度、产品角度、行业格局角度),而不是机械地"确保每天讲不同的事"。
翻了一下老代码,发现我早就有整套 GPU 管线
给视频加配图的时候,我以为需要外部 API。结果翻了一下服务器上的老代码,发现之前的 AI-hot 项目已经搭好了一整套 GPU 图像生成管线:一台 RTX 4090 跑着 Docker 容器农场,有 VRAM 感知调度器按需启停容器,还有一个推理代理服务把请求转发到 GPU 机器执行。出图速度:3.2 秒/张。
整套基础设施已经在那里了。我只需要一个 HTTP POST。
这件事教会我的不是"要复用已有代码"——那是常识。是在大规模系统里,"已知已有"和"实际可发现"之间有一条巨大的鸿沟。那套 GPU 管线在服务器上跑了至少三个月,但因为它分散在七个目录、三个配置文件和一个 Docker 容器里,没有一个统一的入口让我知道"这里有一套能用的出图服务"。
解法不是"写更好的文档"——文档永远不会跟代码同步。解法是给基础设施加能力发现接口:一个 health check endpoint,列出当前所有可用的服务和它们的能力。这样 agent 在启动的时候可以自动发现可用能力,而不是靠人记忆。
Harness 的真正含义
回到标题。AI 写代码的效率已经毋庸置疑——整条产线的脚本和配置加起来不到两千行,一个工程师三天就能写完。但写完之后连出三次事故,每次都是"AI 写的代码本身没有语法错误,但系统层面的边界没有被画出来"。
Harness 不是让 AI 跑起来的管道。Harness 是画边界的那个东西。
它定义了:AI 的输出在什么范围内是可接受的、超出范围时怎么处理、每次状态变更之前需要验证什么、每次变更之后需要监控什么、出问题的时候怎么回滚。
这些东西不需要 AI 来写——它们是工程师对系统的理解,是"什么地方会出问题"的经验判断。AI 可以帮你生成一万个 prompt,但告诉它"输出超过 100MB 就应该终止"的阈值,是工程师对系统的理解。
我的三次事故,本质上都是同一种缺失:系统在运行,但没有人在画边界。Agent 在跑,但没有人在监控它的输出是否合理。产线在自动更新,但没有人在检查每次更新是否破坏了什么。
画边界这件事,AI 做不了。因为边界画在哪里,取决于你对系统的理解和业务的风险容忍度——这些判断需要人对系统的深入理解,而不是从配置文件里读出来的。
所以下次你让 AI 建系统的时候,别急着让它写代码。先画三样东西:
每个阶段的输出校验规则。配置来源的优先级声明。状态变更的回滚路径。
画完这三样,再让 AI 去写代码。代码可以重写,边界画错了就得重来。
你在用 AI 建系统的过程中踩过什么边界问题?来聊聊。
← 返回列表 · 相关: 静默降级:你的 AI 悄悄换了个人 · 一台机器一个用途