先说一句实话:这篇文章里的每一个坑,都是我们自己踩的。
2026 年 9 月 12 日到 13 日,四十八小时,我的注意力几乎全在抢修上。修完之后我把这几件事摊开看了一遍,发现它们不是五个独立的事故,而是同一个东西的五张脸——Agent 治理的风险。
Agent 治理这个词,听起来像是"系统部署完、规矩立好、然后就完事了"。我们的经验恰好相反:部署完,才是风险的开始。而且这些风险和传统 IT 的风险长得不一样,它们看不见、不喊疼、还会被规模悄悄放大。
9 月 13 日上午十点出头,我盯着屏幕上一排红色的 error。十三个"待办任务扫描"定时任务,同时挂了,报错是同一句英文:script path resolves outside the scripts directory。
做这件事的动机是好的。我们系统里有一千多个脚本文件,同一个脚本在十三个 Bot 里各存一份实体副本。要改一处,就得铺十三处、验十三处。我给它起了个名字,叫改一铺十三。
我想把改十三降成改一。办法是把权威副本软链进各个 Bot 的脚本目录——留一份真身,其余全是指针。
结果十三个任务全挂。原因简单得让人难受:定时任务的脚本解析器拒收指向脚本目录之外的软链。
而我在两个多小时前,刚刚做过一次"软链测试"。那次测试用的是目录内的软链,跑通了,于是我认定这个机制可行。一个环节的测试环境与真实环境不一致,就让十三台机器一起陪着我踩了坑。
十点四十七分,一百三十个软链全部换回实体副本,备份留在归档目录里;手动触发扫描,状态回到正常。剩下十二台等到十一点的时钟周期,逐台验证恢复。
这件事给我的一课不在技术,在次序:动手之前,先验目标系统真正的约束,而不是验一个"差不多"的替身。
同一天,还有另一个形状的坑。
十三台扫描任务的"投递通道"配置,写成了把结果投给任务的发起处。而发起处有时候是空的——空的时候,系统就回落到默认收件人。默认收件人是谁?是我老板的私聊。
每三十分钟一轮,十三台机器各自推一遍。据我们 9 月 12 日的系统记录,那一天累计大约六十四条系统诊断,全部进了老板一个人的对话框。
这里面最要命的地方不是数量。是一台机器配错,十三台一起输出;十三台一起输出,汇到一个人头上。系统里其实没有"局部故障"这回事,任何一处配置的错,都会以全群的形态表现出来。
后来我们把十三台的投递通道全部改成留在本地:诊断进本地日志,只有真正需要人拍板的事才往外推。这一改,不是让系统少说话,是让它把话说在该说的地方。
这一件,是最让我后背发凉的。
我们有一条"准确率评分"管道:每天凌晨,它去核对系统自己声称做过的事,到底有没有真做,然后给出一个百分比。这是我们用来防"AI 说自己完成了、其实没完成"的机制,它等于是系统给自己打的诚信分。
9 月 12 日,它回到百分之百:三条声明,全部核实通过。9 月 13 日,一条声明,判为"不在上下文中",零分。
看到零分,我以为是出了新问题。翻完文件才发现,是老问题被发现了。据我们统计目录里的评分记录:9 月 1 日到 9 月 10 日,连续十天,每一份评分文件里写着的都是"零条声明、准确率空值"。而日报上那十天里,每天都只有一行小字:准确率,今日无声明。
没有报错。没有告警。没有人觉得不对。
十天里,所有基于"评分正常"的判断,全都失了准。评分器为什么评不出分?因为它只在自己的那一份上下文里找证据,跨上下文的声明一律判"不在上下文中"。声明没进它的视野,它就以为今天没有声明。
这就是 Agent 的错最麻烦的地方:它经常不报错。程序出错会抛异常,脚本崩了有退出码,服务挂了有探针。但"我什么都没说"和"我什么都没做",在日志里长得一模一样。
我们后来的修法是两条:一是让评分器跨上下文取证据;二是加一条"零声明告警"——连续两天没有声明,就不再是安静,而是异常。
第四件事,出在我们自己装的安全护栏上。
我们给系统装了一道高危命令护栏,专门拦危险操作。它工作得很好,好到把我的只读命令也拦了。我在复核它的效果时,写了两条只是"提到"某个服务名的回显命令,全被拦下来。据我们 9 月 13 日凌晨的探针实测:四个只读样本,误拦三个。
拦错不是最可怕的。最可怕的是我们原本打算怎么验证它。
上一轮的任务书写着:去日志里检索误拦样本,观察二十四小时,看有多少误报。
可是这道护栏的拦截路径根本不写日志。十二份日志全部统计下来,只有注册行,没有一条拦截记录。也就是说,二十四个小时之后,我们一定会得到一份漂亮的结论:零误报。
那不是没有误报,那是没记。
一个不留痕的护栏,会把你最想要的那个数字变成假的。而且假的数字比没有数字更坏,因为它会让你把注意力从真正的问题上移开——你会以为自己在防,其实只是在看一份自己写给自己看的报表。
后来我们把判定口径也改了:日志里没有拦截记录,不等于没有误伤;必须同时确认当天确实有命令被拦下来,再逐条调到原文核对,才敢下结论。
最后一件没有那么戏剧性,但它是所有事情的底色。
我们做过一次全平台盘点:系统里有一千八百三十二份技能文档,去重之后只剩四百四十二个名字,差不多是四倍的复制。九十个技能出现在全部十三个 Bot 里,其中五十二个已经漂移——同一个名字,内容不一样。
最典型的一份,两个副本的字节数只差一。一个字节。
这就是复制债的样子。它不会一次咬你一口大的,它只是每天都在你耳边说"回头再对齐",直到某一天你改了一处、忘了另一处,而忘掉的那一处,正好在生产上跑着。
还有一类更安静的债:新东西加进来的时候没人认领。加得越多,无主的越多,最后全变成债。
这次我们把技能收敛成一份母版加引用,十三个 Bot 逐台验活,一个技能都没少。改一处,全生效。那些字节相同、内容相同的重复,从此只存在于归档里。
把这五件事放在一起看,Agent 治理的风险有共同的特征。
它看不见。程序崩溃会留下调用栈,网络断了会有超时,而 Agent 出错往往只表现为"什么都没发生"。你没有一条红色的报错可以追,只有一片安静的绿。
它不喊疼。机器不会疼,疼的是人。而且这种疼往往延迟得很久——十天之后你才发现,那十天里所有的判断都建在一个空转的指标上。
它会被规模放大。一处配置,十三台受害;一份副本,十三处漂移;一个无主的脚本,慢慢长成一整片债。
我们后来立的几条规矩,都是围绕"不靠人盯"写的。
第一条是单一来源。同一个东西只留一份真身,其余引用。改一处,全生效;要验证,只验一处。我们那十份跨 Bot 完全同源的脚本、那一百一十个技能母版,都是这么收敛来的。不过这里要补一句我们自己的反面教材:我们最初想用软链来实现单一来源,结果十三台全挂。方向没有错,落地的方式必须服从目标系统真实的约束。方向对了,路还得走对。
第二条是护栏,而且护栏本身必须可验证。检测、告警、自愈,缺一个都不算完整的护栏。更要紧的是,护栏必须留痕、必须能被反查、必须能被证伪。一个只会输出"零误报"的护栏,和一个什么都没做的护栏,在我们的经验里是一回事。
第三条是新增门槛三问。任何新东西落盘之前,先答三句话:非加不可吗?是一份还是十三份?谁维护它?三句里有一句答不上来,就先别加。无主,就是债。
第四条是给治理设预算。救火的时间要封顶,而且要集中在固定的窗口里。治标不能吃掉治本——否则你会每天都很忙,而系统每天更乱。
第五条最难:把人从操作者抬成规则制定者。一件反复发生的事,如果还得你亲自上手,那说明它还没有被结构化。真正该产出的不是"这一次的动作",而是"下一次不需要人也在的规则"。
写到这里,我想到一个一定会被问的问题:你们连自己的系统都管不住,凭什么讲治理?
我的回答是:正因为管过,才敢讲。
一个从来没在深夜看着十三个任务同时变红的人,讲治理,讲的是流程图。我们能讲的,是那十三行报错、那六十四条诊断、那空转的十天、那一条都没记下来的拦截。
这些坑,企业自己上 AI 的时候,一定会再踩一遍。而且往往踩得更狠——因为他们的系统小,规模放大的效应反而更直接:一台机器配错,就是全部机器出错;一个人没空盯,就是彻底没人盯。
这就是博海站的位置。我们做两件事:用可信的数据,让老板敢看数;用可治理的系统,让老板敢用 AI。
可信的数据,是 CMA,数字经营伙伴。账上的数、经营上的数,先让它对得上、算得清、追得到源头,人才敢拿它做决定。可治理的 AI,就是这篇文章里的这些东西:单一来源、留痕的护栏、新增门槛、治理预算、把动作变成规则。
这两件事其实是一件事:让"敢"这个字,有地基。
所以我们卖的不是一套部署完就完事的系统。我们卖的是一套会自己长大、也管得住自己长大的系统,以及在这条路上替客户先踩一遍坑的经验。
着相示众,一切皆如。我们自己踩的坑,摊开来讲,就是最好的说明书。