补上图片 token 计量,让超大图片移出请求,避免撑爆上下文
29.9/100
综合分
0
GitHub 星标
—
npm 周下载
—/5
用户评分
数据截至 2026/11/3 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add ender-candle/dsh-llm-pi-ai-image-offload该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)
状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:仅索引
是什么
dsh 原生插件 · vision
装得上吗
本站尚未做安装检查
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 3 天前
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码v2.7.0🟢 扫描:未发现敏感能力尚无人工评估展开查看扫描说明与证据 ↓
安全扫描自动 · 静态分析源码
v2.7.0静态扫描未发现敏感能力:最多只发网络请求、读取自身元数据或只读文件,未发现执行命令、文件写入或敏感信息读取。
扫描于 2026/11/4(0 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库
静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
修复 DSH pi-ai 路由的图片卸载问题:补回缺失的 imageRequestPricing,让超大 base64 图片不再占用上下文窗口。
README
由 DeepSeek 最新模型翻译生成dsh-llm-pi-ai-image-offload
给「不声明图片计价的适配器路由」补上 request-image token 计量。实践中,就是所有由 @deepseek-ai/dsh-llm-pi-ai 服务的路由。
为什么叫 image-offload 而不是 pricing
这个包按它恢复的能力命名,而不是按它补的方法命名。
被补的方法是 imageRequestPricing,它的职责是把一张图折算成 token 数,好让预算检查能拿它跟 maxInlineTokens 比,把放不下的内容挪出请求。
这里的 "pricing" 指 token 计量,不是计费。
补上 imageRequestPricing → 图片有了 token 价 → spill-policy 才能判断「这张图太大放不下」→ 触发 image offload。名字取的是终点,不是起点。
它修的是什么问题
LlmAdapter.imageRequestPricing() 基类默认返回 undefined,含义是「本路由不声明
图片计价」。整包里只有 dsh-llm-deepseek 覆盖了它,dsh-llm-pi-ai 没有。
展开完整文档(README 剩余 1 节)
dsh-llm-pi-ai-image-offload
给「不声明图片计价的适配器路由」补上 request-image token 计量。实践中,就是所有由 @deepseek-ai/dsh-llm-pi-ai 服务的路由。
为什么叫 image-offload 而不是 pricing
这个包按它恢复的能力命名,而不是按它补的方法命名。
被补的方法是 imageRequestPricing,它的职责是把一张图折算成 token 数,好让预算检查能拿它跟 maxInlineTokens 比,把放不下的内容挪出请求。
这里的 "pricing" 指 token 计量,不是计费。
补上 imageRequestPricing → 图片有了 token 价 → spill-policy 才能判断「这张图太大放不下」→ 触发 image offload。名字取的是终点,不是起点。
它修的是什么问题
LlmAdapter.imageRequestPricing() 基类默认返回 undefined,含义是「本路由不声明
图片计价」。整包里只有 dsh-llm-deepseek 覆盖了它,dsh-llm-pi-ai 没有。
@deepseek-ai/dsh-spill-policy 只要遇到带图的工具结果,就会去要这个计算器:
const calculator = ctx.get("llm")?.imageRequestPricing(provider, model);
if (calculator === undefined) throw new Error("the current model has no image token calculator");
这个 throw 被 spill-policy 自己的外层 try 捕获,记一条 spill-policy: ...; keeping the inline content 的 warn,然后 直接 return,什么也不改。
结果就是:整个工具结果原样内联。几 MB 的 base64 图片一字不差地发给 provider,把上下文窗口吃掉。
@deepseek-ai/dsh-token-meter 受同样影响,退化成固定结构估算,而不是按实际发送的字节计价。
实测症状
一张 2048×2048、1,266,320 字节的 JPEG,base64 后约 169 万字符,约 42 万 token。
如果上下文窗口是 262,144,单个工具结果就能直接打爆——表现为 CONTEXT_WINDOW_EXCEEDED。
这个插件做了什么
它给实例上补 imageRequestPricing,只补那些不返回计价的实例,并在每次 llm/adapters-updated 事件时重新应用。
三条自我约束:
- 已有真实实现的不碰。上游一旦自己实现,这个补丁自动退场。
- 实现会抛异常的不替换。抛异常说明有真实现,不能覆盖。
- 零运行时依赖。因此不存在加载期解析不到宿主包的风险。描述文本用到的两个 helper 是照官方实现逐字节复刻的,集成测试会对着真实的 @deepseek-ai/dsh-llm 断言两者完全相等。
计价模型
这些路由不公布 vision token 的账法,所以按实际传输的字节计价:
transmitted = min(attachment.bytes, imageRequestTarget(...).maxBytes)
visualTokens = ceil(base64Length(transmitted) / charsPerToken)
其中 base64Length(b) = ceil(b / 3) * 4,与平台自己的字节账法一致。
关键点:这跟 spill-policy 拿来比 maxInlineTokens 的是同一个单位,所以才能真的触发「把过大的图挪出去」。
前述那台机器上的案例:2048×2048 / 1,266,320 字节、路由请求预算 1 MiB,算下来是
base64(1048576) / 4 = 349,526 token,远高于默认的 maxInlineTokens: 12500。
配置
全部可选。
| 字段 | 默认值 | 含义 |
| enabled | true | 完全关闭此补丁 |
| charsPerToken | 4 | 每个 token 对应多少 base64 字符 |
| maxVisualTokens | 400000 | 单次出现(occurrence)的上限 |
| providers | (全部) | provider 路由 id 白名单 |
| debug | false | 把每条被打补丁的路由写进 logger |
配置示例(写进 profile 的 patch):
- id: llm-pi-ai-image-offload
name: dsh-llm-pi-ai-image-offload
config:
debug: true
移出请求之后,模型还能看到图吗
能。offload 不等于删除:
- 不会从会话里删掉图片块
- 不会动工作区里的原图文件
- 模型收到的是 spill-policy 的通知,外加一个可以再用 read_image 读回来的路径
所以图是可恢复的,不是丢失的。
如何确认它生效了
别去看日志。 平台 logger 只有内存环形缓冲(1000 条),没有文件 sink,重启即丢,事后翻不到那条 warn。
可行的验证方式:
1. 配置里开 debug: true
2. 生成一张大图
3. 查会话日志(session.v4.jsonl.zstd)里有没有 image/offload 事件
改动之前,这个信号从没出现过(本机 40 个会话里 0 次),比看 warn 可靠。
安装
从 GitHub 安装(推荐)
dsh plugin --profile <profile> add github:ender-candle/dsh-llm-pi-ai-image-offload
固定到某个 commit 更稳(可复现):
dsh plugin --profile <profile> add github:ender-candle/dsh-llm-pi-ai-image-offload#<sha>
从本地目录安装
dsh plugin --profile <profile> add /插件目录的绝对路径/dsh-llm-pi-ai-image-offload
然后激活 bundle
以上两种方式都会把包装进 profile 的 node_modules。接着把包名加进 profile package.json 的 dsh.profile.bundles:
{
"dsh": {
"profile": {
"bundles": ["...", "dsh-llm-pi-ai-image-offload"]
}
}
}
bundle 自带的 cordis.patch.yml 会插入 host 行,不需要手改 patch。
之后重启 harness——bundle 只在启动时加载。
dsh plugin add 会同时写 package.json 和 pnpm-lock.yaml,
所以安装状态与 profile 的包管理器一致,不会出现 lockfile 与清单不匹配的问题。
测试
node test/offload.test.mjs # 18 项单测,无需安装任何依赖
插件零运行时依赖,所以单测在任何机器上都能直接跑。
另有一份不随包发布的集成测试:它从 app.asar 里提取真实的宿主模块,断言本插件产出的描述文本与官方 requestImageHandleText / offloadedImageText 逐字节相同。
风险
- LlmAdapter 的实例字段不是官方扩展点。 如果日后 registry 结构变了,这个补丁会静默失效——这是刻意设计:不生效就等于回到打补丁前的行为,不会变得更糟。
- 估算偏保守。 对上游按 vision token 计价的路由会高估。这是有意的:只会更早触发移出请求,不会更晚。provider 返回的 usage 仍然是权威账本。
- 这不是根治。 真正的修法是让 pi-ai 自己实现 imageRequestPricing。
那一天到来时,本插件会自动退场。
兼容性
- 三种 wire 协议已实测表现一致:openai-completions、openai-responses、 anthropic-messages。换 api: 不需要重打补丁——三个协议共用同一个 PiAiAdapter 实例,且图片预算(requestImagePixelBudget / requestImageMaxBytes)是 provider 级字段,与协议无关。
- 前提是模型声明了 input: [text, image]。否则图片在更早阶段就被换成文字占位, spill-policy 根本不会看到它。
- 插件只保证本地不把超大 base64 塞进上下文,不会让不支持视觉的上游网关突然支持图片。上游能否收图是另一回事。预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
ender-candle/dsh-llm-pi-ai-image-offload
补上图片 token 计量,让超大图片移出请求,避免撑爆上下文
相关插件 · 视觉能力
智能体工作台Devin-AXIS/iPolloWork
企业级、本地优先的智能体工作台,面向个人和智能体团队——一个工作区,容纳多个智能体引擎;一套统一体系,管理插件和技能;支…
★ 7,364已汉化DSH
72
开源设计工作台nexu-io/open-design
OpenDesign:首个协作式 AI 设计智能体工作区
★ 105,709已汉化DSH
71.8
GPT 图像提示词库freestylefly/awesome-gpt-image-2
Prompt as Code | GPT Image 2 / 2.5 提示词与案例库,530+ 个案例、20+…
★ 34,534已汉化DSH
71.5
多智能体编码工作区spacering-net/codeg
多智能体协作的 AI 编程工作区:汇总 Claude Code、Codex、OpenCode、Pi、Grok Build 等来源的会话。支持桌面应用、自托管服务器或 Docker。
★ 4,319已汉化DSH
71.5
AI 用量桌面小部件Javis603/token-monitor
EN | 简 | 繁 | KO | JA | PT
★ 3,533已汉化DSH
71.1
架构图生成器tt-a1i/archify
把你想理解、规划或分享的事,变成可以互动的可视化作品。
★ 93,105已汉化DSH
71.1
这是你的仓库?认领条目