Free

Как заставить Claude писать многоязычные треды в Twitter без превышения лимита

Многоязычные треды — не задача перевода: говорите «write», а не «translate», и фильтруйте черновики локальным .length-скриптом.


Сегодня выпустил 5 статей. К каждой — тред твитов на 6 языках (en / zh / ja / ko / ar / id), по 4 твита на язык — всего 120 твитов.

В 4 из 5 пришлось резать китайский тред. Сырые числа (скрипт выводит в формате 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

Всегда одна и та же схема: сначала пишу четыре английских твита (каждый 230–260 символов, впритык к 280), потом прошу Claude «сгенерировать китайскую версию по этим четырём». Китайская версия почти всегда выходит за 140.

Это не баг, это не то слово. В момент, когда вы говорите «translate», Claude уходит в режим «строка за строкой» — но многоязычный тред — не задача перевода. Каждый язык надо писать с нуля под его собственный бюджет символов. В этом посте — как получать первый драфт Claude сразу впритык к лимиту, без 3–5 раундов резки.


Корневая причина: X считает CJK с весом 2 × Claude по умолчанию переводит дословно

Как X считает символы

Лимит длины в X — не «число символов», а weighted characters:
- Латиница, цифры, пунктуация: 1 weight на символ
- CJK-символы (китайский/японский/корейский), некоторые эмодзи: 2 weight на символ
- Общий потолок на твит: 280 weight

На практике:
- Английский твит: потолок 280 символов
- Чисто китайский твит: потолок 140 символов (140 × 2 = 280)
- Смешанный: посимвольно 1 или 2

Так что «перевести английский твит в 260 символов на китайский» не даёт китайскую версию в 260 символов — у китайской версии реально около 130 символов пространства. Вся пунктуация, кавычки и бэктики из английского оригинала всё ещё занимают место, а каждый китайский символ считается вдвойне. Дословный перевод почти гарантирует вылет.

Слово «translate» включает дословный режим Claude

Увидев «translate these 4 EN tweets to ZH», Claude первым делом сохраняет структуру английского предложения и меняет только слова на китайские:

  • EN: «Production 400/500 isn't like local. User's already staring at a blank screen after hitting Pay.»
  • Дословный ZH Claude: «生产环境的 400/500 和本地并不相同。用户已经点击了『付款』并看着一个空白屏幕。» (40 китайских символов)

Смысл верен, но:
- Сохранено «并不相同» (на символ длиннее «不同»)
- Сохранено «已经点击了» («刚点完» короче)
- Сохранено «并看着一个空白屏幕» («看着空白屏» короче)

Каждая сохранённая избыточность съедает символы. Накопленные по 4 твитам 20–40 лишних символов — легко, и лимит перешагнули.

Работающий промпт: «переписать», а не «перевести»

Сравните две формулировки:

Что не работает:

«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» работает в 100 раз лучше «short».

Локальный 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

String#length в Ruby возвращает Unicode-кодпоинты — каждый CJK-символ считается как 1. X взвешивает CJK с 2, но лимит китайского твита — 140 кодпоинтов (потому что 140 × 2 = 280 weighted), поэтому .length напрямую совпадает с потолком X. Крайние случаи:

  • Число кодпоинтов у эмодзи (🧵 — 1 кодпоинт, но некоторые эмодзи — последовательности из нескольких)
  • Zero-width-символы (ZWJ и пр.)

Для подавляющего большинства CJK-твитов .length Ruby отличается от счёта X на ±1. Использовать как локальный шлюз лучше тестового постинга в X в 100 раз.

Ловушки эмодзи и бэктиков

Когда китайский твит надо резать, первыми летят эти две категории:

Бэктики

Цитирование кода вроде `kamal exec` в китайском контексте ест 1 символ на каждый бэктик — 2 символа на цитату, ноль семантики. Решения:

  • Ставьте двоеточие: «命令 kamal exec» короче «`kamal exec`»
  • Если бэктики нужны — только на ключевой идентификатор, не на всю shell-строку

Эмодзи

🧵 — только в первом твите. Прочие эмодзи в китайских твитах — подумайте дважды. Каждый эмодзи стоит фактически 2 символа (1 кодпоинт + иногда ZWJ-модификаторы).

Fullwidth vs halfwidth пунктуация

  • CJK-пунктуация (「」、,。——): 2 weight на символ
  • ASCII-пунктуация ("",-): 1 weight на символ
  • Если в китайском твите смешиваются кавычки: используйте halfwidth-кавычки ('X') — экономия 2 символа на пару по сравнению с fullwidth (「X」)

Четыре дефолтных отклонения Claude, которые нужно перехватывать

При генерации многоязычных тредов блокируйте эти четыре:

1. Дословный перевод с сохранением EN-структуры

Симптом: китайские фразы вроде «并不相同», «已经点击了», «一个空白屏幕» — явные кальки с английского.

Блок: пишите в промпте «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 эмодзи и fullwidth-кавычек.

Блок: не спрашивайте Claude «лимит превышен?» — запустите .length локально и по числам попросите сократить.

4. Непоследовательная позиция 🧵

Симптом: иногда 🧵 на каждом твите, иногда только на первом, иногда приземляется на 4/4.

Блок: зафиксируйте в промпте — «🧵 only on tweet 1». Claude по умолчанию не знает визуальные конвенции тредов.

Чеклист

Шесть правил, чтобы первый драфт многоязычного треда был впритык к лимиту:

  1. Говорите «write», а не «translate». Translate включает дословность = сохранение EN-структуры = вылет.
  2. Явный бюджет на язык. «≤ 140 chars» в 100× лучше «short».
  3. Разрешение резать контент. "cut detail if needed" говорит Claude, что факты можно терять ради длины.
  4. Локальный Ruby .length как шлюз. Точнее собственного счёта Claude, быстрее тестовой публикации.
  5. В китайском первыми режьте бэктики и эмодзи. Каждый бэктик = 1 символ, каждый эмодзи = 2.
  6. Фиксируйте позицию 🧵 в промпте. Claude по умолчанию не знает конвенций треда.

Настоящий инсайт: Claude может писать многоязычные треды правильно — но его дефолтная реакция «перевести». Ваша задача — через промпт переключить его в режим «независимой композиции по языкам». С шлюзом .length китайский тред последней сегодняшней статьи в первом драфте вышел ровно 140/140 — без резки.