Skip to content

Historical thinking message wire formats drift as the metadata table is refreshed, leading to downstream compaction ledger mismatches (normalize the thinking format at request time). | 历史思考消息的 wire 形态随元数据表刷新漂移,下游压缩账本失配(请求时归一化思考形态) #482

Description

@ranxianglei

来源: ranxianglei/billion-context#3301 分析 元数据刷新后 fold re-anchor 失配 时发现

现象

  • 同一会话、同一模型,宿主读取的模型元数据表刷新一次后,带思考的历史 assistant 消息在 wire 上换了序列化形态(思考从独立字段并入正文),按内容哈希计算的消息 id 全部失效。
  • 下游 billion-context 的压缩账本认不回已折叠内容:原文重新上线 → 上下文膨胀 → 再压一遍;长会话反复发生(实测旗舰会话 986 条失配 ≈ 2×带思考消息数)。

机制

  • 宿主按【当前】元数据表决定思考放哪个字段(v1 capabilities.interleaved),这个选择不随消息存储;每次请求现算。
  • 插件 messages.transform 是交给宿主序列化之前最后一个可控边界——在边界上把形态钉死,输出就对元数据表/版本/provider 配置字节确定。

建议修法

在 transform 管线加一步归一化(建议紧随 #368 的 compress.reasoning 裁剪之后):对 assistant 消息,把 reasoning part 合并进 text part,采用固定标记形态 <thinking>\n{全部R拼接}\n</thinking>\n{全部T拼接}:

  • 该标记是 billion-context kernel demoted-thinking FORMS 之一,kernel 会在 minting 前还原为拆分形态 → 归一化后的 wire 与拆分形态 mint 出【完全相同】的 id,存量账本零别名精确对齐;
  • 多个 reasoning/text part 的消息:R 全拼、T 全拼(与宿主 lowerAssistantMessage 的 join 语义一致);tool/file 等其它 part 原位保留;
  • 幂等:归一化后消息不再携带 reasoning part,第二次运行零改动 → 前缀缓存稳定(只变一次);
  • 无状态写入、确定性变换。

影响面与已知边界

  • 上游模型看到的历史思考从独立字段变为正文里的带标记文本。openai-compat/litellm lane(reasoning 字段大多被中转丢弃)实际影响小;
  • 已知边界:直连需要结构化 thinking 回放语义的 provider(Anthropic 原生 thinking block / Gemini thoughtSignature)会失去结构化字段——此类 lane 需单独评估(可后续加开关)。

关联

查重: 无(仓库内检索 reasoning 相关 issue 均为 #368 裁剪类,与本项「形态钉死」机制不同)。

Activity

  1. ranxianglei commented on Oct 16, 2026

    @ranxianglei
    OwnerAuthor

    🤖 Powered by ework · qwen3.8-27b

    查重:不重复。 仓库内检索 reasoning 相关 issue 均为 #368(裁剪类),与本项「形态钉死」机制不同;billion-context 侧 #3301/#3316 属上游/账本侧,不在本仓库范围。

    已实现并开 PR:**https://github.com/ranxianglei/opencode-acp/pull/484**(Closes #482)

    ⚠️ 行为变更(请重点确认):本修复默认开启——历史 assistant 消息的思考从 wire 上的独立字段,变为正文里带 <thinking> 标记的文本。

    • 旧值:独立字段,序列化位置随宿主【每次请求现算】的元数据表漂移;
    • 新值:固定带标记文本,字节对元数据表 / 版本 / provider 配置确定;
    • 逃生开关:compress.reasoning.normalize: false 恢复旧形态(供需要结构化 thinking 回放的直连 lane,如 Anthropic 原生 / Gemini thoughtSignature)。

    按八问:

    1. 是什么问题:同一会话同一模型,宿主元数据表刷新一次后,带思考的历史 assistant 消息在 wire 上换了序列化形态,按内容哈希算的消息 id 全失效 → 下游 billion-context 压缩账本认不回已折叠内容 → 原文重新上线 → 上下文膨胀 → 反复重压。
    2. 什么原因导致的:宿主按【当前】元数据表决定思考放哪个字段(v1 capabilities.interleaved),这个选择不随消息存储、每次请求现算 → 历史消息 wire 形态不稳定。插件 messages.transform 是交给宿主序列化前最后一个可控边界,此前没在这里钉死形态。
    3. 影响范围与严重程度:所有带思考的历史 assistant 消息 + 会话经历过元数据表刷新的场景;表现为长会话反复膨胀、重复压缩(旗舰会话实测 986 条失配 ≈ 2×带思考消息数)。属「特定条件下有实质性能/成本问题」,非完全不可用;openai-compat/litellm lane(reasoning 多被中转丢弃)实际影响小。
    4. 怎么修复的:在 transform 管线 Protected-message exemption inflates the incompressible context floor: per-compression reasoning is never reclaimable (~83.5% of measured residual) #368 裁剪之后加一步归一化——把每个 assistant 消息的所有 reasoning part 合并进一个 text part,固定形态 <thinking>\n{R}\n</thinking>\n{T};R/T 用空串拼接以对齐宿主 .join(""),kernel 在 minting 前还原拆分形态时 mint 出完全相同的 id → 存量账本零别名精确对齐。幂等、无状态、确定性变换。
    5. 是否有回归问题:审过既有行为——Protected-message exemption inflates the incompressible context floor: per-compression reasoning is never reclaimable (~83.5% of measured residual) #368 drop gate 逻辑不变(4 个相关 e2e keep-case 用 normalize:false 隔离继续只验证裁剪);持久化状态格式与内部 dcp tag 未动;支持图片压缩,参考billion-context的对图片支持原理 #478 image-archive 管线步骤不受影响(其 e2e 全绿)。定向套件 151 pass + typecheck + build 通过。唯一有意变更即上面标注的默认开启项。
    6. 是否破坏缓存:不破坏,反而改善——归一化幂等(只变一次),稳定后 wire 字节确定,利于前缀缓存;未触碰去重键 / 增量游标。
    7. 是否改了设计方向:否。只在既有 transform 管线加一步确定性变换,复用现有 feat: per-model growth-nudge floor (modelMinNudgeLimits) for mixed-context installs #344 配置级联;架构 / 边界 / 数据流未转向。
    8. 是否引入新配置:是。新增 compress.reasoning.normalize(布尔),默认开启(消费端判 !== false),支持 provider/model 级覆盖(设 false 关闭某 lane);无迁移成本,不设置即默认生效。

    判定:功能完整、测试到位、行为变更已显式披露并留逃生开关,可进入 review/合并(合并按仓库规则由人工执行)。若你倾向默认关闭、仅按需开启,告诉我即可一行翻转。

  2. changed the title [-]历史思考消息的 wire 形态随元数据表刷新漂移,下游压缩账本失配(请求时归一化思考形态)[/-] [+]Historical thinking message wire formats drift as the metadata table is refreshed, leading to downstream compaction ledger mismatches (normalize the thinking format at request time). | 历史思考消息的 wire 形态随元数据表刷新漂移,下游压缩账本失配(请求时归一化思考形态)[/+] on Oct 16, 2026
  3. added a commit that references this issue on Oct 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions