![[Bug]: /responses API Drops Reasoning Items from Multi-Turn Input (v1.83.7 Regression)](https://www.chat-gpts.plus/wp-content/uploads/2026/07/32335-7e6c9ac3.jpg)
[Bug]: /responses API Drops Reasoning Items from Multi-Turn Input (v1.83.7 Regression)
快速结论:此问题发生在 LiteLLM v1.83.7 代理中使用 /responses API 进行多轮对话时,输入数组中的 reasoning 项被丢弃,导致 Azure OpenAI 返回 400 错误。优先排查 cache_control_injection_points 配置是否启用。
问题场景
用户使用 LiteLLM 代理(Proxy)调用 Azure OpenAI 的 /responses API 进行多轮对话。当将上一轮的 response.output(包含 reasoning 和 message 项)作为下一轮输入时,请求失败。该问题在从 v1.82.3-stable 升级到 v1.83.7 后暴露。
报错原文
{
"error": {
"message": "Item 'msg_<id>' of type 'message' was provided without its required 'reasoning' item: 'rs_<id>'.",
"type": "invalid_request_error",
"param": "input",
"code": null
}
}
原因分析
在 v1.83.7 中,/responses 的 prompt-management 路径在处理输入数组时,先将 input 数组过滤为仅包含带 role 的 chat 消息(message 类型),然后运行 prompt hook,最后用 hook 的输出整体替换原始的 input。这个过滤过程丢弃了 reasoning、function_call 和 function_call_output 等非纯消息项,破坏了 Azure OpenAI 对 reasoning→message 配对的依赖。该回归由 PR #23999 引入。
配置了 cache_control_injection_points 的用户会命中此代码路径,但仅在有 prompt-management hook 激活时才触发过滤。
环境排查
- LiteLLM 代理版本:v1.83.7(v1.82.3-stable 正常)
- 模型类型:Azure OpenAI responses 模式(如
azure/gpt-5-codex) - 配置项检查:是否使用了
cache_control_injection_points、prompt_id、vector_store_ids、file_search工具、knowledge_bases、vector_store_registry等 trigger prompt-management hook 的配置 - 客户端 SDK:openai-agents SDK 或直接使用 openai Python 库
- 对比版本:尝试降级到 v1.82.3-stable 确认问题消失
解决步骤
- 临时降级:将 LiteLLM 代理版本回退到 v1.82.3-stable 可立即解决问题。
- 应用修复 PR #32446:该 PR 在 prompt hook 处理完成后,将非消息项(如
reasoning、function_call_output)重新合并回input数组中。若您能自行构建,可将修复合并到 v1.83.7 代码库。 - 等待官方发布:关注 LiteLLM 的后续版本(v1.83.8 或更高),该修复已通过 pass-through、vector-store、cache-control 和 prompt-template 等钩子的验证。
- 检查配置中是否包含
cache_control_injection_points:如果配置中有该设置且未使用其他 prompt-management hook(如prompt_id),此修复应覆盖您的场景。
验证方法
在应用修复或降级后,执行以下多轮调用确认问题解决:
import openai
client = openai.AsyncOpenAI(
base_url="https://<litellm-proxy>/openai/v1",
api_key="<token>"
)
# 第一轮
response1 = await client.responses.create(
model="my-reasoning-model",
input="Hello, analyze this code.",
)
# 第二轮,包含上一轮输出
response2 = await client.responses.create(
model="my-reasoning-model",
input=[
*response1.output,
{"role": "user", "content": "Check for security issues."}
],
)
# 成功:不返回 400 错误



