大模型API输出莫名截断?
对接大模型 API 时你是否也遇到过这种诡异现象返回结果半截就断了JSON 残缺、段落缺失finish_reason还时而length时而stop很多人只知道max_tokens会截断却忽略了stop sequence 停止词以及推理模型特殊的 token 抢占问题。本文梳理大模型输出突然中断的 3 类真实场景讲清原理、坑点与代码处理思路。前言在对接大模型 API 的过程中输出被截断 是一个非常高频但极易被误判的问题。多数开发者第一反应是max_tokens设置太小但实际上导致输出中断的原因至少有三类Stop Sequence停止词命中Max Tokens 达到上限推理模型推理过程抢占 Token 预算三者现象相似、根因不同排查方式也完全不同。下面逐一拆解。 前提认知默认情况下大模型没有配置 stop sequence输出由模型自身判断 EOS 自然结束。一、Stop Sequence停止词看似正常实则被强制截断Stop sequence 是开发者传入的一组字符串列表语义非常明确一旦生成内容命中该字符串立刻终止生成。1.1 情况一不设置 stop绝大多数业务场景模型自由生成自我判断内容完成输出 EOS 结束标记后自然停止。此时无论输出多少换行、空行都不会触发中断停止逻辑完全由模型自身控制。类比交给写手写文章写手觉得写完了就主动停笔。1.2 情况二显式配置 stop [\n\n]只要生成流中遇到\n\n双换行强制立刻终止后续所有内容。类比告诉写手只要看到句号就停下哪怕句子还没写完。1.3 坑点隐蔽的误截断业务中极容易踩坑文本内容内部本身就包含停止词字符串。例如模型输出一个地址北京市朝阳区某某路文本内部自带双换行恰好命中stop [\n\n]规则直接截断地址残缺。此时 API 返回{finish_reason: stop}从返回字段看属于正常结束但业务内容已经被拦腰截断。这种问题极难排查因为日志上看不出任何异常。1.4 Stop Sequence 适合哪些场景仅适合下面窄场景普通问答、写文章、通用业务接口不要配置 stop场景说明单词/单句输出禁止模型额外解释多轮对话防止模型模拟用户发言结构化输出需要严格切割输出边界二、Max Tokens达到最大长度上限被截断每个大模型请求都存在max_tokens最大输出 token 配额。当生成 token 数量耗尽不管当前语句、JSON 是否完整直接强行切断输出。2.1 现象示例请求返回残缺 JSON{name: 张三,age: 25,address: 北京市朝阳区某某路某某号,hobbies:[读书, 跑步, 编API 返回{finish_reason: length}明确告知输出因为长度上限被截断。2.2 正确代码处理思路拿到响应后优先判断结束原因length代表内容不完整不能直接解析使用if (length.equals(response.getFinishReason())) {// 输出被截断结果不可信// 方案调高 max_tokens 重试 / 标记本次调用失败throw new TruncatedOutputException(大模型输出token达到上限内容截断);}2.3 错误写法不校验finish_reason直接对残缺字符串执行JSON.parse()// ❌ 危险写法Object obj JSON.parseObject(response.getContent()); // 直接抛解析异常✅ 该问题特征明显残缺内容肉眼可识别相比 stop 误截断更容易发现。三、推理模型特殊坑推理过程抢占 Token 预算OpenAI o1 / o3 这类推理型模型输出分为两部分thinking 推理过程内部思考推演用户不可见但消耗 tokencontent 最终回答对外返回给业务方的内容⚠️ 关键点推理内容 最终回答共用同一套 max_tokens 预算。3.1 场景对比设置max_tokens 5000场景推理消耗回答可用结果A1000 token4000 token输出完整 ✅B4500 token500 token回答被截断 ❌此时 API 返回依旧是{finish_reason: length}3.2 排查要点排查时不能只看最终回答文本长短必须同时关注推理过程占用的 token 消耗。如果仅凭回答内容判断容易误以为 回答才几百 token 怎么就截断了从而错过真正原因。四、汇总对比表截断场景finish_reason风险等级现象说明Max Tokens 达到上限length中等内容明显残缺容易发现Stop 停止词命中stop⭐高风险返回标记显示正常业务内容悄悄残缺隐蔽难查推理模型 token 预算耗尽length中等回答被截断根源是推理思考占用大量配额核心结论不能默认 API 返回的内容一定完整三种场景都要在代码层面做判断处理。五、开发最佳实践总结慎用 stop sequence绝大多数业务场景不要自定义stop sequence交给模型自然 EOS 结束只有需要严格切割输出边界时才启用停止词。必须校验 finish_reason每次 API 响应必须校验finish_reasonlength代表内容残缺禁止直接解析 JSON、执行业务逻辑。监控推理 token 消耗使用推理类模型监控thinking推理 token 消耗预留足够 token 给最终输出。警惕停止词误命中stop 模式下警惕业务文本本身包含停止词字符串避免发生看不见的截断 bug。六、健壮响应处理模板public String safeInvoke(LLMRequest request) {LLMResponse response llmClient.chat(request);String finishReason response.getFinishReason();// 1. stop 命中可能被自定义停止词误截断需要业务侧再校验if (stop.equals(finishReason)) {if (hasCustomStop(request)) {log.warn(检测到自定义 stop 命中请确认业务内容是否完整);}return response.getContent();}// 2. length 命中内容残缺不可直接使用if (length.equals(finishReason)) {// 推理模型场景打印 thinking token 消耗辅助定位if (response.getUsage() ! null) {log.warn(输出被截断reasoning_tokens{}, completion_tokens{},response.getUsage().getReasoningTokens(),response.getUsage().getCompletionTokens());}throw new TruncatedOutputException(大模型输出被截断请调高 max_tokens 或重试);}// 3. 其他原因按业务兜底return response.getContent();}结语大模型 API 的 截断 问题本质上是输出边界控制权在谁手里的问题交给模型 → 自然 EOS最安全交给 stop sequence → 人为切割易误伤交给 max_tokens → 硬性上限必然残缺交给推理模型 → 预算共享回答被推理挤占永远不要假设 API 返回的内容是完整的。做好finish_reason校验 业务侧兜底才是稳定的工程实践。