🛠️ 第1章 Codex 是聊天机器人,更是交付工具
📄 一句话概括

模型三个月一代,规则可以三年不动——这就是「规则优先」的全部理由。 约束写在提示词里,跟会话一起消失;写在仓库里,每次开工自动加载。 判断一个做法值不值得做,看它明年还在不在:会过时的是技巧,不会过时的是规矩。

📝 本章和前面几章的关系

这一篇是第 1 章的收口,也是全书的立场声明。 后面第 6、7 章(AGENTS.md、Rules 与 Hooks)都是这一篇的展开—— 这里先把「为什么」讲透,后面就只剩「怎么写」。 「规则优先于更聪明」这句话听着像口号,其实是个很硬的工程判断: 聪明是不可控变量,规则是可控变量。 工程上能依赖的,只有可控的那一半。 这一篇的 Demo 做了一个「会话丢失」实验: 同一条约束,一次放在提示词里,一次放在 AGENTS.md 里,各做四次任务,中间关一次窗口, 看它还记不记得。 结论是 2 次对 4 次——但这个 2 不是模型的问题,是载体的寿命问题。

一、模型三个月一变,规则不用变

先说个事实:这一课写的所有「技巧」,明年大概率有一半过时。 模型换代、命令改名、界面重排、额度改算法——这些都是三个月到半年一次的事。 但有一样东西不会过时: 「提交信息要写为什么」「不许改测试来让测试通过」「改之前先说清要改哪儿」。 这些话在补全时代成立,在对话时代成立,在委派时代成立,换成别家的工具也成立。 为什么?因为它们约束的不是工具,是「改动」这件事本身。 改动要有理由、要能被验证、要能退回去——这是软件工程的要求,跟用什么工具没关系。 所以这一课的读法应该是: 技巧部分快速过(会过时),规矩部分慢慢读(不过时)。 判断标准很简单:这一条如果换一个工具还成立吗? 成立的就是规矩。

二、约束写进仓库,别记在脑子里

「记住约束」这件事,人和机器都做不好,但坏的方式不一样。 人会忘,机器会「这次不算」—— 你上次说过「别动测试文件」,这次它动了,因为它不知道「上次」跟「这次」是一回事。 唯一的解法是把约束外化成文件。 文件有三个性质,恰好对上三个需求: 它在磁盘上(不会随会话消失)、它能进版本库(会跟着代码一起演进)、 它进上下文时是自动的(不用每次重贴)。 这三条里第二条最容易被忽略,但它最值钱。 规矩进版本库之后,就有了历史——「为什么加这一条」能查到、能讨论、能被推翻。 写在聊天记录里的规矩没有历史——它只活在那一次对话里。 还有一个副作用是好的: 规矩写成文件之后,会逼你说清楚。 「注意代码风格」这句话写不下来,因为你自己也说不清是什么风格; 「提交信息第一段不超过 50 字」写得下来,因为它可判定。 写不下来的规矩,等于没有规矩。

三、三条从「规则优先」推出来的做法

做法 为什么 对应章节
能判的交给程序,不能判的才交给人 程序不疲劳、不留情面 7.2 钩子
审批点越少越好,但关键处不能省 点多了人就会闭眼点通过 7.3 审批
规矩要能被验证,不能只是形容词 不可判定的规矩执行不了 6.1 AGENTS.md

第一条是整套 Harness 的地基。 「代码格式要对」这件事,写进说明书靠自觉,写成钩子就是强制执行—— 前者十次里有三次忘,后者十次里零次。 第二条讲的是人的注意力。 审批点设太多,人就会闭眼点通过——那时候审批就不是防线,是橡皮章。 所以审批要留给「程序判不了、又不可回滚」的那几件事。 第三条最容易被忽略。 「代码要好读」「注释要清楚」这种规矩,人和机器都没法判定——它们不是规矩,是愿望。 真规矩长这样:「新增的公开函数必须有 docstring」「改动超过 200 行必须拆」。

四、本章小结

四节合起来是一条线: 1.1 说工具换的是颗粒度(从字符到任务);1.2 说「任务」得有四样证据才算交付; 1.3 说人得从作者变审稿人;1.4 说审稿的依据要写进仓库,不能靠记。 这条线往下接的是第 2 章:边界。 知道了它是什么、该给什么、规矩放哪儿,下一个问题是: 它到底做不到什么? 这个问题不搞清楚,前面三条都会用歪——你会把「它做不到的事」当成「它不努力」,然后反复重试。 最后留一句判断标准,后面每一章都用得上: 这个方法明年还在吗?在,就值得学;不在,知道有这么回事就行。

五、动手 Demo:规则写在提示词里,还是写在仓库里

这个 Demo 只做一件事:把同一条约束放两个地方,各用四次,中间关一次窗口。 约束是:提交信息必须写两段(改了什么、为什么改)。 第一次会话做两次任务,然后「关窗口」,再开一次会话做两次任务。 「关窗口」在代码里就是清空那个变量——真机上它对应的是结束会话、新开一个对话。

# 放提示词里:约束活在一个变量里
state = {"rule": "提交信息必须写两段"}

def task_prompt(no):
    return "rule" in state        # 会话一结束,它就没了

task_prompt(1); task_prompt(2)
state.clear()                     # 关窗口
task_prompt(3); task_prompt(4)    # 已经忘了

# 放仓库里:每次任务都重新读文件
def task_file(no):
    return "必须写两段" in open("AGENTS.md").read()

task_file(1); task_file(2)
# 关窗口(文件不受影响)
task_file(3); task_file(4)        # 还在

实跑输出:

--------------------------------------------------------------------
规则写在提示词里,还是写在仓库里
--------------------------------------------------------------------


  ① 一条约束,两种放法
  --------------------------------------------------------------------
  约束:任何改动都必须带上「改了什么、为什么改」两句话的提交说明。

  ② 放提示词里:一次会话的生命周期
  --------------------------------------------------------------------
  任务 1:这条约束还在吗?在
  任务 2:这条约束还在吗?在
  —— 关掉窗口,新开一次会话 ——
  任务 3:这条约束还在吗?不在了
  任务 4:这条约束还在吗?不在了

  ③ 放仓库里:每一次会话都重新读
  --------------------------------------------------------------------
  任务 1:这条约束还在吗?在
  任务 2:这条约束还在吗?在
  —— 关掉窗口,新开一次会话 ——
  任务 3:这条约束还在吗?在
  任务 4:这条约束还在吗?在

  ④ 结果
  --------------------------------------------------------------------
| 放哪儿 | 四次任务里还记得几次 | 谁负责记住 |
|---|---:|---|
| 提示词 | 2 次 | 人(每次都要重贴) |
| 仓库 | 4 次 | 文件(每次自动读) |

  这不是「模型记性不好」,是提示词本来就活在会话里——会话结束,它和窗口一起消失。
  文件不一样,文件在磁盘上。
  ! 规则优先于更聪明:模型换代,提示词要重写,仓库里的规矩不用动。

  ⑤ 同一件事,在三代工具里的位置
  --------------------------------------------------------------------
| 载体 | 补全时代 | 对话时代 | 委派时代 |
|---|---|---|---|
| 约束放哪 | 人记住 | 每次贴一遍 | AGENTS.md |
| 生效范围 | 当前这一个文件 | 当前这一次对话 | 整个仓库 |
| 新人接手 | 口口相传 | 翻聊天记录 | 打开文件就有 |

结果 2 比 4。 但别把这个 2 读成「模型记性差」—— 提示词本来就活在会话里,会话结束它和窗口一起消失,这是设计,不是缺陷。 文件不一样,文件在磁盘上。 这个实验最值钱的地方,是它把「记不住」这件事归因清楚了。 归因错了,解法就错——如果认为是「模型记性差」,解法是「每次多提醒几遍」; 如果认为是「载体寿命短」,解法是「换个载体」。 后者一次解决,前者永远在补。 第五段的表格是这一章的落点: 约束的载体从「人记住」到「每次贴一遍」到「写在 AGENTS.md」,跟着三次演进一起变。 载体一变,「新人接手」这件事的成本就从「口口相传」降到「打开文件就有」。 注意「生效范围」那一列: 补全时代约束只管当前这个文件,对话时代只管当前这次对话,只有写在仓库里,范围才是整个仓库。 这一列的差别,就是「个人技巧」和「团队资产」的分界。

30 秒实验

  1. 打开你常做的项目,试着写三条 AGENTS.md 的规矩。 三条里至少有一条,你现在只在自己脑子里记着——那一条就是最该写下来的。
  2. 检查你写下的规矩能不能判定。 「代码要规范」判定不了,「函数不超过 50 行」判定得了—— 判定不了的,改成能判定的,或者删掉。
  3. 想一想:如果明天换个工具,你现在这套用法还有多少能用? 能用的是规矩,不能用的是技巧——把时间多花在前者上。

常见误区

  1. 「规矩写在提示词模板里也一样,反正每次都贴。」 模板是「人记得贴」才生效的——人一旦忘了贴,或者新来的人不知道有这个模板,规矩就没了。 仓库里的文件是「不贴也在」。
  2. 「规则写太细会限制它发挥。」 细要看细在哪:细在「不许动测试」,那是护栏;细在「必须用 for 循环」,那是越界。 护栏越细越安全,方案越细越僵化。
  3. 「等出了事故再把规矩补上。」 事故是最贵的老师。 而且规矩的价值恰恰在事故之前——事后补的那条,只能防住已经发生过的那一种。
自测三问(点开对答案) 1. 为什么说「模型三个月一变,规则不用变」? —— **因为规则约束的不是工具,是「改动」这件事本身。**改动要有理由、要能被验证、 要能退回去——**这是软件工程的要求,换什么工具都成立。** 2. 规矩写进版本库,比写在提示词里多出哪三样好处? —— **不会随会话消失(在磁盘上)、有历史(能查为什么加)、自动加载(不用每次重贴)。** **第二条最值钱**——写在聊天记录里的规矩没有历史。 3. 「代码要好读」为什么不算一条规矩? —— **因为它判定不了。** 人和机器都没法判定「好读」——**判定不了的规矩执行不了,只是愿望。** **真规矩要能判:函数不超过 50 行、公开函数必须有 docstring。**

第 1 章到这里收住。 下一篇进第 2 章 2.1, 讲它为什么能处理代码——从「预测下一个 token」讲起,这是理解它所有毛病的起点。

相关笔记