上一篇写了把三块看板的判据从形容词换成「一条命令能算出数字」。换完之后我以为闭环了,结果这几天连续有两个判据亮红灯,两次的第一反应都是同一个:「活没干好」。两次复算下来,结论也是同一个:活没错,尺子错了。
而且错法还不一样。一个错在量错了对象——数出来的 1,777 行违规,真正想抓的违规是 0;另一个错在量了一个不可达的目标——在更硬的预算红线约束下,这个目标的可行集是空的,从设立那天起就不存在任何能让它翻绿的路径。
两个案例都值得记下来,因为它们是「判据数字化」的下半场:数字尺子也会错,而且错起来比形容词更隐蔽——形容词错了你还会怀疑它,数字错了,人人都会先去怪活。
案例一:量错对象——1,777 行「违规」,实测 0
事情从一条治理规则开始。几个 agent 给我产文章,markdown 里的代码块必须带语言标记(比如 ```python),不带的就是「裸围栏」。这条规则本身没问题,问题出在配的尺子上:一把正则,匹配「一行恰好只有三个反引号」的行,命中一次算一次违规。
|
|
全仓跑一遍,命中 1,777 行。1,777,这个数字看着像一场灾难:报告里写的是「大量代码块缺语言标记,交付质量不达标」,有三篇文章直接被这把尺子判了不合格。
我拿着被判不合格的三篇手动翻了一遍,发现每篇的每个代码块都规规矩矩带着语言标记。那 1,777 行是什么?
是收围栏。markdown 的围栏语法里,一个代码块有两道围栏:开围栏,后面跟语言标记,比如 python;收围栏,就是一个光秃秃的 。规范只要求开围栏带标记——收围栏本来就该是裸的,你没法给收栏写语言标记,它后面已经没有代码了。
|
|
那把正则不区分开栏和收栏,把全仓所有收围栏都数了进去。1,777 行「违规」里,绝大部分是这种语法规定的正常形态。尺子把两种语义完全不同的行压成了一个数,数出来的不是违规率,约等于「代码块总数的一半」——每一篇文章每写一个代码块,就自动贡献一条「违规」。
修法很直接:扔掉正则,换成一个几十行的状态机。逐行扫,维护开/合两态:closed 态遇到围栏线是开栏,检查 info string 是否为空,为空才计一次真违规;open 态遇到围栏线一律是收栏,不检查。
|
|
用状态机复算全仓:真正的「开围栏缺 info string」是 363 个,集中在历史存量文章里——这是真实存在、该修的另一件事。而被判不合格的那三篇新文章,实测 0 个。
同一个仓库、同一批文件,1,777 和 0,差别只在尺子量的是哪一行。三篇文章的「不合格」是彻底的冤案:活是好的,判它们不合格的那把尺子从头到尾就没量对过东西。
这个坑和上一篇的「结论行放比值」是亲戚:都是把两种语义不同的东西压进一个数字位。区别是那次错在输出格式,这次错在测量工具本身——但症状相同:不报错、不爆炸,只是安静地产出一个语义错误的数字,然后所有人拿着这个数字去批评活。
案例二:量了不可达的目标——可行集为空
钱那条线上有一条判据 F3:下行名义覆盖率 ≥50%。实测 28.4%,判 N,挂红灯挂了一阵子。
这次我没有拍脑袋下结论,而是认真算了一遍:要把这个数做到 50%,需要付出什么。算完发现这道题无解:
- 覆盖率要达到 50%,保护腿名义需要做到本金的 2.6121%/年;
- 而这条线有一条更硬的纪律红线:年保费预算 2%,换算成绝对金额,预算上限 1,939.36 元/年;
- 在预算内,名义覆盖率最多只能做到 42.54%;
- 50% 所需的保费,是预算的 1.3060 倍。
也就是说:可行集为空。不是「现在还没做到」,是「在预算纪律这条更硬的约束下,不存在任何一条操作序列能做到」。上一篇坑一里那个「建仓日得在 392 天前」的不可达是历史遗留;这一条不一样,它是现役判据,从设立那天起就没有存在过可行路径。
这样的红灯驱动不了任何动作:加覆盖必然超预算,守预算必然到不了 50%。两条约束打架,输的只能是这条判据本身——它每天如实亮着 N,但这个 N 什么都指挥不动。
处理方式和上一篇坑一不同。坑一里 2% 红线本身没错,如实记 N,动作是「在预算内重排结构」;这里错的是 F3 这把尺子选的量:名义覆盖率量的是「账面名义对冲了多少」,它对「真跌起来能不能接住」并不敏感——名义摆在那里不等于赔付真能落地。所以不是降目标(那叫放水),是换一个和预算约束兼容的量。
新判据 F3_B:情景有效赔付覆盖——取一个具体情景「跌 20%」,量保护腿在这个情景下实际能赔出来多少。这个量与保费预算直接挂钩:钱花在哪条腿、该情景赔多少,一条命令能对账。现值 18.05%,判 Y。
换尺子不是一删了之。旧尺子的死因写进了规格,四个数留档当锚点:预算上限 1,939.36 元/年、预算内最大覆盖 42.54%、达 50% 需 2.6121%/年 = 1.3060 倍预算。以后谁想把目标改回「名义覆盖率 ≥50%」,不用辩论,把这四个数摆出来就行。
尺子的两道自检
两个案例修完,我给所有数字判据加了两道自检。红灯亮起,先过这两道,再谈「活没干好」。
第一道,对象校验:这个尺子量的,是不是你想量的那个东西? 裸围栏案里,尺子量的是「孤立围栏行数」,想量的是「开围栏缺标记数」,对象错位,读数放大了约五倍(1,777 对 363),而真正想抓的违规在被判不合格的文章里是 0。判据上线前问一句:这条命令命中的每一行,都是违规吗?有没有天然合法的命中?
第二道,可达性校验:这个目标在所有更硬的约束下,存在可行路径吗? 判据之间会打架:覆盖率要花钱,预算红线不许花钱。当一条判据的翻绿路径必须突破另一条更硬的红线时,它不是「待改进项」,是「定义错误」。处理顺序也不是降目标,是换一个与约束兼容的量——目标里的风险关切(真跌了能不能接住)保留,换到 F3_B 这个量得上。
最后说一下这一轮最深的体会。复算机制的价值在这两案里体现得很完整:红灯 → 不急着改活 → 先复算尺子 → 对象错位就换状态机、可行集为空就换量。尺子错了,错的是尺子,不该让活背锅。但反过来,「尺子错了」这个结论本身,也必须是复算出来的,不是感觉出来的——两次都是先把数字摆满一页纸,确认 1,777 里没有一行真违规、确认 42.54% 就是预算内的天花板,才敢说这句话。怀疑尺子不等于豁免复算,恰恰相反,给尺子翻案的证据,比给活翻案的更严格。