# D15 辅助思考是 llm/stream 上的独立可选旁路 ## 背景 DeepSeek 官方路由的主循环会把模型产出的思考块原样带进后续请求,于是同一份思考会跟着整条对话被反复重放。文本在交给宿主之前就已经在插件手里,改写它看起来是个顺手的位置。 代价是改写**有损**。写坏一份思考,主循环丢的是它下一步的判断依据;写坏一次回放,端点可能不认这段文本。所以这个能力的第一性要求不是"改得好",而是**改不动就不改**。 本次实现还依赖一个用户提供的端点事实:重写后的文本沿用既有的回放与签名形状,端点接受这种形状。本仓库不复验线上签名——测试不发起真实网络请求,签名是否被接受只有端点能回答。 ## 决定 独立可选模块,默认关闭。生效范围**只**由 `iotThinkingTargets` 决定:列表命中的主 provider/model 才生效,主 model 留空表示该 provider 的全部模型,列表为空则一条请求都不改写。没有任何供应商被内建豁免——`deepseek-official` 也不例外。未启用的请求整个穿过,不解析、不改写、不发起辅助调用。 档位(`off` / `compact` / `balanced` / `full`)只决定压缩强度,不参与"对谁生效"的判定;辅助线路在未显式配置时**跟随生效线路自身**(主请求的 provider 与 model 加 `low` 强度)。 不为 `deepseek-official` 保留默认豁免的原因是一条路由的凭据前提不能外溢:该路由只认 API Key,而 `deepseek-account` 只认账号登录,账号登录不构成官方路由的凭据。默认豁免会让"加了一条账号线路"的用户每个思考块都发起一次注定 `MISSING_CREDENTIAL` 的辅助调用——面板显示开启,实际一次都没改写。收紧为用户显式列出线路,是让"开了"等于"在做"的唯一写法。 本模块**不读**插件总开关 `enabled`(「启用 Verifier 工具」)。两者接在同一个开关上时,只想关裁判工具的人会连辅助思考一起关掉:面板上档位与线路都配好了,实际一条请求都不改写,而且没有任何报错。档位 `off` 是这个功能唯一的关闭方式。 三档强度 `compact` / `balanced` / `full`,固定三种,不接受自定义提示词。 全局设置走既有的设置系统,持久化。没有 `/iot` 命令或会话覆盖:所有会话都读取同一个全局档位,不存在命令状态可能隐式覆盖配置的问题。 机制: - 每个符合条件的思考块**一次**辅助调用。辅助线路按 `逐条覆盖 → 全局设置 → 主请求自身` 解算:`iotThinkingProvider` / `iotThinkingModel` / `iotThinkingEffort` 是全局设置(供应商留空 = 跟随线路),每条线路还可带 `rewriteProvider` / `rewriteModel` / `rewriteEffort` 覆盖它。强度最终默认 `low`。 - 指定了辅助模型却没有供应商(全局或逐条)是配置错误:`resolveConfig` 抛错,设置面板在保存前拦下。供应商一旦是动态的,"模型"就没有可归属的供应商,静默忽略等于让面板显示一个不会生效的值。 - 辅助调用不携带主会话的 `sessionId`、不挂任何工具,超时 60 秒;通过 `dsh-compaction-basic` 加载 `compaction` 用途声明,保留端点的 compact 请求元数据。 - **失败即放行**:超时、报错、返回空、格式不合、内容被截断——一律按原样回放原始流。不改写、不重试、不向主循环抛错。 - 复用**已经存在的唯一一个** `llm/stream` 钩子,内部顺序固定为思考重写 → 过程选优([D9](D9-process-selection.md))。不新增第二个钩子:两个旁路挂在同一处,顺序才是可读的;挂两处就是把顺序交给宿主。 - 不介入评分、门控与缓存身份:不动判官判决,不动 [D3](D3-fail-closed.md) / [D5](D5-three-budgets.md) / [D6](D6-acceptance-baseline.md) 的任何判定,不改 [D13](D13-cache-identity.md) 的 `version`。 ## 后果 - 默认关闭:不开就一个请求字节都不会变。开启后若线路列表为空,效果与关闭相同,面板会明确提示"辅助思考不会作用于任何请求"。 - 这是一次**收紧**:升级后没有线路的配置立即不再改写思考块,不提供迁移,不自动补 `deepseek-official` 线路。补一条隐式线路等于把被移除的默认换个地方保留。 - 评审工具与辅助思考互不牵连:关掉评审工具不会静默停掉改写,反之亦然。判定只看档位与生效线路这两项。 - 每个合格思考块多一次辅助调用。这笔开销与它换回的上下文占用**不是同一本账**,净收益必须由真实任务对照评估,不能由模块存在推导出来。 - 指标是进程内内存态,重载即清零;全局辅助模型与生效线路经既有设置系统持久化。会话覆盖已随 `/iot` 一并删除。 - 签名前提没有被本仓库实测覆盖。若它不成立,现象会出现在主循环的下一次请求上,而 [D3](D3-fail-closed.md) 的失败即抛出保护的是判决解析,不是这条旁路。 - **没有**自定义预设:三档是固定的,不允许用户自拟改写提示词。一条 fail-open 的旁路如果接受自由文本,它的行为就没法被回归测试钉住。 - **不**归档原始 CoT:改写前后的思考都不落盘,话题侧车目录([D14](D14-sidecar-and-artifacts.md))不因此多出文件。 - **不**做真实网络测试:签名与端点接受度没有任何自动化证据。 - **不**承诺节省缓存:命中率由端点与请求前缀决定;本模块只改文本,不改缓存身份,也就不能声称省下了什么。