← К списку статей
Web 2026-04-17 · rev. 2026-05-10 ProtoMedia

Сайт, говорящий на десятках языков, без переводчиков

Автоматический перевод с итальянского · смотреть оригинал

Как мы построили систему перевода, которая работает под этими страницами: ИИ по мере необходимости, кэш всегда, нулевое воспринимаемое время ожидания.

Проблема традиционной i18n

На протяжении многих лет интернационализация веб-сайта была небольшим путешествием рабочих процессов: файлы .po, человеческие переводчики, забытые ключи, отложенные развертывания, потому что "немецкий язык еще не готов". Добавление языка стоило времени и денег; добавление десяти было немыслимо для любого малого предприятия.

С появлением LLM последнего поколения качество машинного перевода достигло точки, в которой — для корпоративного сайта, а не для литературы — оно достаточно. Вопрос больше не в том, "можем ли мы перевести это автоматически", а в том, "как мы интегрируем это, не нарушая пользовательский опыт".

Архитектура, вкратце

Сайт обслуживается статически на итальянском языке. Когда пользователь выбирает другой язык, вступает в действие небольшой движок на трех коллекциях MongoDB:

  • i18n_base: исходные тексты на выбранном языке (сейчас итальянский), каждый с указанием своего языка, описанием того, где и почему он появляется на сайте (важно для качества перевода), тоном и лимитом символов. Это описание становится частью запроса к LLM, который таким образом знает, переводит ли он кнопку или абзац.
  • i18n_human: переводы, выполненные вручную, когда для какой-то страницы нам нужно редакционное качество вместо вывода LLM. Они имеют приоритет над автоматическим кэшем и автоматически "отмечаются", когда исходный текст меняется.
  • i18n_cache: уже сгенерированные переводы, проиндексированные по (полю, языку). Каждая запись сохраняет временную метку базового текста на момент генерации.
  • articoli_i18n: та же логика применяется к более длинным текстам, таким как эта статья.

При первом доступе на новом языке система запрашивает у LLM только действительно отсутствующие поля, сохраняет ответ в кэше и возвращает его браузеру. При последующих посещениях тот же язык загружается мгновенно, без дополнительных вызовов ИИ.

Аннулирование, которое работает

Кэш — это упорядоченная ложь: он говорит "моя истина такова", пока кто-нибудь не опровергнет ее. Механизм опровержения здесь прост: каждая закэшированная трансляция сохраняет временную метку базового текста, который ее сгенерировал. Когда вы изменяете итальянский текст и увеличиваете его updated_at, все переводы этого поля на всех языках автоматически становятся устаревшими и генерируются повторно по мере необходимости. Никаких ручных каскадов, никакой необходимости очищать кэш.

Пользователь, который не ждет

Самая интересная часть не в переводе — а в том, как он отображается. При смене языка браузер видит итальянскую страницу с небольшими спиннерами рядом с каждым блоком текста, который нужно обновить. Соблазн заключается в том, чтобы сделать один вызов, который переведет все сразу: просто, чисто, и обрекает пользователя ждать, пока LLM не закончит все, прежде чем он увидит какие-либо изменения.

Мы пошли по противоположному пути. Тексты группируются по разделам (navbar, body, footer) и разбиваются на микропакеты по три поля каждый. Вызовы отправляются последовательно: сначала несколько полей navbar, которые появляются за несколько секунд — пользователь видит, что что-то происходит, и начинает читать. Пока он читает, поступает первая часть body, затем вторая, и, наконец, footer.

Краткий урок: Воспринимаемая скорость — это не общая скорость. Перевод по частям, в порядке видимости, важнее, чем завершение раньше.

Ночная работа

У кэша есть только один настоящий враг: первый визит. Первый немецкий пользователь платит цену за все будущие переводы, и именно этот опыт остается у него в голове. Чтобы устранить (или почти устранить) проблему, фоновая задача просыпается каждую минуту, выбирает наиболее ожидаемый язык среди еще не завершенных, берет непереведенный текст и передает его LLM. На следующей минуте — следующий. За несколько дней самые распространенные языки уже будут готовы.

Ночная задача также выполняет вторую работу: автоматически пересматривает переводы сомнительного качества, пробуя их снова с другой моделью ИИ. Когда выравнивание между языками важно, посредственный перевод не остается таковым.

Если вы первый немец сегодня и заходите, пока система еще завершает кэш, у вас все равно есть прогрессивная загрузка, чтобы занять вас. Если вы второй, вы даже не заметите.

Что вы получаете

Многоязычный сайт без переводчиков, без файлов для управления, без развертывания для добавления языка. Пользователь вводит код — ja, ca, eu, любой, который ему нужен — и страница переводится. Второй раз — мгновенно. К третьему разу мы, скорее всего, уже позаботились об этом, перевод сделан вовремя задачей, которая никогда не спит.

Эта же страница, если вы читаете ее на немецком, испанском или корейском языке, ни разу не была написана переводчиком. Она была переведена один раз, большой языковой моделью (LLM), и с тех пор обслуживается из кэша. Единственное, что написано вручную, — это то, что вы читаете сейчас, если это итальянский язык.

Заинтересованы в том, чтобы внедрить эту архитектуру на свой сайт? Давайте обсудим.

Связаться с нами

Есть замечание? Напишите нам

Сообщение предназначено только для нас. Если ваш комментарий будет интересен, мы можем опубликовать его в конце статьи, но только после проверки.

Пока вы пишете, ваш браузер решает небольшую вычислительную задачу — это наш способ защиты от автоматической рассылки без использования сторонних сервисов и запроса на распознавание изображений. Ничего не требуется, и данные не покидают этот сайт.