2026-09-16 生产正文标签诊断¶
范围与访问方式¶
- 生产主机 SSH 别名
tender,容器tender-api、tender-worker-generation;环境prod,数据库tender_prod。 - 两容器镜像 ID 一致:
sha256:2e268034726003ff792b863999ab01bbc54d2efad2a88311baf07a3262cc2f65。 - 两容器的
section_service.pySHA-256 一致:cfb91fefa6198d97b30739a8c1de487b1258d42c4629b83a854d5a230ef404b7。 - 部署版本只接受精确的
<正文>…</正文>,尚无本地新增的section_output_parser.py。 - 先按近 30 天汇总标签错误,再对近 7 天失败原文做逐条对照。固定复核创建时间上界为北京时间 2026-09-16 12:22:41(UTC
2026-09-16T04:22:41.550428Z)。近 30 天发现的标签错误均在这 7 天内。 - 查询使用
SET TRANSACTION READ ONLY和 20 秒语句超时。完整原文留在服务器内存,只返回协议标签、计数和少量 trace ID;没有导出正文、项目名称或配图 JSON。 - 自动审批拒绝了初拟的完整原文导出,随后采用上述脱敏方式完成;未部署、重启、重放生成请求或修改生产数据。
失败形态与修正¶
共检查 916 条 section_content 且错误含“正文…标签”的生成记录。这是生成尝试数,不是用户数或最终失败章节数。
| 实际返回结构 | finish_reason | 数量 | 修正前本地规则 | 修正后处理 |
|---|---|---|---|---|
<正文>…<正文>,第二个标签在末尾 |
stop |
519 | 作为重复标签拒绝 | 恢复两标签之间的正文 |
<正文>…,缺少整个结束标签 |
stop |
138 | 拒绝 | 仅在正常结束标记下使用 EOF 边界 |
<正文>…,缺少整个结束标签 |
length |
258 | 拒绝 | 仍拒绝,并明确提示生成被截断 |
<正文>…,缺少整个结束标签 |
未记录 | 1 | 拒绝 | 仍拒绝,不能推断已经正常结束 |
此前加入的半闭合括号、转义等规则尚未覆盖这两种生产高频形态;本次修正后,657 条可恢复,259 条继续拒绝。长度截断组的 completion token 数集中在约 8192,和 finish_reason=length 一致;本次未改动模型输出上限。
915 条失败记录的持久化 Prompt 明确包含 </正文>,另 1 条没有 Prompt 记录。因此不能把这些错误归因于用户截图中的结束标签写错。
代表 trace(只用于后续只读关联):
- 末尾重复开始标签:
42a49f8e-5a3f-4035-95aa-bbbdd16f314a。 - 正常结束但漏结束标签:
cbd733e9-6fb1-4c8c-9ea6-bd12dbb5bbbc。 - 长度截断:
34d5ebed-a186-4702-a763-55eb8bc35809。 - 缺少结束原因:
f3b153d9-0e8c-4010-b563-f39132b18e58。
验证结果与限制¶
- 将当前本地纯解析函数发送到生产容器的一次性 Python 进程,在内存中对照原文;没有覆盖部署文件或调用 LLM。
- 657 条恢复记录分别按每片 257 字符重新分片,流式拼接与最终正文提取全部一致(忽略首尾空白)。这是分片模拟,不是实际供应商网络分片回放。
- 最新 200 条原本成功的记录:新旧最终正文逐字相同;流式输出与最终正文全部一致(忽略首尾空白)。未声称对全部成功记录做了回归。
- 固定时间窗内 18,731 条正文 trace 均未出现“配图需求”,所以本次没有实际生产配图输出用于证明覆盖率。配图的末尾同名标签兼容已按相同边界规则实现,并补充合成回归用例。
- 当前
generation_section_jobs中按同类错误文本查询没有记录;不能将 916 条 trace 直接视为仍待重试的后台任务。 - 持续运行的 prod 可能在统计上界之后继续产生错误;这些本地修正尚未发布。
- 初次诊断已补充解析和 service 传递
finish_reason的回归用例,当时未运行 pytest;后续用户要求模拟后的执行结果如下。
全部留存错误模拟(北京时间 2026-09-16 12:38:54)¶
本轮按用户要求只做模拟。数据库使用可重复读的只读事务,以同一快照读取全部留存的 scene_key=section_content 且错误文本含“标签”的记录,不再限制近 7 天。共 917 条,创建时间从 2026-09-11T00:56:39.862130Z 到 2026-09-16T04:38:42.266678Z;比前次增加 1 条末尾重复开始标签的失败。
| 形态 | 数量 | 最终模拟结果 |
|---|---|---|
末尾重复 <正文>、正常结束 |
520 | 全部恢复 |
| 漏写结束标签、正常结束 | 138 | 全部恢复 |
| 达到输出长度上限 | 258 | 全部按预期拒绝 |
| 未记录结束原因 | 1 | 按预期拒绝 |
- 658 条恢复正文均与独立按原始标签位置截取的预期正文逐字相同,不仅是两种新解析路径互相比较。
- 每条恢复记录分别模拟整段输入、每片 17 字符、每片 257 字符和所有实际标签逐字拆分;4 种方式均为 658/658 一致(流式比较忽略首尾空白)。未发现新的未知形态、错误放行或流式不一致。
- 同一快照抽取最新 200 条成功记录:最终正文与旧规则逐字相同,17 字符分片结果也全部一致。
- 本地执行
make test PYTEST_ARGS='tests/test_section_output_parser.py tests/test_section_service_full_code_paths.py tests/test_generation_code_paths.py -q',最终结果 38 passed, 26884 subtests passed。这些是定向解析/生成测试,不是全仓测试。 - 模拟发现并仅在本地修复一处代码围栏边界问题:单反引号标签包装不应跨行吞掉相邻代码围栏的反引号。修正为包装与标签同行,标签内部仍可包含换行;修正后重新完成上述真实记录与本地用例模拟。
- 最终模拟解析模块 SHA-256:
843933e45265a45479c0759fe994a8ecdc927627c8816ab8811dd3b25296e7ec。 - prod 部署源码哈希仍为前述
cfb91f...404b7。全程没有部署、重启、LLM 请求重放或生产文件/数据写入,原文仍只在服务器内存中处理。
结论:截至本次快照,所有已观察到的可恢复标签错误均被覆盖;剩余 259 条属于截断或缺乏正常结束证据,不能通过盲目补标签认定正文完整。结论不代表任意未来输出格式都已穷尽。