前言¶
在 DeepSeek Harness(DSH)里走 OpenCode Go 调用 DeepSeek 系列模型时,上游靠 x-opencode-session 把同一会话钉在后端上,靠重复提示词前缀做 prompt cache。上下文折叠(billion-context)、系统提示词改写、历史压缩都会改写前缀,缓存随之丢失;折叠后的重建请求往往是冷的,但紧跟着的那条请求又可能立刻变热。若在请求已经发出之后才换路由,往往会多打一条无意义的冷启动。下面介绍 TLEWA 维护的 DSH 宿主插件 dsh-opencode-go-router(Cordis 内部 id 为 opencode-router):在请求发出之前预测缓存命中率,并在「判冷且最近很慢」时替换路由 id,同时用两级热路由池让前缀相近的新会话接手已有缓存的 id。
这是什么¶
dsh-opencode-go-router 是发布在 npm 上的 DSH 插件包(当前资料中的版本为 0.6.2,许可证 MIT)。它只修改 OpenCode Go 相关请求的 x-opencode-session 请求头,不是模型适配器。billion-context 可选:有折叠账本时可做折叠诊断;没有会话状态文件时,实测缓存、TTFT/吞吐统计、池替换与轮换历史仍由插件自身采样维护。
维护者与仓库:TLEWA/dsh-opencode-go-router。社区目录页:skillhub.cn 插件页。
为什么需要预测式轮换¶
OpenCode Go 用会话头绑定后端与缓存。前缀一变,该后端上的缓存就对不上新前缀。billion-context 折叠重建时,重建请求本身冷,但重建会把新前缀写进该后端缓存,下一条往往又热。
本插件的切换时机是:在一条本来就会冷的请求发出之前。钩子在 llm/stream、请求头组装之前运行,预测 <= cacheHitThresholdPct(默认 25%)且最近样本很慢时换新的 ses_... 路由 id,使新 id 作用在同一条被判冷的请求上,避免「多打一条额外冷请求」。
系统提示词改写或消息历史被压缩时,预测命中率恒为 0%,但仅「判冷」不够,还须最近请求的平均 TTFT 或吞吐达到慢请求门槛(默认 TTFT ≥ 12000 ms 或吞吐 ≤ 60 tok/s)。连续切换后仍慢于基础目标时,插件会按步进放宽下一次判定(stepTtftGraceMs、stepThroughputGraceTps),而不是重复等价切换。
只处理已配置 provider(默认 opencode-go)且模型 id 以 deepseek 开头(大小写不敏感)的请求;其他模型忽略。
核心能力¶
实测缓存与性能样本¶
插件包装合格请求的 llm/stream,读取最后一个 usage 块。单次命中率定义为 cacheReadTokens / (inputTokens + cacheReadTokens),并记录 TTFT、吞吐、提示词 token 数等;每个 DSH 会话保留最近 sampleSize(默认 5)条有效样本参与判定。
折叠账本(可选诊断)¶
若存在 billion-context 会话状态文件(路径形如 sessions/openai/<host>_<sha256(conversationId).slice(0,24)>.json),可跟踪 metadata.cacheLedger.folds。conversationId 在 DSH 中通常来自优先级更高的 x-bili-plugin-conversation;轮换 x-opencode-session 不改变该文件名。最新折叠主要作为「刚发生过重建式大冷请求」的证据,不单独直接触发轮换。插件不修改 billion-context 以外的文件。
预测与轮换条件¶
合格请求发出前,按 README 描述的顺序预测下一条命中率(含系统提示词变化、历史变短、空闲 cacheTtlMs、上次命中、大前缀 prefill 等规则)。第一个合格请求没有样本,不会因预测而轮换。
仅在预测为冷、minRotationGapMs 已过、最近普通请求模型合格、且(默认)攒满 requireFullSamples 时轮换。dryRun: true 时只记录不改请求头。
热路由 id 池¶
会话空闲入池后,前缀摘要(分块 SHA-256,不存原文)相近的新会话可借入一级或二级池中的老 ses_... id,减少冷启动。一级池要求前缀块命中率至少 poolMatchPct(默认 60%);二级借入还须满足相对会话基线的 poolSpeedGainRatio(默认 1.1)等条件。poolEnabled: false 可关闭池逻辑,行为更接近 0.6 之前「仅轮换时才创建路由」的模式。
Web 状态页¶
安装后可在 DSH Web 端口访问状态路径(README 示例:http://127.0.0.1:<DSH Web 端口>/opencode-router/status)查看实时统计与池对比信息。
环境要求¶
- DSH 版本 ≥ 0.2.1-rc.5 且 < 0.3.0(与
package.json中engines.dsh一致)。 - Node.js 20 或更新。
- 使用带
llm-pi-ai适配器的 DSH,并配置 OpenCode Go provider(默认名opencode-go),且至少有一个模型 id 以deepseek开头的 DeepSeek 系列模型。
安装与启用¶
从 npm 安装(命令须与仓库 README 一致):
dsh plugin add dsh-opencode-go-router --profile <profile>
也可在 DSH 插件管理器的「添加插件」中填写包名 dsh-opencode-go-router。包内声明了 dsh.bundle.patch,正常安装会自动创建 opencode-router 行;不要在 profile 里为它再手动加一条独立 Cordis 行,也不要在 cordis.patch.yml 里重复 insert 同一插件。
安装后若 bundle 已在宿主运行期声明,需在插件管理器中重新加载或重启 DSH。与 dsh-opencode-ip-guard 等配套注入器联用时,路由存在时本插件会替换基线 x-opencode-session;overrideExistingHeader 控制是否覆盖已有头。
典型配置¶
在 profile 的 cordis.patch.yml 中按行 id 覆盖默认值,例如调高或调低缓存命中轮换门槛:
- id: opencode-router
config:
cacheHitThresholdPct: 25
常用项(完整表格见 GitHub README)包括:
| 键 | 默认值 | 作用摘要 |
|---|---|---|
enabled |
true |
总开关 |
predictiveRotation |
true |
关闭则不做预测式切换 |
cacheHitThresholdPct |
25 |
预测命中率低于等于此值才可能轮换 |
ttftThresholdMs |
12000 |
慢请求 TTFT 基础门槛 |
throughputThresholdTps |
60 |
慢请求吞吐基础门槛 |
poolEnabled |
(见 README) | 是否启用热路由池 |
修改实现后,触碰一次插件配置或开关 profile bundle 通常即可重新加载;版本号长期不变时可重启 DSH。
适用场景与注意¶
适合谁: 已在 DSH 中通过 OpenCode Go 稳定使用 DeepSeek 系列模型,且关心 prompt cache 丢失后 TTFT/吞吐变差、希望自动换路由或跨会话复用热 session id 的开发者。
权限与安全: 插件以当前 DSH 进程权限运行,会在本地写入 statePath(默认 $DSH_HOME/storages/opencode-router/state.json)并改写出站请求头。安装前建议阅读 仓库源码 与 MIT 许可证,确认 profile 与 provider 配置符合预期。
边界: 不压缩上下文、不改系统提示词或会话日志;失败判定始终按基础 TTFT/吞吐目标,不按已放宽后的目标。声明了 purpose 的辅助请求不改变「最近一次普通会话模型」的轮换判定状态。
结尾¶
dsh-opencode-go-router 把 OpenCode Go 的路由头管理与缓存命中率预测绑在 DSH 请求链路上:在缓存注定丢失且实测变慢时,于请求发出前替换 x-opencode-session,并用两级池让相似前缀会话继承仍热的后端绑定。DeepSeek Harness 生态奉行「一切皆插件」;SkillHub 目录 与 GitHub 仓库 为独立社区信息与源码归属处,与 DeepSeek / 幻方无官方应用商店从属关系。