AI 实践

匿名不是承诺,是数据模型

一个小团队的月度评选,是怎么做到无人值守的。

📅 2026.10 📖 约 6 分钟 自建系统 · 管理流程自动化

我们在团队里搞过一次月度评选。一开始的方式很原始:发通知、逐人催、收表格、手工汇总、算平均、排榜、再通知。

问题不在于麻烦,而在于它会悄悄毁掉数据本身:

后来我干脆自己写了一套系统。它不大,但有几个设计决定,我觉得比"写代码"本身更值钱。

一、匿名不是承诺,是数据模型

绝大多数系统做匿名,靠的是"我们不查""权限控制住"——这是承诺,承诺是可以被推翻的。

我换了做法:让系统结构上就查不到。

数据分两张表,物理上无法关联:

TABLE A · 只记"谁投过了"

周期 + 投票人 ID,唯一约束保证一人一票——不含任何分数。

TABLE B · 只记"某人某维度得了多少分"

被评人 + 维度 + 分数——不含投票人,也不含精确时间。

结果是:即使有人拿到数据库,也无法把某一分对应到某一票。匿名从"制度上的承诺"变成了"结构上的事实"。

打分的真实性,是所有评价体系的地基。地基不稳,上面盖什么都是假的。

二、把规则写进代码,窗口自己走

评选必须有一个"窗口期",否则永远有人补分、有人反悔。我们定的规则是:每月前 3 个工作日。

系统按法定节假日表和调休表,自动算出当月窗口的起止日期——周期在第一次被访问时自动创建,不需要任何人去开、去关。窗口内才能打分;窗口结束后才公布排名:先打分、后揭榜,避免有人看到结果再改分。

三、榜单上不该出现的人,就不让它出现

这一条是踩坑换来的。早期版本会把"本期没有参与评选的人"也列进榜单,于是他们显示 0 分。问题是:0 分会被人读成"差评",而且并列名次会被搅乱。

改法很简单——只列本期实际被评到的人。宁可少一行,也不要一行错的。展示层的规则必须跟着业务语义走,不能让默认值污染结果。

四、自动化之后,人只做一件事

人只做一件事:在月初确认一下周期。其余全部交给机器。同一套模型,后来又挂了一个"半年一次的全员互评"(互评 + 自评,匿名机制完全一致)——因为底层设计是通的,边际成本几乎为零。

五、踩过的两个坑

坑一:一张节假日表,存在了两个地方。应用里有一张表算"评分窗口",发卡脚本里另有一张表定"月初哪天发卡"。两张表不同步,症状非常隐蔽——卡片发出的时候,窗口其实还没开(或者已经关了)。有一次就出在长假:旧表少录了几天假期,窗口被算到了法定假日里,结果谁都投不了。

教训:跨系统共享的"事实",必须有唯一来源,或者至少要有一次对账机制。两边都靠人维护,早晚会错开。

坑二:改了代码,为什么没生效?因为部署方式是"源码拷进镜像后构建",改动被打进了构建产物。重启不会重新构建——必须真的 build 一次。现在的固定动作是四步:留回滚点 → build → 重启 → 复核镜像里的源码。少了最后一步,你永远只是"以为生效了"。

六、可以复用的四个件

结语

这套系统不大,服务的也就是身边这些同事。但我越来越觉得:真正难的不是写代码,而是把"管理的规则"翻译成"机器能无损执行的约束"——匿名写成数据模型、窗口写成日期计算、榜单规则写成展示过滤。

翻译对了,剩下的事机器自己会做完。

本文所述系统为团队内部自建工具,文中已做脱敏处理。| 飘 · 2026.10