故障排查 · 上下文超限三种伪装

Context Length Exceeded
三种伪装形态,最后一种最难查

同样是上下文超出限制,有的直接报 400,有的悄悄截断你的输入,有的外层显示 200 但流是空的——第三种最容易被误判成别的故障。

#context_length_exceeded#maximum context length#静默截断#空流排查

四个关键事实

400

显式报错(最好查)

错误体里直接出现 context_length_exceeded 或 maximum context length 字样,原因一目了然。

静默截断

输入被悄悄截掉一部分

部分客户端/网关在超限时自动截断早期消息而不报错,模型看到的上下文比你以为的少,输出会显得「忘事」。

200 空流

最难查的一种

外层 HTTP 状态码是 200,流式响应却直接结束、没有任何 token——很容易被误判成网络问题或客户端 bug。

分段/RAG

根治办法

把长上下文切片、做摘要/检索增强(RAG)、或换成支持更长上下文窗口的模型,是三种伪装共同的根治办法。

三种伪装分别长什么样

第一种,显式 400:响应体里直接出现 context_length_exceeded 或 maximum context length 字样,请求整体被拒绝,这种最容易定位。第二种,静默截断:部分 SDK、代理层或历史记录管理逻辑在检测到即将超限时,会自动丢弃最早的一部分消息而不报任何错误,模型能收到请求、正常返回,但因为看不到被截掉的那部分上下文,输出会显得「忘了前面说过的事」或前后矛盾。第三种,外层 200 但流是空的:HTTP 层面一切正常、状态码 200,但流式响应连接建立后立刻结束,没有任何 token 输出——这种最容易被误诊成网络抖动、超时或客户端解析 bug,实际根因往往是请求已经超出模型上下文窗口,底层在流式开始前就已经判定失败,只是没有把 400 错误体透传到流式协议里。

为什么这个问题最近更常见

随着 agent/子代理工作流普及,单次请求里塞进整个代码库、完整对话历史、多轮工具调用结果的场景越来越常见,超出上下文窗口的概率显著上升;而不同客户端/网关对超限的处理方式不统一(有的报错、有的静默截断、有的空流),排查难度也随之上升。

时间线

长期存在

context_length_exceeded 是各大模型 API 长期存在的标准错误类型,伴随上下文窗口这一概念本身。

近期

agent/子代理工作流让单次请求携带的上下文体积显著增大,触发超限的场景变多。

持续中

「外层 200 但流是空」这种最难查的伪装形态,在纯 agent 化工作流中出现频率上升,成为最容易被误诊的一类。

已确认 vs 常见误解

已确认

三种伪装形态(显式 400、静默截断、外层 200 空流)在公开的开发者讨论与各家 SDK/网关的实现里都有据可查;根因都是同一件事——请求内容(含历史消息、工具调用结果、系统提示词)超出了模型的上下文窗口上限。

常见误解

很多人遇到空流时第一反应是怀疑网络或客户端故障,反复重试、换网络环境,但如果根因是超限,这些动作都不会有效果,只会浪费排查时间。

怎么快速定位是不是这个问题

先看请求体积

统计这次请求实际携带的 token 数(系统提示词+历史消息+工具调用结果+新输入),和模型声明的上下文窗口上限做对比,超出或接近上限就要怀疑这个方向。

再看响应形态

显式 400 直接确认;静默截断要看模型输出是否「忘事」;外层 200 空流要看流式连接是否建立后立刻无 token 结束,而不是超时。

定位与解决步骤

第一步,估算这次请求的总 token 数(可用官方 tokenizer 或第三方估算工具),和模型的上下文窗口上限对比。第二步,如果确认接近或超出上限,优先做的不是重试,而是精简输入——把历史对话做摘要压缩、只保留最近若干轮、或改用检索增强(RAG)只取相关片段而不是塞全部历史。第三步,如果任务本身确实需要长上下文,考虑换成支持更大上下文窗口的模型档位。第四步,针对「外层 200 空流」这种情况,专门加一条判据:流式响应建立后如果在很短时间内没有收到任何 token 就直接结束,按超限处理,而不是当成普通的网络超时重试。

在 QCode 上怎么办

QCode 上的模型阵容里,不同家族的上下文窗口上限不一样;同一把密钥可以按任务体积切到上下文窗口更大的模型档位,不需要为了长上下文单独申请或配置。

常见问题

怎么知道自己是不是撞到了这个问题?

先统计这次请求的总 token 数,和模型声明的上下文窗口对比;如果接近或超出,且响应表现为显式 400、输出前后矛盾(疑似被截断)或流式响应无 token 直接结束,基本可以确认。

静默截断为什么不报错?

这是部分客户端/网关自己实现的容错逻辑——检测到超限时,选择丢弃最早的部分消息而不是让整个请求失败,目的是让对话「看起来」能继续,但代价是模型看不到被截掉的上下文。

外层 200 但流是空的,是不是网络问题?

通常不是。这种现象的常见根因是请求在服务端就已经因超限被判定失败,但底层没有把标准的 400 错误体透传进流式协议,于是客户端看到的是「连接成功、但没有内容」。重试同样的超长请求大概率还是空流。

怎么估算一次请求实际用了多少 token?

把系统提示词、完整历史消息、工具调用结果和新输入都算进去,用官方 tokenizer 或第三方估算工具统计;agent/子代理场景尤其容易低估,因为每轮工具调用的结果都会被重新塞进下一次请求。

换更大上下文窗口的模型就能一劳永逸吗?

能缓解,但不是无限的——上下文窗口越大,单次请求成本通常也越高,而且再大的窗口也有上限。更稳妥的做法是同时做输入精简(摘要、RAG),把窗口大小当成余量而不是唯一依赖。

这个问题和 429/529 那类报错是一回事吗?

不是。429/529 是速率或容量层面的问题,和请求内容大小无关;context_length_exceeded 是请求内容本身超出了模型能处理的上限,即使降速、退避重试也不会解决。

信息来源

三种伪装形态基于公开的开发者讨论与各家模型 API 的标准错误类型描述整理;本页不针对具体某个厂商的私有实现细节做断言,只描述跨厂商普遍存在的现象与判别方法。本页内容于 2026-08-27 整理。

上下文超限不该拖慢交付

一把 QCode 密钥按任务体积切到上下文窗口更大的模型档位。

相关阅读

本页内容为跨厂商通用的技术性说明,不针对任何单一厂商的私有实现细节做断言;具体行为以你实际使用的模型与客户端文档为准。