# JSON 流解析中断时翻译被静默截断（未引发错误）

**URL:** https://meta.discourse.org/t/translation-silently-truncated-when-json-stream-parsing-breaks-no-error-raised/407251
**Category:** Bug
**Tags:** ai, dynaloc
**Created:** [2026年七月10日 09:31 UTC](https://meta.discourse.org/t/translation-silently-truncated-when-json-stream-parsing-breaks-no-error-raised/407251 "2026-07-10T09:31:25Z")
**Posts on this page:** 1
**Showing post:** 1

<div class="post-metadata">

### Author: ![dorina](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/dorina/32/490279_2.png) [@dorina](https://meta.discourse.org/u/dorina)
#### Post date: [2026年七月10日 09:31 UTC](https://meta.discourse.org/t/translation-silently-truncated-when-json-stream-parsing-breaks-no-error-raised/407251/1 "2026-07-10T09:31:25Z")

</div>

**摘要**  
`DiscourseAi::Translation::PostLocalizer`（内容本地化）偶尔会产生截断的翻译结果，且未在任何地方记录错误日志（Rails 日志、Sidekiq 日志、Sidekiq 死信/重试队列）。截断发生在句子中间，静默进行，部分结果被保存，仿佛是一次完整且成功的翻译。

**观察到的版本：** Discourse 核心 + discourse-ai `46bea6613` (2026-07-09)，LLM：通过 Google 提供商使用的 Gemini 2.5 Flash。

**复现证据**  
我们实例上的两个真实案例：

- 一篇约 2090 字符的德语帖子翻译成西班牙语后仅产生 50 个字符，在源文本中一个引用词（“aufwendiger”）之前立即截断。
- 一篇约 1830 字符的德语帖子翻译成英语（83 个字符）和斯洛伐克语（97 个字符）——两者均在句子的_完全相同位置_截断，即在源文本中的一个表情符号简码 (💥) 之前立即截断。同一帖子的所有其他语言（法语、意大利语、葡萄牙语、俄语、希伯来语）均完整翻译（1600–1950 个字符）。

**根本原因（据我所能追溯）**  
在 `lib/completions/structured_output.rb` 中，当 `@partial_json_tracker.broken?` 为 true 时，`StructuredOutput#read_buffered_property` 会回退到 `DiscourseAi::Utils::BestEffortJsonParser.extract_key`。此回退返回 JSON 流中断之前解析到的任何内容——没有异常、没有警告、也没有任何地方表明输出不完整。在 `lib/translation/base_translator.rb#get_translation` 中，该值被直接用作最终翻译结果，并通过 `PostLocalization#save!` 持久化保存。

我们数据中的两个截断点都位于源文本中某个“特殊”字符（直引号、表情符号简码）之前，这表明 JSON 流跟踪器因模型流式输出中的某些字符/序列而混乱，并过早地将流标记为 `broken?`。

**影响**  
内容以明显不完整、有时甚至不合逻辑的翻译形式发布，且没有任何操作信号（日志、死信任务、管理员通知）来捕获此问题。我们之所以发现它，是因为一位社区成员在 UI 中注意到了句子中间的乱码。

**建议的修复方案**

- 当 `StructuredOutput#broken?` 为 true 且使用尽力而为的回退机制时，输出警告/错误（Rails.logger + Discourse-error-log），以便管理员能够检测到该问题，而不是静默发布部分内容。
- 考虑在保存 `PostLocalization` 之前，根据源文本长度对翻译长度进行合理性阈值验证。

如果有助于调试 JSON 跟踪器，我很乐意私下提供完整的原始/翻译文本对。

---

_[View the full topic](https://meta.discourse.org/t/translation-silently-truncated-when-json-stream-parsing-breaks-no-error-raised/407251)._
