前言¶
在 DeepSeek Harness(DSH)里跑带截图、识图的多轮智能体时,每次模型请求都会带上完整会话历史;历史里的每一张图都会在请求体里重新编码。对话轮次一多,请求体体积会持续增长,直到超过上游网关的单次请求体上限。以 README 中提到的 agent2api 为例,其上限为 16 MiB:一旦累积图片把请求撑过这条线,网关会以不可重试的 INVALID_REQUEST(例如 HTTP 413)拒绝请求,会话后续再也无法完成一次正常调用;Harness 适配器侧默认的图片预算(20 MiB)往往不会先触发,问题会直接卡在网关层。
下面介绍社区插件 dsh-image-size-guard(维护者 qq744287383,GitHub:qq744287383/dsh-image-size-guard)。它在请求即将超限时,用占位文本批量替换会话里最旧的历史图片,把请求体一次性压到上限以下的低水位,并在设计上尽量降低对 provider 前缀 prompt cache 的反复击穿。插件在 SkillHub 目录中归类为「模型推理」。
这是什么¶
dsh-image-size-guard 是 DeepSeek Harness 插件(npm 包名 dsh-image-size-guard,当前资料中版本 1.2.0,MIT 许可证,要求 Node >=22)。一句话定位:按每个 provider 配置的请求体上限,在超预算前测量真实请求体,批量「退休」最旧的历史图片 occurrence,用占位内容代替,并通过终止当前尝试、让 agent 循环重试的方式,使下一次从会话表面重建的请求体真正变小。
插件主要面向 README 描述的 agent2api 网关 16 MiB 请求体限制场景;配置面板支持为 LLM registry 里出现的任意 provider 路由名单独设限与开关。
核心功能¶
超限时做什么¶
当某次发往已启用 guard 的 provider 的请求会超过预算时,插件会:
- 测量请求体大小,并使用适配器缓存的 request-image 版本,保证统计的是实际会发送的图片字节;
- 计算需要替换多少处「最旧的图片 occurrence」:一次批量退休足够多,使请求体落在上限以下的目标低水位(结合近期每轮增长估算),并默认保留最近若干轮里的图片;
- 以终端失败结束本次尝试,由 agent 循环重试;
- 重试从会话表面重建请求,此时 omission 已写入会话,下一次测量对应更小的 body。
已经能放进预算的请求不会被裁剪,即使当前体积仍高于低水位线。
为何批量替换,而不是每次只删一张¶
README 说明:每省略一张旧消息里的图都会改写历史;provider 的前缀 cache 匹配最长公共前缀,从该图起往后的 cache 都会失效。若每轮只删一张,很容易下一轮再次顶到上限,并每轮付出完整 re-prefill。批量退休则在相同总删除量下,把 cache 失效成本摊到更少次数上。README 在 10 MiB 上限、每轮约 1 MiB 截图的示例中对比了「最小策略」与批量策略的行为差异。
决定批量大小的三个主要参数(可在 YAML 与设置页配置):
targetTurns(默认5):一次删除期望换来多少轮的增长空间;minFillPercent(默认40):批量后请求体占预算的最低比例下限;protectedTurns(默认2):最新若干轮图片默认不参与批量退休,除非不删就会超限。
另有 growthWindow(默认 8)用于采样近期轮次以估计每轮增长。将 targetTurns 设为 0 会关闭批量策略,回到「最小删除」行为。
预算怎么算¶
实际对照的上限为 maxRequestBytes - reserveBytes。reserveBytes 用于在 JSON body 估算之外留出余量,因为 provider 信封或 HTTP 头在该 seam 不可见。
两条执行路径¶
图片 omission 会写成持久的 image/offload 记录。启动时插件根据是否挂载 executor 选择路径:
| 挂载的 executor | 谁写记录 | 结束尝试时的信号 |
|---|---|---|
@deepseek-ai/dsh-compaction-image-offload |
官方 executor | IMAGE_OFFLOAD_REQUIRED |
| 无 | 本插件自身 | REQUEST_TOO_LARGE |
有官方 executor 时,插件只发出带 IMAGE_OFFLOAD_REQUIRED 与正数 offloadImages 的 finish chunk,由 executor 写记录并返回重试动作;无 executor 时插件自行写记录并用 REQUEST_TOO_LARGE 重试。README 强调:信号是 yield 出来的,不是 throw(后文截断处起仍属同一设计说明)。
插件 bundle 会向 Harness 注入 Host 行与 Settings 客户端模块(dsh.client 平台为 web)。
安装与启用¶
官方 README 给出的安装方式如下。资料注明尚未发布到 npm 时,可用本地 clone 路径安装(安装前请自行审阅源码与 MIT 许可证;插件以当前 dsh 进程权限运行)。
从 registry 名称安装(README 原文):
dsh plugin --profile web add dsh-image-size-guard
尚未在 npm 上时,从 clone 目录安装:
git clone https://github.com/qq744287383/dsh-image-size-guard
dsh plugin --profile web add ./dsh-image-size-guard
bundle 首次安装后会插入 Host 行与 Settings 页。首次安装后需重启 Harness 一次,以便浏览器加载新的 client 模块。
典型用法¶
图形设置¶
打开 Settings → Image size guard。页面按 provider 一行一条,支持增删改与启用/禁用。右侧开关只保存 enabled 变更,无需重填限额;关闭后该 provider 请求原样透传,行会变暗。开关为 role="switch",支持键盘与读屏。
各字段按界面单位编辑,保存时写入精确字节;默认行示例为 Request limit 16 MiB、Reserve 256 KiB、Placeholder 512 bytes。页面还会列出 registry 中尚未配置行的 provider,便于一键添加。
保存通过 configEditor.edit 写入 profile patch,由插件自带 Config 校验并协调 Loader,无需重启 Harness 即可生效。面板请求 POST /image-size-guard/limits,经 Host 的 connection.admit 做与其他 API 一致的校验。
| 字段 | 含义 |
|---|---|
| Provider | Provider 路由名,如 agent2api |
| Request limit (MiB) | 该 provider 允许的最大请求体,可小数(如 10.5) |
| Reserve (KiB) | 上限以下保留的空档 |
| Placeholder size (bytes) | 每张被省略图片占位块估算占用字节 |
| Enabled | 是否对该 provider 启用 guard |
文件配置示例¶
与设置页等价的 YAML 片段(README 原文):
- insert:
- id: image-size-guard
name: 'dsh-image-size-guard'
config:
providers:
- provider: agent2api
maxRequestBytes: 16777216
reserveBytes: 262144
placeholderBytes: 512
targetTurns: 5
minFillPercent: 40
protectedTurns: 2
growthWindow: 8
enabled: true
| Key | 默认 | 含义 |
|---|---|---|
providers |
含一行 agent2api |
各 provider 限额行;省略则用默认,显式空列表表示不 guard 任何 provider |
providers[].provider |
— | Provider 路由名 |
providers[].maxRequestBytes |
16777216(16 MiB) |
网关请求体上限 |
providers[].reserveBytes |
262144(256 KiB) |
上限以下保留字节 |
providers[].placeholderBytes |
512 |
单张占位块假设字节 |
providers[].targetTurns |
5 |
一次批量期望支撑的轮数;0 关闭批量 |
providers[].minFillPercent |
40 |
批量后占预算的最低百分比 |
providers[].protectedTurns |
2 |
最新若干轮图片受保护;0 不保护 |
providers[].growthWindow |
8 |
估计每轮增长的采样窗口 |
providers[].enabled |
true |
是否启用 |
删除全部行是允许的,表示不对任何 provider 做 guard。
适用场景与注意¶
适合谁: 在 DSH Web profile 下、经 agent2api 等带严格请求体上限的网关做多轮识图/截图对话的开发者;需要在不手动清会话的前提下,自动把历史图片「 offload」为占位文本、避免会话永久 413 的场景。
注意:
- 插件会改写会话历史中较旧消息里的图片呈现方式;被替换的图片以占位文本形式留在上下文中,模型不再看到原图像字节。
- 批量策略是在「少次 cache 失效」与「一次删更多旧图」之间的权衡;若与
@deepseek-ai/dsh-compaction-image-offload同 profile 共存,优先走 executor 统一写image/offload的路径。 - DSH 生态强调「一切皆插件」;SkillHub 目录(https://www.skillhub.cn/plugins/qq744287383/dsh-image-size-guard)是社区索引,与 DeepSeek / 幻方无官方从属关系。安装第三方 bundle 前请阅读仓库源码与许可证,并确认与本地 Harness 版本、Node 版本(>=22)匹配。
结尾¶
dsh-image-size-guard 解决的是长对话里图片反复进请求体、最终撞上网关请求体上限后会话无法继续的问题:测量真实 body、批量省略最旧历史图片、借重试让下一轮请求真正变小,并在参数上控制低水位与 prompt cache 行为。
- 目录页:https://www.skillhub.cn/plugins/qq744287383/dsh-image-size-guard
- 源码与 README:https://github.com/qq744287383/dsh-image-size-guard