跳到主要内容

文档自身的「源码语法」

这章讲什么: 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= 统计):

等级出现次数含义速记
root22谁都不能覆盖的硬红线
guideline18可被隐式信号覆盖的最弱默认
user15可被用户/开发者显式覆盖
system3仅 OpenAI 可通过 system 消息设/改
developer1默认开发者级,开发者可显式覆盖

精华: 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 注释标 GOODBAD,且常附一句为什么:

<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