Free

Claude に多言語ツイートスレッドを書かせる(字数制限を超えずに)

多言語スレッドは翻訳問題ではない。『translate』ではなく『write』と言い、ローカルの .length で事前チェックする。


今日は 5 本の記事を公開した。各記事に 6 言語(en / zh / ja / ko / ar / id)× 4 ツイートのスレッドが付くので、合計 120 ツイート。

そのうち 4 本で中国語スレッドの削り直しが必要だった。スクリプトが出した生データ(形式 chars/limit):

zh[1]=160/140 OVER
zh[2]=164/140 OVER
zh[3]=152/140 OVER
...
id[3]=286/280 OVER
zh[2]=163/140 OVER
zh[3]=148/140 OVER
zh[2]=152/140 OVER

毎回同じパターン。英語の 4 ツイートを先に書く(各 230〜260 文字、280 の上限ギリギリ)→ Claude に「この 4 本から中国語版を生成して」と頼む → 中国語版はほぼ毎回 140 をオーバーする。

これはバグではない。Claude に投げた言葉が間違っている。「translate」と言った瞬間、Claude は英文を一文ずつ訳すモードに入る。ところが多言語スレッドは翻訳問題ではない。各言語はそれぞれの字数予算に合わせて一から書き直すものだ。本稿では、Claude に 1 発目から上限ギリギリを書かせる方法を示す。3〜5 回の手動削りから解放される。


根本原因:X は CJK を 2 倍で数える × Claude のデフォルトは逐語訳

X の文字カウント規則

X の長さ制限は「文字数」ではなく weighted characters で計算される:
- ラテン文字、数字、記号:1 文字 1 weight
- CJK(中/日/韓)、一部の絵文字:1 文字 2 weight
- 1 ツイートの総上限 280 weight

実際の効果:
- 英語ツイート:280 文字まで
- 純中国語ツイート:140 文字まで(140 × 2 = 280)
- 混在:文字ごとに 1 または 2 でカウント

なので「英語 260 文字を中国語に訳す」は中国語 260 文字分の枠にはならない — 実際の中国語の枠は約 130 文字。英文に残った句読点・引用符・backtick はそのまま場所を取り、中国語の各文字は 2 倍でカウントされる。逐語訳すればオーバーはほぼ確定。

「translate」という単語が Claude の逐語モードを起動する

Claude は "translate these 4 EN tweets to ZH" を見ると、まず英文の文構造を保ったまま単語だけ中国語に置き換える

  • EN:"Production 400/500 isn't like local. User's already staring at a blank screen after hitting Pay."
  • Claude の逐語訳:「生产环境的 400/500 和本地并不相同。用户已经点击了『付款』并看着一个空白屏幕。」(40 字)

意味は合っている。ただし:
- 「并不相同」が残る(「不同」より 1 字多い)
- 「已经点击了」が残る(「刚点完」のほうが短い)
- 「并看着一个空白屏幕」が残る(「看着空白屏」のほうが短い)

こうして残った冗長表現がそれぞれ文字を食う — 4 ツイート分を足せば 20〜40 字のオーバーは簡単で、制限を越える

効くプロンプト:「翻訳」ではなく「書く」

2 つの言い方を比較:

効かないプロンプト

"Translate these 4 English tweets to Chinese, Japanese, Korean, Arabic, Indonesian."

効くプロンプト

"For each of these 4 points, write a thread in ZH / JA / KO / AR / ID. Each language gets a fresh pass — same argument, adjusted for that language's tweet budget.

  • ZH: ≤ 140 chars per tweet, hook-first, cut detail if needed
  • other languages: ≤ 280 chars
  • use each language's natural phrasing, don't preserve EN sentence structure
  • each tweet must be self-contained but add 🧵 only on tweet 1"

違い:

  1. 「write」で「translate」を置き換え。Claude を翻訳モードではなく創作モードに切り替える。
  2. 「fresh pass」「same argument」。文の再構成を明示的に許可する。
  3. 「don't preserve EN sentence structure」。デフォルト挙動を正面から塞ぐ。
  4. 「cut detail if needed」。内容を削る権限を与える(与えないと Claude は事実を全部残してオーバーする)。
  5. 言語ごとに上限を明記。「≤ 140 chars」は「short」の 100 倍効く。

ローカルでの sanity check:Ruby + .length

目視で数えない。毎回走るスクリプトを書く:

tweets.each do |loc, list|
  list.each_with_index do |t, i|
    len = t.length
    limit = loc == "zh" ? 140 : 280
    status = len > limit ? "OVER" : "ok"
    puts "#{loc}[#{i}]=#{len}/#{limit} #{status}"
  end
end

Ruby の String#length は Unicode コードポイント数を返す — CJK は各 1 としてカウントされる。X は CJK を weighted 2 で数えるが、中国語ツイートの上限は 140 コードポイント(140 × 2 = 280 weighted)なので、.length は X の制限とそのまま一致する。誤差が出るのは:
- 絵文字のコードポイント数(🧵 は 1 CP だが、複数 CP で構成される絵文字もある)
- ゼロ幅文字(ZWJ など)

ほとんどの CJK ツイートで Ruby .length は X のカウントと ±1 で一致する。これをローカルゲートにすれば、X に試投するより 100 倍安定する。

絵文字と backtick の罠

中国語ツイートを削るとき、まず手をつける 2 カテゴリ:

backtick(`

`kamal exec` のようなコード引用は、中国語の文脈では backtick 1 つで 1 字を食う — 2 つで 2 字、意味には寄与しない。対処:
- コロンで代替できるならコロン:「命令 kamal exec」のほうが「`kamal exec`」より短い
- どうしても backtick を残すなら重要な識別子だけに絞る(shell 一行まるごとは無理)

絵文字

🧵 はスレッドの 1 本目だけに付ける。それ以外の絵文字は中国語ツイートでは慎重に — 絵文字 1 つで実質 2 字(1 コードポイント + 場合によって ZWJ 修飾子)。

全角 vs 半角の記号

  • 中国語の記号(「」、,。——):1 文字 weighted 2
  • 英語の記号("",-):1 文字 weighted 1
  • 中国語ツイートで引用符を混在させるとき:半角の引用符'X')を使えば、全角(「X」)より 1 ペアあたり 2 字節約

Claude がデフォルトで外す 4 つの方向

多言語スレッドを生成するとき、この 4 つをブロックする:

1. 英文構造を残した逐語訳

症状:中国語の文に「并不相同」「已经点击了」「一个空白屏幕」のような、明らかに英文直訳の表現が出る。

ブロック:プロンプトに明示的に "don't preserve EN sentence structure" / "use natural ZH phrasing" を書く。

2. 長さを自発的にチェックしない

症状:Claude が生成後に「done」と言うが、実際は上限超過で、Claude 自身は気づいていない。

ブロック:プロンプトで 生成後に自分で数えるよう指示("count each tweet's char length and flag any over the limit")するか、ローカルでスクリプトをゲートにする。私は後者を選ぶ — Ruby のほうが正確。

3. 引用符や絵文字の weight を計算に入れない

症状:Claude がカウントする際、絵文字や全角引用符の追加 weight を無視する。

ブロック:Claude に「上限超えてる?」と聞かない — ローカルで .length を計算し、その数字に基づいて Claude に削らせる。

4. 🧵 の位置が一貫しない(全部に付く/1 本目だけ/4 本目に付く)

症状:各ツイートに 🧵 が付いたり、1 本目だけだったり、4/4 の末尾に付いたり。

ブロック:プロンプトに「🧵 only on tweet 1」と固定で書く。Claude はスレッドの視覚的慣習をデフォルトでは知らない。

チェックリスト

Claude の 1 発目の多言語スレッドを上限ギリギリにする 6 ルール:

  1. 「translate」ではなく「write」と言う。「translate」は逐語訳 = 英文構造保持 = オーバー。
  2. 言語ごとに上限を明記。「≤ 140 chars」は「short」の 100 倍効く。
  3. 削除の権限を与える"cut detail if needed" で、長さに合わせて事実を落としていいと伝える。
  4. ローカル Ruby .length でゲート。Claude 自身のカウントより正確、X 試投より速い。
  5. 中国語では backtick と絵文字を最初に削る。backtick 1 つで 1 字、絵文字 1 つで 2 字。
  6. 🧵 の位置をプロンプトで固定。Claude はスレッドの視覚的慣習をデフォルトでは知らない。

本当の洞察:Claude は多言語スレッドを正しく書ける。ただしデフォルトの反応は「翻訳」。プロンプトで「各言語ごとに独立して書き直す」モードに切り替えるのは自分の仕事だ。.length ゲートを足したら、今日最後の記事の中国語スレッドは 1 発目で 140/140 ぴったり — 削り直しなし。