HTTP成功之后,还要看stop_reason
Claude API返回HTTP成功,只说明这次请求获得了消息响应,不保证正文已经完整结束。应用还应读取stop_reason,区分自然结束、输出预算耗尽、工具请求和其他状态,再决定如何展示或继续处理。
最常见的误判是:文本能够解析,就把它保存成完整文章、执行生成的代码或提交给下游。即使没有网络错误,最后一个句子、JSON字段或工具参数仍可能尚未完成。
本文提供一个不执行工具、不重新发请求的状态分类函数,帮助你先明确处理分支。
三类情况先分开
end_turn表示模型自然结束这一轮,但仍需按业务要求检查内容、格式和事实。它不是质量合格或任务权限已经验证的标志。
max_tokens表示达到本次设置的最大生成预算。此时应把内容标为可能截断,再结合任务决定调整预算、缩小任务或受控续写,不能直接隐藏停止原因并宣布完成。
tool_use表示模型正在请求工具调用,不是让前端把工具参数当成最终回答。真正的工具执行必须由应用核对工具名、参数和权限;这里的演示函数只返回待处理状态,不会自动执行。

其他停止原因不要都塞进“成功”
自定义停止序列可能让生成在特定标记处结束,应检查该标记是否符合自己的格式要求。遇到pause_turn、refusal或模型上下文相关停止原因时,也应按当前官方文档及实际模型分别处理。
接口未来可能扩展状态,因此程序应保留未知值的处理分支。把未知状态默认为“自然结束”,会在系统升级后掩盖新的不完整结果。
流式输出还涉及事件中的停止信息和中途错误。收到若干文字片段不能替代最终状态核对;本文讨论非流式响应的分类,不声称提供了完整SSE处理器。
三种停止原因怎样分流
假设一个虚构应用要求返回三个字段。响应A包含完整字段并自然结束;响应B在第二个字段处用完预算;响应C包含工具调用。三者都可能有可解析的外层消息,却需要不同的下一步。
对B,先阻止它进入“正式完成”路径,保留脱敏状态与任务标识,再评估如何继续。不要只给不完整JSON加一个大括号,就声称原结果完整。
对C,把请求交给受约束的工具层,而不是直接使用模型返回的任意字符串执行系统命令。文末函数的返回值是建议进入哪个应用分支,不是授权指令。
续写与重试,要先想清楚成本和重复处理
模型已经返回部分结果时,再发一次请求通常是新的服务调用。应有次数、输出预算和重复内容检查,不能在循环里一直等待“出现一个理想停止原因”。
若中途断线,客户端甚至可能不知道服务端最后状态。这与已经获得max_tokens响应不同,应分别记录,不把所有情况统称为“生成失败再来一次”。
需要固定格式的下游任务,还应做结构校验和业务校验。停止原因、结构合法和事实正确是不同层面的证据,任何一项都不能代替其他两项。
本文验证与未验证范围
分类函数已用本地构造的响应覆盖自然结束、截断、工具请求和未知状态,测试不会调用真实API或执行工具。它没有验证某款模型一定输出何种内容,也没有测量续写成本。
将函数接入真实应用后,应继续验证自己的展示、保存、重试和工具权限路径。文末代码适合作为最小分支起点,不能直接当成已经验收的完整内容生产系统。
保存文件、运行与逐行验收
将文末完整代码保存为classify-stop-reason.mjs,使用Node.js 22或24 LTS,运行:node classify-stop-reason.mjs --demo。无需密钥,不发HTTP请求。
应输出三行JSON,stop_reason依次为end_turn、max_tokens、future_unknown;action分别是validate_result、incomplete、review_unknown_stop。第三个值是虚构未来状态,用来验证保守分支,不是声称官方新增了这个状态。
若要在自己的程序中复用,写import {classifyStop} from "./classify-stop-reason.mjs",把实际已解析响应交给函数。只在明确传入--demo时运行内置示例;分类结果不执行续写、工具或发布。
参考资料与核验范围
资料核对日期:2026年10月18日。以下为官方原始资料;产品入口和可用范围仍以当前账户为准。
1. [官方资料1](https://platform.claude.com/docs/en/build-with-claude/handling-stop-reasons)