Free

Faire écrire à Claude des threads de tweets multilingues sans dépasser la limite

Les threads multilingues ne sont pas un problème de traduction : dites « write », pas « translate », et filtrez les brouillons avec un script .length local.


Aujourd'hui, j'ai publié 5 articles. Chacun est accompagné d'un thread de tweets en 6 langues (en / zh / ja / ko / ar / id), 4 tweets par langue — 120 tweets au total.

4 articles sur 5 ont demandé des coupes sur le thread chinois. Les chiffres bruts (imprimés par mon script, format 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

Toujours le même schéma : j'écris d'abord les quatre tweets anglais (230–260 caractères chacun, au ras du plafond de 280), puis je demande à Claude de « générer la version chinoise à partir de ces quatre ». La version chinoise dépasse 140 presque à chaque fois.

Ce n'est pas un bug, c'est le mauvais mot. Dès que vous dites « translate », Claude passe en mode phrase par phrase — mais un thread multilingue n'est pas un problème de traduction. Chaque langue doit être écrite de zéro face à son propre budget de caractères. Ce billet explique comment obtenir un premier jet de Claude déjà proche de la limite, sans y passer 3 à 5 tours de coupe.


Cause racine : X pondère le CJK en double × Claude traduit littéralement par défaut

Règles de comptage de caractères de X

La limite de X ne se calcule pas en « nombre de caractères », mais en weighted characters :
- Lettres latines, chiffres, ponctuation : 1 weight par caractère
- Caractères CJK (chinois/japonais/coréen), certains emojis : 2 weight par caractère
- Plafond total par tweet : 280 weight

En pratique :
- Tweet anglais : plafond 280 caractères
- Tweet purement chinois : plafond 140 caractères (140 × 2 = 280)
- Mixte : 1 ou 2 par caractère

Donc « traduire un tweet anglais de 260 caractères en chinois » ne donne pas 260 caractères en chinois — la version chinoise dispose en réalité d'environ 130 caractères d'espace. Toute la ponctuation, les guillemets et les backticks de l'original anglais occupent toujours de la place, et chaque caractère chinois compte double. La traduction littérale garantit presque toujours le dépassement.

Le mot « translate » enclenche le mode littéral de Claude

Quand Claude voit « translate these 4 EN tweets to ZH », son premier réflexe est de conserver la structure de la phrase anglaise et de n'échanger que les mots contre leurs équivalents chinois :

  • EN : « Production 400/500 isn't like local. User's already staring at a blank screen after hitting Pay. »
  • ZH littéral de Claude : «生产环境的 400/500 和本地并不相同。用户已经点击了『付款』并看着一个空白屏幕。» (40 caractères chinois)

Le sens est correct, mais :
- «并不相同» conservé (un caractère de plus que «不同»)
- «已经点击了» conservé («刚点完» est plus court)
- «并看着一个空白屏幕» conservé («看着空白屏» est plus court)

Chaque redondance conservée mange des caractères. Cumulé sur 4 tweets, 20–40 caractères en trop arrivent vite, et vous avez dépassé la limite.

Le prompt qui marche : « réécrire », pas « traduire »

Comparez les deux formulations :

Ce qui ne marche pas :

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

Ce qui marche :

« 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 »

Les différences :

  1. « write » remplace « translate » — enclenche le mode composition de Claude, pas le mode traduction.
  2. « fresh pass » / « same argument » — donne à Claude la permission de réorganiser les phrases.
  3. « don't preserve EN sentence structure » — bloque de front le comportement par défaut.
  4. « cut detail if needed » — donne la permission de lâcher du contenu pour tenir la longueur (sans ça, Claude garde tous les faits et dépasse).
  5. Budget explicite par langue — « ≤ 140 chars » est 100× plus efficace que « short ».

Sanity check local : Ruby + .length

Ne comptez pas à l'œil. Écrivez un petit script qui tourne sur chaque brouillon :

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

String#length de Ruby renvoie des codepoints Unicode — chaque caractère CJK compte pour 1. X pondère le CJK à 2, mais la limite d'un tweet chinois est 140 codepoints (parce que 140 × 2 = 280 weighted), donc .length s'aligne directement avec le plafond de X. Les cas limites :

  • Nombre de codepoints des emojis (🧵 = 1 codepoint, mais certains emojis sont des séquences de plusieurs)
  • Caractères de largeur zéro (ZWJ, etc.)

Pour la grande majorité des tweets CJK, .length de Ruby reste à ±1 du compte de X. L'utiliser comme garde local bat le test de publication sur X d'un facteur 100.

Pièges des emojis et des backticks

Quand les tweets chinois doivent être coupés, ces deux catégories tombent en premier :

Les backticks

Les citations de code comme `kamal exec` mangent 1 caractère par backtick dans un contexte chinois — 2 caractères par citation, valeur sémantique nulle. Solutions :

  • Utilisez un deux-points : «命令 kamal exec» bat «`kamal exec`»
  • Si vous devez vraiment garder les backticks, seulement pour l'identifiant-clé, pas pour la ligne de shell entière

Les emojis

🧵 uniquement sur le tweet 1. Les autres emojis dans les tweets chinois — réfléchissez-y à deux fois. Chaque emoji coûte essentiellement 2 caractères (1 codepoint + parfois des modificateurs ZWJ).

Ponctuation pleine largeur vs demi-largeur

  • Ponctuation CJK (「」、,。——) : 2 weight par caractère
  • Ponctuation ASCII ("",-) : 1 weight par caractère
  • Quand un tweet chinois mélange les guillemets : utilisez des guillemets demi-largeur ('X') — économise 2 caractères par paire par rapport à la pleine largeur (「X」)

Quatre écarts par défaut de Claude à intercepter

Pour générer des threads multilingues, bloquez ces quatre-là :

1. Traduction littérale conservant la structure EN

Symptôme : phrases chinoises avec des formules comme «并不相同», «已经点击了», «一个空白屏幕» qui sont clairement des calques de l'anglais.

Blocage : écrivez « don't preserve EN sentence structure » / « use natural ZH phrasing » directement dans le prompt.

2. Pas de vérification de longueur spontanée

Symptôme : Claude termine, dit « done », la sortie dépasse la limite, et il ne s'en aperçoit pas.

Blocage : demandez à Claude de compter la longueur de chaque tweet (« count each tweet's char length and flag any over the limit »), ou posez un script local en garde. Je choisis le script — Ruby est plus précis que Claude.

3. Ignorer le weight des guillemets et emojis

Symptôme : quand Claude compte, il oublie le weight supplémentaire des emojis et des guillemets pleine largeur.

Blocage : ne demandez pas à Claude « est-ce au-dessus de la limite ? » — lancez .length en local et demandez-lui de couper en fonction des chiffres.

4. Incohérence sur la position de 🧵

Symptôme : parfois chaque tweet reçoit 🧵, parfois uniquement le 1, parfois il atterrit en 4/4.

Blocage : fixez-le dans le prompt — « 🧵 only on tweet 1 ». Claude ne connaît pas par défaut les conventions visuelles d'un thread.

Checklist

Six règles pour un premier jet de thread multilingue au ras de la limite :

  1. Dites « write », pas « translate ». Traduire enclenche le littéral = structure EN conservée = dépassement.
  2. Budget explicite par langue. « ≤ 140 chars » vaut 100× « short ».
  3. Permission de couper du contenu. "cut detail if needed" dit à Claude qu'il peut perdre des faits pour tenir la longueur.
  4. Ruby .length local comme garde. Plus précis que Claude qui compte, plus rapide qu'un test sur X.
  5. En chinois, coupez d'abord backticks et emojis. Chaque backtick vaut 1 caractère, chaque emoji 2.
  6. Fixez la position de 🧵 dans le prompt. Claude ignore par défaut les conventions des threads.

La vraie intuition : Claude sait écrire correctement des threads multilingues — mais sa réaction par défaut est « traduire ». Votre travail est de le faire basculer vers « composer indépendamment par langue » via le prompt. Avec la garde .length, le thread chinois du dernier article du jour est sorti à 140/140 pile au premier jet. Pas de coupe.