Skip to content

复盘:单条 toolResult + 45% 估算低估 → 死循环 400(no body)——五层失效链与修复 #204

Description

@ranxianglei

事故复盘:2026-08-23 会话 01a02d90 死循环(五层失效链 + 验尸数据)

会话在 sglang(127.0.0.1:8199,max_model_len=262144,模型 qwen3.8-27b,contextWindow=262144 / maxTokens=131072)上运行,最终对每个请求永久返回 400 status code (no body),模型一次都拿不到成功回合,compress 永远无法被调用,上下文永不收缩。

直接死因

一条 50,358 字符的单行压缩 JS bash toolResult(ACP 自己的计数 ≈ 31,475 tokens,≈ 有效输入窗口的 24%)整体进入上下文。有效输入上限 = 262,144 − 131,072 (maxTokens 预留) = 131,072。真实输入达到 134,569 tokens(见下),超限 → 400。

验尸数据(会话 jsonl + acp.log)

  • 953/953 条 assistant 消息全部带真实 provider usage(pi 确实请求了 stream_options.include_usage,sglang 确实返回了,pi 确实落盘了——传输层没有问题)。
  • 崩溃前最后一条 usage:{input: 169, cacheRead: 134400} → 真实上下文 134,569 tokens,已超有效上限;而同轮仲裁用的估算值是 tokens=57463 pct=51.8 —— 4.5× 低估
  • acp.logdensity=2.5(钳制上限)出现 831 次:密度学习机制一直在工作,只是真比值 ~4.5 永远追不上,所有阈值(75% nudge / 95% emergency)从未触发。

五层失效链

# 为什么没拦住
L1 字节级截断(pi 51,200B / ACP 200KB) 毒消息是一行 minified JS:50,358 字符 < 所有字节上限,行数=1
L2 token 估算(chars/4 × 密度) 45% 系统性低估:原始估算 ~29.7K,density 顶死 2.5 钳制,校准后仍只有真实值的 ~55%
L3 95% 紧急截断 门槛永远没到(51.8% < 95%);且 protectRecentMessages 会跳过最新消息——毒消息恰是最新消息
L4 overflow 自愈 正则只认带错误体的标记(maximum context length is N 等);bodyless 400 一个都不匹配,armed 永远不置位
L5 billion-context-pi 对 pi 自身 session_before_compact 恢复 无条件 cancel,pi 原生自救通道被关

根因(L2 的上游):仲裁用的是估算值,而 provider 锚定的真实值(getContextUsage().tokens,含 cacheRead)就在同一轮上下文事件里、且当轮已 >100%——手里有真数,仲裁却用估算

修复

PR 内容
#214 根因 仲裁改用 max(校准估算, provider 锚定值),带三重防护(pi 无法锚定→跳过;压缩后瞬态轮→跳过;provider 从不报 usage 的整树求和 regime→跳过,即 omp #18)
#215 L4 no-body 4xx 双守卫武装自愈(用量 ≥50% 或连续第 2 次)——循环发生后也能恢复
ranxianglei/acp-kernel#159(叠在 #133 上) L1/L3 单条 toolResult 硬上限 min(10%×limit, 16384),每轮无条件跑、无视新旧保护,head+tail 截断

三者互补:#159 按条拦截(不看总量)、#214 按真实总量掐灭、#215 兜底恢复。任一层单独存在都挡不住这次事故的全部变种。

未修(记录在案)

会话数据

  • 会话文件:~/.pi/agent/sessions/--home-dog-projects-billion-context--/2026-08-23T07-40-13-110Z_01a02d90-17b6-7ca7-b22a-a5170c2f9098.jsonl(已手工修复后可用)
  • 日志:~/.pi/acp.log(sid=01a02d90,事发时段 ~13:45 UTC 前后)

Activity

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