第一性原理 · 第 11 篇

出错时,
裁决权在你

一个会话在写目录,另一个会话在问废标项——这个再正常不过的用法,曾经是被系统禁止的。

因为当年我们做了任务级互斥:一个任务同一时间只允许一个 AI 在干活。

这是我们拆掉的第二把锁。全系列写到收官,这篇把「出错时谁说了算」讲完,也算把前几篇反复出现的那个原则——判断归人——收个尾。

三把锁,都是我们自己装的

第一版产物的编辑保护,我们是按「专业软件」的标准做的,一共三层:

版本管理:AI 每次重跑生成新版本,用户在版本之间切换。问题是谁需要维护「版本」这个心智?大多数时候用户要的不是一堆版本,是「改错了能回去」。

任务互斥:怕并发冲突,一个任务锁起来。就是开头那个反例——写目录和问废标项明明可以同时进行,系统却让它们排队。

编辑租约:谁在编辑就持锁,心跳续租,超时抢锁。这套机制在协作软件里很常见,但它要求用户理解「租约」「续租」「抢锁」这些词。用户不该需要理解这些。

三把锁全部拆掉。拆的过程不是一次想通的:先拆版本管理时还想保留互斥,被开头那个正常场景又杀了一刀。最后沉淀下来的判据是——锁的本质是替用户做决定,并且惩罚所有正常使用。

换成文件夹的语义

拆了锁,换成每个用电脑的人都懂的东西:文件夹的规矩。

默认覆盖。AI 重跑就覆盖。在制品是便宜的,试错成本趋零,覆盖就覆盖。

覆盖前自动备份。最近三版自动留底,随时退回,退回本身还能再撤销。你要的从来不是「不被覆盖」,是「覆盖了能回」。

你改过的,先问你。你在界面里改过的文件,AI 重跑碰到之前会停下来问。改过的内容不是要防的污染,是下游的输入——你保留自己的版本后,AI 后续读取就以你的版本为准。

冲突二选一。AI 在干活时你也在改,系统检测到了会弹给你:「拉取最新 / 保留我的」。两个版本都活着,你选谁留。它比「纯回滚」多了一步——回滚是系统猜你要旧版,这里是问你。

删除就是归档。删会话只清对话记录,文件全保留;删任务是整个文件夹挪进归档区,随时能手工找回。系统里没有真正的「消失」。

有一类保护我们刻意留下了,而且不打算让用户感知:同一个文件被写入的那一瞬间是原子的——读的人要么看到完整的旧版,要么看到完整的新版,永远不会看到写了一半的文件。这类「用户看不见的瞬时保护」是工程卫生,跟前面拆掉的锁不是一回事。判据就一条:用户能感知的锁是负担,感知不到的保护是本分。

每条失败路径,都有出口

AI 干活会出错,服务会断,人会手滑。系统对每种失败给一个出口:

服务不稳,自动重试。模型服务过载时自动重试三次,界面告诉你「正在自动重试(第 2/3 次)」,不假装没发生。三次失败后明说,而不是转圈到天荒地老。

任务中断,从断点继续。服务中断、欠费、断电之后重新打开,已完成的节都在,从断点接着跑。主动取消的任务不提供「继续」——停止是你的决定,系统尊重它。

等待时,随时可以走。AI 提问等你回答时,提问卡上始终有「放弃并停止」。早期版本这里是个死角:模型问了个你答不了的问题,会话就被钉死了。修复之后,任何等待都能取消。

关窗前,先问一句。任务跑着的时候关窗口,先弹确认。误关等于杀掉半小时的任务,这种破坏路径不该是零摩擦的——界面崩溃时确认也拦不住你,连按两次强制退出,这个后门留着。

错误分清是谁的错。服务方过载,显示「自动重试中」;模型 Key 失效,给「去设置」的入口;程序自己的错误,老老实实说程序出错了。把模型服务的错包装成系统故障,或反过来,都是撒谎。

还有一层诚实:界面显示的状态,凭什么信?我们的做法是给每个事件编流水号,界面发现缺号就主动找服务端对账,而不是假装什么都没发生。我们不敢承诺「永不丢事件」,敢承诺的是:丢了能发现,发现了能恢复。

收束

十一个主题讲完了,其实反复说的是同一句话:系统的每一步都该能向人解释,每个冲突都该由人裁决。

这就是首页那句「大事先问你」的全部含义——不是一句口号,是目录要你确认、承诺要你拍板、素材由你勾选、引用带行号、冲突弹二选一、失败有出口。AI 可以干很多活,但责任藏不进一句「生成完成」里。

感谢读到这里。剩下的,请用你手边那份真实的招标文件来检验。

读原文、搭结构、写正文、交付带修订痕迹的 Word——繁琐的交给 AI,关键的你来把关。可以拿一份你手边的真实招标文件试一遍。