Files
EvoScientist/docs/superpowers/specs/2026-07-28-thread-generation-param-overrides-design.md
T
m4 862c1e9743 docs(registry): supersede flat temperature/top_p overrides with mutually-exclusive sampling_override
temperature and top_p cannot be set together; the flat-fields design
allowed both. Replaced by a discriminated union (default | temperature
| top_p) where overriding one omits the other from the request entirely.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-07-30 09:29:06 +08:00

4.2 KiB
Raw Blame History

会话级生成参数覆盖(temperature / top_p)设计

日期:2026-07-28 状态:已被取代 — temperature/top_p 平铺字段方案存在互斥缺陷(temperature 与 top_p 不能同时覆盖),由 2026-07-30-sampling-override-design.md (判别联合方案)替代。本文件仅作历史留存。

背景与目标

聊天栏已有推理程度(reasoning effort)的会话级覆盖:模型名旁的滑块 → 线程元数据 model_selection → CAS PATCH → 运行快照冻结 → resolver override → adapter 参数契约 → request_options。

temperature / top_p 目前只能在模型注册表(registry)按模型或 provider 默认配置, 没有会话级覆盖。本设计为两者补齐与 reasoning_effort 完全同构的会话级覆盖链路。

非目标:不改注册表默认值编辑路径;不覆盖 auxiliary/vision 角色;不做通用 parameter_overrides 字典(方案 B,已否决,避免迁移现有平铺字段的 churn)。

方案

平铺字段,复刻 reasoning_effort 链路(方案 A)。

1. 数据模型与元数据(WebUI)

ThreadModelSelection(EvoScientist-WebUI/src/lib/modelRegistry.ts)扩展:

| { primary: ModelRef;
    reasoning_effort?: ReasoningEffort | null;
    temperature?: number | null;   // null = 用注册表默认
    top_p?: number | null; }
  • 线程元数据 model_selection 携带新字段;useChat 的元数据读取镜像同步扩展。
  • parseThreadModelSelection(src/lib/server/threadModelSelection.ts)增加形状 校验:temperature 为有限数且 0–2;top_p ∈ (0,1];非法 → 400。模型级契约 (如 Anthropic temperature ≤ 1)不在 BFF 硬编码,留给快照创建时 adapter 校验。
  • CAS PATCH 端点不变,载荷带新字段,model_selection_revision 照常递增。
  • inherit 模式:与推理滑块一致,未显式选模型时滑块禁用。

2. 后端快照与 resolver(Python)

  • 快照创建请求模型(EvoScientist/model_registry/snapshots.py)增加 temperature: float | None(0–2)、top_p: float | None((0,1])。
  • compute_selection_hash 从 {primary, reasoning_effort} 扩为 {primary, reasoning_effort, temperature, top_p}。旧 hash 自然失效生成新快照, 无需迁移。
  • ModelResolver.resolve() 增加 temperature_override / top_p_override 关键字参数,传入 resolve_parameters,与 reasoning_effort_override 同路: 经 adapter ParameterRule 契约校验(越界 → 快照创建 4xx),通过后进入 request_options,由 build_request 映射到 provider 实际参数名。
  • 快照 payload 的 request_options 已含 temperature/top_p,结构不变,只改值来源。
  • WebUI BFF runs 路由(src/app/api/conversations/[threadId]/runs/route.ts) POST /api/runtime-snapshots 的 body 带两个新字段(inherit 时为 null)。

3. 聊天栏 UI

复用 ReasoningEffortSlider 模式,新增两个紧凑内联滑块,排在推理滑块后:

[✨ qwen3.7-plus · 阿里] [推理: 中▔] [T:0.7▔] [P:0.95▔]
  • 交互与推理滑块一致:拖动即时预览,松手(onCommit)发 CAS PATCH;失败 toast 并回滚显示;点击数值可键盘输入精确值。
  • 量程/步进:temperature 0–2 步进 0.05;top_p 0–1 步进 0.05。
  • 未覆盖(null)时滑块停在注册表生效值(目录已下发模型与 provider 默认), 弱化样式标注"默认";拖动后变为覆盖值;提供"重置为默认"(提交 null)。
  • model_selection === "inherit" 时三个滑块一起禁用。
  • 小屏(<sm):三个滑块收进模型名旁的展开按钮,避免挤压输入区。

4. 错误处理

  • adapter 契约拒绝 → runs 路由透传 4xx,前端 toast 提示合法范围,滑块回滚; 不产生快照。
  • CAS revision 冲突沿用现有逻辑,不新增机制。
  • 非法载荷在 BFF parseThreadModelSelection 直接 400。

5. 测试

  • WebUI:threadModelSelection.test.ts 增 parse 校验用例(合法/越界/非数字/ null);runs 路由测试断言快照请求体带新字段;useChat 元数据读取镜像用例。
  • 后端:tests/test_snapshots.py 增 override 冻结进 request_options、契约拒绝、 override 改变 selection_hash、null 不改变 hash;resolver 层 override 用例。
  • 端到端:dev 环境聊天栏调 temperature 后发消息,对照 provider test 的 effective_request_options 确认生效。