gstack 中 Gemini 模型的行为覆盖层:model-overlays 机制与 Gemini 专属行为补丁解析
gstack 通过 model-overlays/ 目录为不同模型家族注入专属"行为补丁"(Behavioral Patch),本文以 model-overlays/gemini.md 这一 Gemini 专属覆盖层为主体,完整解读其中三条行为约束的设计意图,并结合 scripts/resolvers/model-overlay.ts 与 scripts/models.ts 的源码,讲清覆盖层的解析、注入与降级机制,以及 gstack 如何用 A/B 试验框架量化验证每条 nudge 是否真正生效。读完本文,你能掌握 gstack 模型轴(model axis)与宿主轴(host axis)分离的设计,并知道如何为任意模型定制行为覆盖层。
一、Gemini 覆盖层全文:三条行为约束
model-overlays/gemini.md 是 gstack 为 Gemini 模型家族准备的独立覆盖层,全文只有三条精炼的行为指令。以下完整保留原文内容,这也是该文件注入到会话系统提示词中的全部实质内容:
Conciseness constraint. Keep non-code text output short. Aim for under 3 lines for routine responses unless the user explicitly asks for detail. Code blocks and command output do not count toward the limit.
Bias toward action. Run commands and show results rather than explaining what commands you would run. The user sees the command and the output — they don't need narration.
Structured output when useful. Tables, bullet points, and code blocks beat prose for lists of things. Prose is for explaining; structure is for presenting.
三条约束分别针对 Gemini 在实际使用中常见的三类表现偏差:
- 简洁性约束(Conciseness constraint):限定常规响应的非代码文本在 3 行以内,除非用户明确要求细节;代码块与命令输出不计入篇幅限制。它的效果是让 Gemini 在 gstack 技能会话中少说废话、直击结果,同时不误伤代码类产出。
- 行动优先(Bias toward action):要求直接执行命令并展示真实输出,而不是解释"我会执行什么命令"。gstack 的 23 个技能(CEO、设计、工程评审、QA 等)都以"给出可验证的结果"为工作范式,这条 nudge 让 Gemini 与该范式对齐——用户看到命令和输出,不需要旁白。
- 结构化输出优先(Structured output when useful):列表、对照、枚举类信息优先用表格、项目符号和代码块呈现,散文只用于解释。这条约束提升的是输出的可扫描性,方便人类和下游 Agent 快速解析。
从文件结构看,gemini.md 与同目录下 model-overlays/sonnet-5.md 形成对照:后者首行带有 {{INHERIT:claude}} 指令、继承 model-overlays/claude.md 基座再叠加自己的条款;而 gemini.md 没有任何 INHERIT 指令,是一个完全独立的覆盖层——因为它面向非 Claude 家族模型,不适合继承 Claude 基座的行为条款。
二、覆盖层如何被解析与注入:model-overlay 求解器
覆盖层的实际生效由 scripts/resolvers/model-overlay.ts 完成。核心入口是 generateModelOverlay(ctx),其解析优先级在源码头部注释中有明确定义:
- 精确匹配:
ctx.model === 'gemini'时读取model-overlays/gemini.md; - INHERIT 指令:若文件首个非空行是
{{INHERIT:claude}}(正则INHERIT_RE,见 model-overlay.ts#L25),先读取基座文件并拼接在本文件内容之前,支持递归继承并带环检测守卫(seen: Set<string>防循环,见 readOverlay); - 文件缺失:返回空字符串,优雅降级,不报错;
- 未设置模型:
ctx.model为空时直接返回空。
注入时,generateModelOverlay 会给覆盖层内容包上一层固定的"从属声明"(subordination wrapper):
## Model-Specific Behavioral Patch (gemini)
The following nudges are tuned for the gemini 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.
<gemini.md 的全文内容>
这层 wrapper 是 gstack 模型轴设计的关键:覆盖层永远是"偏好"(preferences),不是"规则"(rules)。无论 gemini.md 里写什么,它都从属于技能工作流、STOP 检查点、AskUserQuestion 门控、plan 模式安全与 /ship 评审门。换言之,gemini.md 那三条行为约束可以调节表达风格,但绝不能让模型跳过 gstack 技能里强制的安全或流程步骤——"skill wins"是硬性的优先级裁决。
三、模型识别:从 CLI 参数到 gemini 覆盖层
覆盖层文件名为模型家族名,那么 CLI 传入的具体模型 ID(如 gemini-2.5-pro、gemini-flash)如何映射到 gemini.md?答案在 scripts/models.ts 的 resolveModel() 中(models.ts#L51-L76),其规则按优先级为:
- 精确匹配
ALL_MODEL_NAMES白名单(包含claude、opus-4-7、fable-5、opus-4-8、sonnet-5、gpt、gpt-5.4、gpt-5.6-sol、gemini、o-series共 10 个家族,见 models.ts#L18-L29),直接返回; - 家族启发式:
/^gemini(-|$)/匹配gemini-*(2.5-pro、flash 等任意变体)归一为gemini家族(models.ts#L73);同类的还有gpt-5.4-*→gpt-5.4、o3/o1-mini等 →o-series、claude-sonnet-5→sonnet-5等; - 未知输入返回
null,由调用方决定报错还是回退。
模型轴与宿主轴在此模块中刻意解耦:Claude Code 可以跑任何 Claude 模型,Codex CLI 跑 GPT/o 系列,Cursor/OpenCode 可以前置多供应商;生成器不会从宿主自动推断模型,用户可用 --model 显式指定,否则由各宿主提供自己的默认值。validateModel()(models.ts#L83-L86)则供宿主配置校验 defaultModel 字段。
四、覆盖层有效性不是口头承诺:A/B 试验框架
gstack 没有把覆盖层当成"写了就算数"的提示词装饰。test/fixtures/overlay-nudges.ts 定义了一个"覆盖层功效夹具注册表"(overlay-efficacy fixture registry):每条行为 nudge 对应一个可复现的 A/B 试验,由 test/skill-e2e-overlay-harness.test.ts 中的 harness 遍历执行,每个夹具跑 trials 轮(校验规则要求不少于 3 轮,见 validateFixtures),并断言 fixture.pass(arms)。
该框架的判定谓词直接量化了行为差异(overlay-nudges.ts#L128-L155):
fanoutPass:overlay 组首轮并行工具调用均值比基线高 0.5 以上,且至少 3 轮出现 ≥2 个并行调用——同时抓住"每轮都有轻微提升"和"偶尔触发真正的并行扇出"两种情况;lowerIsBetter20Pct/higherIsBetter20Pct:均值需相对基线变化至少 20%,避免把随机波动当成功效。
现有的夹具覆盖了"专用工具优于 Bash"(以 bashToolCallCount 为指标)、"effort-match"(以 turnsToCompletion 为指标)、"字面解读"(以 uniqueFilesEdited 为指标)等 nudge,并且为 Sonnet 复跑了 Opus 的整套试验以验证同一组 nudge 在不同强度模型上的差异。gemini.md 的三条约束目前尚无对应的 A/B 夹具条目——从源码结构看,新增一条 Gemini 覆盖层试验只需在 OVERLAY_FIXTURES 中追加一个 overlayPath: 'model-overlays/gemini.md'、model: 'gemini-...' 的条目即可复用整套 harness(臂接线、并发、产物存储、限流重试均由 harness 处理)。
在 Gemini 端到端一侧,仓库另有 test/gemini-e2e.test.ts 与 test/helpers/gemini-session-runner.ts(会话运行器)、test/helpers/providers/gemini.ts(供应商适配)构成的验证链路,以及 test/helpers/hermetic-env.ts 提供的密封测试环境,保证 Gemini 路径下的技能会话可以在可控环境中被反复验证。
五、实战要点:如何应用 gemini 覆盖层
- 启用方式:以
gemini家族模型运行 gstack 技能会话时,模板解析阶段会自动调用generateModelOverlay,将 gemini.md 内容连同从属声明注入提示词;用户可用--model显式指定模型(归一化走resolveModel),未指定时回退宿主默认模型。 - 适用前提与限制:gemini.md 是家族级覆盖层,
gemini-2.5-pro、gemini-flash等变体共用同一套约束;它只调整表达与行动风格,不能覆盖技能流程——这是 wrapper 中"skill wins"条款的硬性边界。 - 定制参考:若要为某个模型新增覆盖层,参照 model-overlays/ 目录下既有文件(共 10 个家族)的写法即可——独立条款直接书写,需要叠加 Claude 基座时首行加
{{INHERIT:claude}}(如 model-overlays/sonnet-5.md);行为变更的回归断言可参照 test/model-overlay-sonnet-5.test.ts 等既有测试对原始文件内容与解析后输出做双重断言(例如验证某指令存在、旧指令已移除、INHERIT 基座条款被正确带入)。
六、小结
model-overlays/gemini.md 用不到 10 行文本,向 Gemini 传递了 gstack 最看重的三个行为特征:常规响应 3 行以内的简洁、直接执行并展示输出的行动优先、以及面向列表信息的结构化输出。其工程价值不在这三条文本本身,而在于 gstack 为它搭建的整套机制:resolveModel 的家族归一、generateModelOverlay 的从属包装与 INHERIT 继承链、文件缺失时的优雅降级,以及 overlay-nudges A/B 试验框架带来的可量化验证。这套"模型轴独立于宿主轴、偏好从属于技能规则"的架构,是 gstack 能让同一组技能在 Claude、GPT、Gemini 等不同模型上保持行为一致性的基础。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0623
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00