Skip to content

[Bug] 同一会话在不同 Responses API 模型间切换后,历史 reasoning 数据可能导致后续模型请求 400 #9724

Description

@C10H14N2O5

问题描述

在 AstrBot v4.27.3 中,同一会话先后使用不同的 OpenAI-compatible Responses API 模型时,疑似存在 Responses reasoning 历史数据跨 Provider / 模型回放时的兼容性问题。

目前能够稳定复现以下情况:

  • 清空会话上下文后,使用通过 CLIProxyAPI 接入的 gpt-5.6-luna,可以正常连续对话;
  • 在同一会话中切换至 deepseek-v4-flash 的 OpenAI-compatible Responses API,可以继续正常对话;
  • deepseek-v4-flash 至少完成一次回复后,再将同一会话切换回 gpt-5.6-luna;
  • 此时请求稳定返回 HTTP 400:Unknown parameter: 'input[2].status'
  • 如果清空该会话的上下文历史,再继续使用 gpt-5.6-luna,请求会立即恢复正常。

因此目前看起来并非 gpt-5.6-luna / CLIProxyAPI 本身无法正常使用,也不像是消息平台适配器导致,而更像是 DeepSeek Responses API 产生的某些 reasoning 历史 item 被 AstrBot 保存后,在切换至另一个 Responses API Provider 时被继续回放,而目标 Provider 不接受其中的部分字段。


初步排查

查看目前的:

astrbot/core/provider/sources/openai_responses_source.py

后发现,Responses API 返回 reasoning item 时,会通过类似以下方式进行完整序列化:

if item_type == "reasoning":
    if hasattr(item, "model_dump"):
        serialized_item = item.model_dump(mode="json", exclude_none=True)
    elif isinstance(item, dict):
        serialized_item = copy.deepcopy(item)
    else:
        serialized_item = {}

    if serialized_item:
        serialized_reasoning_items.append(serialized_item)

后续恢复上下文时,又会从保存的 reasoning state 中恢复完整 item:

restored_items = [
    item
    for item in state["items"]
    if isinstance(item, dict)
]

if restored_items:
    reasoning_items.extend(restored_items)

最终重新加入下一次 Responses 请求的 input:

response_input.extend(reasoning_items)

通过 CLIProxyAPI 的错误请求日志进一步确认,AstrBot 实际发送的 Responses API 请求中,历史 reasoning item 确实包含 status: "completed" 字段。该请求经 CLIProxyAPI 转发至目标 Responses 上游后,上游返回 Unknown parameter: 'input[5].status' ,且 input[5] 正好对应上述 reasoning item。

AstrBot 将完整 output item 保存进会话历史后,在同一会话切换到其他 Responses Provider 时,又将这个 item 原样作为下一次请求的 input 重新发送。

而当前通过 CLIProxyAPI 接入的 gpt-5.6-luna 对该 input 中的 status 字段进行校验时,会返回:

Unknown parameter: 'input[2].status'

目前已通过 CLIProxyAPI 的错误请求日志确认,AstrBot 实际发送的请求中确实包含带有 status: "completed" 的历史 reasoning item,且上游报错参数位置与该 item 一致。尚未验证 OpenAI 官方 Responses API 是否同样拒绝该字段,因此目前仅能确认该问题在上述测试链路中稳定复现。

从行为上看,这也可能不仅局限于 status 字段:如果不同 OpenAI-compatible Responses 实现返回的 reasoning item schema 存在差异,那么完整保存并跨 Provider 回放 output item 时,理论上还可能遇到其他 Provider-specific 字段的兼容性问题。


如何复现?

  1. 在 WebChat 中新建会话或清空上下文;
  2. 使用一个 OpenAI-compatible Responses API Provider(本人测试环境为通过 CLIProxyAPI 接入的 GPT-5.6);
  3. 正常发送一条消息;
  4. 不清空上下文,切换至 deepseek-v4-flash 的 Responses API,并发送一条消息;
  5. 再切回原 Responses Provider;
  6. 此时请求返回 400 Unknown parameter: 'input[N].status';
  7. 清空上下文后恢复正常。

AstrBot 版本

4.27.3

操作系统

Windows

部署方式

AstrBot Launcher

其他系统信息

  • 后端操作系统:Windows 11 家庭版 25H2,操作系统版本 26200.9168
  • Cli Proxy API 版本:v7.2.135
  • 浏览器所在系统:Windows 11 家庭中文版 25H2,操作系统版本 26200.9168
  • 浏览器:Microsoft Edge 151.0.4129.86 (正式版本) (64 位)

使用的消息平台适配器

QQ 官方机器人(WebSocket)、WebChat


错误日志

AstrBot终端日志:

[2026-08-18 10:56:33.039] [Core]
[WARN]
[v4.27.3] [runners.tool_loop_agent_runner:616]: Chat Model C10/gpt-5.6-luna request error: Error code: 400 - {'error': {'type': 'invalid_request_error', 'code': 'unknown_parameter', 'message': "Unknown parameter: 'input[2].status'.", 'param': 'input[2].status'}}

openai.BadRequestError: Error code: 400 - {
    'error': {
        'type': 'invalid_request_error',
        'code': 'unknown_parameter',
        'message': "Unknown parameter: 'input[2].status'.",
        'param': 'input[2].status'
    }
}

完整 traceback 中请求最终经过:

astrbot/core/provider/sources/openai_responses_source.py
→ _query_stream()
→ self.client.responses.create()

并由上游返回 HTTP 400。


CliProxy API Request Log(经过裁剪和脱敏处理):

=== REQUEST INFO ===
CLIProxyAPI Version: 7.2.135
URL: /v1/responses
Method: POST
Timestamp: 2026-08-18T11:18:00+08:00

=== RELEVANT REQUEST BODY ===

{
  "input": [
    {
      "type": "message",
      "role": "developer",
      "content": "<omitted>"
    },
    {
      "type": "message",
      "role": "user",
      "content": "<omitted>"
    },
    {
      "id": "<omitted>",
      "summary": [],
      "type": "reasoning",
      "content": [],
      "encrypted_content": "<omitted>"
    },
    {
      "type": "message",
      "role": "assistant",
      "content": "<omitted>"
    },
    {
      "type": "message",
      "role": "user",
      "content": "<omitted>"
    },
    {
      "id": "<omitted>",
      "summary": [],
      "type": "reasoning",
      "content": [
        {
          "text": "<omitted>",
          "type": "reasoning_text"
        }
      ],
      "status": "completed"
    },
    {
      "type": "message",
      "role": "assistant",
      "content": "<omitted>"
    }

    // remaining conversation history omitted
  ],

  "model": "gpt-5.6-luna",
  "store": false,
  "stream": true,
  "reasoning": {
    "effort": "max"
  }
}

=== UPSTREAM REQUEST ===

Upstream endpoint:
https://chatgpt.com/backend-api/codex/responses

Relevant input item:

input[5] = {
  "summary": [],
  "type": "reasoning",
  "content": [
    {
      "text": "<omitted>",
      "type": "reasoning_text"
    }
  ],
  "status": "completed"
}

=== API RESPONSE ===

HTTP 400

{
  "error": {
    "type": "invalid_request_error",
    "code": "unknown_parameter",
    "message": "Unknown parameter: 'input[5].status'.",
    "param": "input[5].status"
  }
}

辅助信息

No response

检查清单

  • 我已在 Issue 列表中搜索过相关问题仍无法解决,或该问题从未被报告过。
  • 我已尝试过禁用所有插件,排除了可能是因插件导致的问题。
  • 我报告的问题与 AstrBot 本体相关,而非在报告某一插件的问题。
  • 我已阅读并同意本项目的贡献者行为准则
  • (可选)我愿意提交 PR 以帮助修复该问题。

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:providerThe bug / feature is about AI Provider, Models, LLM Agent, LLM Agent Runner.bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions