ข้ามไปยังเนื้อหาหลัก

การทำงานของ Sync

คำสั่ง sync คือการทำงานหลักของ rosetta และนี่คือสิ่งที่จะเกิดขึ้นเมื่อคุณรัน npx i18n-rosetta sync

ภาพรวมของ Pipeline

ขั้นตอนการทำงาน

1. การอ่านค่า Config

Rosetta จะโหลด i18n-rosetta.config.json (หรือตรวจจับการตั้งค่าโดยอัตโนมัติ) โดยจะจัดการสิ่งต่อไปนี้:

  • Locale ต้นทางและ locale ปลายทาง
  • กราฟการจับคู่ (การจับคู่ต้นทาง→ปลายทางใดบ้างที่ต้องประมวลผล)
  • การตั้งค่า method, model และคุณภาพสำหรับแต่ละคู่

ก่อนที่จะสแกนไฟล์ rosetta จะแสดงส่วนหัวตอนเริ่มต้นทำงาน:

i18n-rosetta v3.3.2

[INFO] Detected format: json (auto)
[INFO] Detected framework: Hugo
  • ป้ายแสดงเวอร์ชัน: แสดงเวอร์ชันที่ติดตั้งไว้สำหรับการดีบักและการรายงานปัญหา
  • การตรวจจับรูปแบบไฟล์: รายงานรูปแบบไฟล์และระบุว่าเป็นการตรวจจับอัตโนมัติ (auto) หรือมีการตั้งค่าไว้อย่างชัดเจน (config) รองรับ json, toml และ yaml
  • การตรวจจับ Framework: เมื่อมีการตั้งค่า contentDir จะทำการระบุ framework (Hugo) เพื่อยืนยันว่าการซิงค์เนื้อหา (content sync) ทำงานอยู่

2. การสแกนไฟล์ต้นทาง

ไฟล์ locale ต้นทางจะถูกโหลดและแปลงให้อยู่ในรูปแบบ key→value map แบบแบนราบ (flattened):

// Input (nested)
{ "hero": { "title": "Welcome", "subtitle": "Build" } }

// Flattened
{ "hero.title": "Welcome", "hero.subtitle": "Build" }

3. การตรวจจับการเปลี่ยนแปลง

Rosetta จะอ่าน .i18n-rosetta.lock ซึ่งเก็บค่า SHA-256 hashes ของค่าต้นทางที่เคยแปลไปแล้ว สำหรับแต่ละ key ระบบจะตรวจสอบดังนี้:

เงื่อนไขการดำเนินการ
ไม่มี Key ในไฟล์ปลายทางแปล
Hash ต้นทางเปลี่ยนไปจากการซิงค์ครั้งล่าสุดแปลใหม่ (ข้อมูลเก่า)
ค่าปลายทางขึ้นต้นด้วย [EN]แปลใหม่ (เครื่องหมาย fallback แบบเก่า)
Hash ต้นทางไม่เปลี่ยนแปลง และมี key อยู่แล้วข้าม

นี่คือเหตุผลที่ rosetta แปลเฉพาะส่วนที่มีการเปลี่ยนแปลงเท่านั้น — ระบบไม่ได้แปลไฟล์ของคุณใหม่ทั้งหมดในทุกๆ การซิงค์

4. การจัดกลุ่ม (Batching)

Key ต่างๆ จะถูกจัดกลุ่มเป็น batch (ค่าเริ่มต้น: 80 keys/batch สำหรับ LLM, 128 สำหรับ Google Translate) การจัดกลุ่มช่วยลดจำนวนครั้งในการเรียก API ในขณะที่ยังคงรักษาขนาดของ prompt ให้อยู่ในระดับที่จัดการได้

ในระหว่างการแปล rosetta จะแสดงแถบความคืบหน้าแบบอินไลน์ที่จะอัปเดตหลังจากแต่ละ batch เสร็จสมบูรณ์:

[INFO] fr.json — 2,847 missing
████████████████░░░░░░░░░░░░░░░░ 1,440/2,847 keys

แถบความคืบหน้าจะแสดงผลโดยใช้ \r carriage return เพื่ออัปเดตในบรรทัดเดิม — ไม่มีการเลื่อนหน้าจอ จะถูกระงับการแสดงผลในโหมด --quiet และ --json

4b. Translation Memory

ก่อนการจัดกลุ่ม rosetta จะตรวจสอบแคชของ Translation Memory (.rosetta/tm.json) Key ที่มีข้อความต้นทาง + locale + method ตรงกับที่เคยแปลไปแล้ว จะถูกดึงมาจากแคชทันที — โดยไม่ต้องเรียก API

[TM] 142 key(s) served from cache
Translating 3 key(s) to French (llm)... [OK]

TM คือกลไกหลักในการประหยัดค่าใช้จ่าย การรัน sync ใหม่หลังจากมีการเปลี่ยนแปลงเพียง key เดียว จะแปลเฉพาะ key นั้น ไม่ใช่ทั้งไฟล์ ดูรายละเอียดเพิ่มเติมได้ที่ Translation Memory

หากต้องการข้ามการใช้แคชสำหรับการรันเพียงครั้งเดียว: i18n-rosetta sync --no-tm

5. การแปล

แต่ละ batch จะถูกส่งไปยัง translation method ที่ตั้งค่าไว้:

  • llm: ส่ง prompt แบบมีโครงสร้างไปยัง OpenRouter พร้อมคำแนะนำเรื่องระดับภาษา (register) และเพศ
  • llm-coached: เหมือนกัน แต่มีการแทรกกฎไวยากรณ์ พจนานุกรม และบันทึกรูปแบบการเขียน (style notes) เข้าไปด้วย
  • google-translate: การส่ง request แบบ batch ไปยัง Google Cloud Translation API v2
  • api: ส่ง HTTP POST ไปยัง remote endpoint

ข้อความระบบ (ระดับภาษา, คำแนะนำเรื่องเพศ, กฎต่างๆ) จะเหมือนกันในทุกๆ batch สำหรับ locale นั้นๆ ซึ่งช่วยให้เกิด prompt caching — ผู้ให้บริการอย่าง Anthropic และ Google จะแคชข้อความระบบที่ซ้ำกัน ช่วยลดค่าใช้จ่ายของ token ได้

6. Quality Gate

ทุกการแปลจะถูกตรวจสอบความถูกต้องก่อนที่จะเขียนลงดิสก์ โดยจะมีการตรวจสอบ 5 รายการ:

การตรวจสอบสิ่งที่ตรวจจับได้ตัวอย่าง
ว่างเปล่า/ไม่มีข้อมูลModel ไม่ส่งค่าใดๆ กลับมา""
คืนค่าต้นทางModel ส่งคืนข้อความภาษาอังกฤษที่รับเข้าไป"Welcome" สำหรับภาษาญี่ปุ่น
การวนลูปแบบ Hallucinationมีการทำซ้ำ trigrams"Qo' Qo' Qo' Qo'"
ความยาวเกินจริงผลลัพธ์ยาวกว่าต้นทาง 4 เท่าขึ้นไปต้นทาง 10 ตัวอักษร → ผลลัพธ์ 50 ตัวอักษร
ความถูกต้องของตัวอักษรใช้ตัวอักษรผิดสำหรับ locale นั้นข้อความละตินสำหรับ locale ภาษาอาหรับ

ข้อผิดพลาดจะถูกบันทึกไว้พร้อมกับคำนำหน้า [GATE] จะไม่มีการ fallback แบบเงียบๆ

ดูรายละเอียดเพิ่มเติมได้ที่ Quality Gate

6b. การตรวจสอบคำศัพท์ (Terminology Verification)

สำหรับการจับคู่แบบ coached ที่มีพจนานุกรม rosetta จะตรวจสอบว่า LLM ได้ใช้คำศัพท์ที่กำหนดไว้หลังจากการแปลหรือไม่ การละเมิดจะถูกบันทึกเป็นคำเตือน [TERM]:

[TERM] en→fr: 2 term violation(s)
• "dashboard" → expected "tableau de bord" but got "panneau"

สิ่งเหล่านี้เป็นเพียงคำเตือน ไม่ใช่ข้อผิดพลาดที่บล็อกการทำงาน — การแปลจะยังคงถูกเขียนลงไฟล์

7. การลองใหม่แบบลดหลั่น (Retry Cascade)

เมื่อเกิดความล้มเหลวในการแยกวิเคราะห์ JSON หรือเกิดข้อผิดพลาดระดับ batch rosetta จะลองใหม่โดยลดขนาด batch ลงเรื่อยๆ:

Full batch (80 keys) → Failed
└→ Half batch (40 keys) → 1 failure
└→ Individual keys (1 each) → Isolates the problem key

จำนวนครั้งในการลองใหม่จะถูกจำกัดโดย maxRetries (ค่าเริ่มต้น: 3) เพื่อป้องกันการใช้ token มากเกินไป

8. การเขียนและการล็อก (Write & Lock)

การแปลที่ผ่านการตรวจสอบจะถูกเขียนลงในไฟล์ locale ปลายทาง โดยยังคงโครงสร้างการซ้อนทับ (nesting structure) แบบเดิมไว้ ไฟล์ล็อกจะถูกอัปเดตด้วยค่า SHA-256 hashes ใหม่

9. การตรวจสอบความถูกต้อง (Verification)

หลังจากประมวลผลทุกคู่เสร็จสิ้น rosetta จะอ่านไฟล์ locale ที่เขียนลงดิสก์อีกครั้งและทำการตรวจสอบความถูกต้อง (ยกเว้นจะมีการตั้งค่า --no-verify) ขั้นตอนนี้ช่วยตรวจจับช่องโหว่ระหว่างการรายงานผลการซิงค์ว่าสำเร็จกับความผิดพลาดของ key ที่เกิดขึ้นจริง:

  • ความเท่าเทียมกันของ Key — key ต้นทางทั้งหมดต้องมีอยู่ในแต่ละไฟล์ปลายทาง
  • เครื่องหมาย fallback [EN] — เครื่องหมายแบบเก่าจากการรันครั้งก่อนๆ
  • การแปลที่ว่างเปล่า — ค่าว่างที่หลุดรอดไปได้
  • ความถูกต้องของตัวอักษร — locale ที่ไม่ใช่ภาษาละตินแต่มีการแปลเป็น ASCII เท่านั้น
  • การรักษา Placeholder — ICU placeholders ต้องตรงกับต้นทาง
  • ปัญหาการเข้ารหัส — เครื่องหมาย BOM, ตัวอักษรที่มองไม่เห็น

นอกจากนี้ยังสามารถใช้เป็นคำสั่ง i18n-rosetta verify แบบสแตนด์อโลนสำหรับ CI gates ได้อีกด้วย

การแปลเนื้อหา (Phase 2)

สำหรับโปรเจกต์ Docusaurus และ Hugo sync จะรันเฟสที่สองหลังจากการแปล JSON key เฟสนี้จะแปลไฟล์ Markdown และ MDX (เอกสาร, บล็อกโพสต์, บทช่วยสอน) โดยใช้วิธีการและ quality gate เดียวกัน

วิธีการทำงาน

  1. Rosetta จะค้นหาไฟล์เนื้อหาต้นทางทั้งหมด (.md, .mdx) โดยการไล่ดูในไดเรกทอรี content/docs
  2. สำหรับแต่ละคู่ของไฟล์ × locale ระบบจะตรวจสอบไฟล์ล็อกเนื้อหาที่แยกต่างหาก (.i18n-rosetta-content.lock) เพื่อหาการเปลี่ยนแปลงของค่า SHA-256 hash
  3. ไฟล์ที่มีการเปลี่ยนแปลงหรือสูญหายจะถูกรวบรวมไว้ในพูลรายการงานแบบแบนราบ (flat work-item pool)
  4. พูลดังกล่าวจะถูกประมวลผลด้วย การทำงานพร้อมกันแบบขนาน (parallel concurrency) (ค่าเริ่มต้น: เรียก API พร้อมกัน 12 รายการ)
Phase 2: content (79 translations to process, 341 skipped, concurrency: 48)

[1/79] (1%) docs/concepts/security.md → ja [RE-TRANSLATE] (~3328s left)
[2/79] (3%) docs/concepts/security.md → th [RE-TRANSLATE] (~1821s left)
...
[79/79] (100%) blog/v3-2-quality.md → de [OK]

[OK] Created 79 content file(s), 341 unchanged

การทำงานแบบขนาน (Parallelism)

ขณะนี้ทั้ง Phase 1 (JSON keys) และ Phase 2 (เนื้อหา) ทำงานแบบขนานกัน:

  • Phase 1: การแปล locale ทั้งหมดจะทำงานพร้อมกัน (ค่าเริ่มต้น: 50 locales พร้อมกัน) ภายในแต่ละ locale การทำงานแบบ API batches ก็จะรันแบบขนานเช่นกัน (4 batches พร้อมกัน) การซิงค์ 12-locale ที่มี 120 keys จะเสร็จสิ้นในเวลาประมาณ 1 นาทีแทนที่จะเป็น 15 นาที
  • Phase 2: การรวมกันของไฟล์×locale ทั้งหมดจะถูกแปลเป็นพูลแบบแบนราบ (ค่าเริ่มต้น: เรียก API พร้อมกัน 12 รายการ) ไฟล์ที่แตกต่างกันและ locale ที่แตกต่างกันจะถูกแปลไปพร้อมๆ กัน

ควบคุมการทำงานแบบขนานด้วย --json-concurrency, --content-concurrency หรือ --concurrency (ตั้งค่าทั้งสองอย่าง):

# Faster JSON sync (more parallel locale translations)
npx i18n-rosetta sync --json-concurrency 30

# Faster content sync (more parallel API calls)
npx i18n-rosetta sync --content-concurrency 20

# Slower (gentler on rate limits)
npx i18n-rosetta sync --concurrency 4

การปกป้องเนื้อหา

ในระหว่างการแปล rosetta จะปกป้องเนื้อหาที่ไม่สามารถแปลได้:

  • บล็อกโค้ด (แบบมีกรอบและแบบย่อหน้า) จะถูกแทนที่ด้วย placeholders
  • ฟิลด์ Frontmatter ที่ไม่อยู่ในรายการ translatableFields จะถูกเก็บไว้ตามเดิม
  • ลิงก์, พาธของรูปภาพ และแท็ก HTML จะถูกปกป้องไว้
  • Shortcodes และตัวแปรแทรก (เช่น {count}, {{.Params.title}}) จะถูกป้องกันไว้

หลังจากการแปล placeholders ทั้งหมดจะถูกกู้คืนและตรวจสอบความถูกต้อง หากมีส่วนใดขาดหายไปหรือเสียหาย การแปลนั้นจะถูกปฏิเสธและทำการลองใหม่

ความสำเร็จบางส่วน (Partial Success)

batch ที่ล้มเหลวเพียงหนึ่งรายการจะไม่บล็อกการทำงานส่วนที่เหลือ หาก 9 จาก 10 batches สำเร็จ ทั้ง 9 รายการนั้นจะถูกเขียนลงไฟล์ batch ที่ล้มเหลวจะถูกบันทึกไว้ และคุณสามารถรัน sync อีกครั้งเพื่อลองใหม่ได้

การทดสอบรัน (Dry Run)

ดูตัวอย่างสิ่งที่จะเปลี่ยนแปลงโดยไม่มีการเขียนไฟล์ใดๆ:

npx i18n-rosetta sync --dry-run

บังคับแปลใหม่ (Force Re-translate)

บังคับให้แปล key ที่ระบุใหม่แม้ว่าจะไม่มีการเปลี่ยนแปลงก็ตาม:

npx i18n-rosetta sync --force-keys "hero.title,nav.about"

การประเมินค่าใช้จ่าย

ก่อนทำการแปล rosetta จะสร้าง รายงานค่าใช้จ่ายก่อนการซิงค์ (pre-sync cost report) ซึ่งแสดงค่าใช้จ่ายโดยประมาณต่อคู่ การทำงานนี้จะรันโดยอัตโนมัติในทุกๆ sync — คุณจะเห็นรายงานนี้ก่อนที่จะมีการเรียก API ใดๆ

╔══════════════════════════════════════════════════════════╗
║ Cost Estimate ║
╠════════════╦═══════╦════════════╦════════════════════════╣
║ Pair ║ Keys ║ Est. Cost ║ Method ║
╠════════════╬═══════╬════════════╬════════════════════════╣
║ en → fr ║ 142 ║ $0.07 ║ google-translate ║
║ en → ja ║ 38 ║ — ║ llm (model-dependent) ║
║ en → crk ║ 38 ║ — ║ llm-coached ║
╚════════════╩═══════╩════════════╩════════════════════════╝

สิ่งที่ได้รับการประเมิน

แต่ละ translation method จะมีการประเมินค่าใช้จ่ายของตัวเอง:

Methodเกณฑ์ค่าใช้จ่ายความแม่นยำ
google-translateอัตราที่เผยแพร่โดย Google ($20/ล้านตัวอักษร)แม่นยำ
llmแตกต่างกันไปตามโมเดลของ OpenRouterขึ้นอยู่กับโมเดล — ตรวจสอบ ราคาของ OpenRouter
llm-coachedเหมือนกับ llm บวกกับ token ของบริบทการโค้ชขึ้นอยู่กับโมเดล
apiกำหนดโดยเซิร์ฟเวอร์ไม่ทราบ — ไม่สามารถประเมินได้หากไม่สอบถามไปยัง endpoint

เมื่อ method ใดไม่สามารถกำหนดค่าใช้จ่ายได้ (LLM methods, remote APIs) rosetta จะรายงานเป็น แทนที่จะคาดเดา ใช้ --dry เพื่อดูการประเมินค่าใช้จ่ายโดยไม่ต้องทำการแปลจริง


ดูเพิ่มเติม

  • CLI Reference — sync — แฟล็กคำสั่งและตัวเลือกต่างๆ
  • Translation Memory — การแคชและการประหยัดค่าใช้จ่าย
  • Quality Gate — วิธีการตรวจสอบความถูกต้องของการแปล
  • Translation Methods — วิธีการทำงานของแต่ละ method
  • Working with Professional Translators — เวิร์กโฟลว์ XLIFF
  • Configuration — ข้อมูลอ้างอิงการตั้งค่า config
  • CI/CD Guide — การทำ sync อัตโนมัติใน pipeline ของคุณ