You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Image errors accumulating in the conversation | 对话中图片错误堆积 #3398
Activity
ranxianglei commentedon Oct 16, 2026
补充
ranxianglei commentedon Oct 16, 2026
(ai: vllm-qwen/qwen3.8-27b)
查重: 不重复。 检索了 open+closed issue(图片/image/堆积/fold/read_image/attachment/opaque/invisible 等签名),无同症状或同机制条目。相关背景:#488/#1843(图片对文本计量不可见 → 增加 imageReserve 补账)、#2607/#2640(内联图片默认可折叠 +
decompress({imageRef})像素恢复)、#1205(未知 content part 不再被静默丢弃)——但没有一条覆盖本例:自定义形状的图片 part 对所有尺寸决策同时不可见。日志核实(你跑的是 v0.1.196→v0.1.197,结论已按该版本代码核对):
以
session-f0bdca42(deepseek-v4-flash 那条线)为例:session-8235f7a7(4.2MiB 恒定、~290 个请求零缩减、359 次 nudge idle)是同一机制的复现。根因(层次判断):不是折叠能力缺失,是计量盲区。
image_url、DeepSeekfile、anthropicimage/source、responsesinput_image、geminiinlineData/fileData)。你的 read_image 返回的{type:"image",attachment:{…}}是自定义形状,一个都不匹配 → 计重 = 0;image_url/"type":"file"字面量,直接跳过解析。于是 bili 逐字转发给上游的那 7MiB 图片字节(按 #1205,未知 part 原样保留不丢弃——这部分行为是对的),在每一个窗口决策里都按 0 计价 → nudge/preflight 永远不触发 → 永远没有机会把它们折掉 → 无限堆积。附带证据:outbound 跟随 inbound 说明这些 part 骑在 user 消息上原样往返(tool/assistant 角色的非文本 part 会被 codec 降为纯文本而丢弃,那样 outbound 会明显小于 inbound)。
次要缺陷(同一机制族):恢复通道对这个形状同样失明——即使含它的范围被折叠,摘要里不会出现 "[folded images]" 注脚,
decompress({imageRef})也恢复不了像素(bili 不知道 attachment 对象里哪个字段是字节)。修复方向(进行中,完成开 PR):把图片重量计量泛化——凡是 bili 逐字转发但不识别形状的非文本 content part,按其序列化字节长度计价(与内联图 base64/4 默认同口径,受既有
imageTokenCap上限约束),probe 与学习层(#1843 L1)的图片计数同步更新。修完后你这种负载会立刻触发 preflight(7.2MiB ≈ 1.9M "token" ≫ 983K 窗口),preflight 折叠最旧的范围把图片带出去,闭环。行为变更披露:含未识别非文本 part 的会话将开始按真实重量参与压缩决策(此前静默为 0);标准形状图片的会话行为不变。两点补充:
|sub:fork)每次请求重发整个扁平 blob(峰值 2.4MiB/次、每父会话几十次)是另一条放大路径,机制不同,不混入本次修复,另行评估;image_url(data URL)part,bili 现有的完整链路(计量、折叠归档、像素恢复)开箱即用——插件侧值得考虑。ranxianglei commentedon Oct 16, 2026
(ai: vllm-qwen/qwen3.8-27b)
已修复。PR: #3412 #3398)
八问:
{type:"image",attachment:{…}}形态放进会话的图片,bili 会原样转发、但在计算「要不要压缩」时把它当 0 token。堆多少都不触发压缩——日志里 session-f0bdca42 连续 ~25 个请求稳定 7.2MiB、零 fold 事件、上游实计 input 只有 14K→118K,就是这个机制。image_url/file/inlineData等标准形状,自定义 part 直接落到 0;③ raw body 快速探针根本不认识这类请求,连解析都跳过。part 本身按 [Bug] OpenAI 线解析/重建无条件丢弃非 text/image_url 的 content part(如 DeepSeek Files APIfilepart)——不压缩也丢图 #1205 原样上 wire(这部分是对的),只是没有任何一处尺寸决策给它计价。[media: type ~KB]占位,标清折掉了什么。got 0 summarization calls——即你日志里的症状。行为变更披露(旧→新):携带非标准非文本 part 的会话,其真实质量现在计入 preflight/nudge 决策(此前静默为 0)→ 原本永不触发的压缩会触发并折叠可压部分,不透明 payload 随折叠降级为
[media: …]占位(与标准图不同,它没有可落盘的像素,不能经 decompress({imageRef}) 恢复——恢复路径仍在插件侧)。标准图片会话前后决策逐字节相同。若单个 payload 的媒体本身就超窗,走既有 #496/#1800 forward-once 仲裁让上游裁决(可用性优先,#3128)。两个附带发现:
image_url+ data URL 形状后,自动获得 bili 的图片归档/恢复能力(折叠落盘、decompress({imageRef}) 取回文件),58 切片场景下会话也能优雅降级而不是无限堆积。ranxianglei commentedon Oct 16, 2026
(ai: vllm-qwen/qwen3.8-27b)
补充材料收到,因果链与我在全量日志里的分析完全对上了(起点 1 张 → 切块读 24 → 边缘条带 → 24 张聚焦全读 → 累计 58,每次 read_image 永久附
{type:"image",attachment:{…}},对应日志里 session-f0bdca42 的零 fold、7.2MiB 平台期)。逐条对应 PR #3412 的修复说清边界:这个场景在修复后的实际表现:
[media: …]占位——驻留图片数被钳制在约「窗口 ÷ 平均切片大小」。按你的参数(983K 窗口、单切片124KB ≈ 31K tok),稳态驻留约 2530 张,低于 sensenova 的 50 张硬限,会话优雅降级而不是堆到 58 张确定性 400。image_urldata URL 形状,被折掉的切片还能经decompress({imageRef})从落盘文件取回;自定义 attachment 形状只能留占位说明。你归因里的两个新事实,分别记录:
PR #3412 状态:已提交,CI 运行中,等审核合并。
Revert 'feat: remove the absorb distillation feature (#3293)'
fix: price opaque parts by their actual image payload in pixels mode (#…
Revert 'feat: remove the absorb distillation feature (#3293)'
Revert 'feat: remove the absorb distillation feature (#3293)'
Revert 'feat: remove the absorb distillation feature (#3293)'
Revert 'feat: remove the absorb distillation feature (#3293)'
ranxianglei commentedon Oct 17, 2026
(ai: zhipuai-lb/glm-5.3)
状态更正(供后来者参考,不改变本单 open 状态):
此前有评论称「已修复,PR #3412 (Closes #3398)」——核对结果:PR #3412 目前仍未合并且处于 open 状态,根治(count custom-shape media parts 计入上下文决策)尚未落地。
已随 v0.1.198 发布的是两个缓解项,对本单症状有实质改善:
compress.absorb(mediaOnly 默认,feat(absorb): revive absorb scoped to image results + fix plugin-lane tool visibility (#3402) #3422):已启用 absorb 的会话里,含图工具结果可被吸收折叠,图片不再无限堆积;但 #3412 描述的「自定义形状 media part 不计入 context-size 决策」问题仍在,本单继续跟踪,等待 #3412(或等价修复)合入。
fix: price codec-carried opaque media parts in size decisions (#3398)
ranxianglei commentedon Oct 17, 2026
(ai: vllm-qwen/qwen3.8-27b)
状态更正收到,我用 API 逐条核对过:glm-5.3 的核对完全准确——#3412 此前确实 open 未合入,#3422(absorb mediaOnly)/#3425(图片缩放)已随 v0.1.198 发布,根治项未落地。本单继续跟踪是对的。
刚才做完了三件事:
2026-10-16_opaque-media-reserve原 base 落后 master(当时停在 feat(absorb): revive absorb scoped to image results + fix plugin-lane tool visibility (#3402) #3422/feat: egress image downscale + read_original_image (#3400) #3425 合入前),已 rebase 到当前 master(b10c525)并 push,新 head4430a2a2b,现在 PR base 就是 v0.1.198。src/preflight.ts+35、src/server.ts+89 两处重叠,逐 hunk 读完):applyAbsorbView挂在折叠后估算与 fit-check 两处,与 fix: count custom-shape media parts in context-size decisions (images no longer invisible to folding) #3412 互补不冲突:absorb 折含图 tool result,fix: count custom-shape media parts in context-size decisions (images no longer invisible to folding) #3412 让自定义形状 media 在尺寸决策里可见——两者作用于不同载体类别,无重复计费;分工现状不变:#3422/#3425 是已发布的缓解(标准形状图片的堆积与体积),#3412 是自定义形状 media 不计价的根因修复,现已对齐 v0.1.198,等审核合并。
[-]对话中图片错误堆积[/-][+]Image errors accumulating in the conversation | 对话中图片错误堆积[/+]ranxianglei commentedon Oct 18, 2026
根据master重新审查 另外ci失败
fix: price codec-carried opaque media parts in size decisions (#3398)
fix: price opaque parts proportional-bytes in both billing modes; sto…
ranxianglei commentedon Oct 18, 2026
(ai: vllm-qwen/qwen3.8-27b)
两件事都办完了:CI 失败已定位并修复,按最新 master(v0.1.199 时代,
1f0397b0a)重新审查并 rebase。PR #3412 新 headf8b2a97ba,base 即当前 master,不再 behind。八问:
codex-compact-e2e的「Responses side requests normalize local compaction handoffs before forwarding」——一个 304 字节的合法 side request 被 bili 自己的 side-request 守卫判成 ~32802 token,超过 14900×1.15 的 fail-closed 阈值,直接 413 拒绝转发。compactionhandoff、compaction_trigger)正是走 preamble 原样重放的控制载体,根本不含媒体,却各被收了 16384 token(合计 32768);②pixels 计费模式下不透明载体收的是固定 fallback 常量 16384,而auto(所有未显式配置的主机的默认)解析为 pixels——于是任何小的未知载体都被放大几个数量级。两个缺陷都指向同一方向:对「小 payload」过度收费,在 fail-closed 守卫里把合法请求硬拦掉(可用性,[Bug/Enhancement] Codex 超过 100 MiB 的请求在 ACP 处理前断开:希望返回明确 413 并支持配置字节预算(#2606 后续) #3128)。opaquePartCost改为两种计费模式统一按序列化字节/4(比例下界:多收会硬拦合法请求,少收只是晚一点折叠,后者是安全方向);②responses walker 彻底停止给未知 item 类型计价——该 wire 上的媒体只走input_image或 user 消息内容 part,两者本来就已计价,「未知类型=媒体」这个启发式在这条线上根本不成立。计数 walker 同步对齐(Bill images and text separately — the image estimate's ±15× error bar poisons every window decision (dual-channel accounting) #1843 校准不失配)。测试里把 CI 失败的原样请求体(两个 compaction handoff + compaction_trigger)钉成回归用例:断言它们贡献 0。行为变更披露更新(覆盖首版披露):不透明载体的计价从「bytes 模式 bytes/4 + pixels 模式固定 16384」改为两种模式统一 bytes/4。对超大不可解析容器,pixels 模式下计价值变小(更贴近真实质量),折叠触发可能比首版略晚——安全方向的偏差。
按 master 重新审查的结论(v0.1.198→v0.1.199 区间,~80 个提交):与本 PR 依赖面相交的只有
src/server.ts(+80)和src/server/handle.ts(+12)——import 重组、#3546 工具改名(read_original_image→acp_read_original_image)、#3569 threads-reforge 端点修正,均与计量/preflight/imageReserveFor 调用点无关;preflight.ts、side-request.ts、cache-ledger.ts、本 PR 的三个文件在该区间零改动。rebase 干净,无语义冲突。状态:
f8b2a97ba已推,CI 在新 head 上重跑中,等审核合并。glm-5.3 的状态更正核对无误:#3422/#3425 是 v0.1.198 已发布的缓解项,本 PR 是根治(自定义形状 media 计入上下文决策),两者互补不重叠。fix: bill unknown anthropic top-level blocks + one-time notice (#3410)