Pi Agent 写到一半就停了?一个扩展让它把话说完

Pi Agent 写到一半就停了?一个扩展让它把话说完

先说症状

我让 Pi Agent 写点长的。一段大代码,一份长分析。它写到一半,蹦出一行红字:

Model stopped because it reached the maximum output token limit.

然后停住,半截话杵在那儿。

我得手动敲一句「继续」,它才接上。过一会儿写长了,又截断,又停。我守在旁边当复读机。

还有更烦的一种:它只憋出几个字,也报这行红字。我递「继续」,它还是只憋几个字,又截断,又继续,红字刷屏。

同一行红字,两种病。下面把两种病、两种药都讲清楚。

原因有两个

模型规格页上写着三个数,拿这篇用的这个举例:最大输入 991K,最大输出 131K,上下文窗口 1M。原因就藏在这三个数里。

一个比方串起来。上下文窗口是一张桌子,1M 是桌面的大小。你塞进去的材料、模型写出来的稿子,全摊在这张桌上,加起来不能超出桌面。

最大输入 991K,是一次能往桌上堆多少材料。最大输出 131K,是模型一口气能写多长——肺活量。

桌子明明是 1M,为什么最大输入只有 991K?因为得给输出留地方。材料堆到 991K,剩下的刚好是 131K 的肺活量。两个数共用一张桌子,谁也不能独占。

认完数,看两个原因。

原因一,肺活量到头。一口气写得太长,撞了 131K,回复被拦腰截断。这时候桌子还空着呢,只是一口气太长。

原因二,桌子堆满。上下文快满了,模型刚开口,连输入带输出就顶到天花板,也报「截断」。可它这一轮其实只说了几个字。

两个症状很像,根子不一样。分不清,药就会下错。

分别怎么解决

两种病都交给同一个扩展,叫 continue-on-length。但下药之前先看病:看这一轮输出了多少。

修复后的分流判断

输出量大,说明写了一大段才撞上限,是肺活量到头,该续。输出量小到不正常,说明是桌子满,续了也白续,该去腾地方。

肺活量到头:自动递一句「继续」

既然它停了不会自己接,扩展就在截断的时候,自动替我喂一句「从中断处继续」。模型看得见自己上一条被截断的回复,给个由头,它就知道从哪儿接。

截断后自动递一句继续

两个坑。

一,不能见截断就续。有一种截断 Pi Agent 自己会处理:截断的那句话里如果带着工具调用,Pi Agent 会把残缺的调用判失败、自己重试。这种时候我再去塞「继续」,等于两个人同时指挥,把模型搞晕。所以扩展只接 Pi Agent 不管的那种:纯文本、说到一半被掐断。

二,得有刹车。一个很长的文件分十次吐完,每次都是合法续命,所以上限给得宽松。但万一模型真卡死了,每次截断同一坨,无脑续会把额度烧穿。续到上限就停,弹个提醒;只要它正常收尾过一次,计数清零。

说白了,治死循环的主防线是前面「看输出量」那一步:桌子满根本就不续,轮不到烧额度。刹车是兜底,防的是阈值没拦住、续命本身又不收敛的情况,续到上限强制停。

顺带回答一个疑问:桌子满去压缩,那输出截断为什么不去压缩?

因为压缩治的是「桌子满」,不是「肺活量」。最大输出是每条回复独立的上限,跟上下文空不空无关——就算压缩到只剩一行,这一口气还是 131K 到头。而且压缩是有损的,把已有的内容总结掉、丢掉细节;截断时你想要的是完整原文,续写从断点无损补齐。没病不吃药。

桌子堆满:不续,提示去压缩

这种病如果被当成「话没说完」,继续递「继续」,就是死循环:上下文还是满的,下一轮还是刚开口就停,每次只憋出几个字。

上下文满时的死循环

所以对桌子满,扩展不续,改提示去 /compact 腾地方。压缩把内容总结一遍、腾出桌面,模型才说得动。

药对上病根:肺活量到头 → 续写;桌子堆满 → 压缩。

总结

同一行红字,两种病。一个是单条回复的长度上限,一个是整个上下文被塞满。症状像,根子不同。

治之前先看清楚是哪一种,比什么都重要。

如果觉得有用,点个在看,转发给也被「写到一半就停」折磨过的朋友。有什么想法,评论区聊聊——你遇到过哪些 Pi Agent「该说不说完」的时刻?

END