Skip to content

[Bug] claude-sonnet-5-5 请求 max_tokens=131072 被上游 400 拒绝(真实上限 128000),且被误判为上下文超限 #71

Description

@sperictao

环境

  • 插件:@mars-sea/dsh-commandcode-provider@0.12.0(npm 最新版)
  • DSH:桌面端 win-x64(nightly 通道),Windows 11
  • 模型:commandcode/claude-sonnet-5-5,reasoningEffort: xhigh
  • 会话记录的 contextWindow 为 1000000

现象

会话第一步即失败,界面上依次出现两条提示:

Command Code stream error: max_tokens: 131072 > 128000, which is the maximum allowed number of output tokens for claude-sonnet-5-5
Command Code API 拒绝了这次请求:内容超出模型上下文窗口。正在压缩上下文后重试;如仍失败,请新建会话或减少上下文

第二条提示具有误导性:这不是上下文超限。压缩上下文后重试时 max_tokens 并没有下调,仍会以 131072 被同一个 400 拒绝,因此"新建会话 / 减少上下文"永远不会解决问题。

原因

1. 目录只有 context_length,插件用窗口推算输出上限,得到 131072

/provider/v1/models 只发布 context_length,parseCatalogResponse() 便以 Math.min(contextLength, DEFAULT_MAX_OUTPUT_TOKENS) 代替输出上限(DEFAULT_MAX_OUTPUT_TOKENS = 131072)。claude-sonnet-5-5 的窗口是 1,000,000,于是推导出的 maxTokens 就是 131072。

2. 请求侧同样落到 131072

stream() 中:

const modelMax = modelEntry?.maxTokens ?? 131072;
const requestedMaxTokens = Math.min(options.maxTokens ?? modelMax, modelMax, DEFAULT_GENERATE_MAX_TOKENS);

宿主不传 options.maxTokens 时,max_tokens = 131072。

3. 该模型的真实输出上限是 128000

131072 = 128 × 1024,比十进制的 128K 多 1072,上游按模型自己的上限直接 400 拒绝。

4. 这个 400 被误判为上下文超限,触发了无效的压缩重试

isContextOverflowDetail() 用 CLI_CONTEXT_OVERFLOW_PATTERN 判定:

/prompt is too long|context.*(length|window)|max_tokens|maximum.*tokens/i

错误正文里含 max_tokens,因此命中该正则,被当成上下文超限,进入"压缩后重试"分支;而重试并没有降低 max_tokens,必然再次失败,最终把错误暴露给用户。

建议修复

  1. 为有真实输出上限的模型维护上限表(至少 Claude 家族 ≤ 128000);或直接把 DEFAULT_MAX_OUTPUT_TOKENS / DEFAULT_GENERATE_MAX_TOKENS 从 131072 降到 128000——插件 CHANGELOG 自己也说明这些模型的真实输出上限是 64K / 128K,131072 并不比 128000 多出任何可用空间。
  2. 解析 400 里的上限并降额重试一次:max_tokens: X > Y, which is the maximum allowed... 这类错误可以直接取出 Y,用 Y 重发,而不是压缩上下文。
  3. 不要把含 max_tokens 字样的错误一律当作上下文超限:它同时掩盖了这类输出上限错误,用户看到的是"上下文超限"的误导提示。

复现

任选 claude-* 模型(claude-sonnet-5-5 必现),宿主不传 options.maxTokens,插件即发送 max_tokens: 131072。

临时规避(供其他用户参考)

  • 该会话改用非 Claude 模型(如 z-ai/glm-5.3-flash、deepseek/deepseek-v4.1-flash);
  • 或在本地把请求上限对 claude-* 收窄到 128000(lib/index.js 的 stream() 内):
const modelMax = Math.min(modelEntry?.maxTokens ?? 131072, options.model.startsWith("claude-") ? 128000 : Infinity);

已验证改后请求为 max_tokens: 128000,语法校验通过。

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