Localize:本地化與譯文審校
0. 一句話定位
本地化不是把 A 語言換成 B 語言,是先把 A 還原成意思,再用 B 重新寫一遍。 這個 skill 的價值不在「產出通順的譯文」(模型本來就會),而在抓住「通順但錯」的句子,並把每次的判斷沉澱成可複用的術語表、樣式表和待確認清單。
文中「實測」案例均來自真實專案,已去敏:專案與產品不具名;引語、票數和統計數字是原始記錄;標了「示意」的詞例是替換過的,不是原詞。
1. 鐵律(任何入口都適用)
- 不改用戶的原始檔案和譯文檔案。 所有產物寫進工作目錄(見 §3)。審校輸出的是發現清單,用戶勾選後才應用修改。
- 讀不出原意的地方不猜。 列進待確認清單。翻譯入口裡,影響多處的疑問先問用戶再動筆;只影響一處的,在成品旁標註「推測」。
- 模型不得聲稱「有出處」。 凡是「這個詞目標市場就這麼用」的判斷,要麼在語對包/locale 包裡有依據,要麼用 WebSearch 找到目標語同類材料的真實用例,要麼標「未驗證」。
- 生成與審校分上下文。 審校由獨立 subagent 執行;生成譯文的上下文不能審自己的譯文。
- 事實層交給腳本。 數字、日期、貨幣、URL、單位、字元規範先跑
scripts/,模型只處理腳本查不出的語義問題。模型在符號/單位層的誤報率很高,不要讓它憑感覺判 locale 錯誤。 - 每條發現帶嚴重度,且區分「錯誤」與「偏好」。 見 §6。
- 分段審,不整篇丟。 每段約 1500 原始文字元;文字越長模型標出的錯誤越少。
- 改寫可以改措辭,不能改所指。 允許換句式、換詞、重排資訊(品牌文案甚至可以重寫),但不允許換掉原文指的那個東西——用途、對象、數量、主體。發現原文的事實有問題(不存在的產品、算不通的數、自相矛盾),記進待確認清單交作者裁決,不替作者改。改了所指還會連帶製造新矛盾。
- 譯文欄只放能直接上線的字串。 待確認佔位、方案對比(A 案/B 案)、內部指標(「見下方…」)、寬度標註、處理說明,一律進獨立列或獨立清單。不是翻譯單元的東西不要在譯文表裡立行——比如「這個標籤是程式碼拼的,沒有 i18n key」「這個數存疑」,整條移進待確認清單,不要立一行然後在譯文欄寫說明。交付前跑
scripts/deliverable_check.py;char_lint.py檢雙語表時必須帶--tgt-col,否則原文列的字符會被當譯文報錯。 - 本專案的開工檔案與核心規則打架時,先記錄下來,再按衝突方向決定聽誰。 開工時寫的合規表、樣式表、術語表是當時的判斷,核心規則是跨專案的判斷,兩者會衝突(典型:合規表要求整段軟化,
diagnostics.md§10 要求功能描述保持肯定)。先分清衝突的方向,再決定聽誰:- 開工檔案比核心更嚴(禁用詞、必須寫的免責、更保守的表述強度)→ 照開工檔案做,等裁決。合規通常有它的理由,寬鬆側的錯代價更高。
- 開工檔案的事實過期了,或比核心更鬆(規格改了、限制放寬了、少了一道核心要求的處理)→ 照核心做,並把開工檔案更新掉。 兩種情況都要:① 記進待確認清單,標明是內部規則衝突而非原文問題;② 在報告裡寫明按哪條做的、為什麼。 不許靜默擇一——獨立審校遍看不到你的取捨,會把它當成違規重報一遍。
2. 輸入契約
開工前收集下表。缺項按「缺失時」列處理,並在報告頭部標註。
| 輸入 | 必需 | 缺失時 |
|---|---|---|
| 原始檔案(檔案路徑或貼上) | review/translate 必需 | 無原始檔案 → 走 §5.3 降級流程 |
| 譯文 | review 必需 | — |
| 源語 locale / 目標 locale | 必需 | 從文字自動判斷,報告標註「自動判斷」 |
材料類型(見 references/material-types.md) | 必需 | 問一次;不答則按文字特徵判斷並標註 |
| 場景一句話:誰,在什麼場合,讀這份材料,要做什麼決定 | 必需 | 問一次;不答則按材料類型取預設並在報告頭部標「場景未確認」 |
| 已有術語表 / 樣式表 | 可選 | 從 templates/ 起一份新的 |
| 版式約束(字數上限、框寬、是否軟體字串) | 可選 | 不做 G7 版式閘,報告註明 |
| 目標語同類材料樣本(translate 入口強烈建議) | 可選 | 報告註明「場景重建無樣本參照」 |
| 譯文來源(人譯 / 機器翻譯 / AI / 上一版) | review 建議 | 標「未知」 |
| 目標語文字作者/來源(目標語母語者 / 非母語者 / 未知) | 無原始檔案時必問 | 未知則降級並標明 |
| 投入檔位(見 §8) | 可選 | 預設「完整檔」 |
3. 工作目錄與產物
預設在原始檔案所在目錄建 <原始檔案名去擴展>.l10n/。用戶指定則用用戶的。
⚠ 最終報告的落盤責任在主對話,subagent 以文字返回。
實測:某些運行環境按檔名攔截 subagent 寫 findings.md/report/summary 類檔案,
而同一份 skill 在另一次工作階段裡寫同名檔案卻是通的——攔截跨工作階段會變,兩頭都不能假設。
→ subagent 產出內容、以文字返回;主對話自己落盤並核驗(ls -lT + 條目數)。
寫盤失敗時 subagent 不許改名或換 Bash 繞過——那是用另一個工具打掉剛下的攔截。
中間產物(list-a.md scripts-report.md open-questions.md 等)實測不受限,可直接寫。
歸因紀律:斷言「環境攔了我」之前先做隔離實驗(換名/換目錄/換體量各一次)。 同一次運行裡有反例(別的檔案寫成了)就不能歸因於環境。 實測:主對話斷言「沒攔是你沒寫」,subagent 用三次探針證明主對話錯了。做實驗的一方是對的。
| 檔案 | 內容 |
|---|---|
00-brief.md | 場景一句話、材料類型、語對與 locale、本次捷徑、檔位、空格等策略開關、輸入缺項 |
glossary.md | 術語表(範本 templates/glossary.md),含否決理由與狀態 |
style-sheet.md | 樣式表(範本 templates/style-sheet.md),從 locale 包預設值起 |
open-questions.md | 待確認清單(範本 templates/open-questions.md) |
scripts-report.md | R1 各腳本的輸出 |
findings.md | 審校發現清單(範本 templates/findings-report.md)。落盤責任在主對話,不在 subagent,見下 |
draft.<locale>.md | translate 入口的譯文成品(含「推測」標記) |
decisions.md | 全篇統一事項的決定記錄(術語、符號、語體、關鍵取捨) |
4. 開工前四樣東西 + 載入規則包
按順序做,寫進 00-brief.md:
-
場景一句話(§2),然後立刻把它展開成一組「能考不及格」的判據。
實測教訓:光有場景一句話不管用。 某商業提案的場景定得很具體(寫明了讀者身份、閱讀時長和讀完要做的決定), 還原樣寫進了術語決策 agent 的提示詞,好幾個關鍵術語照樣全被母語者否掉; 事後一數,術語表 60 條裡只有 9 條的依據提到「誰在讀」。場景成了座右銘,沒進到任何一條「這算不算通過」的判據裡。
所以場景必須落成下面這張表,寫進
00-brief.md,後面每個決定都拿它考一次:決定類型 用場景怎麼考(要能答「不及格」) 選詞 檢索時把場景拆成限定詞和詞一起搜(材料類型+讀者身分)。限定後找不到用例=未驗證,不許換寬泛搜法蒙混。見 diagnostics.md§7 第一關數字・單位・通貨 「這個讀者在這個時長內掃過去,能立刻有量感嗎?」——實測栽過:場景寫著「数十分で読む」,卻決定不做日圓換算,三位母語者的原話是「都度計算しなければならず読むのをやめる原因」 語域 「這個詞出現在這個讀者的日常文書裡(盡職調查報告/仕様書/社内稟議),違和嗎?」違和就換同語域的同義詞,但別把意思一起降了。見 diagnostics.md§10b結構・順序 「他在這個時長內要做那個決定,需要的信息順序是什麼?」與原始檔案順序不同時,記進待確認清單 保留不譯 「這個讀者看到原文型態(英文小標題、外幣、規格名),是專業感還是外來感?」實測:一個原樣保留的英文小標題被判「海外テンプレをそのまま使っている印象」 判據要能失敗,才叫判據。 答不出「不及格是什麼樣」的那一條,等於沒考。
-
寫下本次的「廉價對應」捷徑。 每個語對都有一條看起來合法的捷徑:語對之間存在一個「看起來能一一映射」的淺層(詞形/字形/詞序),真正的差異住在更深一層(義項/地區詞彙/句法)。映射表越好用,越危險。 從語對包的第一節抄,或者(無語對包時)讓模型先寫一條假設。
-
載入規則包:
| 包 | 路徑 | 無包時 |
|---|---|---|
| 語對包(方向相關) | references/pairs/<src>-<tgt>.md,如 zh-ja.md | 模型自寫捷徑假設;G3/G6 置信度降級;報告頭部標「無語對包」 |
| 目標 locale 包 | references/locales/<locale>.md,如 ja-JP.md | 樣式表從空範本起;G5 置信度降級;報告標「無 locale 包」 |
| 材料類型規則 | references/material-types.md | — |
現有包:pairs = zh-ja(完整)、ja-zh、en-ja、ja-en、zh-en、en-zh(種子);locales = ja-JP(完整)、zh-CN、zh-TW、en-US、en-GB(種子)。種子包只放有出處的內容,缺的部分明寫。 4. 起術語表、樣式表、待確認清單。 術語表邊做邊長,每定一個詞記一條;樣式表從 locale 包預設值複製後按專案改;待確認清單從第一句就開始記。
5. 三個入口
5.1 review:審校已有譯文(有原始檔案 + 有譯文)
這是最容易做錯的型態,誘惑是「只讀譯文找彆扭的地方」。實證結論:單語單獨一遍最差;必須有雙語對照這一遍;從譯文起步;兩遍順序自由。
R0 收集輸入(含目標語文字作者/來源)→ 寫 00-brief.md → 載入規則包 → 起三樣東西
R1 跑腳本(§7):fact_check / char_lint / length_estimate / term_coverage / **distribution_check** → scripts-report.md
**`distribution_check` 要在單語遍之前跑**:它報的是全篇分佈,而單語遍是逐條看的,
先拿到分佈數據,單語遍才知道該往哪看。
R2 分段:原始檔案與譯文按段落對齊,每段 ≤ 約1500 原始文字元,編號 S01, S02…
R3 單語遍(獨立 subagent,只給譯文 + locale 包 + 場景):
標出「讀起來不像母語者寫的」位置、四觸發器命中、語體斷裂
→ **原樣寫進 `review/list-a.md`**(不是摘要,是原件)
→ **主對話核驗檔案存在、行數 ≥ 候選條數**,核不過就重跑 R3,不許帶著摘要往下走
R4 雙語遍(獨立 subagent,逐段給原始檔案 + 譯文 + 語對包 + 術語表中命中的條目):
五類只有對照才能發現的錯誤 + 模型特有失敗(漏句/加戲/過度潤色)+ 資訊顆粒計數
→ 輸出 list-B
R5 合併去重,按 §6 定嚴重度,按 §6 三選項格式寫建議
**合併後必須報一行:list-A 有 N 條,其中 M 條進了最終清單。**
單語遍的發現被整批篩掉是流程失敗,不是「它們不重要」——見 §5.5。
R6 懷疑論者覆核(獨立 subagent,**必須給它 Read/grep 能力**):逐條審 critical/major,
預設不確定即降級;按建議改寫一次,改後沒有明顯變好的降為 neutral;
實測經驗:約一半的 critical/major 會被降級,且有條目的論據會被 grep 直接推翻
**懷疑論者只管降級,不管漏判。** 它審不到的 minor 不等於可以不處理,見 §5.5。
R7 寫 findings.md;更新 glossary.md / open-questions.md / decisions.md
R8 給用戶:先列全篇統一事項讓用戶定,再逐條清單讓用戶勾選;勾選後才應用
R3/R4/R6 的 subagent 提示詞範本在 references/subagent-prompts.md,必須自包含(把檔案路徑、場景、捷徑都寫進去,不依賴繼承的上下文)。
本 skill 的絕對路徑是 ${CLAUDE_SKILL_DIR}。 派發前把範本裡的 {{skill_dir}} 全部替換成它,否則 subagent 讀不到語對包/locale 包。
(若上面顯示的仍是字面的 ${CLAUDE_SKILL_DIR}、沒被替換成路徑——例如在 Codex 等其他工具裡——就用本 SKILL.md 所在目錄的絕對路徑;本檔案裡其他 ${CLAUDE_SKILL_DIR} 同理。)
5.5 單語遍的發現不許在合併時蒸發
這是實測踩過的坑,不是理論擔心。 某 SaaS 落地頁專案那次,母語者回饋的 10 條裡有 8 條我方單語遍早就報過,其中 6 條根本沒進懷疑論者覆核——因為合併時是從雙語遍的發現(漏譯/所指/術語)裡挑候選,單語遍的讀感發現被整批篩掉了。單語遍存在的唯一理由就是抓「讀起來像翻譯」,它的產出在進覆核之前就被丟了。
成因是結構性的三條疊加:① 單語遍的發現幾乎都是 minor(那正是 minor 的定義);② 懷疑論者按設計只審 critical/major,minor 永遠進不了覆核;③ 嚴重度表按單條定級,單條「不影響理解」、一堆疊在同一句上就是「這句讀著像翻譯」,沒有任何一步會把它們加起來。
四條固定動作(按流程先後):
- A. list-A 必須落盤,且由主對話核驗。 摘要頂不上原件——§9.1 的交叉核對是逐條比對 list-A,只有摘要就斷鏈,事後想查「這條我們當初報過沒有」都查不了。光寫「必須落盤」這條規則不夠:實測那次沒落盤,是因為 subagent 回寫時 API 400 中斷了,規則攔不住網路錯誤。所以這是主對話自己的動作——R3 結束後主對話自己
wc -l確認檔案在、行數對得上,才准進 R5。(agent 說完成了,主對話必須自己核。) - B. 密度升級。 同一條字串被單語遍報 ≥3 次,無論單條多輕,整條進 T5 重寫候選。理由:三個獨立毛病壓在一句上,逐條改改不動它,重寫才快。
- C. 單語遍的「重寫更快」「讀不通」是硬訊號。 單語遍說某段「個別修正より書き直しが早い」或「完全讀不懂」時,直接進 T5,不經過嚴重度篩選。這是它作為母語視角唯一能給的強判斷,不許當成 minor 處理掉。
- D. 合併時報存活率。 R5 輸出必須有一行「list-A N 條 → 最終清單 M 條」。M/N 明顯偏低就回去看是不是又只挑了雙語遍的發現。
為什麼不直接讓懷疑論者也審 minor:會把它的職責沖淡。它的任務是降級(防定級過重),不是兜底。漏判要靠上面四條在落盤和合併階段解決,不能指望覆核環節補。
5.6 組級的發現,不許靠改一個成員來「修掉」
實測踩過,而且改出了負分。 某真實專案裡一組四個選項各有一條說明標籤,單語遍報的是 「四個選項說明軸不齊」——四條分別在講用途、推薦度、品質和規格。 這是一條關於這四條作為一組的發現。當時的處理是只重寫了最扎眼的那一條。結果: 軸還是不齊(另外三條沒動),而被改的那條在後來的三人盲測裡全票判為三版中最差, 比我改之前的原文還差。改一個成員,既沒解決組的問題,又新增了一個個體問題。
判據:發現的表述裡出現「不齊」「不統一」「不平行」「風格不一致」「這幾條之間」—— 主語是複數,那它就是組級發現。
兩個合法處理,沒有第三個:
- 整組一起改,改完整組一起驗(版式、寬度、軸、語體都按組看)。
- 整組不動,把這條記進待確認清單,寫明「需整組重寫,本輪未做」。
不許挑組裡最扎眼的一條改掉然後當它解決了。組級發現的正確交付物是 一整組的替換方案,不是一條。
5.6a 整組重寫完,必須回樣式表覆核——組級修復不許違反已經管著這些成員的約束
§5.6 說「整組改」,但只說了一半。 實測:按 §5.6 整組重寫了那組標籤,軸統一了、寬度也收斂了 (3.00×→1.43×),母語者盲測卻輸給「只改被點名那一條」——兩人否決的理由是 「体言止めで短く揃えるのが日本のUI標準」,而這條早就寫在該專案自己的樣式表裡。 軸修好了,語體規矩踩了。根因不在規則,在提示詞憑記憶複述約束、沒抄樣式表原文。
固定動作:改寫任何已定稿的字串之前,先問「這條已經被哪些決定管著」, 並把那些條目的原文抄進提示詞——不許憑記憶複述。 至少要抄這四類:
| 要抄的 | 從哪抄 |
|---|---|
| 命中的術語條目 | glossary.md |
| 適用的樣式表行(語體、結尾、標點、空格、寬度硬約束) | style-sheet.md ← 最容易漏的就是這一類 |
| 該平行組既定的寫法軸 | style-sheet.md「平行組的寫法軸」行 |
| 場景一句話與本次捷徑 | 00-brief.md |
T3 本來就有這條要求(§5.2「每段帶 glossary 命中條目 + style-sheet + 場景 + 捷徑」)。 踩坑的是流程外的臨時改寫任務——修母語回饋、做融合版、補一條漏譯。 這類任務不走 T3 編號,就容易被當成「順手改一下」而不帶 payload。它們和 T3 一樣要帶全。
平行組的軸撞上「所指」時,所指優先——破軸,不許改意思。
實測:原始檔案四格裡三格是 A + B、一格是 A / B(或),樣式表把這一組的連接符統一定成「+」。
生成側照軸走,把那一格的**「或」寫成了「與」——為了版式統一改掉了原始檔案的意思,正是鐵律 8 禁的事。
軸是措辭層,所指是事實層。 撞上了就讓這一格破軸(用「/」),並在報告裡寫明為什麼破。
版式一致性不能凌駕於所指之上**——這一條也要寫進審校側的檢查項,因為它讀起來完全通順,只有對照原始檔案才看得出。
覆核動作:整組改完,拿新的一組逐條對樣式表打勾,
再確認新組沒有引入舊組沒有的問題(寬度、語體、標點、與相鄰組的一致性)。
length_estimate.py --siblings 只能看寬度,語體得人看。
副產品:組內離散度是可機檢的。 平行組(key 裡只有一個 token 變化,如
plan_lite_/standard_/pro_/max_description,示意)的顯示寬度極差,length_estimate.py --siblings
會列出來。某真實專案實測 6 個平行組,5 組極差 ≤1.67 倍,只有被改壞的那組是 3.00 倍。
腳本只列不判——閾值定在幾倍沒有跨專案依據,別硬編一個。
5.2 translate:從零翻譯(只有原始檔案)
T0 收集輸入(盡量要目標語同類材料樣本)→ 00-brief.md → 載入規則包
T1 全文預分析,不動筆:通讀全文 → 抽術語候選 → 列待確認清單
影響多處的疑問 → 先問用戶;只影響一處 → 標「推測」繼續
T2 術語決策(三關:既有詞?撞車?放得進版式?)→ glossary.md
**確定性刻度、狀態徽章這類「自成一套」的詞,必須去目標市場的同類材料裡找既有說法。**
實測:流程為防止確定性上調設計了四檔刻度,最強檔定為 `検証済み`——**設計對,選詞錯**。
三位母語者一致指出投資材料 traction 徽章的定番是 `実績`,`検証済み` 會讓人想到第三方驗證。
**一套自洽的刻度,不等於目標市場在用的刻度。**
**術語的出處要連「那份材料給誰看」一起記——詞在目標語裡存在 ≠ 目標讀者一讀就懂。**
實測**四次同型**:四個詞都被當成「已驗證」,依據分別是別家的產品頁、通用詞典、自己設計的刻度、廠商技術部落格——
結果一個是別家產品能做、材料中的產品做不到的事;一個在日語裡只用於另一個領域;
一個在目標讀者的材料裡是過大表示;一個技術讀者常用、業務讀者幾乎不用。
**共同根因**:出處的讀者和材料的讀者不是同一群人。
→ 出處欄必須寫成 `來源(讀者畫像)` 的形式:`某廠商技術部落格(讀者=エンジニア)` 與
`面向投資方的事業計畫書(讀者=投資担当)` **是兩回事,不能互相頂替**。
驗證時優先找**面向同一類讀者**的材料。
**詞條的挑選不能只憑「這個詞看著難」,必須先跑一遍頻次**:
`term_coverage.py cover` 列出原始檔案高頻實詞裡術語表沒收的。**高頻 + 反覆出現在並列位置的詞必須有條目**,
哪怕它看著一點都不難——決定不收的,也在表裡寫一行「不需要統一,理由是…」,讓下一個人看得見。
實測漏過:`團隊`(9 處) 和 `企業`(10 處) 都因為「看著不難」沒進表,譯文各出現兩種譯法,
而**表裡收了的詞一致性 100%**。沒有條目 → 機械一致清單不覆蓋 → 交付前 grep 閘查不到 →
雙語遍「有沒有照表用」無表可照。**一層漏,四層全空。**
樣式表從 locale 包預設值起 → style-sheet.md
**收工前必須做決定檔案之間的一致性對帳**:同一個詞在 glossary / style-sheet / decisions
三處的寫法必須一致。實測踩過——glossary 定 `一括エクスポート`,
style-sheet 的同一個平行組卻寫 `まとめて書き出し`(詞例為示意),生成側只能二選一,
選哪個都會讓審校側報錯。**兩份決定檔案打架,下游無解。**
機檢:把 glossary 的「目標語詞」欄逐個 grep 另外兩個檔案,出現不同形態就停下來統一。
T3 分段生成(每段帶同一份 glossary 中命中的條目 + style-sheet + 場景 + 捷徑):
① 意圖抽出:這句到底想說什麼(脫離字面)
② 場景重建:目標市場的人在這個場景會怎麼寫(有樣本就對照樣本的句式/語體)
③ 語感打磨:語體、長度、與全篇一致
隨時自問:我選這個詞是因為源語也是這個形式(翻譯),還是這類材料就這麼寫(本地化)?
→ draft.<locale>.md
T4 對 (原始檔案, draft) 跑 §5.1 的 R1–R7(獨立上下文)
T5 按 findings 修訂 draft;跑一致性掃描(術語表每個詞在全文的實際用法);
**再跑一次 `distribution_check`**——逐條修訂會改變全篇分佈,改完必須重新看分佈
T6 交付:draft + glossary + style-sheet + open-questions + decisions(+ 長度報告)
5.2b adapt:作者授權後的結構/體裁重構(MVP)
translate 已允許換句式和重排措辭;adapt 的區別是事前授權 + 可審計的結構/體裁重構。使用者只說「翻譯/本地化」時仍走 translate;說「按日本市場重做/改成日本公司寫法/重構提案」且明確授權時才走 adapt。
開始前必須具備:目標讀者匹配的同類材料樣本、作者授權表、成功標準。缺任何一項就停止 adapt 或退回 translate,不能靠模型自判。
可以重構:標題和資訊層級、段落/步驟順序、合併/拆分表達單元、目標市場的顯示層級、已獲授權的行業/體裁表達、 呈現形式(散文 ↔ 表格/編號步驟,AUTH-08)——這一項單列,因為散文改表格會把一句話拆進幾個格子,條件和否定最容易在拆的過程中掉出去。 永遠不能改:數字、日期、主體、對象、數量、時間、功能、價格、免費/付費條件、效果強度、法律含義、否定和限制。
流程:A0 輸入/授權 → A1 目標市場慣例 → A2 事實帳本 → A3 最多兩個結構方案並等待作者批准 → A4 分段重構 → A5 獨立事實/所指與自然度審校 → A6 作者驗收。作者未批准結構方案不能生成;作者未驗收不能稱為完成。
產物:authorization.md、market-conventions.md、fact-ledger.md、structure-options.md、adapt-map.md、decisions.md、open-questions.md、成稿;adapt-map 支援一個源單元對應多個目標單元、多個源單元合併到一個目標單元。N≠M 不等於漏譯,必須經映射和事實帳本核對。
操作型材料還要有 task-test.md:關鍵任務成功率不能低於 translate;更自然但讓使用者更容易操作失敗,adapt 判失敗。
兩道機檢閘(不跑不許往下走):
# A3→A4:沒有真實的作者批准事件就不許生成
python3 ${CLAUDE_SKILL_DIR}/scripts/adapt_check.py gate \
--authorization <授權表> --structure <結構方案> --conventions <市場慣例> [--map <adapt-map>]
# A4→A5:多對多映射與事實顆粒逐個落地
python3 ${CLAUDE_SKILL_DIR}/scripts/adapt_check.py map \
--source <原始檔案> --ledger <事實帳本> --map <adapt-map> --draft <目標稿> \
--authorization <授權表> --glossary <術語表>
原始檔案和目標稿都要打單元錨點(<!-- SRC-001 --> / <!-- TGT-001 -->),否則無法做單元級核對。
gate 退出碼 2 = 不得生成。它攔的是:AUTH-07 被解鎖、標了「已授權」卻沒有作者確認事件、
批准方案還是 A / B / 不批准 這種佔位、沒有讀者匹配的已驗證樣本、map 引用了未授權的 AUTH。
「模型自己在表裡填已批准」正是這道閘要攔的東西。
map 退出碼 1 = 有阻塞。它攔的是:帳本雜湊與原始檔案對不上(生成後回頭改帳本)、原始/目標單元未映射或無來源、
帳本顆粒在落地表裡沒有行(映射缺口)、落地表改寫了帳本的原始檔案值、
聲明的目標實現串在那個目標單元裡找不到(合併時顆粒被丟)、主體的目標實現與術語表定譯不符(受益人被換)、
數字/日期/URL 有一邊獨有(丟事實或加事實)。
這兩道閘能證明和不能證明什麼,必須一起說:腳本只驗證「聲明的串是否逐字出現在指定單元」,
不判斷這個串在語義上是否真的表達了那個顆粒——把否定刪了同時把落地表也改成一個確實存在的無關串,機檢會放過。
另一個洞是目標側覆蓋只到單元級:它保證每個目標單元有來源,不保證單元內部每句話都有來源,
所以在已映射的單元裡塞一句編造的話,腳本看不見(只有數字/日期/URL 那一層能兜住一部分)。
→ 對策:adapt-map 裡必須人工列一張「新增的文字」表,把表頭、腳註記號、指路句、小標題這類
非原始檔案斷言的東西逐條寫出來,交獨立審校核。
語義是否保住歸範本 F 的獨立審校,體裁是否合適歸作者驗收。腳本通過 ≠ adapt 通過。
詳細範本和提示詞見 templates/authorization.md、templates/adapt-map.md、references/subagent-prompts.md 範本 E/F。
當前驗證狀態:授權門與事實映射合約有 32 項自動正反回歸(evals/test_adapt_checks.py,樣本在 evals/smoke/adapt/),
含「2→1 合併保留全部條件應通過 / 刪一個否定必須失敗 / 換受益人必須失敗 / 未批准不得生成」。
真實材料(Joplin 說明文件 en→ja,Evernote 一節 15 單元 → 9 單元)跑通了 A0–A4:
gate 與 map 均 0 阻塞,五次對抗性篡改全部被攔(含「同時改稿又改申報」的受益人偷換)。
A5 獨立審校已做(埋坑輪 + 乾淨輪雙輪驗證);A6 作者驗收、目標使用者任務測試、母語通讀還沒做——這三項不做完不得宣稱 adapt 通過。
實測教訓:真實材料上首跑報出的 5 個問題全部是閘門/範本自身的缺陷
(方案名限死單字母、慣例檔案的兩表式、英語拼寫數字、閘門攔住它自己授權的「散文→編號步驟」、
無結構變化的行被逼引用授權)。閘門第一次接觸真材料時報的錯,先懷疑閘門。
5.3 無原始檔案(只有譯文)
沒有原始檔案時,漏譯、所指偏移、數字錯配等翻譯實質錯誤不能排查;能做語感、內部一致性、表記規範。
跑 char_lint / term_coverage / distribution_check(轉寫率不適用)與 R3,並把不能判斷的列入待確認。
但 sourceLanguage 標的語言 ≠ 文字作者是該語言的母語者。 無原始檔案開工時必問:
「這段目標語是誰寫的?」
- 目標語母語者寫的 → 上述限制成立;不能把讀感問題寫成翻譯錯誤。
- 非母語者直接寫的(獨立開發者、出海團隊自研文案)→ 作者母語是「隱形原始檔案」,
載入對應
pairs/<作者母語>-<目標語>.md,按雙語遍的方法掃母語干擾;可以查出假朋友、作者母語詞殘留、同概念漏統一, 但報告寫清這是「母語干擾」,不是原始檔案—譯文對照結論。 - 作者未知 → 不猜作者母語;只報目標語內部可證的問題,另標「作者來源未確認」。
實測(某 App,目標語文案由非母語作者直接寫成):單語遍找出幾處作者母語的詞殘留; 同一 App 的其他字串裡,同一概念已經寫成了地道的說法,因此這些是內部可證的母語干擾。 這類在獨立開發者/出海團隊裡是常態,不是特例。
5.4 多語並行 / 持續更新(簡要)
多語並行:先定 source of truth;術語表加列(概念 | 語言 A | 語言 B…);數字和事實在所有版本間對帳(fact_check.py 兩兩跑);保留「有意不同」說明。
持續更新:術語表和樣式表是長期資產,放在使用者專案裡而不是 .l10n/ 臨時目錄;新增內容只走 R1–R4。
6. 嚴重度、發現格式、三選項
…