# Спецификация: Сервис LLM-перевода табличных данных **Дата**: 2026-05-18 **Назначение**: Передача сторонней команде для оценки трудозатрат **Фокус**: только требования к конечному результату, без технологий --- ## 1. Фронтенд (Web-интерфейс) ### 1.1 Управление задачами перевода (Jobs) - Список всех задач перевода с фильтрацией по датасорсу, целевой таблице, статусу. - Создание новой задачи перевода: - Выбор Superset-датасорса (источник данных). - Выбор колонки для перевода (одна, обязательная). - Выбор колонок контекста (ноль или более) — их значения передаются LLM для повышения качества. - Выбор ключевых колонок (одна или более, composite key) — по ним данные будут сопоставляться при вставке в целевую таблицу. - Указание целевой таблицы и целевой колонки. - Выбор одного или нескольких языков перевода. - Редактирование системного промпта (шаблон сообщения LLM). - Выбор LLM-провайдера и модели. - Прикрепление одного или нескольких справочников терминов. - Указание стратегии UPSERT (skip_existing / overwrite / insert). - Редактирование, копирование, удаление задачи. ### 1.2 Превью (Quality Gate) - Запуск превью на ограниченной выборке строк (1–100, по умолчанию 10). - Отображение source-строк, контекста, обнаруженного языка оригинала и перевода на каждый целевой язык — рядом, в табличном виде. - Approve / Edit / Reject для каждой строки превью. - Повторный запуск превью с изменёнными настройками (промпт, язык, провайдер). - Подтверждение превью (accept) — открывает возможность полного прогона. - Предупреждение о стоимости перед запуском полного прогона (оценка токенов и цены). ### 1.3 Выполнение (Run) - Запуск полного прогона (только после accepted превью). - Живой индикатор прогресса: сколько строк обработано, успешно, с ошибками, процент выполнения. - Возможность отмены прогона. - Построчный просмотр результатов после завершения: - Исходный текст, контекст, перевод по каждому языку. - Статус каждой строки (OK / ошибка / пропущена). - Сгенерированный SQL (для аудита). - Статус вставки в Superset. - Повтор проблемных batch-ей (retry failed). - Inline-редактирование любой переведённой строки в результатах. - Bulk Find & Replace по результатам прогона (с превью замен). ### 1.4 Очередь и планировщик - Возможность настроить расписание для задачи: - Одноразовый запуск в будущем. - Интервальный (каждые N минут/часов/дней). - Cron-выражение с выбором часового пояса. - Scheduled-прогон создаёт новый Run и выполняет полный цикл. - Для scheduled-прогонов: new-key-only (только новые строки, которых нет в последнем успешном прогоне). - Если последний успешный прогон старше 90 дней — fallback на полный прогон. - Защита от overlap: если предыдущий scheduled-прогон ещё выполняется — пропуск или очередь (1 в очереди). - После N последовательных ошибок (по умолч. 3) — автоотключение расписания и уведомление. ### 1.5 История и аудит - Список всех прогонов с деталями: датасорс, целевая таблица, кол-во строк, статус, кто запустил. - Детальный просмотр прогона: configuration snapshot, промпт, результаты по строкам, сгенерированный SQL, Superset execution reference. - Фильтрация по датасорсу, целевой таблице, дате, статусу. ### 1.6 Справочники терминов (Dictionaries) - Создание справочника. - Добавление пар «термин оригинала → перевод» с указанием языка оригинала и языка перевода. - Импорт из CSV/TSV с превью, разрешением конфликтов (overwrite / keep / skip). - Inline-редактирование, удаление записей. - Прикрепление справочника к задаче перевода. - Приоритет справочников (низкий номер = выше приоритет). ### 1.7 Коррекция и обратная связь - Из любого завершённого прогона: клик на ячейку перевода → inline-редактирование. - После редактирования: кнопка «Отправить в справочник». - Popup с предзаполненными: исходный термин, старый перевод, новый перевод, язык оригинала (из строки), язык перевода (из колонки), context_data (из строк, автоматически), usage notes (вручную). - Выбор целевого справочника (фильтр по языковой паре). - Bulk-режим: массовое редактирование и отправка нескольких терминов за раз. - Конфликт при повторной отправке: overwrite / keep existing / cancel. --- ## 2. Оркестратор (Run Lifecycle) ### 2.1 Жизненный цикл прогона 1. **Создание**: формируется snapshot конфигурации задачи + snapshot прикреплённых справочников. 2. **Планирование**: определяются целевые языки, размер batch-ей (динамически, по token budget), порядок обработки. 3. **Выполнение**: - Выборка source-строк: для scheduled new-key-only — только новые ключи; для manual — все строки. - Разбивка на batch-и. - Для каждого batch: a. Запрос к LLM с промптом, контекстом, отфильтрованными записями справочников. b. Парсинг структурированного JSON-ответа. c. Валидация: все ли строки batch переведены, нет ли дубликатов. d. Если ошибка — запись в TranslationBatch как failed. - После всех batch-ей: финализация (статус, error_message если все строки упали). 4. **Вставка (Insert phase)**: - Генерация UPSERT SQL под диалект БД (определяется динамически из Superset connection). - Отправка SQL через Superset SQL Lab API. - Polling статуса выполнения. - Запись результата (query reference, статус, ошибка). 5. **Завершение**: запись метрик, отправка уведомления (опционально), авто-dismiss через N секунд на UI. ### 2.2 Snapshot isolation - Все прогоны используют snapshot конфигурации и справочников, взятый на момент старта. - Изменения конфигурации во время выполнения прогона НЕ влияют на текущий прогон. ### 2.3 Retry - Возможность повторно запустить только failed batch-и (не трогая успешные). - При перезапуске можно сменить LLM-провайдера. ### 2.4 Data retention - 90 дней — полная детализация (source-строки, переводы, SQL). - После 90 дней — агрегация: только метаданные прогона и агрегированные метрики. - Перед прунингом — сохранение cumulative snapshot метрик. --- ## 3. Перевод (LLM) ### 3.1 Multi-language - Задача поддерживает N целевых языков (массив, а не один язык). - LLM получает исходный текст один раз на batch и возвращает переводы для ВСЕХ целевых языков в одном JSON-ответе. - Не нужно N отдельных LLM-вызовов. ### 3.2 Автоопределение языка оригинала - LLM определяет язык каждой строки автоматически. - Возвращает BCP-47 tag (например, "fr", "de", "und" для неопределённого). - Пользователь НЕ указывает язык оригинала вручную. ### 3.3 Reference copy - Если язык оригинала включён в список целевых языков — «переводом» для него будет исходный текст (verification copy). ### 3.4 Dictionary injection - Перед каждым LLM-запросом выполняется per-batch фильтрация справочника: - Отбираются только те записи, чей source_term встречается (case-insensitive substring match) хотя бы в одной строке batch-а. - Учитывается языковая пара (source_language записи === detected_language строки, target_language записи === языка промпта). - Отфильтрованные записи вставляются в промпт как authoritative glossary. - Записи с совпадающим контекстом (context_data) помечаются priority. ### 3.4 Превью - Quality gate, а не построчное утверждение. - Принятие превью = одобрение настроек (промпт, языки, справочники), после чего полный прогон обрабатывает ВСЕ строки. - Редактуры на уровне превью переносятся в полный прогон для тех же строк (carry-forward). - Rejected строки превью исключаются из полного прогона (только если были в sample). --- ## 4. Справочники (Dictionaries) ### 4.1 Структура - Справочник содержит пары «термин оригинала → перевод». - Каждая запись имеет: - source_term — термин на языке оригинала. - target_translation — корректный перевод. - source_language (BCP-47) — язык термина. - target_language (BCP-47) — язык перевода. - context_data (JSON, опционально) — значения контекстных колонок из строки, где был найден термин. - usage_notes (текст, опционально) — заметки по использованию. - has_context (boolean) — есть ли контекстные данные. ### 4.2 Привязка к задаче - К задаче можно привязать несколько справочников. - Порядок приоритета: чем меньше номер, тем выше приоритет. - При конфликте (один source_term в нескольких справочниках) побеждает высший приоритет. ### 4.3 Per-batch фильтрация - В каждый LLM-запрос включаются ТОЛЬКО те записи справочника, чей source_term: - Встречается хотя бы в одной строке batch-а (substring match). - source_language совпадает с detected_language строки. - target_language совпадает с языком текущего промпта. - Размер справочника не ограничен (фильтрация не даёт промпту расти бесконечно). ### 4.4 Контекстная приоритизация - Если context_data записи совпадает с контекстом строки batch-а (Jaccard similarity > 50%) — запись помечается как priority_context. - Priority-записи перечисляются первыми с пометкой # PRIORITY. - Это soft signal для LLM, не хард-фильтр. ### 4.5 Коррекция через результаты прогонов - Из любого завершённого прогона можно отправить исправление в справочник. - context_data заполняется автоматически из строки, где был найден термин. - Пользователь может отредактировать context_data, добавить usage_notes, убрать контекст. - Если context_data превышает 500 токенов — обрезается с пометкой. --- ## 5. Обработка ошибок (Edge Cases) - NULL в колонке перевода → пропуск строки с логированием. - NULL в ключевой колонке → reject строки (не может быть вставлена). - LLM вернул неожиданный формат → запрос структурированного JSON, валидация, failed batch. - Все строки batch упали → run.error_message с деталями. - Редактирование задачи во время выполнения прогона → не влияет на текущий прогон (snapshot isolation). - Удаление справочника, привязанного к активной задаче → запрет, предупреждение. - Scheduled прогон при недоступном датасорсе → запись ошибки, попытка следующего триггера. - Неподдерживаемый диалект БД → блокировка выполнения с сообщением. - Вставка через Superset SQL Lab вернула ошибку → insert_status = failed, error_message заполнен.