---
metadata:
  - name: generator
    content: Diplodoc Platform v5.54.3
alternate:
  - https://diplodoc-platform--docs.viewer.diplodoc.com/en/tools/docs/translate-ai.md
  - https://diplodoc-platform--docs.viewer.diplodoc.com/ru/tools/docs/translate-ai.md
  - href: ru/tools/docs/translate-ai.md
    type: text/markdown
    title: Markdown version
  - href: ../../llms.txt
    type: text/markdown
    title: llms.txt
keywords:
  - translate
  - ai
  - llm
  - yandexgpt
  - openai
  - openrouter
  - anthropic
  - перевод
  - машинный перевод
updatedAt: '2026-08-13T07:48:22.000Z'
---
> **Documentation Index:** Fetch the complete configuration index at https://diplodoc-platform--docs.viewer.diplodoc.com/ru/llms.txt

# AI-перевод

Команда `yfm translate` умеет переводить документацию большими языковыми моделями (LLM). Поддерживаются провайдеры `yandexgpt`, `openai`, `openrouter` и `anthropic`.

Пайплайн тот же, что и у [остальных провайдеров перевода](https://diplodoc-platform--docs.viewer.diplodoc.com/ru/tools/docs/translate.md): текст извлекается из разметки, переводится и собирается обратно. Разметка Markdown, HTML-теги, код и Liquid-конструкции в модель не попадают - переводятся только текстовые сегменты.

Провайдер здесь описывает протокол API, а не конкретного вендора: любую совместимую инсталляцию (self-hosted модель, внутренний шлюз) можно подключить тем же провайдером, [заменив адрес API](#custom-api).

## Быстрый старт {#quickstart}

1. Получите ключ API и передайте его через переменную окружения или опцию `--auth` (значение или путь к файлу с токеном):

   ```bash
   export OPENAI_API_KEY="sk-..."
   ```

2. Оцените объем перевода без запросов к API:

   ```bash
   yfm translate -i . -o ./translated --provider openai --source ru --target en --dry-run
   ```

   В строке `PROCESSED` будет прогноз количества запросов и токенов. Файлы в output при этом собираются с исходным, непереведенным текстом - не принимайте их за результат перевода.

3. Попробуйте перевод на одном файле или разделе:

   ```bash
   yfm translate -i . -o ./translated --provider openai --source ru --target en \
     --files ru/index.md --cache-dir .translate-cache
   ```

   Проверьте качество результата и при необходимости настройте [глоссарий](#glossary) или [промпты](#prompts).

4. Запустите полный прогон с кэшем и копированием ассетов:

   ```bash
   yfm translate -i . -o ./translated --provider openai --source ru --target en \
     --cache-dir .translate-cache --copy-assets
   ```

5. Проверьте результат: повторный запуск той же команды должен показать `requests: 0` - все сегменты берутся из [кэша](#cache). Переведенную версию можно собрать обычным `yfm build`.

Ошибка одного файла или превышение лимитов не останавливают прогон: упавшие файлы помечаются `ERR`, остальные продолжаются. Перезапуск команды доведет хвосты - уже переведенные сегменты возьмутся из кэша.

## Провайдеры {#providers}

#|
|| **Провайдер** | **API** | **Модель по умолчанию** | **Переменные окружения** ||
|| `yandexgpt` | [Yandex AI Studio](https://yandex.cloud/ru/docs/ai-studio/) | `yandexgpt-lite` | `YANDEX_API_KEY`, `YC_IAM_TOKEN` ||
|| `openai` | [OpenAI Chat Completions](https://platform.openai.com/docs/api-reference/chat) | `gpt-4o-mini` | `OPENAI_API_KEY` ||
|| `openrouter` | [OpenRouter](https://openrouter.ai/docs) | `openai/gpt-4o-mini` | `OPENROUTER_API_KEY` ||
|| `anthropic` | [Anthropic Messages](https://docs.anthropic.com/en/api/messages) | `claude-sonnet-4-5` | `ANTHROPIC_API_KEY` ||
|#

Авторизация:

* `yandexgpt` - IAM-токен (`t1.`) или OAuth-токен (`y0_`) передаются как `Bearer`, любое другое значение - как `Api-Key` сервисного аккаунта. Дополнительно требуется `--folder` - [идентификатор каталога](https://yandex.cloud/ru/docs/resource-manager/operations/folder/get-id), если `--model` задана коротким именем (`yandexgpt-lite`). Полный URI модели (`gpt://<folder>/yandexgpt/latest`) можно указывать без `--folder`.
* `openai`, `openrouter` - Bearer-ключ.
* `anthropic` - ключ в заголовке `x-api-key`.

### Подключение совместимых инсталляций {#custom-api}

Self-hosted модель или внутренний шлюз с совместимым API подключается тем же провайдером с опцией `--api-base`. Путь запроса доклеивается к базе автоматически:

#|
|| **Провайдер** | **База по умолчанию** | **Путь запроса** ||
|| `yandexgpt` | `https://llm.api.cloud.yandex.net` | `/foundationModels/v1/completion` ||
|| `openai` | `https://api.openai.com/v1` | `/chat/completions` ||
|| `openrouter` | `https://openrouter.ai/api/v1` | `/chat/completions` ||
|| `anthropic` | `https://api.anthropic.com/v1` | `/messages` ||
|#

Для `openai`, `openrouter` и `anthropic` включайте `/v1` в базу. Базу можно задать и переменными окружения `OPENAI_BASE_URL`, `OPENROUTER_BASE_URL`, `ANTHROPIC_BASE_URL`.

Если шлюз требует свою схему авторизации, передайте заголовки опцией `--api-header` (можно повторять). Пользовательские заголовки перекрывают стандартные, поэтому так можно целиком заменить авторизацию. Опция `--auth` при этом формально обязательна - передайте заглушку:

```bash
yfm translate -i . -o ./translated \
  --provider openai \
  --api-base https://llm.internal.example.com/v1 \
  --model my-model \
  --auth dummy \
  --api-header "Authorization: OAuth $(cat ~/.tokens/llm)" \
  --source ru --target en --cache-dir .translate-cache
```

Путь запроса для каждого провайдера фиксирован: если шлюз использует нестандартный путь, переопределить его нельзя.

## Справочник опций {#options}

Общие опции команды (`--source`, `--target`, `--files`, `--include`, `--exclude`, `--dry-run` и другие) описаны на странице [Локализация](https://diplodoc-platform--docs.viewer.diplodoc.com/ru/tools/docs/translate.md). Опция `--target` может быть передана несколько раз - перевод выполнится на каждый язык. Ниже - опции AI-провайдеров.

#|
|| **Опция** | **По умолчанию** | **Описание** ||
|| `--provider` | `yandex` | Провайдер перевода. Для AI-перевода: `yandexgpt`, `openai`, `openrouter` или `anthropic`. Значение по умолчанию `yandex` - это машинный перевод [Yandex Translate](https://diplodoc-platform--docs.viewer.diplodoc.com/ru/tools/docs/translate.md#auto), не LLM ||
|| `--auth` | из переменной окружения | Токен или путь к файлу с токеном. В файл конфигурации класть нельзя ||
|| `--model` | зависит от провайдера | Идентификатор модели ||
|| `--folder` | - | Идентификатор каталога Yandex AI Studio. Только для `yandexgpt`, обязателен при коротком имени модели ||
|| `--api-base` | URL API провайдера | База URL для [совместимых инсталляций](#custom-api) ||
|| `--api-header` | - | Дополнительный HTTP-заголовок в формате `"Name: value"`. Можно повторять. Перекрывает стандартные заголовки ||
|| `--system-prompt` | встроенный | Системный промпт: строка или путь к файлу. См. [Промпты](#prompts) ||
|| `--user-prompt` | встроенный | Пользовательский промпт: строка или путь к файлу ||
|| `--prompt-mode` | `append` | `append` - ваш системный промпт добавляется к встроенному, `replace` - полностью заменяет его ||
|| `--glossary` | - | Путь к YAML-файлу с обязательными переводами терминов, относительно input. См. [Глоссарий](#glossary) ||
|| `--judge` | выключено | Оценка качества перевода второй моделью. См. [Оценка качества](#judge) ||
|| `--judge-model` | модель перевода | Модель для оценки качества ||
|| `--judge-threshold` | `70` | Порог: сегменты с оценкой ниже попадают в отчет и в лог ||
|| `--cache-dir` | - | Директория персистентного кэша переводов. См. [Кэш](#cache) ||
|| `--no-cache` | - | Отключить кэш для текущего запуска ||
|| `--temperature` | `0` | Температура сэмплирования. `0` - детерминированный перевод ||
|| `--max-output-tokens` | `4000` | Максимум токенов в одном ответе модели ||
|| `--max-batch-tokens` | `2000` | Бюджет входных токенов одного запроса. Сегменты группируются в батчи до этого лимита ||
|| `--max-concurrency` | `5` | Максимум одновременных запросов к API ||
|| `--retry` | `3` | Число повторов при временных ошибках API ||
|| `--timeout` | `60000` | Таймаут одного запроса в миллисекундах ||
|#

### Конфигурация в файле {#config}

Все опции, кроме `--auth`, можно зафиксировать в секции `translate` [файла конфигурации](https://diplodoc-platform--docs.viewer.diplodoc.com/ru/settings.md) `.yfm`. Имена - в camelCase, флаги командной строки имеют приоритет:

```yaml
translate:
  provider: openai
  model: gpt-4o-mini
  cacheDir: .translate-cache
  maxConcurrency: 2
  apiHeaders:
    X-Custom-Header: value
```

Токен в конфигурации хранить нельзя: команда завершится ошибкой `Do not store authToken in public config`. Используйте переменные окружения или `--auth`.

### Промпты {#prompts}

Встроенный системный промпт настроен на технический перевод: сохранять разметку, не переводить код и идентификаторы, не добавлять пояснений. Свои инструкции можно добавить к нему (`--prompt-mode append`, по умолчанию) или полностью заменить его (`--prompt-mode replace`).

Значение `--system-prompt` и `--user-prompt` - строка или путь к файлу. Поддерживаются плейсхолдеры:

* `{{source}}`, `{{target}}` - языки перевода;
* `{{glossary}}` - глоссарий в текстовом виде;
* `{{context}}` - контекст документа (заголовок и путь файла);
* `{{separator}}` - разделитель фрагментов;
* `{{fragments}}`, `{{text}}` - переводимые фрагменты (только в `--user-prompt`).

Пример: потребовать соблюдения корпоративного тона:

```bash
yfm translate -i . -o ./translated --provider openai --source ru --target en \
  --system-prompt "Use formal tone. Address the reader as 'you'."
```

### Глоссарий {#glossary}

Модель переводит каждый сегмент отдельно и не видит, как этот же термин переведен в соседнем файле или в предыдущем запуске. Из-за этого «сборка» в одном месте становится `build`, в другом - `assembly`, а название продукта неожиданно переводится. Глоссарий задает обязательные переводы терминов и убирает такой разнобой.

Типовые случаи:

* у продукта есть устоявшаяся терминология, и перевод должен совпадать с интерфейсом и остальной документацией;
* термин, название или идентификатор не должен переводиться вообще - тогда `translatedText` повторяет `sourceText`;
* модель систематически ошибается в конкретном термине.

Глоссарий - YAML-файл с единственным ключом `glossaryPairs`. Это список пар «термин в оригинале - требуемый перевод»:

```yaml
glossaryPairs:
  - sourceText: оглавление
    translatedText: table of contents
  - sourceText: сборка
    translatedText: build
  - sourceText: Diplodoc
    translatedText: Diplodoc
```

#|
|| **Поле** | **Описание** ||
|| `sourceText` | Термин на языке оригинала, то есть на языке из `--source` ||
|| `translatedText` | Перевод, который должен попасть в результат. Повторите исходное написание, чтобы термин остался без изменений ||
|#

Глоссарий один на запуск и не привязан к языковой паре, поэтому для перевода на несколько языков нужен отдельный файл на каждый `--target`.

Путь в `--glossary` указывается относительно `--input`:

```bash
yfm translate -i . -o ./translated --provider openai --source ru --target en \
  --glossary glossary.yaml
```

В [файле конфигурации](#config) путь указывается относительно самого `.yfm`:

```yaml
translate:
  glossary: glossary.yaml
```

Если файла нет, команда завершится с ошибкой.

Пары подставляются в промпт каждого запроса к модели списком вида `термин → перевод` (плейсхолдер `{{glossary}}`, см. [Промпты](#prompts)). Отсюда следуют три особенности:

* Это инструкция модели, а не замена по тексту после перевода. Термин из глоссария соблюдается почти всегда, но гарантии нет: результат стоит проверять поиском по переводу или [оценкой качества](#judge).
* Словоформы модель разбирает сама, отдельные строки на падежи и множественное число заводить не нужно.
* Глоссарий целиком уходит в каждый запрос и расходует токены на каждом батче. Держите в нем только термины, которые действительно важны или которые модель путает, а не весь словарь продукта.

Изменение глоссария инвалидирует [кэш переводов](#cache): после правки файла все сегменты переводятся заново.

## Кэш переводов {#cache}

Опция `--cache-dir` включает персистентный кэш: пары «сегмент - перевод» сохраняются на диск, и повторные запуски отправляют в модель только новые и измененные сегменты. Кэш сбрасывается на диск после каждого обработанного файла, поэтому прерывание прогона безопасно - перезапуск продолжит с того же места.

Как устроен кэш:

* На каждую комбинацию «провайдер + модель + пара языков» создается отдельный файл `<провайдер>.<модель>.<источник>-<цель>.json`. Смена `--model` не затирает кэш другой модели, но и не использует его.
* Изменение промптов или глоссария автоматически инвалидирует кэш: сохраненные переводы устаревают и выполняются заново. Обновление CLI со встроенными промптами действует так же.
* `--no-cache` отключает кэш на один запуск, не удаляя сохраненные переводы.

Директорию кэша имеет смысл коммитить в репозиторий или сохранять между запусками CI - тогда при регулярных переводах оплачиваются только изменившиеся сегменты.

## Оценка качества {#judge}

Опция `--judge` включает оценку перевода второй моделью: каждая пара «оригинал - перевод» получает балл от 0 до 100. Режим строго опциональный - расход токенов вырастает примерно вдвое.

```bash
yfm translate -i . -o ./translated --provider openai --source ru --target en \
  --cache-dir .translate-cache --judge --judge-model gpt-4o --judge-threshold 80
```

По умолчанию оценивает та же модель, что переводила. Это удобно для поиска грубых ошибок, но такая самооценка завышена. Для честного сравнения используйте `--judge-model` с моделью не слабее переводящей: слабый судья не заметит ошибок сильного переводчика.

Результаты:

* Сегменты с оценкой ниже `--judge-threshold` попадают в лог как `WARN` с баллом и причиной.
* В output записывается отчет `translate-quality.<язык>.json`:

  ```json
  {
    "model": "gpt-4o",
    "threshold": 80,
    "scored": 214,
    "averageScore": 93.4,
    "low": 2,
    "segments": [
      {
        "path": "ru/tools/docs/build.md",
        "source": "Сборка проекта выполняется командой...",
        "translation": "The project is built with...",
        "score": 55,
        "issue": "Omitted the second sentence"
      }
    ]
  }
  ```

  В `segments` попадают только сегменты ниже порога, отсортированные от худших к лучшим.
* Итоговая строка в логе: `judge: 214 units scored, average score 93.4/100, 2 below threshold 80`. Первое число - количество оцененных сегментов, не балл.

Оценка не влияет на результат перевода и не прерывает прогон: сбой оценки отдельного батча логируется и пропускается. В `--dry-run` оценка не выполняется.

## Как читать лог {#log}

#|
|| **Строка** | **Что означает** ||
|| `TRANSLATE <файл>` | Файл взят в работу. Если строки нет - файл не попал в scope прогона (фильтры `--files`, `--include`, `--exclude`, язык) ||
|| `SKIPPED [reason] <файл>` | Файл отфильтрован; в скобках причина: `exclude`, `include`, `language` ||
|| `REQUEST <файл> N units, ~X tokens` | Батч из N сегментов отправлен в модель. В `--dry-run` таких строк нет ||
|| `TRANSLATED <файл>` | Файл переведен и записан в output ||
|| `WARN ... Part is too big (~N tokens > M)` | Сегмент крупнее `--max-batch-tokens` и остался на исходном языке ||
|| `WARN ... Batch of N fragments failed ... retrying one-by-one` | Ответ модели не разобрался на фрагменты, батч повторяется по одному сегменту ||
|| `WARN <файл> Translation quality N/100: ...` | Оценка сегмента ниже `--judge-threshold` ||
|| `ERR <файл> ...` | Файл не переведен, прогон продолжается. Фатальна только ошибка авторизации ||
|| `PROCESSED requests: R input-tokens: I output-tokens: O bytes: B cached-units: C` | Итог по прогону: запросы, токены, объем текста и число сегментов из кэша ||
|| `PROCESSED judge: N units scored, average score A/100, M below threshold T` | Итог оценки качества ||
|#

## Решение проблем {#troubleshooting}

### Ошибка 429 (rate limit) {#throttling}

CLI сам повторяет запрос до `--retry` раз с экспоненциальной паузой и учитывает заголовок `Retry-After`. Если лимиты API все равно превышаются, перезапустите прогон с меньшей параллельностью:

```bash
yfm translate -i . -o ./translated --provider openai --source ru --target en \
  --cache-dir .translate-cache --max-concurrency 2
```

Уже переведенные сегменты возьмутся из кэша, в модель уйдут только оставшиеся.

### WARN Part is too big {#too-big}

Сегмент оказался крупнее `--max-batch-tokens` и остался на исходном языке. Увеличьте `--max-batch-tokens` (при необходимости вместе с `--max-output-tokens`) или разбейте текст в исходнике на более короткие абзацы.

### Ответ модели обрезан {#truncated}

Ошибки вида `response was truncated` означают, что модели не хватило лимита ответа. Увеличьте `--max-output-tokens` или уменьшите `--max-batch-tokens`.

### Файл не переводится {#out-of-scope}

Если правка в файле не попадает в перевод, сначала проверьте scope прогона: опции `--files` и `--include` сужают набор файлов, и изменения вне этого набора в прогон не попадают - в логе для такого файла нет строки `TRANSLATE`. Это не проблема кэша.

Также помните, что кэш ведется отдельно на каждую модель: после смены `--model` переводы другой модели не переиспользуются.

### В output исходный текст {#source-text-in-output}

* После `--dry-run` это ожидаемо: файлы собираются без обращения к модели, с исходным текстом.
* Отдельный сегмент может совпадать с оригиналом и в обычном прогоне: модель осознанно не переводит текст, который уже на целевом языке, имена собственные и нетекстовые фрагменты. Пустой ответ модели никогда не принимается за перевод - в этом случае сохраняется исходный текст.

## Известные ограничения {#limitations}

* Страницы с блоками `::: page-constructor` внутри `.md` переводятся ненадежно ([translation#273](https://github.com/diplodoc-platform/translation/issues/273)). Пока рекомендуется исключать их из прогона через `--exclude`.
* Путь запроса для каждого провайдера фиксирован - шлюз с нестандартным путем API подключить не получится.
* Модель может повредить инлайн-разметку внутри сегмента (ссылки, выделение). Структурной валидации Markdown после перевода нет - такие случаи помогает находить [оценка качества](#judge).
