网易首页 > 网易号 > 正文 申请入驻

83份报告被悄悄截断,真凶是一个没人读的字段

0
分享至

一封两行的客服邮件,把整条流水线的底裤掀了:“我的报告停在第6题,一共9题。另外‘下一步建议’那一节也没了?”


打开报告看,格式干净、分数齐全、评语完整,没有报错横幅。它只是提前结束了——像一本书最后三章被撕掉,封面又原样粘了回去。查下去,原因是一个从来没被读过的字段:Claude 的 stop_reason。

当它返回 max_tokens,意思是模型没写完。代码不在乎,一个 JSON 修复工具又确保别人也看不出来。这是一次解剖:一个字段如何让 83 份报告静默截断,以及把它降到零的四项改动。

先看结论

  • Claude 的响应里 stop_reason == "max_tokens",输出就是不完整的。解析之前必须先查它。
  • JSON 修复库会很乐意给截断的 JSON 补上括号,交给你一个合法但错误的对象。命中 token 上限的输出,永远不要修。
  • 这条流水线里,1,140 份报告中有 83 份(7.3%)被截断。83 份全部来自 8 题以上的会话;7 题及以下的会话一份都没有。
  • 调高 max_tokens 本身不花钱。你为实际生成的 token 付费,不为上限付费。
  • 把不能丢的字段(分数)放在 schema 最前面。模型按顺序生成,截断吃掉的永远是尾巴。

这套系统是什么

系统是 Preterview 内部的报告生成器,一个面试练习平台,由作者本人开发和运营。它跑三种面试官风格的语音面试,然后把完整转录文本发给 Claude,要求产出一份结构化书面报告:逐题反馈、评分表分数、下一步建议。

报告调用是整条链路里输出长度波动最大的地方。5 题的会话报告很短,9 题、候选人又话多的会话报告很长。当初每个会话都是 5 题时设了 max_tokens=1500,然后就把这个数字忘了。

max_tokens 到底意味着什么

stop_reason: "max_tokens" 表示 Claude 停下是因为撞到了你设的上限,不是因为它写完了。你拿回的文本只是模型本打算写的内容的前缀。对散文来说,是戛然而止;对 JSON 来说,是一份括号没闭合的文档。

正常的值是 "end_turn",模型自己写完了。还有 "tool_use"、"stop_sequence" 等取值,但对一个“给我写份 JSON 报告”的普通调用来说,任何不是 end_turn 的值都值得怀疑。

原始代码大致是这样:调用 messages.create,设 max_tokens=1500,取 resp.content[0].text,然后 json.loads(repair_json(raw)),注释还写着“以防万一”。

缺了什么?没有任何一行去读 resp.stop_reason。而那个 repair_json 调用才是真正的元凶。

截断的 JSON 为什么没报错

因为解析器外面包了一层 JSON 修复助手(json_repair 包),几个月前加进来,是为了扛住偶尔出现的多余逗号和跑偏的 markdown 代码围栏。修复库的职责就是把坏 JSON 变成合法 JSON。截断的文档只是缺了结尾的坏 JSON,于是它补上未闭合的字符串、数组和对象,返回一个能解析的东西。

截断处的尾巴长这样:第 6 题的 feedback 字符串停在半句话上。修复之后,第 6 题的评语在半句处结束,第 7 到 9 题不存在,next_steps 数组消失。然后 Pydantic 校验通过——因为 next_steps 给了默认空数组,逐题反馈又允许任意长度。

每一层都干了它该干的事。结果是一份自信满满的错误报告。

83 份截断响应里,修复助手“修好”了 79 份。只有 4 份硬失败,死法是在 key 中间断掉,修复器猜不出来。于是错误监控三周只显示 4 次失败,看起来像噪声。真实失败率是它的 20 倍。

83 份是怎么数出来的

靠数日志里的 stop_reason。这些日志一直在存,只是从来没被读过。每次调用都记录了原始 API 响应元数据,一条查询覆盖三周,答案就出来了。

这个分布就是全部故事。1,500 的 token 上限是按当初发布的产品定的,不是按正在跑的产品定的。加上更长的会话之后,大约每 10 个长会话就有 4 个报告超出上限,而流水线里没有任何环节负责说出来。

被打得最惨的用户,恰恰是练得最长、最认真的那批人。对产品投入最多的人拿到了最差的报告。这一点最扎心。

四项改动

  1. 用 stop_reason 做闸门。解析前先判断,不等于 "end_turn" 就抛 TruncatedOutput,带上 stop_reason 和 output_tokens,触发重试路径并发出告警。截断的报告从此是响亮的失败,不是安静的谎言。
  2. 抬高上限,它是免费的。max_tokens 不是预算,是防止输出失控的安全栏。报告需要 1,100 token 时,上限 4,096 和上限 1,500 花掉的钱完全一样。选 4,096,是因为之后观察到的最长报告在 p99 上是 2,350 token,留出了真实余量。
  3. 重排 schema,分数放最前。Claude 从上到下写 JSON,schema 末尾就是被切掉的地方。原顺序是摘要、逐题反馈、分数、下一步建议——分数这个用户会截图、会逐周对比的部分,正好在危险区。新顺序:分数、摘要、下一步建议,逐题反馈放最后。再截断,用户丢的是最后一题的细节,不是分数。
  4. 只修干净收尾的输出。repair_json 保留,但只在 stop_reason == "end_turn" 且 json.loads 失败时运行。那时它修的是完整答案的格式毛刺,正是它擅长的活。被切断的响应,它永远不碰。

万一还是撞上限

重试路径把它拆成两次更小的调用,而不是一次更大的。第一次要分数、摘要和下一步建议,第二次要后半段题目的逐题反馈,然后合并。每一半都稳稳落在上限内,拆分多花约 4 秒,对一份面试结束后才读的报告来说可以接受。

到目前为止,重试路径跑了 0 次。修复之后的 1,300 份报告里,stop_reason 每一次都是 end_turn。拆分调用之所以存在,是因为“这不可能发生”正是当初对原 bug 的信念。

代价

总输出 token 涨了约 5%,全部来自 8 到 9 题的报告现在能写完而不是提前停。长报告的延迟增加了大约生成缺失尾巴所需的时间。短会话没有变化。另外给 83 份截断报告背后的 61 位用户发了邮件,用存下来的转录文本重新生成了报告,花了一个脚本和一段略显尴尬的道歉。

值得刻进 CI 配置的几条:每次调用都记录 stop_reason 和 usage.output_tokens,数据躺了三周,它本可以在第一天就告诉你;在期望完整输出的流水线里,任何一次 max_tokens 停止都要告警,那是一次 bug 报告,不是噪声;输入分布一变,就重新检查你的上限,那个数字在写下的当天是对的;把“宽容”的解析当成 LLM 流水线里的负债,每一层原谅错误,就是一层掩盖错误;错误率只和你的最严检查一样诚实——监控说 0.35%,真相是 7.3%。

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
赵辰昕任河北省委副书记、省政府党组书记

赵辰昕任河北省委副书记、省政府党组书记

界面新闻
2026-10-24 18:45:46
王智、谢峰任洛阳市人民政府副市长

王智、谢峰任洛阳市人民政府副市长

极目新闻
2026-10-23 21:26:20
德国教授伪装流浪汉,在成都街头乞讨三天,成都人的做法让他泪目

德国教授伪装流浪汉,在成都街头乞讨三天,成都人的做法让他泪目

小影的娱乐
2026-10-22 02:38:12
中美大决战提前结束,中国已拿到未来,这场关乎国运的仗胜负已分

中美大决战提前结束,中国已拿到未来,这场关乎国运的仗胜负已分

最美的开始
2026-10-18 06:56:20
一辆问界汽车在陕西撞柱起火司机死亡,官方称车速139.1km/h,为何视频上车速看起来没那么快?事故责任该怎么划分?

一辆问界汽车在陕西撞柱起火司机死亡,官方称车速139.1km/h,为何视频上车速看起来没那么快?事故责任该怎么划分?

贵重物品爱美食
2026-10-21 17:50:32
马斯克的大麻烦要来了!

马斯克的大麻烦要来了!

冲哥瞰天下
2026-10-23 16:15:55
险胜马刺,火箭队火线变阵!9人轮换上线,老将中锋首秀,替补射手伤缺

险胜马刺,火箭队火线变阵!9人轮换上线,老将中锋首秀,替补射手伤缺

熊哥爱篮球
2026-10-24 18:32:38
军史上的沉默:刘伯承与徐向前,为何成了毛主席的“例外”?

军史上的沉默:刘伯承与徐向前,为何成了毛主席的“例外”?

纪史行者
2026-08-31 00:20:09
NBA常规赛明天10月25日赛程:马刺避免三连败,火箭VS老鹰

NBA常规赛明天10月25日赛程:马刺避免三连败,火箭VS老鹰

薇说体育
2026-10-24 16:09:51
官媒发文!大衣哥风波升级,涉事举报者再迎噩耗,肠子悔青也晚了

官媒发文!大衣哥风波升级,涉事举报者再迎噩耗,肠子悔青也晚了

林轻吟
2026-10-24 14:24:12
热议大连1-0成都:李国旭为本土教练扛旗,成都心态已碎成渣

热议大连1-0成都:李国旭为本土教练扛旗,成都心态已碎成渣

懂球帝
2026-10-24 17:54:13
《伟大的长征》别只埋怨博古和李德,真正要负责的人,始终不认错

《伟大的长征》别只埋怨博古和李德,真正要负责的人,始终不认错

天玑影视说
2026-10-21 11:18:14
艾弗森:31岁大女儿发消息无非三句话,要钱谢谢爱你

艾弗森:31岁大女儿发消息无非三句话,要钱谢谢爱你

赛场速报局
2026-10-22 02:19:26
全网呼吁统一养老金,决策层却为何选了另一条路?

全网呼吁统一养老金,决策层却为何选了另一条路?

你在偷看谁
2026-10-09 18:40:35
事态已经全面升级!赖清德有可能成为新中国历史上,唯一一位在任台湾地区领导人中出现重大变故的人物

事态已经全面升级!赖清德有可能成为新中国历史上,唯一一位在任台湾地区领导人中出现重大变故的人物

人生录
2026-09-11 00:05:21
12岁藏族男孩捡4岁女孩,18年后两人坠入爱河,在爱与亲情间挣扎

12岁藏族男孩捡4岁女孩,18年后两人坠入爱河,在爱与亲情间挣扎

晓艾故事汇
2025-07-05 08:09:07
曝72岁成龙跟朋友聚餐,曾志伟、谭咏麟喝到脸红,叶倩文夫妇也在

曝72岁成龙跟朋友聚餐,曾志伟、谭咏麟喝到脸红,叶倩文夫妇也在

白面书誏
2026-10-24 14:14:01
“一家人就林依轮一个中国人,其余都是外国人”!林依轮儿子结婚,家庭成员国籍话题引发热议

“一家人就林依轮一个中国人,其余都是外国人”!林依轮儿子结婚,家庭成员国籍话题引发热议

火山詩话
2026-10-24 09:58:15
普京表示,每个人都清楚地看到,在战场上击败俄罗斯是不可能的

普京表示,每个人都清楚地看到,在战场上击败俄罗斯是不可能的

山河路口
2026-10-23 19:07:24
冠军悬念留到末轮,大连英博拼下天王山之战,马马杜制胜球,朝着“奇迹”迈进

冠军悬念留到末轮,大连英博拼下天王山之战,马马杜制胜球,朝着“奇迹”迈进

替补席看球
2026-10-24 17:30:51
2026-10-24 19:24:49
薛定谔的BUG
薛定谔的BUG
有态度网友ytd
250文章数 108关注度
往期回顾 全部

科技要闻

写程序、做3D,新Kimi还有多少本事?

头条要闻

媒体:俄美乌要谈了 顿巴斯地区归属成关键“卡点”

头条要闻

媒体:俄美乌要谈了 顿巴斯地区归属成关键“卡点”

体育要闻

从乐透秀到总冠军再到没工作 一共要几年?

娱乐要闻

翁虹19岁女儿三次拒爱,在美国上学却“不随便”

财经要闻

叫"保障"不叫"保险":租车平台的文字游戏

汽车要闻

大众安徽与众09正式上市 双十一权益价16.99万起

态度原创

时尚
旅游
教育
健康
军事航空

中国韵特别策划|二胡:弦上双生,形停处意不断

旅游要闻

山城这条网红路,深深镌刻“两岸印记”

教育要闻

山东高考报名问题合集!验证码加载不出来?

痘痘能根治吗?皮肤科医生说实话

军事要闻

辽宁舰编队远海训练细节首度披露

无障碍浏览 进入关怀版