01 · 出发点
口令扛账的三种死法
我的 AI 工作台每天要记四本状态账:哪些事在途、哪些决策等我拍、今天发生了什么、有哪些素材和知识卡候选。很长一段时间里,记账靠两个口头命令驱动——我对 AI 说「开始这轮对话」,它去读账;说「结束这轮对话」,它把这轮产生的待办、决策、语料写回各本账。
这套口令机制死了三次,死因各不相同:
- 忘写。对话聊到深夜直接关窗口,「结束」口令没喊,这轮的待办和决策就丢了——不是 AI 不听话,是触发记账的动作本身依赖人记得。
- 写错账。「这个决定记一下」——记进哪本账?待决策还是待办?AI 现场判断,判断标准每次漂移,账与账的边界慢慢糊掉。
- 写了没人看。账越记越多,但没有固定的消费出口。记账动作完成了,记账的目的没完成。
第三次死法促使我下了个判词:账本的生死判据=有没有消费者。两本没人消费的账(一份每周待办、一份对话日志)被直接判死停写,剩下的账各自配好消费者。但前两类的根子问题还在:只要「触发」和「路由」还靠人和自觉,账就记不稳。
解法在设计稿的需求锚点里只有一句话:
两个口令原来扛的全部读写义务,拆散后各自找到自动触发点:写=当轮打标、机器每轮自动收自动写;读=启动时自动注入工作上下文。问题=口令消亡;答案=读写各有触发器。
—— 阶段二施工设计稿 v1.6 · 需求锚点(原文;启动命令名按脱敏口径改写)
这篇讲的就是把这句话落成机制的全过程。
02 · 承上启下
四层规则栈里的位置
我的规则体系分四层,前两篇各讲了一层,本篇讲最后一层怎么让上面三层转起来:
| 层 | 载体 | 管什么 | 哪篇讲的 |
|---|---|---|---|
| L4 行为规则 | 根目录一份总章程 | AI 是谁、怎么说话、红线、会话流程 | 第 1 篇《CLAUDE 工作说明书》 |
| L3 记忆 | 记忆库 | 历次对话沉淀的偏好与判例 | 第 1 篇附述 |
| L2 目录守则 | 每个目录一份 README | 房间里什么能进、怎么放、何时清 | 第 2 篇《README 工作法》 |
| L1 机器门 | 钩子脚本 + 写入合同 | 到点必触发、写账必留回执——不靠自觉的东西 | 本篇 |
上面三层都是「文本规则」:写得再好,执行率都取决于 AI 当场注不注意得到。L1 是「机器规则」:利用 AI 运行环境(我用的是 Claude Code)提供的钩子机制,在特定动作发生时由运行时强制调用脚本——脚本不需要 AI 想起它,它自己会跑。
03 · 机制一
一轮对话的一生:六个触发位
以下是我工作台当前真实注册的钩子清单(逐条提取自配置文件,未做省略):六个触发时机,七个脚本。
| 时机 | 触发事件 | 干什么 | 替代的旧义务 |
|---|---|---|---|
| 敲启动命令时 | SessionStart |
薄入口脚本:注入工作上下文(今日状态摘要+在途球清单);唯一被允许的写副作用=创建本轮会话文件 | 「开始这轮对话」口令 + 人工开场汇报 |
| 我每提交一句话 | UserPromptSubmit |
纪律提醒脚本:按当前任务类型注入对应红线与流程提示 | 靠 AI 自己记得纪律 |
| 每次写文件前 | PreToolUse(写/编辑类工具) |
目录守则门:要写哪个目录,先把那个目录的 README 守则注入——写前消费,不靠自觉去读 | 「记得先读 README」这条文本规则 |
| 每次写文件后 | PostToolUse |
更新知识索引 + 记一行文件流水(哪个会话、写了哪个文件、成败) | 定期人工盘点文件变动 |
| 写入失败时 | PostToolUseFailure |
失败同样记流水——失败不留痕=悄悄丢失 | 错误沉底,无人知晓 |
| 每轮对话结束 | Stop |
标记捕获器:扫描这轮对话里我打的所有状态标记,按写入合同投进各本账(当前为影子模式,见第 06 节) | 「结束这轮对话」口令的全部写入义务 |
两个口令的读写义务就这样被六个触发位分完了:读的义务归启动钩子(自动注入,不用喊),写的义务归结束钩子(每轮必跑,不用催),中间过程由写入前/写入后/失败三个钩子把「目录守则消费」和「文件流水」也变成自动的。
有一个设计细节值得说:启动钩子被规定只准有一个写副作用——创建本轮会话文件。这个限制不是洁癖,是因为审查时发现:如果入口脚本可以随便写,它就成了新的不受合同约束的写入口,整个写入体系的口子就从这里开始漏。
04 · 机制二
九类事件写入合同
触发器只解决「什么时候记」,不解决「记进哪本账」。后者由一张事先签死的合同规定:九类事件,每类写明信号是什么、写进哪本账、谁消费、失败了怎么办。AI 当场不做路由判断,只按合同执行。
合同表全文在附录 B,这里给它的阅读方式和一个真实样例行:
| 事件 | 信号 | 写进哪本账 | 消费者 | 失败恢复 |
|---|---|---|---|---|
| 待办承诺 | [任务:*] 标记 |
在途事项表 | AI 工作上下文 | 逐项回执,停该目标不停整批 |
每一列都是一次「把判断变成合同」:信号列消灭了「这算不算一个待办」的现场判断;目标列消灭了「记哪本账」的现场判断;消费者列回答「记它干嘛」;失败恢复列回答「没记成会怎样」——答案是不会悄悄沉底。
不沉底靠的是回执状态机。每一笔写入都有回执,回执只有六种状态:
已收 / 已核 / 已投 / 明确无需动作 / 待人工 / 已人工(待人工的完结子态,含新位置+新指纹;原文五、六两态名为 needs_manual / 已人工,此处中文化)。
—— 设计稿 v1.6 §一(回执状态枚举)
其中「待人工」这条链最能说明这套机制的脾气:机器干不了的(比如跨表格迁移一行数据),不是硬干也不是丢掉,而是登记进流水账 → 每次启动时注入「待补清单」持续浮出 → 人工执行前重新核对原行指纹,指纹失效就停手 → 完成后流水账同行迁移为「已人工」。未完成不算已投,跨会话由待补清单承接。
05 · 机制三
标记文法与解析合同
合同要能被执行,先得有一种「AI 在对话里随手打、机器能稳定收」的标记格式。我的文法只有一行:
[类:动作] {单行JSON载荷} | 人读正文
真实样子(对话里直接打,打完机器自动收):
[任务:派活] {"op":"任务-20261023-a1b2c3d4-01","线程名":"驾驶舱重构","下一步":"出模块清单","球":"CC"} | 驾驶舱重构立项,先出模块清单
竖线前是机器读的,竖线后是人读的。每条标记带一个操作身份 op(类-日期-会话前八位-序号),用于去重、对账和冲突检测——同 op 不同内容指纹=冲突,停投该目标并报警,不静默跳过。
真正见功力的是解析合同。文法一行就能写完,但「遇到坏标记怎么办」必须写死,否则解析器在边界情况下行为漂移。审查后落成五步算法合同(次序即合同,全文见附录 A):
- 从标记起点起,允许空白后紧邻
{则先行 JSON 解码,消费恰好一个值;解码尝试限定当前行。 - 解码失败=从标记起点到行末整段隔离+回执;标记后没有
{=载荷缺失,同按整段隔离——文法载荷必填,无裸标记通道。 - 解码成功→载荷区间排除出后续扫描;
|为字面分隔符,其后为正文。 - 语义校验(必填字段/未知字段/op 格式)失败同按整段隔离——合法 JSON 但非法载荷=隔离,无第三条路。
- 载荷区间排除后,剩余文本走常规语料扫描。
五步里反复出现的「整段隔离」是关键决策:坏标记不容忍、不猜测、不降级处理,隔离起来打回执让人看见。宁可漏收,不可错收——漏收有回执浮出,错收污染账本。
06 · 机制四
先影子,后真投
机制一收标记、机制二签合同,然后是最重要的一条纪律:机器写的账,先不写真账。
当前所有自动写入都跑在「影子模式」:机器每轮把标记写进一套独立的影子账,真账一个字不动。影子账旁边配三本辅助账:
- 流水账(journal):每笔写入落一行——操作身份、内容指纹、目标清单、各目标回执态。流水落盘后才推进读取游标,崩溃恢复有据。
- 映射账(sidecar):操作→目标行指纹的映射,专供崩溃后恢复时核对,不污染人读账本。
- 待补队列:没收到的、没收尾的事件登记在册,启动时注入浮出,不静默沉底。
影子账和真账之间立着一台对账器,做三层核对:
| 层 | 核对什么 |
|---|---|
| 1 · 预期集 vs 收件集 | 这轮对话应该产生哪些标记(独立重建)vs 机器实际收到哪些 |
| 2 · 事件×目标回执 | 每个事件投向每个目标的回执态是否正确、有无重复写入 |
| 3 · 归一后对象状态 | 影子账归一后的最终状态与预期状态是否一致 |
第一层里的「独立重建」是整套机制的信用根基,规则写得很硬:
每个影子运行批次抽 3 个会话,由独立的一次性审查者重建「这轮该记什么」——材料只有原始对话记录和工具回执,禁止携带标记与机器结果。分歧升级给人裁定;抽检零分歧=切换真账的前提之一。
—— 设计稿 v1.6 §六(盲审抽检规则,原文要点)
审查者不知道机器收了什么,也就无法迎合机器的结果——这是「盲审」。对账器给的零差异也只声称受测区间,不宣称全局正确。
为什么不直接信 AI 写账?因为它会漏、会错、会产生幻觉,而状态账错写的代价是后面所有基于账的决策都被污染。影子期的成本是磁盘和对账算力,收益是用真实生产数据验证机器,错了不伤真账。
07 · 过程实录
审查实录:42 项发现,全认账
这套机制的设计稿没有一版通过。从 v1.0 到施工基线 v1.6,七个版本,四轮独立对抗审查,42 项发现全部认账、全部吸收,无一抗辩:
| 轮次 | 判决 | 发现 | 处置 |
|---|---|---|---|
| 第一轮 | 不通过 | 12 项 | 全文重写为合同稿 |
| 第二轮 | 不通过 | 9 项 | 补载荷/分工/混合模式/预期独立性 |
| 第三轮 | 不通过 | 14 项 | 定向补稿:解析合同、映射账、抽检规则等 |
| 第四轮 | 有条件通过 | 7 项(均为文字登记级) | 全量吸收条件后封板为施工基线 |
三个代表性发现,看审查到底在查什么:
发现一:第九类事件无家可归
九类事件里的「知识卡候选」设计了写入,但审查发现它要写的那个会话文件没有任何人负责创建——候选无家可归。补救:启动钩子被特许唯一一个写副作用=创建会话文件,可重入,不覆盖已有。设计稿原话:不建会话文件则第九类无家可归,此为承重条款。
发现二:解析算法未闭合
初稿只写了文法,没写「坏标记怎么办」,解析器在边界情况行为未定义。补救:五步解析算法合同(见第 05 节),隔离单位=单行,幽灵标记由此杜绝。
发现三:旧脚本归档后删源文件
复审实测旧会话收尾脚本发现一个既定行为:归档后删除源文件。一旦切换新机制,知识卡候选的查询指针会指到已删除的文件。补救:切换真账时把归档分支改为只复制不删源,过渡期以新会话文件为主、归档路径兜底。
施工期又抓到两个真 bug:一张表的列对错位置(改为按表头索引定位)、流水账存在登记黑洞(改为统一登记循环,任何分支不得绕过)。这两个不是审查查出来的,是测试跑出来的——129 个测试场景全绿之后才敢动生产链路。
这套流程的价值不在「查出了 42 个问题」,在于它把「我觉得设计得挺好」变成了不可接受的理由:设计稿不许自我表扬,只许独立审查判决。
08 · 诚实条款
这套机制还没做到什么
和第 2 篇一样,规则里要写明没做到的事,文章也一样:
- 影子期还在跑。机器现在写的仍是影子账,真账的自动切换(「切真」)还没发生。影子期实测要跑满一周并对账零差异才收口。
- 切真验收四用例没跑。两路交替失败、进程重启、回执写失败、水位切换——四个故障场景的验收用例已写好判定标准,但还没在真实链路跑过。
- 生产链路只手动验证过一次。129 个测试场景全绿是在测试环境;生产链路目前只做了一次手动模拟投真事件+一次真实对账,通过了,但样本是一,不是一百。
- 人看出口还没建。机制保证「账记对了」,但「人一眼看到账」的出口(一个本地驾驶舱页面)还没建。过渡期我看账的方式=直接读文件,或问 AI。
- 人不在场时的调度不在本期范围。这套机制只管我在场的会话;我不在时(另一台机器上无人值守跑批)的调度补偿是下一阶段的事。
09 · 实测
一些数字
以下全部为实测值(测试报告、配置文件、设计稿逐条核对),非估值:
10 · 问答
三个常见问题
为什么不让 AI 自觉记账?它已经够聪明了。
自觉不可审计。「它觉得自己记了」和「它确实记了」之间没有任何可核对的证据。合同把「该记什么」变成可核对清单,回执把「记没记成」变成可验证状态,对账把两者定期比对。聪明解决理解问题,不解决信用问题。
影子模式是不是过度工程?
看错的代价。聊天写错一个字无所谓,状态账写错一行,后面所有基于这本账的判断都被污染,而且污染会复利。影子期的全部成本是磁盘和对账算力;它换来的是用真实数据跑机器、错了不伤真账、切真前有证据。等这套机制稳定后影子层会退役——脚手架的使命就是被拆除。
这套东西别人能直接用吗?
能抄的是合同,不是脚本。钩子是 Claude Code 的机制,概念可移植到任何有类似能力的 AI 运行环境;真正值钱、也真正难写的是附录里那几张合同——事件怎么分类、文法怎么定、坏了怎么办、怎么证明机器没骗你。脚本按合同谁都能写。
附录 · 公开核心版
核心合同全文
以下是这套机制四份核心合同的接近全文收录。隐去处用 [omitted] 标明,只打三类:绑我本机环境的路径与清单、过渡期临时安排、内部沿革细节。不妨碍直接复制改写。
附录 A · 标记文法与解析算法合同
全文收录文法:[类:动作] {单行JSON载荷} | 人读正文
解析算法合同(次序即合同):
- 从每个标记起点
[类:动作]起,允许空白后紧邻{→先行 JSON 解码,消费恰好一个值(字符串内括号按 JSON 词法配对;解码尝试限定当前行——行内无法消费完一个完整值=按步骤 2 隔离该行,多行载荷直接判非法)。 - 解码失败=从标记起点到行末整段隔离+回执(隔离单位=单行),该段剩余文本不再参与本轮任何边界扫描(幽灵标记由此杜绝);标记后无
{(含空白后非{)=载荷缺失,同按整段隔离+回执——文法载荷必填,无裸标记通道。 - 解码成功→载荷区间排除出边界扫描;
|为字面分隔符,其后为正文;正文终止=下一有效标记或空行;正文允许含|。 - 语义校验(必填字段/未知字段/op 格式):失败同按整段隔离+回执——合法 JSON 非法载荷=隔离,无第三条路。
- 载荷区间排除后,剩余文本走现役两阶段语料扫描 [omitted:现役语料扫描为另一套机制的既有行为,与本合同无关,从略]。
稳定操作身份:op=类-YYYYMMDD-会话前8位-序号(含会话分量,并行会话不撞号);唯一性=打标自律+流水账登记检测兜底(同 op 异内容指纹=冲突回执停投,不静默跳过);新发生的同文事件用新 op。
附录 B · 九事件合同表
全文收录保证的准确表述=在约定宿主事件与运行条件下触发;失败可见并可补偿——不宣称语义完整。语义兜底=受控预期封存+盲审抽检。
| # | 事件 | 信号 | 目标账 | 消费者 | 失败恢复 |
|---|---|---|---|---|---|
| 1 | 语料 | 六类标记 [omitted:六类语料标记的定义清单,绑我个人知识管理场景] | 六库正本 | 检索 | 待补队列+事件去重 |
| 2 | 待决策 | [决策:*] | 待决策看板(档案库) | 人查档案;浮面出口 [omitted:驾驶舱出口,绑我本机] | 逐项回执,停该目标不停批 |
| 3 | 待办承诺 | [任务:*] | 只在途事项 | AI 工作上下文;人看出口同上 | 同上 |
| 4 | 事实变化 | 三路信号 [omitted:三路信号的判定细节] | 候选区→项目卡 | 新会话读项目卡 | 候选合同,半完成可恢复 |
| 5 | 业务事件 | [事件] | 事件簿(追加型) | 追溯/月报 | 操作幂等 |
| 6 | 今日状态 | [日报](只此一路,派生信号删除——规则未定义不承诺) | 今日状态 | 启动读摘要;人看出口同上 | 写入脚本修复后写入 |
| 7 | 文件流水 | 写入后钩子 | 机器数据区 | 排错 | 本地落盘,失败只警告 |
| 8 | 失败错误 | 机器回执+AI 报错 | 失败队列+试错库 | AI 补做 | 持续失败才浮出 |
| 9 | 知识卡/记忆/规则候选 | 当轮发起 | 会话文件候选区 | 人批次终审 | 最小保全约定(附录 D 后注) |
附录 C · 回执六态与待人工链
全文收录回执六态:已收 / 已核 / 已投 / 明确无需动作 / 待人工 / 已人工(待人工的完结子态,含新位置+新指纹)。「已核」语义=AI 对事实候选的核定动作。
待人工链:流水账登记 → 启动注入的待补清单持续浮出 → 人工执行前重核原行指纹(失效即停)→ 流水账同行迁移为「已人工+新位置+新指纹」。未完成不算已投;跨会话由待补注入承接,不静默沉底。
回执身份:操作+目标+模式+影子批次;已成功目标查回执跳过,失败目标独立补;影子成功≠真投成功(回执含模式位强制区分)。
附录 D · 逐动作字段表
节选,结构未改| 类:动作 | 必填字段 | 目标动作 |
|---|---|---|
| 决策:新增 | op, 事项;expect_absent=true | 看板主表追加(锁内查重分配编号) |
| 决策:已决 | op, key, 结果, expect=原行指纹 | 状态列更新+推荐列追加决策文本 |
| 决策:撤销 / 改判 | op, key, expect | 状态列;改判仅主表可机器执行,其余表形走待人工 |
| 任务:派活 | op, 线程名, 下一步, 球;expect_absent=true | 按「球在谁」路由到对应表追加新行 |
| 任务:完成/阻塞/解除/撤销/下一步 | op, key, expect(阻塞须填原因) | 按指纹改本行 |
| 任务:交接/休眠/激活 | op, key, expect, 目标态 | 机器不干,走待人工退回当人处理 |
| 事件 | op, 事件名, 结果 | 事件簿追加 |
| 日报 | op, 标题 | 今日状态写入脚本(正文=竖线后人读正文) |
[omitted:第九类「知识卡候选」的最小保全约定(候选 ID 格式/落盘确认/查询指针)与表结构逐列映射细节——前者要点已在正文第 07 节发现一说明,后者绑我本机账本的实测表形。]
最后:机制也是长出来的
第 2 篇的结尾说「规则是长出来的」。这套机制更极端一点:它的 42 处要害没有一处来自提前设计完美,全部来自四轮审查查出的真实缺陷和施工跑出的真实 bug。
所以这篇的标题答案只有一句:规则写下来不算数,能被对账的才算数。记账不靠记性靠触发器,写账不靠判断靠合同,信用不靠自信靠盲审——AI 系统的可靠性不是设计出来的,是一次次「不许通过」堆出来的。
下一篇讲这套机制的「人看出口」:驾驶舱怎么搭——让记账的系统和看账的人之间,只隔一块屏幕。