前言¶
在 DSH 里跑大上下文对话时,如果宿主进程挂着 billion-context(ACP) 做代理与压缩,按理说不该再出现「一百多万 token 直接打上游」或「消息卡十五秒无首字后失败」。实际环境里常见两类现象:上游返回 prompt is too long(code 11115),或本地没有把超长请求拦住却最终 400。
根因往往不在模型本身,而在于 ACP 对「可用窗口」的估算路径不一致:有的请求带齐插件上下文头,有的走匿名链 pfa-* 或旁路 fetch,默认配置只有 20 万级窗口,再叠加升级后补丁被覆盖,超窗保险会整段失效。下面介绍社区插件 dsh-acp-window-guard(维护者 Lumid0uce,分类 admin-security),在启动时用幂等步骤抬高配置下限、重打 dsh-native.js 补丁,并在 fetch 层把模型请求钉回 ACP /bili/ 通道。
这是什么¶
dsh-acp-window-guard 是 DeepSeek Harness 的 Cordis patch 型插件(当前资料中版本 0.3.0,MIT 许可证)。它面向已使用 billion-context(ACP) 的 DSH 配置,解决三件事:
- 避免匿名或未归因请求按 ACP 默认
modelContextLimit(200000)推算窗口,导致压缩目标偏小、上游仲裁失败。 - 在
declaredWindow缺失时,让本地「可证超窗」逻辑仍有 1M token 量级兜底,超长请求在本地 422 拒掉,而不是裸发。 - 从 0.2.0 起在
globalThis.fetch上安装桥接,防止部分轮次(资料中提及手机 App 消息等场景)模型请求绕过 ACP。
插件全程 try/catch,任一步失败只记日志,不阻塞宿主启动。上游 issue #5907 与 PR #5910 修合后,作者说明可卸载本插件;届时 bundle 补丁可能与上游重叠并出现 pattern not found(不抛错)。
问题背景:窗口从哪里来¶
ACP 的「可用窗口」为 contextWindow − maxTokens。contextWindow 常见两种来源(资料中的表格归纳):
| 来源 | 数值 | 结果 |
|---|---|---|
宿主透传 x-bili-plugin-context-window |
1,000,000 − 128,000 | 约 872,000,压缩后行为正常 |
| 拿不到头(匿名链、部分子代理调用等) | 配置默认 200000 − 预留 32768 | 167,232,仍可能判超窗并触发 forwarding once for the upstream to arbitrate |
此外,bodyProvablyOverWindow 在 declaredWindow === undefined 时直接返回 undefined,本地超窗保险不生效,百万级 prompt 会原样外出。插件针对的就是「窗口算小 + 保险哑火 + 请求旁路」这一组合。
核心功能¶
启动时执行两类幂等操作(可通过 cordis.patch.yml 的 config 调整或关闭部分能力):
1. 抬高 ACP 配置里的 context 下限¶
把 ~/.config/billion-context/billion-context.json 的 modelContextLimit 抬到 minContextLimit(默认 1000000),修改前备份为 .bak-window-guard-<ts>。
2. 维护 dsh-native.js 超窗补丁¶
在 profile 内 billion-context 包的 dist/agent/dsh-native.js 中,将两处
bodyProvablyOverWindow2(body,init,effectiveContextWindow(ctx))
改为带 ??MIN_ASSUMED_WINDOW_TOKENS 的形式(兼容 bodyOverWindowDetail2 的 0.1.213 命名);上游覆盖文件后会自动重打。patchAcpCode: false 可只改配置、不动代码。
3. fetch 桥接(0.2.0+)与身份头(0.3.0)¶
- fetch bridge:对模型端点(
/chat/completions、/completions、/responses、/messages)且目标不在 ACP 的请求,改写为{ACP代理}/bili/{原始URL}。启动日志可见bridge: installed:<origin>或fetch bridge installed;fetchBridge: false可关闭。 - 0.3.0:改写时补上
x-bili-plugin、x-bili-plugin-conversation等头,减轻漏网请求被当成匿名链;日志中期望hook: on,bili.log不再频繁出现new anonymous session pfa-…。
可选的环境变量 ACP_GUARD_BASEURL=1 会改动 ~/.dsh/settings.yaml 里 provider 的 loopback baseURL,但桌面端退出时会写回配置,默认关闭;日常一般只需运行时 bridge。
安装与启用¶
资料中的安装方式是将插件目录挂进当前 DSH profile 的 node_modules,并在 package.json 里声明 link 依赖与 bundle(Windows 示例 profile 名为 desktop,macOS/Linux 换成本机 profile 目录名)。修改 package.json 前请先备份。
Windows(junction + package.json)示例:
$src = "C:\path\to\dsh-acp-window-guard"
$dst = "$env:USERPROFILE\.dsh\profiles\desktop\node_modules\dsh-acp-window-guard"
New-Item -ItemType Junction -Path $dst -Target $src
在 ~/.dsh/profiles/desktop/package.json 中:
dependencies增加:"dsh-acp-window-guard": "link:<$src 的绝对路径>"dsh.profile.bundles数组追加:"dsh-acp-window-guard"
Unix 环境将 junction 换为 ln -s 即可,路径按本机 profile 调整。
生效顺序(仅在下一次 ACP 代理启动时应用插件逻辑):
- 退出 DSH 桌面端(以便 bundle 写回 profile)。
- 结束旧 billion-context 节点进程并重新启动代理,例如 Windows:
Get-CimInstance Win32_Process -Filter "Name='node.exe'" |
Where-Object { $_.CommandLine -match 'billion-context' } |
ForEach-Object { Stop-Process -Id $_.ProcessId -Force }
Start-Sleep -Seconds 2
node "$env:USERPROFILE\.dsh\profiles\desktop\node_modules\billion-context\dist\index.js" start --host 127.0.0.1 --port 18790
- 重新打开 DSH。
运行环境要求(package.json):Node ^22.19.0 || >=24.0.0。
验证方式¶
查看 ACP 日志 ~/.local/state/billion-context/bili.log:
- 匿名链窗口应从约 167232 变为约 967232(1,000,000 − 32,768);有归因会话仍约 872000。
- 被本地拦下的裸发请求:HTTP 422,响应头
x-bili-gate: oversize-refusal-unattributed。
资料还给出了直连代理与 /bili/ 重写通道的 curl 对照(非 /bili/ POST 得 403,/bili/http://… 形式得 200),用于确认代理只接受改写通道。
不想装插件时,仓库内脚本可手工等价执行(幂等):
- Windows:
pwsh scripts/reapply-acp-window-patch.ps1(-CheckOnly只查不改) - macOS / Linux:
bash scripts/reapply-acp-window-patch.sh(--check只查不改)
配置项¶
cordis.patch.yml 内 config 常用字段:
| 键 | 默认 | 说明 |
|---|---|---|
minContextLimit |
1000000 |
期望的最小 modelContextLimit |
patchAcpCode |
true |
是否维护 dsh-native.js 补丁 |
dryRun |
false |
只报告,不写盘 |
configFile |
自动 | 覆盖 ACP 配置路径(亦认 BILI_CONFIG_FILE / XDG_CONFIG_HOME) |
acpBundlePath |
自动 | 覆盖 dsh-native.js 路径 |
fetchBridge |
默认开启 | 设为 false 关闭 fetch 兜底 |
回滚¶
从 .bak-window-guard-* 恢复 billion-context.json 与 dsh-native.js 即可;或设置 patchAcpCode: false 停止改代码。资料中含 PowerShell 的 Copy-Item 回滚示例,路径需按本机 profile 下的 billion-context 包位置替换。
适用场景与注意¶
适合谁: 已在 DSH profile 中启用 billion-context,并出现超长 prompt 报错、匿名会话窗口异常偏小,或日志显示部分轮次完全未经 ACP 的开发者。
权限与安全: 插件以当前 DSH 进程权限运行,会修改用户目录下的 ACP 配置与(可选)node_modules 内 JS 文件。安装前应阅读 GitHub 仓库 源码与 MIT 许可证,确认可接受对 ACP 的二进制邻近补丁策略。社区插件目录 SkillHub 条目 与 GitHub 无 DeepSeek / 幻方官方从属关系,属社区「一切皆插件」生态。
版本提示: 0.2.1 起兼容 billion-context 0.1.213 的 bodyOverWindowDetail2 命名;命令输出中的 shape 字段可确认命中哪一版补丁逻辑。
结尾¶
经过上面的步骤,dsh-acp-window-guard 把 ACP 的窗口下限、本地超窗拒发和 fetch 通道路由收成启动期可重复的护栏,专门针对匿名窗口与旁路请求两类长期痛点。上游 billion-context 合入正式修复并升级后,可按 README 建议卸掉插件,仅保留无害的配置抬高亦可。
- 社区目录:https://www.skillhub.cn/plugins/Lumid0uce/dsh-acp-window-guard
- 源码与说明:https://github.com/Lumid0uce/dsh-acp-window-guard