Skip to content

同一任务从 DeepSeek 切换到 GPT 后,明文 reasoning_text 历史导致请求持续 400 #17

Description

@LEILEI0628

现象

在同一个 Codex 任务中先使用 DSCodex 的 DeepSeek V4 Flash/Pro,再切换到 GPT 模型(例如 gpt-5.6-sol),下一次 GPT 请求会立即失败:

Invalid 'input[7].content': array too long.
Expected an array with maximum length 0, but got an array with length 1 instead.

任务切回 DeepSeek 后可以继续运行;再次切换到 GPT 仍会触发相同错误。

这不是 Responses-Lite 请求头缺失导致的。补齐 Responses-Lite 请求头只会让请求正确到达 ChatGPT 后端,随后暴露已有的跨 provider 历史格式不兼容。

根因分析

DeepSeek Responses API 返回的 reasoning item 形状类似:

{
  "type": "reasoning",
  "content": [
    {
      "type": "reasoning_text",
      "text": "<omitted>"
    }
  ],
  "encrypted_content": null,
  "summary": []
}

Codex 将这个 item 写入任务历史。

切换到 GPT 后,DSCodex v1.0.0 对 GPT 请求执行透明旁路:

let outgoingBody = raw;

因此 DeepSeek 生成的明文 reasoning_text item 会被原样发送到 ChatGPT Responses 后端。

ChatGPT 后端接受的 reasoning 历史使用空 content 和 opaque/encrypted reasoning 数据,不接受上述带一个 reasoning_text content item 的 DeepSeek 形状,于是返回:

{
  "error": {
    "message": "Invalid 'input[7].content': array too long. Expected an array with maximum length 0, but got an array with length 1 instead.",
    "param": "input[7].content",
    "code": "array_above_max_length"
  }
}

官方 OpenAI Responses 文档建议在同一模型的无状态多轮请求中重放完整 output,包括加密 reasoning item;但这里重放的是另一 provider 生成的非 OpenAI reasoning 格式,二者不兼容。

复现步骤

  1. 安装并启动 DSCodex v1.0.0。

  2. 新建 Codex 任务,选择 deepseek/deepseek-v4-pro

  3. 让模型完成至少一个响应,使任务历史中产生 reasoning item。

  4. 在同一任务内切换到 gpt-5.6-sol

  5. 发送任意消息。

  6. GPT 请求返回 HTTP 400:

    Invalid 'input[N].content': array too long.
    Expected an array with maximum length 0, but got an array with length 1 instead.
    
  7. 切回 V4 Pro 后任务恢复运行。

复现证据

该问题已在两个独立任务中出现:

  • DSCodex v1.0.0、Codex CLI 0.147.0-alpha.6.5:V4 Pro → GPT-5.6 Sol 后报 input[7].content
  • 较长的旧任务在直通 ChatGPT remote compact 时:报 input[316].content

两个位置对应的历史 item 均为:

  • type: "reasoning"
  • content.length: 1
  • content 类型为 reasoning_text
  • encrypted_content: null

未在 issue 中包含任何 reasoning 正文、OAuth 信息或真实账户标识。

影响

  • 在同一任务内从 DeepSeek 切回 GPT 无法继续工作;
  • 错误 item 已保存在任务历史中,所以每次 GPT 请求都会重复失败;
  • 用户只能切回 DeepSeek 或新建任务,现有任务无法正常使用 GPT 接续;
  • remote compaction 也可能在请求头问题修复后继续被该历史 item 阻塞。

期望行为

DSCodex 应允许同一任务在 DeepSeek 与 GPT 之间安全切换。

发送 GPT-bound 请求前,应识别并处理 DeepSeek 特有的明文 reasoning item,避免将 GPT 不接受的 reasoning_text 形状直接发送给 ChatGPT。

处理过程必须保留用户消息、assistant 可见输出、工具调用及工具输出的相对顺序,不应修改用户的 rollout JSONL 文件。

建议修复方向

可考虑在 GPT-bound 请求中识别:

  • type === "reasoning"
  • content 包含 reasoning_text
  • encrypted_content == null

并在转发前安全移除这类 DeepSeek-only reasoning item。

由于 GPT 请求可能使用 zstd 压缩,只有实际发生迁移时才应解码、修改并以正确编码重新构造请求;不含 DeepSeek reasoning 的普通 GPT 流量仍应保持透明字节旁路。

另一种方案是在 provider 切换时生成可跨 provider 使用的 compact summary,但不应把明文 reasoning 内容转换成普通消息或直接泄露给另一 provider。

环境

  • DSCodex:v1.0.0(45e9f84
  • Codex Desktop,底层 CLI:0.147.0-alpha.6.5
  • OS:macOS 26.4.1
  • 切换方向:DeepSeek V4 Pro → GPT-5.6 Sol

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