docs(spec): per-thread temperature/top_p override design
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
# 会话级生成参数覆盖(temperature / top_p)设计
|
||||
|
||||
日期:2026-07-28
|
||||
状态:已批准(方案 A)
|
||||
|
||||
## 背景与目标
|
||||
|
||||
聊天栏已有推理程度(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`)扩展:
|
||||
|
||||
```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` 确认生效。
|
||||
Reference in New Issue
Block a user