Skip to content

fix: 词典替换的 CJK 边界校验(不改 ASCII 行为) - #96

Merged
IchenDEV merged 1 commit into
mainfrom
agent/qa/vocabulary-cjk-boundary
Sep 18, 2026
Merged

IchenDEV merged 1 commit into
mainfrom
agent/qa/vocabulary-cjk-boundary

Conversation

@IchenDEV

Copy link
Copy Markdown
Owner

背景

VocabularyReplacementEngine 只在词条自身的首/尾字符是 ASCII 单词字符时校验边界;纯 CJK 与以 CJK 结尾的混合词条不校验,导致短 CJK 词条会改写混合标识符的 CJK 尾部,例如词典里有 密码 -> PW 时,Wi-Fi密码 被改写成 Wi-FiPW,且发生在 LLM 之前(TextProcessor.swift:35),下游无法恢复。

改动

Sources/Processing/VocabularyReplacementEngine.swift:

  • 边界校验改为对称地检查匹配两侧相邻文本字符是否 ASCII 单词字符(字母/数字/下划线),任一侧命中即不替换。
    • 纯 ASCII 词条:其首/尾字符本就是 ASCII 单词字符,校验结果与改动前完全一致。
    • CJK-only 与混合词条(如 Wi-Fi密码):获得同样的校验,不再改写混合标识符的 CJK 尾部。
  • 保留既有确定性匹配:长条目优先(再按 personal 优先于 industry、插入序兜底),从左到右贪心、游标越过整个匹配,同一位置不做重叠替换。
  • 空 original 词条在排序阶段过滤,避免零长度匹配导致的死循环。

行为对照:

输入 词条 之前 现在
Wi-Fi密码 密码->PW Wi-FiPW Wi-Fi密码
Wi-Fi密码 密码->PW, Wi-Fi密码->WFP WFP WFP
菜单栏 栏->X 菜单X 菜单X
菜单栏 栏->X, 菜单栏->MENU MENU MENU
使用开放类型输入 开放类型->OpenType 使用OpenType输入 使用OpenType输入(不变)
rapid api->API rapid rapid(不变)

测试

新增 Tests/OpenTypeTests/VocabularyReplacementEngineTests.swift(9 条),覆盖:长条目优先、短 CJK 不误替混合标识符尾部、混合条目在中文句中正常匹配、单字 CJK 在中文句中仍替换、同位置不重叠、ASCII 边界行为不变、personal 优先于 industry、空词条忽略。

  • swift build → Build complete! (4.97 secs)
  • 聚焦 swift test --filter 'VocabularyReplacementEngineTests|PromptAndProcessingTests|PersonalDictionaryLearningTests|IndustryLexiconTests|TextProcessingSnapshotTests' → 39 passed / 0 failures
  • 扩展 swift test --filter 'Processing|Prompt|Fidelity|Sanitizer|Dictionary|Lexicon|Text|Translation|QualityProbe' → 285 passed / 1 skipped / 0 failures(含行业词库 16 条评估用例与非目标文本保真)

范围

仅上述 2 个文件;无阈值、无诊断、无 UI 变更。

Vocabulary replacement only checked ASCII word boundaries when the entry's own first/last character was ASCII, so a short CJK entry could rewrite the CJK tail of a mixed identifier (e.g. 密码 inside Wi-Fi密码). Apply the boundary check to the adjacent text character on both sides, which keeps pure ASCII rule behavior identical while giving CJK-only and mixed entries the same validation. Longest-match-first ranking and non-overlapping left-to-right application are unchanged, and empty originals are ignored.

Co-authored-by: multica-agent <github@multica.ai>
@IchenDEV
IchenDEV merged commit e9037f8 into main Sep 18, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant