生成到一半就断了:输出上限、上下文挤爆、网络中断还是工具超时

2026-07-28

数据截至 2026-07,各产品的额度与报错口径以官方最新说明为准。

多数人把「生成到一半停住」一律记成网络不好,点重试,于是同一个坑反复踩。 真正常见的成因有四类,它们的处置动作互相冲突:输出长度到顶要的是「接着写」,上下文被挤出要的是「先瘦身再重来」,传输层断掉要的是「幂等重放」,工具调用超时要的是「把那一步单独拎出来跑」。选错一类,你不只浪费一次生成,还会把已经产出的半成品搞脏——比如在上下文已经溢出的会话里反复要它续写,它会开始改错你之前改对的地方。

好在这四类的「断口长相」差别很大,肉眼加两条命令基本就能分开。本篇讲的是断了以后怎么定位和收拾;上下文窗口本身是什么机制、为什么会挤出,另开一篇讲清楚了,见上下文窗口是什么,两篇分工是它讲原理、这篇讲现场处置,不重复。

一、先看断口,别先看日志

排查顺序上,第一手证据是那段被截断的文本本身,它比日志更快指向成因。

齐整地停在一个完整词或半句话上,末尾没有报错,工具界面显示这一轮「正常结束」。 这是输出长度到顶的典型样子。模型不是不想写完,是这一轮能吐的字数用满了,它被硬切在那里。判别点是:界面没有任何异常提示,甚至可能显示成功;你把光标放到末尾,会发现文本是可以接续的——语义没坏,只是没写完。

断口毛糙,出现半个单词、半行 JSON、少一个右花括号,或者进度条转着突然什么都不动了。 这是传输层的样子。流式输出是一段段推过来的,连接掉了就在任意字节处断开,不会挑一个语义边界。客户端这时往往能给你一个网络层错误名:ETIMEDOUT 是某个等待阶段超时了(握手等不到应答,或连上后等不到下一段数据,具体是哪一段要看它同时报的阶段信息),ECONNRESET 是对端直接把连接掀了(收到 RST),还有一类是「连接被提前关闭」,表现为流没读完就结束、没有任何错误码。另外一类很好认:代理中间人替换证书导致的证书链校验失败——它在请求刚发出、还没有任何数据回来时就失败,不会先吐半段再断。

内容还在生成,但质量塌了:开始重复前面的段落,把你已经确认过的结论又推翻一遍,或者反问你二十分钟前就给过的文件路径。 这是上下文被挤出的样子。它不是「断」,是「忘」,只不过在长任务里你感受到的就是「后半段废了」。

卡在某一步不动,界面停在某个工具调用上,过一会整轮失败或者那步被跳过。 这是工具超时的样子。判别点是停住的位置——它不是停在文字中间,是停在一次外部调用上。

弹出明确的状态码或额度提示。 429 是被限流,401 是凭据不对,403 是有凭据但没权限,500 一类是服务端自己出问题。这一类最省事,它已经把答案告诉你了,只要你别把它当成「网络波动」重试到死。

二、判别表

现象大概率成因怎么验证处置动作
文本齐整停住,无报错,本轮显示正常结束单轮输出长度到顶走 API 的看响应里的结束原因字段是长度类还是正常完成;走客户端的看这轮有没有异常标记让它从末尾接续;长产物改成先要目录、再逐节生成
断口毛糙,半词半行,客户端报 ETIMEDOUT / ECONNRESET 或流式静默中断传输层断开用 curl 打同一个端点看状态码与耗时;换一个网络环境复测;确认有没有中间代理幂等重放;关掉可疑代理;把长任务切小降低单次连接时长
越写越忘前文,重复、推翻已定结论、反问已给信息上下文被挤出多数编程类客户端会显示本轮上下文占用比例或「已压缩历史」之类的提示,先看它;没有这类提示的,回头数这轮塞进去的大件(整个大文件、长日志、整目录)开新会话,只带必要摘要重来;把大文件换成片段引用
返回 429,或提示额度已用尽限流或额度耗尽隔几分钟用一个最小请求再打一次:还是失败多半是额度或配额用尽,通了就是瞬时限流。控制台的用量页是唯一权威限流走指数退避并降并发;额度类换路由或等窗口刷新,别原地重试
返回 401 或 403凭据无效或权限不足用同一份凭据打一个最简单的只读端点:也失败是凭据本身的问题,只有这个端点失败就是权限或区域不开放换发凭据;核对项目与模型的访问权限,别当网络问题重试
停在某次外部调用上,之后整轮失败或跳过该步工具 / MCP 调用超时把那个工具单独跑一次,看它自己的日志和退出码修工具本身;给它单独的超时与重试;把耗时步骤改成异步取结果
500 一类服务端错误,且换请求也复现上游故障用一个最小请求复测,排除你自己的载荷问题等待,同时切到备用路由;不要改自己的代码去迁就

表里最容易被忽略的是第三行。它的现象不像故障,像模型变笨了,很多人于是去改要求、加约束、换措辞,全是白费——载荷已经装不下了,怎么措辞都没用。

三、四组动作,按这个顺序做

第一组,止血:把已产出的东西存下来。 不管哪一类成因,先把半成品落到文件或版本库里。代码类的直接:

git add -A && git commit -m "wip: 半成品,生成中断"

-A 会把新生成的文件一并纳入,这在中断现场恰好是想要的——半成品最容易漏在未跟踪文件里。这条提交只是给自己一个回滚点,别推到远端,收拾干净后用 git reset --soft 退回去重新组织提交就行。后面无论续写还是重来,你都能 git diff 出到底改了什么。中断现场最贵的不是那次生成,是你搞不清「哪些改动是完整的、哪些是断在一半的」。

第二组,续写还是重来,二选一。 输出到顶就续写:把断口前的最后一小段原文贴回去,明确要求从这里接着写,不要重述已写内容。上下文挤出就重来:开新会话,把前面的成果压成一份短结论带过去,绝不把整段历史再贴一遍。这两个动作绝不能混——在挤出的会话里续写,等于让它在残缺记忆上编造衔接。怎么主动管上下文别等到挤爆,可以看上下文管理实践

第三组,网络与传输的确认。 用一条通用请求看端点到底通不通、慢在哪:

curl -sS -o /dev/null -w 'code=%{http_code} dns=%{time_namelookup} tls=%{time_appconnect} total=%{time_total}\n' https://example.com/

time_appconnect 明显偏大或直接失败,多半是 TLS 环节;total 大而状态码正常,是链路慢;证书链校验失败通常来自公司网络里替换证书的中间设备,正确做法是把企业根证书配进运行时的信任库(Node 侧常用 NODE_EXTRA_CA_CERTS,Python 侧常用 REQUESTS_CA_BUNDLE),而不是把证书校验关掉。同时查一遍代理环境变量,它经常是被同事的脚本悄悄写进去的:

env | grep -iE 'proxy|_CA_|SSL_CERT'

第四组,限流与工具。 429 的正确姿势是退避而不是猛冲,各家的窗口规则不同且会调整,以官方最新说明为准;具体的退避写法和踩过的坑,429 限流处置那篇写得更细。工具超时的正确姿势是隔离——把那一步从整条链路里摘出来单独跑通,再接回去,别在一整轮生成里反复试探它,那样每次试探都要重烧一遍前面的步骤,参考MCP 调试技巧

如果你跑的是多步骤的自动化任务,中断的代价会被放大:它可能在第七步断掉,而重跑要从第一步开始。这类任务的重试与断点设计是另一套功夫,见任务失败与重试

四、什么情况下别再折腾了

排查也要有止损点,下面几条命中任意一条,停手。

同一类错误连续重试三次以上仍然复现,且错误文本一字不变。 一字不变意味着你没有改变任何变量,重试只是消耗额度和时间。停下来,换一个变量再试:换网络、换路由、换更小的输入。

你已经开始为了绕过报错而修改与任务无关的代码。 典型场景是为了让某次调用不超时而去改业务超时配置,或者为了避开证书报错而全局关掉校验。这类改动会活很久,而且会在别的地方咬你一口。回滚,把问题记下来,走正规修法。

工作区里出现冲突标记而你不确定它们是怎么来的。 看到 <<<<<<<=======>>>>>>> 这类标记散落在几个文件里、来源不明,别手动挑拣。用回滚点整片放弃,重新来一遍比逐行猜测便宜得多:

# 先看范围:哪些文件被动过、各改了多少行
git diff --stat
# 再逐个放弃确认不要的文件(新版 git 用 restore,老版本用 checkout --)
git restore -- path/to/file

git restore 会直接丢掉工作区改动、不进回收站,所以务必先有前面那个 wip 提交垫底。如果连「哪些改动是断在一半的」都分不清,就整片放弃回到 wip 提交,再从干净状态重跑一次。

海外工具连不上的情况,别把时间花在网络上。 一部分海外 AI 编程工具与模型服务,官方对中国大陆有区域限制、不支持直连,你在本地看到的连接超时不是你的配置问题。市面上存在第三方中转服务,但稳定性、合规性与数据流向都要自己评估,我不给具体渠道也不背书。如果一个工具反复因为区域原因断,理性的选择是换一条能长期稳定用的路,而不是每天修网络。

产物质量已经明显下滑而你还在同一个会话里救。 上下文一旦挤出,这个会话的信息完整性就不可逆了。新开一个、带干净的摘要重来,是最省时间的动作,不是失败。

五、避坑清单

把「正常结束」误读成「写完了」。 为什么会踩:长度到顶时很多界面不报错,甚至显示成功。怎么避:凡是长产物,收尾先看最后一句是否语义完整、有没有该有的收束段或右括号,别看状态提示。

中断后不看 diff 就继续让它改。 为什么会踩:你以为它只写了一半文件,其实它已经改了三个文件、两个改完一个改一半。怎么避:中断后第一条命令永远是 git diff --stat,先看范围再决定动作。

用「重试」当万能解药。 为什么会踩:重试对传输层断确实有效,成功过一次就形成肌肉记忆。怎么避:先分类再动作,429 要退避、长度到顶要续写、上下文挤出要重来,只有传输层断适合原样重放。

把整个大文件或整份长日志贴进会话。 为什么会踩:贴全量最省事,一次也确实能跑通。怎么避:改成贴关键片段加文件路径,让工具自己去读它需要的部分;日志先过滤再贴。

非幂等操作放在会被重试的链路里。 为什么会踩:写库、发消息、扣款这类动作在本地测试时都只跑一遍。怎么避:凡可能被重放的步骤,加请求标识做去重,或者把副作用挪到链路最后一步、由人确认后触发。

为了赶时间把并发拉满。 为什么会踩:并发确实快,直到撞上限流。怎么避:限流是共享资源的保护机制,撞上它说明你的节奏错了,降并发加排队比重试划算。

关掉证书校验来「解决」证书问题。 为什么会踩:一行配置就见效,诱惑极大。怎么避:把企业根证书正确装进信任库,改动写进项目文档,别留在某个人的环境变量里。

中断现场不留记录。 为什么会踩:当时急着救活,觉得自己记得住。怎么避:把断口现象、状态码、当时的输入规模三样记一行到项目笔记里,第三次遇到同类问题时它值一小时。

收尾:一份自检清单

下次再看到「生成到一半就断了」,按这个顺序过一遍,基本不会走错路:

  • 半成品存下来了吗(有回滚点)
  • 断口是齐整的还是毛糙的(长度到顶 vs 传输层断)
  • 有没有明确状态码(429 / 401 / 403 / 500 各走各的路)
  • 后半段是不是开始忘事(上下文挤出,该开新会话了)
  • 停住的位置是文字中间还是某次外部调用(工具超时要单独隔离)
  • 我这一次重试,到底改变了哪个变量(没改就别重试)
  • 这次的处置,会不会在别处留坑(改了无关配置就回滚)

把断口当证据看,而不是当噪音看,这一个习惯就能让你少走大半的弯路——因为四类成因里有三类都不该重试,而重试恰好是大多数人的第一反应。剩下的力气,留给真正值得改的东西。

想系统学会用 AI?报名体系课或加入会员,照着学、照着用。