---
type: design
node_id: design:sampling-params
title: "采样参数透传设计(issue #4)"
date: 2026-07-31
---

# 采样参数透传设计(issue #4)

正文: `2026-07-31-sampling-params-design.md`。状态: 待人类审批。

- **选定方案**: 两层入口——调用级 `chat(..., overlay=)` 供逐 rollout 变化的 `seed`,配置级 `SourceConfig.extra_body`(env 键 `{SCOPE}__{PROVIDER}__{N}__EXTRA_BODY`,JSON 串)供恒定的 `temperature=0`。优先级 **结构化注入 > 调用级 > 配置级** 由现有层序天然给出,不加新机制。
- **issue 未提但必须一并处理的四件事**: ① 采样参数进缓存 key(否则 5 个 seed 全命中同一缓存、标准差恒为 0,实验静默作废——「无缓存毒化」铁律);② 保护键黑名单 `{model, messages, stream, stream_options}` 与值可 JSON 序列化,均在构造期报错(覆盖它们会击穿流式看门狗、成本遥测与 TPM 结算;不可序列化的值会在 `CacheMW` 降级 try 之外抛裸 `TypeError`,一行遥测都没有);③ 采样参数入遥测(端口 20 → 21 字段,列名 `sampling`);④ 入参拷贝语义。
- **关键结构决策**: `ChatRequest` 增 `sampling` 快照字段作为**跨洋葱层恒定的读取点**。`request.overlay` 在 `StructuredMW` 内侧含 `response_format`、外侧不含,缓存 key 与三个遥测 emit 入口若各读各的层就会口径分叉。`sampling` 列语义定死为「调用方意图 ⊎ 生效源 `extra_body`」,**不含**结构化注入。
- **被否决备选及理由**: `chat()` 展开为 `temperature=`/`seed=` 具名参数(供应商私有参数无穷尽,等于永久追加签名,违「深模块窄接口」);配置级放装配层全局字典(采样参数与源强相关,会把无效键发给不认识它的源);overlay 不进 key 靠调用方传 `cache_salt`(把毒化防护责任推给调用方,漏传不报错——正是 issue 抱怨的失败形态);采样参数不入遥测由下游 run 快照自记(中间态数据不可追溯,且分两步要做两遍 DDL 迁移);缓存与遥测直接读 `request.overlay` 不加 `sampling` 字段(口径必分叉);`sampling` 记含 `response_format` 的完整合并结果(列名为采样参数,且数 KB schema 逐行落库无谓膨胀);给 embedding 加 `extra_body` 透传(embedding 无采样一说,装配期报错比静默无效更能指路);transport 层重复校验保护键(三入口已构造期收口,属 gold-plating)。
- **附带修正**: `providers.py` 的 `minimax`/`openai` 空 thinking profile 补后果说明(`enable_thinking=False` 对两者不产生效果,调用方以为关掉了实际没关);`_SOURCE_FIELDS` 跨 scope 共用导致 `EXTRA_BODY` 在 OCR/EMBED scope 静默无效,改为构造期**剥离 + warning**(2026-07-31 人类拍板由原「装配期 `ValueError`」改此档: 这两条路径无采样语义,不值得让下游装配起不来)。**剥离不可省**——不剥离则遥测会记录一个从未发出的参数(决策 D 的 merge 读 `source.extra_body`,而 `monkey_ocr` 只发 multipart、`embed` payload 硬编码),那是数据造假而非参数失效;在 emitter 内特判调用方身份则违「遥测调用点收敛单一 helper」铁律。
- **审查留痕**: Codex CLI 不可用(vendor 二进制缺失),改派全新上下文 subagent 两轮只读审查。首轮报 5 项必修(三个 emit 入口口径分叉、OCR/embedding 耦合、JSON 序列化缺口、注释归属写反、同步清单漏 4 处),逐条核实后全部采纳;次轮结论通过,其 5 条建议(承重不变式测试、`sampling` 类型定死、拷贝语义跟进、共用范围收窄、报错文案指路)亦已就地收进。
