# 别再用制度文档守你的护城河 (3/5)

Source: https://lodos.md/zh/blog/make-your-moat-a-ratchet-zh
Published: 2026-08-11 · Author: Samet Samyeli · Language: zh · Reading time: 1 min

制度型护城河只要来一位新人工程师、或者赶上一次深夜重构，就会开始悄悄烂掉。lodos 每次提交都跑两条断言：拒绝机制一旦倒退，构建失败；教训一旦被忘掉，wiki 的自查通不过。两条断言的记录都写进同一条 HMAC 链。

---

> 大多数 AI 产品靠制度文档来守自己的护城河，而这类文档只要来一位新人工程师、或者赶上一次深夜重构，就会悄无声息地烂掉。我守的方式不一样：每次提交都会跑两条硬断言。一条盯着我发誓永远不做的那些东西，只要它们真的出现在代码里，构建当场失败；另一条盯着我拿代价换来的教训，只要它变得查不到、或者和别的页面自相矛盾，wiki 就通不过自己的检查。两条断言的记录都写进同一条 HMAC 链，谁也改不动。这样得来的护城河才是只进不退的：每一次拒绝、每一条教训，都让这套系统更难倒退一步，也更好用一分。

每次提交，我都会跑两个脚本。

第一个脚本把整个代码库 grep 一遍，找的就是我发誓永远不做的那几样东西：任何形式的动态求值、会把明文密钥原样交回来的工具、绕开防线直接调模型厂商接口的裸模块，以及能让 AI 把数据偷偷带出去的那套致命三件套。只要其中任何一样露头，构建立刻失败，没有余地。

![左右两列结构对称，共用同一条 HMAC 链：拒绝这一侧，代码先过一遍 grep，查的是不该存在的东西，一旦查到就让构建失败；知识这一侧，wiki 先过一遍 lint，查的是不该缺席的东西，一旦查出问题就让完整性校验失败；两侧都把各自的事件写进同一份防篡改日志。](/blog/make-your-moat-a-ratchet/2a.webp)

第二个脚本扫的是 wiki，问的是完全相反的问题：这里本该有、却没有的是什么？一条找不到出处的论断。一个没有任何页面链接进来的概念页。两篇隔了几个月写下、结论却互相打架的文章。第一个脚本不让这套系统变成一个 CVE，第二个脚本不让它把学过的东西又忘掉。

lodos 就是围着一条规则搭起来的：重要的拒绝，都要落成构建里的一次 grep；重要的知识，都要落成一个带版本、能被查询的页面。

两者都写进同一条 HMAC 链，任何一处被动过手脚，链子当场就断。把你拒绝加进来的东西写下来，把你拒绝忘掉的东西也写下来，然后让构建在缺了任何一样时就拒绝发版。大多数 AI 产品写下的是自己想成为什么，再拿制度去守；少数产品写下的是自己拒绝成为什么，拿代码去守；最少见的那一类还会写下自己拒绝忘掉什么，再拿一个 wiki 去守：页面一走样，wiki 自己的完整性校验就通不过。只有最后这一类，做出来的护城河才会复利。

![制度型护城河与棘轮型护城河的对照。左边，一句写在纸上的承诺依次经过一位新人工程师、一次重构和一段没人察觉的悄悄走样，信任曲线一路衰减到接近零；右边，grep 和 wiki lint 在每次提交时都会大声报错，同样是十二个月，信任曲线一级一级往上走。](/blog/make-your-moat-a-ratchet/3a.webp)

## 什么会烂掉，什么不会

制度型护城河是悄悄死掉的。“我们绝不记录密钥。”“工具输出一律沙箱隔离。”“数据进 LLM 之前一定先校验。”这些句子写在 SOC 2 文档里，写下的那天全是真的。然后新人加了一行调试日志。一次重构把清洗输入的那段代码挪到了功能开关后面。句子还留在文档里，系统的行为已经对不上号了。没有一条检查报错，也没有一个人察觉。

知识型护城河死得更快。创始人凌晨两点终于想明白某个客户为什么流失，把这条判断丢进 Slack，一周之内忘得干干净净。这条教训没有落在任何查得到的地方。三个月后同一个坑再出现一次，学费重新交一遍。这是最贵的一种腐烂，因为交学费的人根本不知道自己在重复交。

两种腐烂用的是同一味药：把它绑在一个结构上，它一坏，这个结构就跟着报错。拒绝机制一旦倒退，构建就失败；wiki 里的页面一旦变成孤岛、跑偏或者自相矛盾，lint 就通不过。解法不是流程，而是一条断言：系统每一次都拿它对着自己跑一遍。

![三种操作构成的循环：录入把原始资料变成一份待审的页面提案，先在差异对照弹窗里过一遍审阅，才能成为正式内容；查询给出带出处的答案，而这些答案可以直接存回成页面；lint 则负责揪出孤岛页面、没有出处的论断和互相打架的说法。下方列着 lodos 有意做的三处改动：加密的 SQLite 存储、只提案不落笔的自主权，以及一条 HMAC 链式审计日志。](/blog/make-your-moat-a-ratchet/4a.webp)

## Karpathy 那套模式的商业化版本

知识这一半不是我原创的。Andrej Karpathy 描述过一个只有三种操作的 LLM wiki，还打过一个比方：wiki 是可执行文件，原始资料是源码，LLM 是编译器，lint 是测试，查询是运行时。

这套模式我照抄了，但有三处是故意改的。

- **存储。** Karpathy 用的是一堆 markdown 文件加 git。我用的是 SQLite，外加一个按分区分别加密的保险库。这笔买卖是拿互通性换机密性。真想要 Obsidian 的时候，导出一份干净的 markdown 就行。
- **自主权。** Karpathy 让 LLM 直接落笔。我这边每一次改动都得先走提案、再走审批：改动停在一个差异对照弹窗前，AI 永远碰不到正式页面本身。每次审批我花五到十秒，换来的是它没法在我不知情的时候改写我的行为。
- **审计。** Karpathy 留的是一份纯 markdown 日志。我留的是一条 HMAC 链，用主密码派生出的子密钥签名。日志一旦被改，下次启动时就会以断链的形式暴露出来。

这三点不是理念之争，而是把一套个人知识管理的玩法改造成商业产品时必须做的适配。骨子里的东西没变，但能卖出合规买家愿意付的价格。

## 两边转的是同一根棘轮

拒绝这一侧和知识这一侧，形状一模一样。一侧用 grep 找绝对不该出现的东西，另一侧用 lint 找绝对不该缺席的东西。说到底两边查的都是缺不缺：前者要求禁忌之物必须缺席，后者要求该有之物一件都不能少。两边都会大声报错，记录也都写进同一条 HMAC 链。

我向 wiki 提一个问题，如果答案够好，界面上会出现一个“存成页面”的按钮。我一点，这个答案就沉淀下来了：下次会话能找到它，同一个问题不用再问第二遍。我盯的指标是保存率，这个数字会一路往上走。整套系统里，只有 wiki 是用得越多、就实打实变得越强的那一部分。

拒绝那一侧也是一个道理。每来一个可能动摇某条不变量的新功能，就往校验脚本里加一条新的不变量。八个月里，这个脚本从七条检查长到了三十二条。每上线一项能力，都得连着一条 grep 一起上：那条 grep 专门堵死它被滥用的那条路。功能越多，代码库里被明令禁止的东西只增不减。

大多数团队把这两件事当成两码事。其实是同一套纪律，用在两种缺失上：什么绝不该存在，什么绝不该被忘掉。

## 它的代价，以及为什么代价本身就是重点

我被拖慢的地方很集中，就两类：和拒绝机制硬碰硬的功能，以及想绕开 wiki 的重写。有位重度用户想要一个内联的表达式求值器，不行。有位客户想要一个能把明文密钥取回来的工具，不行。将来的我一定会嫌审批循环慢、想把它拆掉，构建不会答应。

我的发布说明和任何一个竞品都长得不一样：提到拒绝了什么的次数，和提到做了什么一样多。我讲不出那种漂亮干净的增长故事：那种故事得把我有意不做的事全部略过。

我换回来的东西放不进落地页，只在一场跟受监管客户的销售对话里管用。对那位客户来说，“我们做不到”和“我们保证不会”是两种完全不同的话。合规负责人看一条防篡改的 HMAC 链，和看一份 markdown 日志，态度也是两样。今天在写 wiki 的这位创始人，是在写给六个月后急着要答案的自己看。这些人里，没有一个是靠营销话术能打动的。

![五个零件先摊成卡片，再连成一张图：代码仓库接上拒绝这一侧的不变量校验脚本，wiki lint 守着知识这一侧，两边都写进共用的那条 HMAC 链；而在只提案不落笔的循环里，任何一次改动都要先过差异对照弹窗，才能成为正式内容。](/blog/make-your-moat-a-ratchet/5a.webp)

## 五个你可以直接搬走的零件

它们互相不依赖，谁都能单独拿走。合在一起，才是完整的那套打法。

1. 一个声明式的工作流引擎，里面不含任何形式的表达式求值。
2. 一个双存储的密钥保险库，AI 在机制上根本无法把明文密钥交出来。
3. 一份构建期运行的不变量校验脚本，每加一条检查，都要先故意破坏一次、确认它真的会拦下来。
4. 一个 wiki，实现 Karpathy 的那三种操作，日志封进 HMAC 链。
5. 一套只提案、不落笔的学习循环，AI 永远改不了自己的行为。

顺序随便。它们唯一共通的是那道纪律：把你拒绝上线的东西和你拒绝忘掉的东西都写下来，在构建里对两者都下断言，然后故意去违反一次，看断言是不是真的会拦住你。剩下的全是工程活。

![下一个循环画成六步链条：AI 观察对话，发现自己有一处技能缺口，起草一份提案；提案停在一个标着“关卡”的左右对照差异弹窗前，由人来批准或驳回，之后才可能成为正式内容并上线；每一份提案、每一次决定，都会写进 HMAC 链。](/blog/make-your-moat-a-ratchet/6a.webp)

## 下一篇预告

*最后那个循环，是最难做对、也花时间最久的一个。AI 一边听着对话，一边留意自己的技能清单哪里该补，然后提交一份修改提案。我批准，或者驳回。这次修改走的是和每一份 wiki 提案完全相同的那道差异对照弹窗。AI 永远不能自己改写自己的行为。提案和批准之间的那道关卡，才是真正的护城河。下一篇就讲这个循环，还有它行为提示词里的一小段话：正是那段话，让整项工程投入变得值得。*

[加入等候名单](https://lodos.md/)
