问题描述
在 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 字段的兼容性问题。
如何复现?
- 在 WebChat 中新建会话或清空上下文;
- 使用一个 OpenAI-compatible Responses API Provider(本人测试环境为通过 CLIProxyAPI 接入的 GPT-5.6);
- 正常发送一条消息;
- 不清空上下文,切换至 deepseek-v4-flash 的 Responses API,并发送一条消息;
- 再切回原 Responses Provider;
- 此时请求返回 400 Unknown parameter: 'input[N].status';
- 清空上下文后恢复正常。
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
检查清单
问题描述
在 AstrBot
v4.27.3中,同一会话先后使用不同的 OpenAI-compatible Responses API 模型时,疑似存在 Responses reasoning 历史数据跨 Provider / 模型回放时的兼容性问题。目前能够稳定复现以下情况:
因此目前看起来并非 gpt-5.6-luna / CLIProxyAPI 本身无法正常使用,也不像是消息平台适配器导致,而更像是 DeepSeek Responses API 产生的某些 reasoning 历史 item 被 AstrBot 保存后,在切换至另一个 Responses API Provider 时被继续回放,而目标 Provider 不接受其中的部分字段。
初步排查
查看目前的:
后发现,Responses API 返回 reasoning item 时,会通过类似以下方式进行完整序列化:
后续恢复上下文时,又会从保存的 reasoning state 中恢复完整 item:
最终重新加入下一次 Responses 请求的 input:
通过 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 字段进行校验时,会返回:
目前已通过 CLIProxyAPI 的错误请求日志确认,AstrBot 实际发送的请求中确实包含带有 status: "completed" 的历史 reasoning item,且上游报错参数位置与该 item 一致。尚未验证 OpenAI 官方 Responses API 是否同样拒绝该字段,因此目前仅能确认该问题在上述测试链路中稳定复现。
从行为上看,这也可能不仅局限于 status 字段:如果不同 OpenAI-compatible Responses 实现返回的 reasoning item schema 存在差异,那么完整保存并跨 Provider 回放 output item 时,理论上还可能遇到其他 Provider-specific 字段的兼容性问题。
如何复现?
AstrBot 版本
4.27.3
操作系统
Windows
部署方式
AstrBot Launcher
其他系统信息
使用的消息平台适配器
QQ 官方机器人(WebSocket)、WebChat
错误日志
AstrBot终端日志:
完整 traceback 中请求最终经过:
并由上游返回 HTTP 400。
CliProxy API Request Log(经过裁剪和脱敏处理):
辅助信息
No response
检查清单