BOOK-LIBRARY: LLM-переводы книг
LLM-переводы в BOOK-LIBRARY нужны не ради красивой кнопки «перевести книгу», а ради более практичной цели: сделать текст доступным читателю, не превращая перевод в непрозрачный чёрный ящик. Если книга есть только на одном языке, хочется быстро получить рабочую версию на другом. Но книга — это не короткая заметка: в ней есть главы, сноски, повторы терминов, авторский ритм и места, где автоматике нельзя доверять вслепую.
Поэтому переводы в BOOK-LIBRARY сделаны как pipeline, а не как один большой prompt. Книгу нельзя нормально отправить модели целиком, получить файл обратно и считать задачу закрытой. Нужны подготовка текста, деление на сегменты, устойчивое выполнение, проверка качества, сборка artifacts и ручное решение о публикации.
Переводы вынесены в отдельный рабочий контур рядом с импортом, но не смешаны с ним. Импорт добавляет книгу в каталог. Translation pipeline готовит перевод, который может остаться черновиком или стать опубликованным EPUB/PDF для читателя. Так сохраняется важная граница: LLM помогает получить полезный перевод, но исходный текст, проверка и решение о публикации остаются отдельными частями процесса.
Почему не один prompt
На коротком тексте один prompt может выглядеть убедительно. С книгой всё иначе: ошибка не всегда заметна сразу, а потерянный термин или переставленная сноска портят не один абзац, а впечатление от всего чтения. У книги есть несколько проблем, которые плохо решаются одной LLM-командой:
- текст может быть слишком большим для context window;
- главы и сноски нужно сохранить в правильном порядке;
- ошибки одного фрагмента не должны ломать весь перевод;
- разные модели могут вести себя по-разному на длинных текстах;
- результат нужно проверить до публикации;
- стоимость и повторы должны быть управляемыми.
Pipeline делает процесс менее эффектным, зато более надёжным. Вместо «переведи всё» появляется набор этапов, каждый из которых можно показать в админке, повторить или остановить. Для читателя это означает не магическое обещание идеального текста, а более честный путь к версии, которую хотя бы можно проверить перед публикацией.
Durable translation jobs
Перевод запускается как durable job. Backend сохраняет задачу в SQLite, обновляет её состояние и даёт React-админке читать прогресс через polling. Это тот же принцип, что и у долгого импорта: вкладка может обновиться, но задача не должна исчезнуть.
У translation job есть понятное состояние: queued, running, failed, cancelled или completed. Отдельные этапы могут фиксировать свои ошибки. Если provider упал или сегмент не перевёлся, администратор должен увидеть проблему, а не получить общий ответ «что-то пошло не так».
Общая цепочка
Типовая цепочка перевода выглядит так:
- Ingestion — система берёт исходную книгу и готовит её к обработке.
- Canonical document — текст приводится к внутреннему представлению, с которым дальше работает pipeline.
- Segmentation — документ делится на управляемые сегменты.
- LLM batch translation — сегменты переводятся пакетами через выбранного провайдера.
- QA — система собирает findings: пропуски, подозрительные места, ошибки или несоответствия.
- Assembly — переведённые сегменты собираются обратно в документ.
- Review — администратор проверяет результат и спорные места.
- Publish — готовые EPUB/PDF artifacts становятся видимыми публичной витрине.
Эта схема не обещает идеальный перевод без человека. Наоборот, она признаёт, что ручная проверка нужна, и создаёт для неё место. Перевод здесь не подменяет исходник и не объявляется финальным только потому, что его вернула модель: сначала он становится кандидатом, потом проходит проверку, и только после этого может попасть в публичную витрину.
Провайдеры и fallback
LLM providers хранятся в SQLite как runtime-сущности. Их можно настраивать из админки: включать, выключать, менять priority и использовать fallback. Это не абстрактная гибкость «на будущее», а нормальная страховка для длинной работы: LLM-интеграции зависят от лимитов, стоимости, доступности и качества конкретной модели.
Если один provider временно недоступен, pipeline может переключиться на другой. Если для части задач нужен более дешёвый или более стабильный endpoint, это тоже лучше решать настройкой, а не правкой кода.
При этом provider не становится источником истины. Он выполняет этап перевода, а качество результата проверяется отдельно.
Сегменты и ручная проверка
Сегментация нужна не только из-за технических лимитов. Она делает перевод проверяемым и менее пугающим. Если один фрагмент выглядит плохо, можно посмотреть именно его, сравнить с исходником и повторить работу над конкретным местом, а не искать ошибку в огромном файле.
В админке важны такие действия:
- открыть список сегментов;
- увидеть статус каждого сегмента;
- посмотреть исходный и переведённый текст;
- повторить перевод отдельного сегмента;
- отметить проблемное место;
- вернуться к QA findings после правки.
Это особенно важно для книг с терминами, именами, диалогами и длинными главами. LLM может дать гладкий текст, но потерять смысл в деталях: сгладить интонацию, перепутать устойчивый термин или пропустить важную связку между фрагментами. Поэтому review — обязательная часть pipeline, а не необязательный бонус.
QA findings
QA findings помогают не читать весь результат вслепую. Система может подсветить подозрительные места: пропущенный сегмент, слишком короткий перевод, странное расхождение, ошибку provider или технический сбой сборки.
Такие findings не заменяют редактора. Их задача скромнее и полезнее: показать, куда смотреть в первую очередь. Для частной библиотеки этого достаточно, чтобы не публиковать совсем сырой результат и не заставлять читателя первым находить технические ошибки.
Retry и cancel
У длинной задачи обязательно должны быть retry и cancel. Без этого любой сбой превращается в ручную чистку базы или полный перезапуск книги.
Retry полезен, когда:
- упал один provider;
- сегмент не прошёл проверку;
- запрос оборвался по лимиту;
- нужно повторить только неудачную часть.
Cancel нужен, если администратор понял, что выбрал не ту книгу, не тот язык, неподходящего provider или слишком дорогой сценарий. Отмена должна быть нормальным состоянием задачи, а не аварией.
Artifacts: EPUB и PDF
Результат pipeline — не просто текст в базе. Читателю нужен привычный файл, который можно открыть и читать, поэтому система собирает output artifacts, прежде всего EPUB и PDF. Именно artifacts потом могут быть опубликованы для читателя.
Важно разделять «artifact собран» и «artifact опубликован». Сборка файла означает, что технический результат появился. Публикация означает, что администратор проверил его достаточно, чтобы показать в публичной витрине. Эта пауза между сборкой и публикацией защищает проект от соблазна выдавать любой сгенерированный файл за готовую книгу.
Публично видны только published translations. Черновики, неудачные сборки, спорные версии и внутренние проверки остаются в админке.
Deferred scope
У переводческого направления есть честно отложенные части:
- OCR для сканов и сложных PDF;
- production PDF renderer;
- извлечение медиа из DOCX/PDF;
- translation memory;
- budget dashboards;
- более глубокое сравнение версий перевода;
- удобная редактура больших книг внутри админки.
Это не мелкие украшения. Каждая такая задача может стать отдельным слоем продукта. Поэтому лучше держать их как deferred scope, а не притворяться, что текущий pipeline уже закрывает все случаи.
Почему это отдельная статья
LLM-переводы легко описать слишком громко: будто модель сама превращает любую книгу в готовое издание. В BOOK-LIBRARY подход спокойнее и честнее. Модель — часть процесса, но вокруг неё нужны очередь, сегменты, QA, retry, artifacts и публикация.
Именно поэтому этому направлению нужна отдельная заметка. Здесь важна не сама возможность вызвать LLM, а способ встроить её в библиотеку так, чтобы перевод был полезен читателю и при этом оставался проверяемым. Такой pipeline сложнее, чем одна кнопка, зато он ближе к реальной эксплуатации: администратор видит, что происходит, может вмешаться и решает, когда перевод действительно можно показать читателю.
Связанные заметки
- React-админка и операционный центр — где управляются translation jobs, сегменты и providers.
- Архитектура — как переводы ложатся на backend, SQLite и durable jobs.
- Roadmap — какие части переводческого направления оставлены на следующий этап.