思远 AI Labs
作品集/我的操作系统
我的操作系统 / v0.1 /

我的操作系统 · 第 3 篇 · 方法论公开

规则怎么才算数

从「AI 你记得记账」到机器触发器:六个钩子、一张九类事件写入合同、一套先影子后真投的对账机制

前两篇讲了规则写什么(一份给 AI 的工作说明书)和规则放哪(八个目录门口的八份守则)。这篇讲最难的第三件事:规则写好了,谁来执行。我的答案是把「每轮对话该记什么账」从人的口令和 AI 的自觉,变成机器的触发器和事先签死的合同。附录收录了这套机制的核心合同全文——标记文法、解析算法、九事件合同表、回执状态机,只隐去绑我机器的部分,可以直接复制改写。

6 个机器触发位 9 类写入事件合同 6 态回执 129 个测试场景全绿 4 轮对抗审查 42 项发现 附录收录核心合同全文

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):

  1. 从标记起点起,允许空白后紧邻 { 则先行 JSON 解码,消费恰好一个值;解码尝试限定当前行。
  2. 解码失败=从标记起点到行末整段隔离+回执;标记后没有 {=载荷缺失,同按整段隔离——文法载荷必填,无裸标记通道。
  3. 解码成功→载荷区间排除出后续扫描;| 为字面分隔符,其后为正文。
  4. 语义校验(必填字段/未知字段/op 格式)失败同按整段隔离——合法 JSON 但非法载荷=隔离,无第三条路。
  5. 载荷区间排除后,剩余文本走常规语料扫描。

五步里反复出现的「整段隔离」是关键决策:坏标记不容忍、不猜测、不降级处理,隔离起来打回执让人看见。宁可漏收,不可错收——漏收有回执浮出,错收污染账本。

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 · 实测

一些数字

以下全部为实测值(测试报告、配置文件、设计稿逐条核对),非估值:

6
机器触发位(七个脚本),覆盖一轮对话从启动到结束
9
类写入事件,每类有信号/目标账/消费者/失败恢复四列合同
6
态回执:已收/已核/已投/明确无需动作/待人工/已人工
4
本状态账各有消费者;两本无消费者的账被判死停写
129
个测试场景全绿(五套测试),之后才碰生产链路
42
项审查发现(4 轮独立对抗审查),全认账全吸收
7
个设计版本(v1.0→v1.6),前三轮审查全部不通过
6000
字符的启动注入预算——上下文是燃料,不是垃圾场
3
个会话/每批次盲审抽检,审查者禁带标记与机器结果

10 · 问答

三个常见问题

为什么不让 AI 自觉记账?它已经够聪明了。

自觉不可审计。「它觉得自己记了」和「它确实记了」之间没有任何可核对的证据。合同把「该记什么」变成可核对清单,回执把「记没记成」变成可验证状态,对账把两者定期比对。聪明解决理解问题,不解决信用问题。

影子模式是不是过度工程?

看错的代价。聊天写错一个字无所谓,状态账写错一行,后面所有基于这本账的判断都被污染,而且污染会复利。影子期的全部成本是磁盘和对账算力;它换来的是用真实数据跑机器、错了不伤真账、切真前有证据。等这套机制稳定后影子层会退役——脚手架的使命就是被拆除。

这套东西别人能直接用吗?

能抄的是合同,不是脚本。钩子是 Claude Code 的机制,概念可移植到任何有类似能力的 AI 运行环境;真正值钱、也真正难写的是附录里那几张合同——事件怎么分类、文法怎么定、坏了怎么办、怎么证明机器没骗你。脚本按合同谁都能写。

附录 · 公开核心版

核心合同全文

以下是这套机制四份核心合同的接近全文收录。隐去处用 [omitted] 标明,只打三类:绑我本机环境的路径与清单、过渡期临时安排、内部沿革细节。不妨碍直接复制改写。

附录 A · 标记文法与解析算法合同

全文收录

文法:[类:动作] {单行JSON载荷} | 人读正文

解析算法合同(次序即合同):

  1. 从每个标记起点 [类:动作] 起,允许空白后紧邻 {→先行 JSON 解码,消费恰好一个值(字符串内括号按 JSON 词法配对;解码尝试限定当前行——行内无法消费完一个完整值=按步骤 2 隔离该行,多行载荷直接判非法)。
  2. 解码失败=从标记起点到行末整段隔离+回执(隔离单位=单行),该段剩余文本不再参与本轮任何边界扫描(幽灵标记由此杜绝);标记后无 {(含空白后非 {)=载荷缺失,同按整段隔离+回执——文法载荷必填,无裸标记通道。
  3. 解码成功→载荷区间排除出边界扫描;| 为字面分隔符,其后为正文;正文终止=下一有效标记或空行;正文允许含 |。
  4. 语义校验(必填字段/未知字段/op 格式):失败同按整段隔离+回执——合法 JSON 非法载荷=隔离,无第三条路。
  5. 载荷区间排除后,剩余文本走现役两阶段语料扫描 [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 系统的可靠性不是设计出来的,是一次次「不许通过」堆出来的。

下一篇讲这套机制的「人看出口」:驾驶舱怎么搭——让记账的系统和看账的人之间,只隔一块屏幕。