zai-org / zai-org/feedback

[Bug] auto-compact 对 OpenAI-compatible 模型静默失效致超限报错;95% 阈值硬编码且不可配置

Open
#114 4 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

priority: P2
Dominant language
No language data
Stars
22
Forks
1
PR merge metrics
No merged PRs in 30d

Description

问题类别 · Category

对话 / Agent 交互 · Agent chat(auto-compact / 上下文压缩)

涉及框架 · Agent framework

ZCode Agent(自研)

严重程度 · Severity

阻塞使用 · Blocking — 上下文增长到一定规模后会话直接不可用,且无法自行恢复

复现频率 · Reproducibility

必现 · Always(对话足够长 + OpenAI-compatible 小上下文模型)


问题描述 · Description

使用自建 OpenAI-compatible 模型(sglang 部署 nvidia/GLM-5.2-NVFP4,contextWindow=409600)长时间对话后,出现 The input (410089 tokens) is longer than the model's context length (409600 tokens) 硬报错,auto-compact 从未自动触发。根因有两层:

第 1 层(#93 的下游后果):OpenAI-compatible 流式请求未带 stream_options.include_usage,服务端不返回 usage → auto-compact 拿不到真实 token 数 → 永久回退到本地估算(source:"estimate"),本地估算对长会话偏低 → compact 永远不触发。完整源码证据链见我在 #93 的补充评论。

第 2 层(本 issue 的核心诉求):即使 #93 修复,auto-compact 触发阈值硬编码 95%glm/zcode.cjs 常量 DTt=95)。thresholdPercentOverride 钩子已存在(函数 OTt,接受 1–100)但从未接到任何用户入口——config / setting / env / CLI / 设置面板都没有。对 409600 的小窗口,95% = 389120,只剩 ~20K 缓冲;单次 send(尤其带大文件/大附件)极易从 <95% 一步跨过 100%,越过 compact 窗口直接超限。

此外,超限后会话反复重发同一上下文:session 一旦因超限进入 error 状态,后续每次 send 都带着同一份超限上下文发出去,重复失败,无法恢复——既不自动 compact,也不提示用户新开 session。

复现步骤 · Steps to reproduce

  1. ZCode 3.3.4,macOS,添加自定义 OpenAI-compatible provider 指向 sglang(nvidia/GLM-5.2-NVFP4,contextWindow=409600)
  2. 在同一 session 持续对话至 ~500 条消息、上下文接近 40 万 tokens
  3. 发送一条消息(即便很短,如 2 字符)
  4. 报错:The input (410089 tokens) is longer than the model's context length (409600 tokens)
  5. 此后该 session 处于 error 状态,任何后续 send 都带着同一超限上下文重复失败,无法恢复

期望表现 · Expected behavior

  • 逼近上限时 auto-compact 自动触发,且基于服务端真实 token 数(而非偏低的本地估算)
  • 阈值可由用户配置,小上下文模型可调低(如 80%)留足缓冲
  • 上下文超限报错后,不应反复重发同一超限上下文;应自动 compact 或明确提示用户新开 session / 执行 /compact

实际表现 · Actual behavior

  • auto-compact 从未触发(本地估算未达 95%,真实用量已超 100%)
  • 单次 send 从 <95% 直接跳到 100.1%,越过 compact 窗口
  • session 进入 error 后,后续 send 反复失败、无法恢复

证据 · Evidence

日志时序~/.zcode/v2/logs/2026-07-10.log,session sess_c1234ab7-...):

时间 事件 messageCount 说明
22:16:29 resume+send 493 上下文安全(< 95%)
22:17:35 resume+send 497 又发两条消息
22:20:26 resume 506,sessionStatus:"error" 上次请求已超限,session 被标记 error
22:20:27 send(textLength: 2) 410089 > 409600 → 拒绝

源码证据glm/zcode.cjs):

  • auto-compact 判定函数 xWtokenCount = tokenOverride?.tokenCount ?? 本地估算source 默认 "estimate"
  • tokenOverride 来自 syn(latestProviderContextUsage),而 latestProviderContextUsage = Ojt(g, ...)
  • Ojt:仅当 y4e(e.usage) 有值且 >0 才返回;usage 为空 → 返回 undefined → 无 tokenOverride → 永久走本地估算
  • 阈值常量 DTt = 95(硬编码);OTtthresholdPercentOverride 钩子接受 1–100,但在整个 out/ 目录出现 0 次赋值,未接入任何 zod schema,手填 config/setting 也不会被解析

服务端验证(同一 sglang 端点):

  • 流式不带 stream_options → 末尾 chunk 无 usage(grep -c '"usage"' = 0)
  • 流式带 stream_options:{include_usage:true} → 末尾 chunk 正常返回 {"usage":{"prompt_tokens":13,"total_tokens":18,...}}
  • 非流式 → usage 正常
  • 即服务端符合 OpenAI 规范,是 ZCode 没主动要

ZCode 版本 · Version

3.3.4(desktop,production,darwin-aarch64)

设备 / 系统 · Device / OS

macOS 25.5.0 arm64;后端 sglang nvidia/GLM-5.2-NVFP4(OpenAI-compatible,contextWindow=409600)

关联 · Related

  • #93 —— include_usage 不发送的根因(本 issue 第 1 层根因的上游)。我在 #93 补充了完整源码证据链与超限复现。

建议 · Asks

  1. 修复 #93:给 openai-compatible 工厂传 includeUsage: true,让 auto-compact 拿到服务端真实 token 数。
  2. 暴露 thresholdPercentOverride 到用户配置(config.json / setting.json),小上下文模型可调低阈值留缓冲。钩子代码已就绪,只差接线。
  3. 超限报错后停止重复发送同一上下文:改为自动触发一次 compact,或明确提示用户新开 session / 执行 /compact,避免 error 状态下的重复失败循环。

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with glm/zcode.cjs and trace xW, Ojt, OTt, and the hard-coded DTt threshold, then compare the behavior with the evidence and reproduction steps in the issue. Review related issue #93 for the missing usage path and inspect how configuration is parsed. Done means real provider usage reaches auto-compact, the threshold is user-configurable, and an over-limit session does not repeatedly resend the same context.

Written by the indexing model from the issue text.

Assessment

Domain
api, backend-api-design
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.