前言¶
DeepSeek Harness(下称 DSH)的会话会越跑越长。点开一条积累了很久的会话,常见的现象是:界面先愣几秒,接着一片白,然后整个 DSH 没了。换别的会话就正常,重装、清缓存都没用——因为卡死发生在数据已经取回来、正准备画到屏幕上的那几秒,不在网络,也不在模型。
dsh-lag-guard 就是冲着这个来的。它是社区维护者 456erddgr 写的一个客户端插件,只做一件事:让很长的会话能正常打开。下面介绍它测出的原因、它怎么修,以及装上之后你能看到什么。
先看证据:打开一个会话到底搬了多少东西¶
作者自己的会话 DSH 安装与快速启动 解压后 5.3MB,共 1087 条事件、176 条 user/assistant 消息。而 DSH 打开会话时的取数参数是写死的:
// dsh-api-session-controller/lib/client.js:2177
const HISTORY_PAGE_OPTIONS = { maxMessages: 500, turnWindow: { minMessages: 50, minTurns: 2 } };
176 条没到 500,于是「首页」就等于「全部」,一次搬进 484 条事件 / 3290.8KB,占全会话的 61.7%。其中 request/header 只有 4 条,却占了 2510.9KB、约 47.1%;单条 header.tools 里是 201 个工具的完整 JSON schema,627KB。也就是说,将近一半的传输量,是把当时所有工具的说明书全文抄了一遍,而这类事件每轮请求都会攒一份。
再叠加另外两层:
// dsh-client-ui-chat/lib/client.js:290-300
useVirtualizer({
getItemKey: (i) => items[i]?.turn ?? i,
estimateSize: () => TURN_SPACING_PX,
measureElement: () => TURN_SPACING_PX, // 动态测量被关掉了
});
虚拟化按 turn 切,而该会话只有 7 个 turn,肥瘦极不均(turn1 375 条事件 1.2MB,turn5 309 条 1.6MB),窗口里就那么几块,等于整块整块地画。
// dsh-client-ui-conversation/lib/client.js:1641
const toolsChanged = previous !== undefined && JSON.stringify(previous.tools) !== JSON.stringify(prompt.tools);
每次视图重建都要对窗口里 3 条 header、合计数百个 schema 做一次纯 JSON.stringify 比较,耗时 13.4ms,并产出 3.6MB 临时字符串。问题不在渲染次数(notifier 是 microtask 合批的),也不在 dsh-chunked-list(那只是持久化链表),而是 3.3MB 数据、不虚拟化的 turn、反复 13.4ms 序列化一起落在首帧同步路径上,主线程被占死。
它怎么修¶
Host 侧改不了,typert 注册表碰上重名会直接抛错。插件改落在浏览器侧:会话控制器的客户端包导出了 SessionEventStream,而它的 follow() 是所有历史取数的必经之路(开窗首页、断档修复、实时追加都走这一个 async generator),readPage() 走的是旁边的分页接口。插件包住这两个方法,做两件事。
1、把请求收紧。默认 maxMessages 从 500 收到 120,turnWindow 从 {50, 2} 收到 {20, 1}。取较小值,不会把手动设的更小窗口放大,也保证 minMessages <= maxMessages——不满足这个不等式会被 Host 的 validatePageRequest 整页拒成 gateway/bad-request。
2、把帧瘦身。request/header.tools 序列化后超过 20 万字符,就换成空数组,留下 toolsDropped(原来几个)和 toolsChars(原来多大);单条 tool/result 超过 128KB 就截断并标 contentTruncated(兜底,作者那个会话里 0 命中)。
同一个会话改完的对比:
| 窗口参数 | 搬入事件 | 体积 | 再丢掉 tools | 对比全量 |
|---|---|---|---|---|
| 500 / 50,2(原样) | 484 | 3290.8KB | — | 61.7% |
| 120 / 20,1(默认) | 175 | 1604.9KB | 350.5KB | −78% |
| 50 / 10,1(更猛) | 67 | 770.2KB | 143.0KB | −81% |
安装与启用¶
插件市场里搜 lag-guard(或者 卡、卡顿)就能看到,点安装即可。手动安装命令来自 README:
dsh plugin --profile desktop add github:456erddgr/dsh-lag-guard
装完要重启 DSH。重启后点开那个一直卡你的会话,控制台应该会多一行:
[lag-guard] session-77a714c5-... opened with 175 events, dropped 627KB of tool schemas in 29ms
没出现这行说明没加载上,去 profile 的 package.json 里看 dsh.profile.bundles 有没有 dsh-lag-guard。
典型用法:调窗口和看省了多少¶
想自己调参数,改 profile 的 cordis.patch.yml。注意补丁会整体替换 config,没写的键回默认值:
- id: dsh-lag-guard
config:
maxMessages: 80 # 更省,首屏更短
minMessages: 10
minTurns: 1
maxHeaderToolsChars: 50000
想临时改回来、不落盘,在渲染进程控制台里执行,立即生效:
globalThis.__DSH_LAG_GUARD__ = { maxMessages: 500, minMessages: 50, minTurns: 2, maxHeaderToolsChars: Infinity };
想量化它省了多少,跑自带的指标收集器:
node tools/sink.mjs # 本地 17891 端口收数据,写 tools/metrics.jsonl
node tools/sink.mjs --flush # 汇总:开了几次、搬了多少事件、砍了多少 KB schema、最长卡顿
数据只发到 127.0.0.1,不联网、不上报。想撤掉就把 dependencies 和 dsh.profile.bundles 里的 dsh-lag-guard 删掉,pnpm install 后重启。
会丢什么、不影响什么¶
丢的都不是正文,数据一条没删:
- 首屏历史变短,更早的内容点「加载更早」再取。
- 超大 schema 的那几次请求,Chat 里「工具集已变更」的小徽标会失效(
tools变空数组,比较结果恒为「没变」)。 - Trajectory 页签里那几条请求的「工具列表 / 工具差异」视图会是空的,同一原因。
- 单条超过 128KB 的工具输出会截断显示并标注。
不影响的:会话日志文件、Host 的分页与校验、模型上下文、工具实际执行、projections、实时流、其它会话。
验证和已知短板¶
插件自带的测试不拿 mock 骗自己:它把 DSH 真实的 dsh-api-session-controller/lib/client.js 丢进 node:vm 跑起来(只 stub 掉 window.__ModuleLoader__ 和三个依赖),再加载插件,用真实会话事件驱动 follow 和 readPage:
node test/verify.mjs --asar <path to @deepseek-ai> --session <path to session.v4.jsonl>
输出为 21 项契约全绿,包括「open request clamps maxMessages 500 -> 120」「request/header tools are dropped before publication」「a second module load does not stack wrappers」等。
几句需要说清楚的短板:
- 体积数字是精确的,手感不是。作者没做端到端帧率对比,重启后还卡不卡以你的体感为准;还卡就把
maxMessages调到 50 再试。 - 它修的是「传输 + 首帧」这一层。如果卡顿来自别处(比如某个第三方插件在会话打开时做重型工作),它最多减轻,救不了。
- 上游一改就失效。依赖的是
SessionEventStream的导出和follow/readPage的形态。哪天 DSH 改了名,install()会返回false并安静地什么都不做——不会弄崩 DSH,但也不会帮你。
README 里给出的版本信息:package.json 为 0.2.0,更新日志只写到 0.1.1 与 0.1.0。许可证 MIT。项目不修改 DSH 安装目录里的任何文件,全部逻辑在一个 253 行的文件里。
适用场景与提醒¶
适合经常打开又长又重的历史会话、且已在排查首帧卡顿的 DSH 用户。它以当前 DSH 进程权限在浏览器侧运行,装之前建议先读一遍源码与许可证,确认与你环境的兼容。
这是社区目录收录的第三方插件,由 456erddgr 维护,与 DeepSeek / 幻方无官方从属关系。目录页在 https://www.skillhub.cn/plugins/456erddgr/dsh-lag-guard,源码在 https://github.com/456erddgr/dsh-lag-guard。