Free

Để Claude dịch một bài viết sang 19 ngôn ngữ

Một bài 19 ngôn ngữ: cấu trúc file, prompt dịch, 5 cái bẫy thực tế, cách POST một lần.


Tài liệu chính thức của Anthropic và OpenAI chỉ có tiếng Anh. Đó là khoảng trống lớn trong hệ sinh thái nội dung cho developer AI toàn cầu. how2claude đang lấp khoảng trống đó — mỗi bài ra mắt bằng 19 ngôn ngữ cùng lúc: zh / en / zh-TW / ja / ko / es / pt-BR / id / vi / tr / ar / fr / de / it / ru / uk / pl / he / th.

Thuê người thì không thực tế (20 bản dịch mỗi bài, mỗi bản vài nghìn đô). Để Claude làm đưa chi phí biên về gần zero — nhưng ném một câu "dịch sang tiếng Nhật" qua hàng rào sẽ nhận lại bản dịch đậm mùi máy móc và tiếng nói tác giả bay sạch. Dưới đây là quy trình đầy đủ để làm đúng: cấu trúc file, cách viết prompt dịch, nơi Claude chắc chắn sẽ vấp, cách POST 19 ngôn ngữ cùng các tweet theo ngôn ngữ tới API trong một lần gọi.


Quyết định cốt lõi: dịch vs. bản địa hóa

Hai thứ khác nhau rất nhiều.

Dịch đưa ý nghĩa từ ngôn ngữ A sang B — việc Google Translate làm. Đọc "đúng" nhưng "phẳng".

Bản địa hóa giữ nguyên phong cách, nhịp điệu, độ chuyên nghiệp của tác giả, viết lại bằng "giọng blog kỹ thuật" của ngôn ngữ đích. Kết quả đọc như được viết bởi người bản địa.

Dịch là công việc 5 phút với Claude; bản địa hóa đòi hỏi prompt phải chỉ rõ:

  • Ai là độc giả mục tiêu (developer, team kỹ thuật)
  • Giọng điệu tham chiếu (giống blog nào)
  • Thuật ngữ phải giữ nguyên gốc (tên API, tên framework, câu lệnh, URL)
  • Nơi được phép tái cấu trúc (chia câu dài, đổi ẩn dụ sang những gì độc giả bản địa quen)

Lệnh /write-article của how2claude nhúng sẵn yêu cầu phong cách cho từng ngôn ngữ:

File ngôn ngữ Yêu cầu phong cách
ja.md Giọng blog kỹ thuật, tiếng Nhật tự nhiên
ko.md Giọng blog kỹ thuật, tiếng Hàn tự nhiên
zh-TW.md Dùng từ Đài Loan, phồn thể
ar.md Tiếng Ả-rập chuẩn hiện đại (viết)
id.md Tiếng Indonesia chuẩn

Nhìn như thêm một dòng. Nhưng với Claude đó là quyết định — không có dòng này, mặc định sinh ra "bản dịch sách giáo khoa".

Cấu trúc file: 19 ngôn ngữ sống chung một thư mục

Một thư mục cho mỗi bản nháp, 20 file:

docs/drafts/let-claude-translate-articles/
├── meta.json        # title + summary cho tất cả 19 ngôn ngữ
├── zh.md            # tiếng Trung (nguồn, viết trước)
├── en.md            # tiếng Anh (lô dịch đầu tiên)
├── zh-TW.md
├── ja.md
├── ko.md
├── ...(14 ngôn ngữ khác)
└── th.md

meta.json:

{
  "category_slug": "use-cases",
  "series_slug": "writing",
  "free": true,
  "title": {
    "zh": "让 Claude 把一篇文章翻译成 19 种语言",
    "en": "Letting Claude Translate One Article Into 19 Languages",
    "vi": "Để Claude dịch một bài viết sang 19 ngôn ngữ",
    "...": "..."
  },
  "summary": {
    "vi": "Một bài 19 ngôn ngữ: cấu trúc file, prompt dịch, 5 cái bẫy thực tế, cách POST một lần.",
    "...": "..."
  }
}

Dòng đầu mỗi file .md# tiêu đề, phần còn lại là thân bài. Title không lấy từ dòng đầu md — lấy từ meta.json, nhờ vậy tiêu đề từng ngôn ngữ là câu ngắn được chuốt riêng, không phải câu mở đầu bài có thể đã bị kéo dài khi dịch.

Quy trình: viết zh, rồi tỏa ra 18 ngôn ngữ

Hai quy trình sai:

Sai: dịch chuỗi. zh → en → ja → ko → ...
Vấn đề: ja dựa trên en, ko dựa trên ja — mỗi lần nhảy rò rỉ chút ý. Tới th (tiếng Thái) đã là thông tin qua bốn tay.

Đúng: dịch tỏa. Chốt zh → sinh en / ja / ko / ar / id / ... thẳng từ nguồn.
Mọi ngôn ngữ sinh trực tiếp từ bản gốc, không trạm trung chuyển.

Cấu trúc prompt (đóng gói trong /write-article):

Đây là bài blog kỹ thuật về X, nguồn tiếng Trung:
[toàn bộ zh.md]

Dịch sang các ngôn ngữ sau, với yêu cầu riêng từng ngôn ngữ:
- ja.md: giọng blog kỹ thuật, tiếng Nhật tự nhiên
- ko.md: giọng blog kỹ thuật, tiếng Hàn tự nhiên
- ar.md: tiếng Ả-rập chuẩn hiện đại (viết)
...

Quy tắc:
1. Giữ giọng trực tiếp, chuyên nghiệp, hơi tự giễu của tác giả
2. Không dịch code block, câu lệnh, tên API, URL
3. Tiêu đề, tiểu mục, mạch đoạn được phép tái cấu trúc
4. Xuất title riêng cho từng ngôn ngữ — ngắn, có hook, không dịch sát tiêu đề gốc

Dịch 18 ngôn ngữ song song, một phiên Claude là xong. Một chi tiết then chốt: làm trong cùng một phiên / cùng phiên bản model — giọng điệu trôi dạt qua các phiên và qua các thế hệ model.

5 chỗ thật sự vấp

1. Giới hạn ký tự tweet khác nhau theo ngôn ngữ

X đếm ký tự CJK (Trung/Nhật/Hàn) khắt khe hơn. Tôi yêu cầu Claude sinh tweet với ràng buộc này:

  • Tweet tiếng Trung ≤ 140 ký tự
  • Ngôn ngữ khác ≤ 280 ký tự

Lần chạy đầu tiên, ba tweet tiếng Trung vượt (160, 164, 152). Claude đã dịch sát tweet tiếng Anh — tweet Anh 260 ký tự dịch sang Trung đúng chạm giới hạn.

Quy tắc: tweet tiếng Trung phải viết lại, không phải dịch. Yêu cầu: trần 140 ký tự, bắt buộc có hook, mất chi tiết chút được.

2. zh-TW không phải chuyển đổi ký tự

zhzh-TW rất dễ lười: quăng qua công cụ giản thể → phồn thể. Ký tự khớp, từ vựng không:

zh zh-TW (sai) zh-TW (đúng)
文件 文件 檔案
信息 信息 資訊
软件 軟件 軟體
视频 視頻 影片

Khi yêu cầu zh-TW từ Claude, nói đủ hai vế: "dùng từ Đài Loan, phồn thể". Chỉ nói "phồn thể" sẽ nhận chuyển đổi ký tự.

3. Ngôn ngữ RTL (ar, he) làm vỡ layout

Tiếng Ả-rập và Hebrew đọc từ phải sang trái. Phía Rails cần <html dir="rtl"> và các biến thể rtl: của Tailwind. Nhưng bản thân phần dịch cũng có bẫy:

  • Code block vẫn tiếng Anh, nhưng khi đoạn văn Ả-rập bọc lấy code block, trình duyệt cần unicode-bidi: isolate, nếu không code sẽ bị "hút" vào dòng chảy RTL
  • Dấu câu pha trộn: tiếng Ả-rập dùng ، thay ,, ؟ thay ?. Claude mặc định dùng dấu tiếng Anh; phải chỉ rõ
  • Hướng số: tiếng Ả-rập viết chữ số trái-sang-phải (2026) trong đoạn văn phải-sang-trái. Trình duyệt xử lý, nhưng Claude thường lẫn lộn khi viết text thô

4. Claude mặc định "làm nghiêm túc hóa" giọng tác giả

Các cụm khẩu ngữ bản gốc ("một phát xong", "đạp hầm", "lật kèo") Claude dịch sang Nhật/Hàn mặc định thành dạng viết trang trọng (「一気に実装」「落とし穴」「失敗」) — nghĩa khớp, giọng bay hơi.

Sửa: nói rõ trong prompt — "giữ giọng blog kỹ thuật trực tiếp, hơi tự giễu, không trang trọng; không hàn lâm hóa". Dù vậy, một số ngôn ngữ (Đức, Nga) vẫn hạ cánh "trang trọng" hơn bản gốc một chút — bản thân ngôn ngữ đó có thiên lệch về đăng ký viết.

5. Placeholder và biến không dịch

Chuỗi trong code thuộc hai rổ — chữ UI (dịch) và placeholder/tên biến (không):

t("pricing.page_title")        # không dịch (i18n key)
"user_id"                      # không dịch (tên biến)
"Monthly subscription"         # hiển thị làm ví dụ trong bài → không dịch

Với bất cứ thứ gì kề code, "không dịch" là mặc định an toàn hơn. Dịch file locale i18n (config/locales/xx.yml) là việc riêng.

Xuất bản: một POST, 19 ngôn ngữ

/publish-article POST bản nháp lên how2claude.com/api/articles:

{
  "category_slug": "use-cases",
  "series_slug": "writing",
  "free": true,
  "thread": true,
  "title":   { "zh": "...", "en": "...", "ja": "...", ... },
  "summary": { "zh": "...", "en": "...", ... },
  "content": { "zh": "<md>", "en": "<md>", ... },
  "tweets":  { "en": ["...", "..."], "zh": [...], ... }
}

Một request khoảng 300KB (19 ngôn ngữ × ~15KB). Server tách về các bảng DB:

  • bảng articles, title / summary / content là jsonb key theo locale
  • bảng x_queue_tweets, theo locale + account, đẩy vào queue lịch đăng

Tweet chỉ gửi cho locale có tài khoản X đã kết nối (hiện tại en/zh/ja/ko/ar/id — 6). Ngôn ngữ chưa kết nối gửi []. Kiểm tra tài khoản:

Account.all.each { |a| puts "#{a.locale}: #{a.name}" }
# en: @how2claude
# zh: @howtoclaude
# ja: @how2claude_ja
# ko: @how2claude_ko
# ar: @how2claude_ar
# id: @how2claude_id

Checklist

Để Claude dịch một bài viết sang 19 ngôn ngữ — checklist đầy đủ:

  1. Chốt zh (hoặc en) trước, rồi tỏa 18 bản dịch khác từ nguồn đó. Không dịch chuỗi.
  2. Yêu cầu phong cách riêng từng ngôn ngữ vào prompt. "Tiếng Nhật tự nhiên" chưa đủ — nói "giọng blog kỹ thuật, tiếng Nhật tự nhiên".
  3. Dịch title và summary riêng, đừng rút từ đoạn đầu bài. Toàn bộ 19 title/summary gom về meta.json.
  4. Liệt kê rõ những gì không dịch: code block, câu lệnh, tên API, URL, i18n key, tên biến. Cái được dịch: văn giải thích, ẩn dụ, cấu trúc đoạn.
  5. Tweet phải viết lại, không phải dịch. 140 ký tự cho tiếng Trung, 280 cho còn lại. Dịch sát Anh-sang-Trung luôn vượt giới hạn.
  6. Với zh-TW nói "dùng từ Đài Loan + phồn thể"; nếu không, chỉ được chuyển đổi ký tự và từ vựng vẫn kiểu đại lục.
  7. Ngôn ngữ RTL (ar, he) cần dir="rtl" + biến thể rtl: của Tailwind phía Rails. Dấu câu pha trộn và cô lập code block xử lý riêng.
  8. POST mọi ngôn ngữ trong một lần — 19 content + 19 title/summary + tweet cho từng account đã kết nối, một request tới backend.

Nút thắt thực sự không phải chất lượng dịch — model cỡ Claude 4 dịch sang Nhật/Hàn/Ả-rập/Nga gần bằng bản địa. Nút thắt là bạn có sẵn sàng đặt một bài viết trước mặt độc giả 19 ngôn ngữ hay không. Kỹ thuật mất 5 phút. Về nội dung, chỉ cần ý chí phục vụ 200 lần lượng độc giả cùng lúc.