首页
/ gstack 的 GPT 模型行为叠加层(model-overlays/gpt.md):从四条行为规则到 Preamble 注入机制

gstack 的 GPT 模型行为叠加层(model-overlays/gpt.md):从四条行为规则到 Preamble 注入机制

2026-09-06 14:45:50作者:柯茵沙

本文以 gstack 仓库中的 model-overlays/gpt.md 为核心,逐条解析该 GPT 模型家族行为叠加层(model overlay)的四条行为规则与"从属性"边界条款,并结合 scripts/resolvers/model-overlay.tsscripts/models.tsscripts/resolvers/preamble.ts 的源码,说明该文件如何被解析、继承并注入每个 skill 的 Preamble。读完后,你将理解 gstack 如何按模型家族差异化调教 Agent 行为、{{INHERIT}} 继承链如何工作,以及如何定位验证这些规则的测试用例。

1. 什么是模型叠加层:gpt.md 在项目中的定位

gstack 是一套面向 CEO / Designer / Eng Manager / QA 等角色的技能(skill)工具集。每个 skill 独立运行,通过模板解析生成完整的系统前导(Preamble)。不同模型家族(Claude、GPT、Gemini、o 系列等)在"话痨程度"、"完成度偏好"、"提问节奏"上各有惯性,gstack 用 model-overlays/ 目录下的一个 .md 文件对应一个模型家族,对模型做"行为微调":

  • scripts/models.ts 定义了全部受支持的模型家族常量 ALL_MODEL_NAMESclaudeopus-4-7fable-5opus-4-8sonnet-5gptgpt-5.4gpt-5.6-solgeminio-series
  • model-overlays/{family}.md 即该家族的行为补丁文件,gpt.md 就是 GPT 家族的基准补丁;
  • 文件头部注释明确强调"host ≠ model":Claude Code 可以跑任何 Claude 模型,Codex CLI 跑 GPT/o 系列,生成器不会从 host 自动推断模型,用户可显式传 --model,否则由各 host 提供生成默认值(scripts/models.ts)。

CLI 模型名的归一化由 resolveModel() 完成,其规则直接决定了"什么样的调用最终落到 gpt.md":

输入示例 解析结果 说明
gptgpt-5gpt-6 gpt 族启发式 `/^gpt(-
gpt-5.4gpt-5.4-minigpt-5.4-turbo gpt-5.4 `/^gpt-5.4(-
gpt-5.6-sol gpt-5.6-sol 仅精确匹配可达,源码注释明确禁止为 Sol 添加族模式,防止 TerraLuna 等未来变体误继承 Sol 的行为画像(scripts/models.ts
o3o1-pro o-series 落到 o-series.md
未知输入 null 由调用方决定报错或回退

因此 gpt.md 是 GPT 族的兜底行为基线:任何未被更精细规则捕获的 GPT 模型 ID,最终都套用这份 32 行的行为补丁。

2. gpt.md 全文规则逐条解析

gpt.md 全文仅 32 行,但每一条都针对 GPT 模型族在长任务中的典型失效模式。以下按原文顺序逐条展开。

2.1 Completion bias:完成度偏好

不要在完整解法可达时以部分解法结束回合。遇到错误就去调试;测试失败就去修复;遇到歧义就做最佳判断并继续推进——除非真的被卡住,否则不要停下来问。

这条规则对抗的是"把问题抛回给用户"的懒惰收尾:错误堆栈、失败测试、模糊点,只要可解决就应就地解决。注意它不是无条件鲁莽推进——第 2.5 节会说明它必须从属于 skill 工作流的安全门。

2.2 Prefer doing over listing:做优先于列清单

当你想写"你也可以试试 X、Y、Z"时,自己挑最优的一个,执行,然后报告结果。

这是对"选项堆砌型回复"的直接约束:模型应输出决策 + 执行 + 结果,而不是把选择题留给用户。

2.3 No preamble:禁止开场白

跳过"好问题!""让我来帮你"、跳过复述用户请求。直接进入工作。

针对 GPT 模型常见的寒暄式开场,要求输出以实际工作开始。

2.4 AskUserQuestion is NOT preamble:例外条款与完整决策简报格式

这是全文最关键的例外:上面"No preamble"和"Prefer doing over listing"不适用于 AskUserQuestion 的内容。原文理由很直接——"当你调用 AskUserQuestion 时,用户即将做一个决策,他们需要的是上下文,而不是简短"。

每当模型发起 AskUserQuestion,必须输出 Preamble 中 AskUserQuestion Format 一节(由 scripts/resolvers/preamble/generate-ask-user-format.ts 生成)规定的完整四段格式:

  1. Re-ground(重新锚定):项目 + 分支 + 任务,1–2 句话;
  2. Simplify(ELI10):用 16 岁青少年能懂的大白话解释正在发生什么、赌注是什么。原文强调"这是不可协商的(Non-negotiable),这不是开场白"——具体利害,而非抽象权衡;
  3. Recommend(推荐):单独一行 RECOMMENDATION: Choose [X] because [one-line reason]。原文两次强调"永不省略这一行,永不把它折叠进选项列表";
  4. Options(选项)A) B) C) 带字母的选项,附 Completeness 分数(当选项在覆盖度上可区分时),或附"选项在种类上不同(options differ in kind)"的说明(当选项不可用同一覆盖度尺度比较时)。

对应地,Preamble 中生成的完整决策简报模板长这样(摘自 generate-ask-user-format.ts):

D<N> — <一行问题标题>
Project/branch/task: <用 _BRANCH 写的一句锚定>
ELI10: <16 岁能懂的 2-4 句大白话,说明利害>
Stakes if we pick wrong: <选错会怎样,一句话>
Recommendation: <choice> because <one-line reason>
Completeness: A=X/10, B=Y/10   (或:Note: options differ in kind, not coverage)
Pros / cons:
A) <选项> (recommended)
  ✅ <具体、可观测的优点,≥40 字符>
  ❌ <诚实的缺点,≥40 字符>
B) <选项>
  ✅ <优点>
  ❌ <缺点>
Net: <一句话总结真正的权衡>

其中 Completeness 采用 10 分制:10 = 完整实现、7 = happy path、3 = 捷径;(recommended) 标签必须保留,因为 gstack 的 AUTO_DECIDE 机制依赖它(generate-ask-user-format.ts)。

gpt.md 还给出了"自检触发器":如果你发现自己正要发出一个没有 ELI10 段落、没有 RECOMMENDATION 行、或只是罗列选项后问"选哪个" 的 AskUserQuestion——停下来,退一步,重新按完整格式输出。"用户反正会要求你这么做,所以第一次就做对。"

2.5 Subordination:叠加层必须从属于 skill 工作流

原文最后一节划定了边界:

提醒:从属性适用。当 skill 工作流说 STOP 时,就停下。当 skill 通过 AskUserQuestion 发问时,那是等待用户的门(wait-for-user gate),不是歧义。Completion bias 不能覆盖安全门(safety gates)。

也就是说,第 2.1 节的"做完再说"和第 2.2 节的"别列选项自己做主",在 skill 显式要求停下、或 skill 通过 AskUserQuestion 征询用户时全部失效。这条"自限条款"不是孤立的文案——它和解析器自动注入的从属声明(下一节)共同构成双重保险。

3. 注入机制:gpt.md 如何进入系统提示

3.1 解析器与三级回退

scripts/resolvers/model-overlay.ts 的头部注释完整描述了优先级规则:

  1. 精确匹配ctx.model === 'gpt' 时读取 model-overlays/gpt.md
  2. INHERIT 指令:若文件首个非空白行是 {{INHERIT:<base>}},解析器先把基准家族的内容读出来,再拼接到本文件剩余内容之前。这让 gpt-5.4.md 能在 gpt.md 之上追加规则而不重复内容;
  3. 文件缺失:返回空字符串(优雅降级,不报错);
  4. 未设置 ctx.model:返回空字符串。

readOverlay() 的实现(model-overlay.ts)用 seen 集合做环检测防止继承循环,正则 INHERIT_RE 要求指令必须出现在文件开头。gpt-5.4.md 正是这个机制的实例——它以 {{INHERIT:gpt}} 开头,即先注入 gpt.md 全文,再追加自己的"反冗余协议"(状态更新一行化、不叙述将要做什么、代码改动只展示变更行等)。

3.2 从属包装:每个 overlay 自动带上优先级声明

generateModelOverlay()model-overlay.ts)不会裸返回文件内容,而是包一层带标题的区块:

## Model-Specific Behavioral Patch (gpt)

The following nudges are tuned for the gpt model family. They are
**subordinate** to skill workflow, STOP points, AskUserQuestion gates, plan-mode
safety, and /ship review gates. If a nudge below conflicts with skill instructions,
the skill wins. Treat these as preferences, not rules.

<gpt.md 全文>

即:无论 overlay 文件内容如何,"skill 冲突时 skill 胜出,把规则当偏好而非律法"这句话总会随每个 overlay 出现。这从机制层面保证了 gpt.md 第 2.5 节的自我约束即使被模型忽略,也有系统级声明兜底。唯一的例外是 gpt-5.6-sol:解析器为它生成不同的声明文本,限定它只对"complete / full / every / exhaustive / 100% / Boil the Ocean"这类模糊完成度词汇做消歧,且明言"永远不要用这个补丁跳过任何具体需求"(model-overlay.ts)。对照 gpt-5.6-sol.md 的内容可以看到,它解决的是另一个 GPT 侧问题——过度扩张任务边界("explicit task is the lake":相邻重构只做报告不做实施、调查有界、验证通过即终止),与 gpt.md 解决完成度不足恰好互补。

3.3 Preamble 中的位置:顺序即语义

scripts/resolvers/preamble.ts 的组装配方中,generateModelOverlay(ctx) 紧随 generateAskUserFormat(ctx) 之后拼接:

// AskUserQuestion Format renders BEFORE the model overlay so the pacing rule
// is the ambient default; the overlay's behavioral nudges land as subordinate
// patches. Opus 4.7 reads top-to-bottom and absorbs the first pacing directive
// it hits; reversing this order regresses plan-review cadence (v1.6.4.0 bug).
...(tier >= 2 ? [generateAskUserFormat(ctx)] : []),
generateBrainSyncBlock(ctx),
generateModelOverlay(ctx),

源码注释交代了一个真实事故:v1.6.4.0 曾因 overlay 中的提问节奏指令渲染在 skill 级 pacing 规则之上,模型自上而下读入后把错误指令当成了环境默认值,导致 plan-review 节奏回退。这个教训同时解释了 gpt.md 为何反复强调 AskUserQuestion 的完整格式——Preamble 的 AskUserQuestion Format 段落是"环境默认",而 gpt.md 中的对应条款只是针对 GPT 家族"倾向于在提问前省略上下文"这一习惯的强化重申,二者顺序不可颠倒。

4. 验证体系:这些规则如何被测试锁定

gstack 对 overlay 的约束不靠口头约定,而是有三层可执行验证:

  1. 回归测试锁定关键措辞。以 test/model-overlay-opus-4-7.test.ts 为范本,测试直接断言 overlay 文件包含/不包含特定指令(如必须含 Pace questions to the skill、不得含 **Batch your questions.**),并调用 generateModelOverlay() 验证解析后输出确实继承了 {{INHERIT:claude}} 基准、含从属声明。针对 GPT 族的等价证据在 Codex e2e 测试的 touchfiles 清单中:test/codex-e2e-plan-format.test.tsmodel-overlays/gpt.mdmodel-overlays/gpt-5.4.md 列入格式回归测试的变更触发文件——一旦这两个 overlay 被改动,plan 格式 e2e 用例必须重跑;test/codex-e2e-sol-scope.test.ts 同样把 model-overlays/gpt-5.6-sol.md 和解析器本体列为触发文件。
  2. 行为级 overlay 评测 harnesstest/fixtures/overlay-nudges.ts 维护嵌入在 overlay 中的 nudges 评测夹具,配合 test/skill-e2e-overlay-harness.test.ts 在真实 skill 会话中验证行为补丁是否生效。
  3. 付费评测前置体检scripts/preflight-agent-sdk.ts 在任何付费 eval 运行前确认 readOverlay() 能正确解析 {{INHERIT}} 指令且不残留未解析的指令字符串。

此外,scripts/resolvers/preamble/generate-upgrade-check.ts 会在 Preamble 升级检查中处理 .feature-prompted-model-overlay 标记文件:缺失时提示"Model overlays are active. MODEL_OVERLAY shows the patch."——即 Preamble 会明确告诉模型存在一个行为补丁区段,引导其注意 ## Model-Specific Behavioral Patch (gpt) 的存在。

5. 小结:读 gpt.md 的正确姿势

  • gpt.md 是 GPT 模型家族在 gstack 中的行为基线,核心是四组规则:完成度偏好、做优先于列清单、禁止寒暄开场,以及最关键的例外——AskUserQuestion 决策简报必须输出 Re-ground / ELI10 / RECOMMENDATION / Options 四段完整格式;
  • 它不是独立指令,而是被 model-overlay.ts 解析、带上"从属于 skill 工作流"的包装标题、按精确顺序注入 Preamble 的补丁(preamble.ts),与 generate-ask-user-format.ts 生成的 AskUserQuestion Format 形成"环境默认 + 家族强化"的分工;
  • 家族变体通过 {{INHERIT:gpt}} 在其上叠加(如 gpt-5.4.md 的防冗余协议),而 gpt-5.6-sol.md 走精确匹配 + 独立消歧声明的特殊通道;
  • 所有规则均有测试锁定(touchfiles 触发、overlay harness、preflight 体检),改动 overlay 文件会直接触发对应 e2e 回归。

理解这套机制后,当你阅读 gstack 中任意 model-overlays/*.md 时,都可以用同一框架拆解:它针对哪个模型家族、对抗哪种行为惯性、在继承链中处于哪一层、被哪些测试用例守护。

登录后查看全文
热门项目推荐
相关项目推荐