
我的 Blog 原本已經有 `cmpt-translate`, 也就是頁面可以即時翻譯成英文

但在多倫多 coffee chat 的時候, 有人直接建議我: 如果 Blog 要當作品集的一部分, 預設語言應該是英文

這句話點到的不是功能問題, 而是內容主體問題

即時翻譯可以把頁面轉成另一種語言, 但它不等於我真的有英文內容, 也不等於我有一套可以長期維護英文文章的 workflow

所以我開始做 [`content-i18n`](https://github.com/loustack17/content-i18n)

目標很明確: 把 Blog 從 "中文為主, 英文靠即時翻譯" 變成真的有英文文章可以維護

## 問題不是翻得更快

如果只是要先拿到英文草稿, 方法很多:

- 直接貼到 AI Chat
- 用 Google Translate 或 DeepL
- call translation API 產生初稿
- 讓 agent 幫忙改成英文

這些方法都能用, 速度也快

但技術 Blog 不是只有 prose

一篇文章通常會混在一起:

- heading 和 section 順序
- code block
- inline command
- config key
- product name
- error string
- table
- blockquote
- argument flow

我要保留的是同一篇文章, 不是只把文字換成另一種語言

所以核心規則很簡單:

- same article
- different language only

## Fidelity-first 的意思

fidelity-first 不是逐字翻譯, 也不是讓英文變得很僵

它處理的是一個取捨: 當 "讀起來更順" 和 "保住原文" 開始衝突時, workflow 要先保哪一邊

我的答案是先保原文

所以 `content-i18n` 會檢查這些東西:

- heading hierarchy
- section order
- paragraph coverage
- list structure
- table structure
- code block
- technical inline literal
- link 和 reference
- argument flow
- conclusion scope

如果英文讀起來很順, 但少了一個 caveat, 壓掉一個例子, 或把 command 改成另一種說法, 那就不是我要的結果

這也是為什麼我後來把 translation 當成 validation problem, 而不是只看 generation quality

## 即時翻譯不夠的地方

最麻煩的不是模型翻得完全錯

更常見的是看起來差不多, 但內容慢慢 drift

我遇過的問題包括:

- opening paragraph 被翻得比原文更曲折, 甚至多出原文沒有的內容
- heading 變得像文章標題, 但原本要強調的點不見了
- code block 還在, 但 surrounding sentence 意思偏掉
- 某一段被 AI 覺得重複, 就自己幫我精簡
- 英文稿裡還殘留中文

這些問題不一定會讓文章看起來壞掉, 但會讓文章慢慢變成另一篇

所以我不想要每次都靠 copy-paste, 再自己從頭檢查一次

## Workflow 設計

最後我需要的是 workflow, 不是一個 prompt

```text
prepare
  -> write target
  -> review
  -> fix
  -> sync-status
```

每一步都有自己的責任

### prepare

`prepare` 不只是讀 source file

它在定義 translation unit:

- source path
- target path
- structure fingerprint
- glossary
- style pack
- prompt context
- target metadata

這一步會影響輸出穩定性

如果每次給 AI 或 provider 的 context 都不一樣, target 很難穩定

### write target

`write target` 是產生草稿

草稿可以來自人, AI model, 或 provider-backed workflow

但 target file 存在不代表完成

草稿永遠只是草稿

### review

`review` 是整條 workflow 最重要的一步

它不能只看英文順不順或文法對不對

它要檢查:

- heading 有沒有對齊
- blockquote 和 table 還在不在
- code block 有沒有被改
- technical inline literal 有沒有 drift
- 應該翻譯的地方還有沒有 source language

對知識管理內容來說, 這種 review 比單純看文法更有用

### sync-status

`sync-status` 會把 completion 寫成正式狀態

沒有這一步, queue 很難分辨:

- 只是有人改過的草稿
- 還是真的 review 過, 且仍然跟 source 同步的 translation

## Queue state

Queue state 讓這個工具開始不像一堆 command, 而比較像一個 system

`content-i18n` 用三種 state:

- `completed`
- `stale`
- `missing`

這些 state 不是手動標記, 而是從這些資料推導:

- source discovery
- expected target file
- source hash
- translation status

翻譯不是一次性任務

今天 complete 的 target, 只要 source 改了, 明天就可能 stale

我的 Blog 文章本來就會一直修: 改句子, 補段落, 調例子, 修結構

所以 workflow 不能只問有沒有翻過

它還要問現在還有沒有 match source

## Completion rule

Completion 不能模糊

我最後把規則定成這樣:

1. review 或 validation 要 pass
2. 應該翻譯的地方不能殘留 source language
3. `sync-status` 要成功

這比 "看起來差不多" 窄很多

我常遇到 structure 看起來沒問題, 但 heading, metadata, inline note 裡還殘留沒翻完整的內容

這種東西如果不擋, 很容易混進正式內容

`sync-status` 的價值就在這裡

它把 completion 從主觀感覺, 變成系統可以推導和追蹤的狀態

## 為什麼做成 standalone tool

如果只是翻譯 Blog, 幾支 script 也能用

但後來我需要這些東西:

- queue model
- provider option
- repeatable prepare / review / sync step
- stricter validation
- MCP interface 給 agent 用

這些需求一多, script 就不夠清楚

做成 standalone tool 之後, boundary 比較乾淨:

- config 留在 consumer repo
- provider secret 留在 repo 外
- workflow 邏輯留在工具裡
- site routing 和 theme 不跟 translation engine 混在一起

這樣它才比較像可以長期維護的工具, 不是只在 Blog 裡湊合著用的 script

## 最後整理

`content-i18n` 一開始要解的問題很單純: 讓 Blog 從 runtime translation, 變成真的有英文內容可以維護

但實作後, 問題變成:

- 如何保持同一篇文章
- 哪些東西必須被保住
- 什麼才算真的完成
- queue 要怎麼追蹤 translation state

最後我需要的不是一次產生英文稿, 而是一套可以長期維護英文內容的 workflow

## References

1. [content-i18n GitHub Repository](https://github.com/loustack17/content-i18n)
2. [Model Context Protocol — What is MCP?](https://modelcontextprotocol.io/docs/getting-started/intro)
3. [Model Context Protocol — Architecture Overview](https://modelcontextprotocol.io/docs/learn/architecture)
4. [DeepL Documentation — Supported Languages](https://developers.deepl.com/docs/resources/supported-languages)
5. [GitHub Docs — Reusing Workflows](https://docs.github.com/actions/learn-github-actions/reusing-workflows)
