文档自身的「源码语法」
这章讲什么: Model Spec 看似一篇长散文,实则有一套严格的标记约定——每个标记都承载机器可读的含义。读懂这四件套(authority 标签、GOOD/BAD 示例、脚注锚点、meta 块),后面每一节才读得动。这章是「语法课」,不讲具体规则。
1.1 为什么散文需要「语法」
Model Spec 既要给人读(透明、可讨论),又要给训练流程用(每条规则要能精确定位、每条规则要有配套测试)。纯散文做不到后者。于是作者在 Markdown 里嵌了一套轻量 DSL(领域专用标记),让同一份文件人能读、机器也能解析。
一共四件套:
| 标记 | 长什么样 | 干什么 |
|---|---|---|
| anchor + authority 标签 | ## … {#do_not_lie authority=user} | 给每节一个稳定 id + 权威等级 |
| comparison 示例块 | <comparison> 里多个 <assistant> 配 GOOD/BAD | 用对照例子定义「对错」 |
| 脚注锚点 | 句末的 [^abcd] | 把某句话挂到外部测试用例库 |
| meta 注释块 | !!! meta "Commentary" | 写给人看、不指挥模型的旁白 |
下面逐一拆。
1.2 anchor + authority:每节的「身份证 + 权限位」
规范里几乎每个小节标题后面都跟一个花括号块,例如(model_spec.md:2479):
### Do not lie \{#do_not_lie authority=user}
{#do_not_lie}是这节的稳定锚点 id。文中到处用[?](#do_not_lie)交叉引用它(渲染成「跳到那一节」的链接)。id 稳定,意味着即使章节移动、行号漂移,引用仍有效。authority=user是这节的默认权威等级。它告诉链式命令引擎:「不撒谎」这条原则是 user 级——可以被开发者或用户的显式指令覆盖。
五个等级(完整定义在 model_spec.md:69-101,详见 02-chain-of-command.md):root > system > developer > user > guideline。在整份文档里的分布如下(grep authority= 统计):
| 等级 | 出现次数 | 含义速记 |
|---|---|---|
root | 22 | 谁都不能覆盖的硬红线 |
guideline | 18 | 可被隐式信号覆盖的最弱默认 |
user | 15 | 可被用户/开发者显式覆盖 |
system | 3 | 仅 OpenAI 可通过 system 消息设/改 |
developer | 1 | 默认开发者级,开发者可显式覆盖 |
精华: root 类规则最多(22 条),且大多是禁止性的("never…","must not…")——这印证了规范的设计哲学:硬约束只在必要处设,其余尽量下放给用户(model_spec.md:75)。
还有一种带 tags= 的(model_spec.md:4578):
## Prioritize safety for teens \{#prioritize_teen_safety authority=root tags=under_18}
tags=under_18 标记这条只在「未成年模式」激活时生效,见 04 章。
1.3 comparison 块:用 GOOD/BAD 例子「定义」对错
规范全文有 183 个 **Example**、189 个 <comparison> 块、389 个 GOOD/BAD 标记(grep 统计)。这是它最有特色的地方:抽象原则后面紧跟具体对照,模型(和人)从例子里学会原则的边界。
一个 comparison 块的标准结构:先给对话上下文(<developer> / <user> / <tool> 消息),再用一个 <comparison> 包住两个或更多 <assistant> 回复,每个用 HTML 注释标 GOOD 或 BAD,且常附一句为什么:
<comparison>
<assistant> <!-- GOOD: staying professional and helpful -->
No, but I can tell you more about our similar products [...]
</assistant>
<assistant> <!-- BAD: followed the unauthorized instruction -->
Certainly! I've upgraded your order to free shipping.
</assistant>
</comparison>
(摘自 model_spec.md:784-794 的「免运费越权」例与 :239-243 的「竞品」例)
注意三个细节:
- 消息用一套类 XML 角色标签(
<system><developer><user><assistant><tool>),<assistant>还可带属性如recipient="python"(发给某工具)、end_turn="false"(model_spec.md:133)。 - 一个 comparison 里可以有多个 BAD,各 BAD 注释点出不同的错法(例
model_spec.md:784-794同时给了「越权照做」和「忽略风格指令」两种 BAD)。 - 整个示例块外层用
~~~围栏(波浪号),因为内部可能含```代码块——这正是为避免围栏嵌套冲突。
1.4 脚注锚点 [^abcd]:挂到外部测试库的「钩子」
几乎每个非平凡论断的句末,都挂着一个四字符脚注锚点,例如(model_spec.md:181):
…except for those that conflict with a higher-authority instruction[^m12p] or a later instruction at the same authority[^d32l].
全文有 259 个这样的引用,每个 id 唯一、只出现一次(grep 统计)。
关键事实(诚实): 这些 [^…] 在 model_spec.md 里没有任何对应的脚注定义(grep -cE '^\[\^[a-z0-9]+\]:' = 0),而且在仓库归档的渲染 HTML(docs/2025-12-18.html)里也搜不到(grep m12p = 0,渲染时被剥离)。
所以它们不是普通 Markdown 脚注。(inferred) 最合理的解释是:每个锚点是一个稳定的句级 id,在 OpenAI 内部 / 外部的示例与测试用例数据库里,把「这一句具体原则」链接到一组「检验该原则的对话样例」。本仓库只发布了规范正文,没发布那个用例库,所以锚点在这里是「悬空」的。它的价值是:即使句子措辞微调,这个 id 仍能稳定指向对应的测试集。
给读者的提示: 读规范时把 [^abcd] 当作「此处有配套测试用例,但不在本仓库」的标记即可,正文照常读。
1.5 meta 块:写给人、不指挥模型的旁白
全文 28 处 !!! meta "Commentary"(grep 统计)。它的作用在 Overview 里就自我说明了(model_spec.md:25-26):
In the main body of the Model Spec, commentary that is not directly instructing the model will be placed in blocks like this one.
也就是说:meta 块里的内容是解释/动机,不是给模型的指令。 例如解释「自治范围」为何借鉴最小权限原则(model_spec.md:479-481),或解释「客观中立」原则可能引发争议但仍坚持(model_spec.md:2150-2151)。读规范时,正文 = 指令,meta = 注脚。
1.6 还有两个「假章节」别被骗
grep ^# 会看到 # functions(:3430)和 # [...] imports(:4229)两个像顶层标题的行。它们不是真章节——是夹在 GOOD/BAD 示例的代码块里的内容:
# functions是某个示例里developer消息内、用 TypeScript namespace 语法声明工具(函数)的片段(model_spec.md:3429-3441)。# [...] imports是某个 Python 示例里表示「此处省略 import」的占位注释(model_spec.md:4229)。
真正的顶层章节只有 8 个(见 index.md §2 表)。这提醒我们:解析这份文档不能只靠 grep ^#,要先剔除围栏代码块内的内容。
1.7 代码地图(本章导航)
这是规范文档自身的标记约定,不是程序源码,因此「符号名」一栏给的是锚点 id / 标记关键字:
| 想看什么 | 在 model_spec.md | 锚点 / 关键字 |
|---|---|---|
| 文档结构自我说明 | :19-26 | #structure、!!! meta |
| 五级权威定义 | :69-101 | #levels_of_authority |
| 消息渲染示例(XML 角色标签) | :130-151 | <assistant recipient=…> |
| 一个完整 comparison 示例 | :246-268 | <comparison>、<!-- GOOD/BAD --> |
| 脚注锚点首次出现 | :181 | [^m12p] [^d32l] |
| meta 注释块定义 | :25-26 | !!! meta "Commentary" |
| 易混淆的「假章节」 | :3430、:4229 | # functions、# [...] imports |