[omni] 多模态模式开启翻译后,译文时有时无,或混在 JSON 字段里

Offen
#1,306 0 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Maintainer antworten meist innerhalb von 1 Tag

@Breadswim arbeitet bereits daran.

Seit 31.10.2026.

  • #1310 von @Breadswim — offen

Bewertung

Schwierigkeit
4/5
Geschätzter Aufwand
3-5 Tage
Anfängerfreundlichkeit
52/100
Issue-Typ
Bug
Klarheit
Größtenteils klar
Aktivitätsstatus
Aktiv
Tech-Stack
rust
Bereich
ai, backend

Rechercherichtung

Start with build_omni_prompt in openless-all/app/crates/openless-core/src/cloud_providers.rs and compare its translation handling with compose_translate_prompts in prompt_compose.rs. Trace how multimodal output and streaming deltas are parsed, then add coverage for prompt composition and translation parsing; done means translation-enabled output contains only the target-language text, including across delta boundaries.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Beschreibung

现象
  • 触发条件:

    • 识别管线:多模态模式;供应商 OpenAI(支持音频);模型 gpt-audio-1.5;风格「轻度润色」「清晰结构」
    • 翻译目标语言 English;工作语言 简体中文;输出语言偏好 简体中文
    • 录音中按翻译键,日志为 [coord] translation requested during Recording, effective=true,历史记录为 translationActive: true
    • 平台 / 版本:macOS;2.0.1+build.20261016 与 2.0.2-Beta.3+build.20261026-c9f49c60 均复现;代码定位基于 beta 最新提交 85b243ab
  • 预期行为:开启翻译时,只插入目标语言(English)的译文纯文本;未开启时,插入原语言的润色结果纯文本。这与传统模式一致:传统模式开启翻译时插入的是译文,润色后的源文另存为 source_text。

  • 当前表现:同一设置下 13 次开启翻译的听写,结果随机,没有一次能直接使用:

    结果 次数
    没有翻译:只有中文 final_text 8
    没有翻译:original_text + final_text,两个都是中文 1
    翻译了:中文 final_text + 英文 translated_text 2
    翻译了:英文放在 final_text 里 2

    所有结果都被包在 JSON 对象里上屏(见 #1304)。示例:

    {"final_text": "我使用了翻译,为什么没有输出翻译内容呢?"}
    {"final_text": "你帮我检查一下这是代码的问题还是什么原因。", "translated_text": "Please help me check whether this is a code issue or something else."}
    
  • 证据:翻译状态确实传到了多模态会话。停止录音时,update_context 把 translation_active = true 的上下文经 DictationEngineRouter 推给 SharedOmniDictationEngine:

https://github.com/Open-Less/openless/blob/85b243abd83abb295cd99e0ec31ba483c3f5c6fe/openless-all/app/crates/openless-core/src/api.rs#L8184-L8189

多模态会话据此在 system prompt 末尾追加翻译段;部分结果含英文译文,也说明模型收到了翻译指令。

初步定位
  1. 翻译指令只是在润色 system prompt(仅风格模板就有三千到五千多字)末尾追加的一行,user 消息里只有音频:

https://github.com/Open-Less/openless/blob/85b243abd83abb295cd99e0ec31ba483c3f5c6fe/openless-all/app/crates/openless-core/src/cloud_providers.rs#L2727-L2738

  1. 同一份 system prompt 开头的上下文前提里有「最终输出语言偏好:简体中文。若回答可用中文表达,请优先使用简体中文。」(来自输出语言偏好设置),与翻译目标直接冲突:

https://github.com/Open-Less/openless/blob/85b243abd83abb295cd99e0ec31ba483c3f5c6fe/openless-all/app/crates/openless-core/src/prompt_compose.rs#L180-L183

纯翻译路径 compose_translate_prompts 为避免这种冲突,会把输出语言偏好强制设为 Auto(同文件 L386-L397),多模态路径没有这样处理。
3. 多模态翻译没有可解析的输出约定。传统模式「润色 + 翻译」使用 build_polish_translate_system_prompt:输出格式标注「优先级最高」,源文 / 译文分别用 [[OPENLESS_POLISHED_SOURCE]] / [[OPENLESS_TRANSLATION]] 标记,代码用 split_polish_translate_output(流式用 PolishTranslationStream)取出译文。多模态路径没有这些,所以即使模型给出了 translated_text,应用也取不出译文。
4. 与 #1304 同源:gpt-audio-1.5 不遵循文本输出要求。例如翻译段要求「只输出译文,不要输出源文」,模型却同时输出了源文和译文。

影响
  • 多模态模式下翻译基本不可用:多数情况下得到中文原文;即使翻译了,也和原文一起包在 JSON 里上屏。
  • 界面和历史记录都显示翻译已开启,用户无法判断这次翻译是否真的生效。
建议接受标准
  • 多模态模式开启翻译时,最终插入的只有目标语言的译文(纯文本),连续多次测试结果稳定。
  • 多模态翻译采用可解析的输出约定:复用传统模式的源文 / 译文标记与 split_polish_translate_output / PolishTranslationStream,或等价方案;最终文本和流式 delta 都只包含译文。
  • 开启翻译时,输出语言偏好不再与翻译目标冲突(与 compose_translate_prompts 一致,按 Auto 处理)。
  • 识别不出译文时,不把原文当作译文静默插入(具体降级方式由维护者确定)。
  • 测试覆盖:多模态翻译的提示词组成、译文解析(含跨 delta 切分)。
TODO / 不确定项
  • 输出语言偏好冲突对结果的影响程度未单独验证(可把输出语言偏好设为「自动」做对照)。
  • Gemini、百炼等其他多模态模型共用同一份 build_omni_prompt,它们在多模态翻译下的表现未验证。
  • 多模态模式下是否改为两段式(先出源文再翻译)需要维护者确定。
  • 我可以和 #1304 一起修复,并用真实 gpt-audio-1.5 验证。
Vorherrschende Sprache
Rust
Sterne
3.7k
Forks
349
Ø Merge
2 T. 14 Std.
Gemergte PRs (30 T.)
97

Entwicklungsumgebung

Dieses Projekt bietet weder Dev-Container noch Dockerfile noch Beitragsleitfaden – die Einrichtung liegt bei Ihnen. Beginnen Sie mit der README; die allgemeinen Schritte stehen in unserem Leitfaden für den ersten Beitrag.

Erste Schritte

  1. Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
  3. Forken Sie das Repository und arbeiten Sie in einem Branch.
  4. Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.

Mehr aus Open-Less/openless

Alle Issues in Open-Less/openless

Ähnliche Issues

Weitere Issues zu Rust

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.