Как перевести текст в GPT через командную строку

В этой статье

Перевод из терминала начинается не с curl. Сначала сохраните исходный текст в UTF-8, затем явно опишите задачу для модели и только после этого проверьте, что ответ не потерял важную деталь.

Ниже — один маршрут для Linux, macOS и Windows PowerShell. Он не использует Python SDK и веб-интерфейс ChatGPT: текст уходит из локального файла в Responses API.

Подготовьте исходный файл

Создайте файл source.txt и сохраните его в UTF-8 без изменения строк. Например:

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

В этом примере язык оригинала — русский, язык перевода — английский. Важны не только слова, но и три условия: срок «до пятницы», оговорка об изменении срока и вежливый тон.

API-ключ не записывайте в source.txt, скрипт или репозиторий. Передайте его процессу через переменную окружения. Модель тоже задайте переменной: конкретное имя должно быть доступно вашему API-проекту. В примерах ниже указано gpt-5.2 как заменяемое значение, а не как гарантия доступа.

Для запроса Responses API используется POST /v1/responses; в теле нужны как минимум model и input. Документация метода создания ответа описывает эти поля и структуру результата.

Linux и macOS: отправьте файл через curl

Сначала задайте ключ только в текущей сессии терминала:

export OPENAI_API_KEY='ваш_ключ_из_переменных_окружения'

В реальной работе удобнее получить его из защищённого хранилища или заранее настроенной переменной окружения. Не вставляйте настоящий ключ в команду, которую собираетесь сохранять или отправлять кому-то.

Соберите JSON из файла с помощью jq. Ключ --rawfile читает содержимое source.txt как строку и корректно экранирует кавычки и переводы строк внутри JSON:

jq -n \
  --arg model 'gpt-5.2' \
  --rawfile source 'source.txt' \
  '{
    model: $model,
    input: (
      "Переведи следующий текст с русского на английский.\n" +
      "Сохрани смысл, числа, даты, имена и условия.\n" +
      "Контекст: деловая переписка о договоре.\n" +
      "Не добавляй комментарии, пояснения или вступление — верни только перевод.\n\n" +
      $source
    )
  }' > request.json

Теперь отправьте запрос. Тело ответа останется чистым JSON в response.json, а HTTP-код попадёт в отдельную переменную:

status=$(curl --silent --show-error \
  --output response.json \
  --write-out '%{http_code}' \
  --request POST 'https://api.openai.com/v1/responses' \
  --header "Authorization: Bearer $OPENAI_API_KEY" \
  --header 'Content-Type: application/json' \
  --data-binary @request.json)

printf 'HTTP status: %s\n' "$status"

Здесь Authorization: Bearer ... и Content-Type: application/json передаются в заголовках, как в официальном примере для curl. Руководство по моделям и запросам поможет сверить актуальное имя доступной модели.

Код 2xx показывает, что запрос принят, но не доказывает качество перевода. Поэтому сохраняйте response.json и разбирайте его после запроса. При ошибке проверьте код, модель, права проекта и лимиты, не публикуя сам ключ.

Ожидаемый синтетический перевод для исходной фразы может выглядеть так:

Please send the final version of the contract by Friday. If the deadline changes, please let me know in advance.

Этот фрагмент — иллюстрация ожидаемого содержания, а не результат выполненного здесь API-запроса.

Windows PowerShell: тот же запрос без Python

В PowerShell ключ можно временно задать так:

$env:OPENAI_API_KEY = 'ваш_ключ_из_переменных_окружения'

Прочитайте файл целиком и соберите объект запроса. -Raw не даёт PowerShell превратить каждую строку исходника в отдельное поле.

$source = Get-Content -Raw -Encoding utf8 .\source.txt
$body = @{
    model = 'gpt-5.2'
    input = @"
Переведи следующий текст с русского на английский.
Сохрани смысл, числа, даты, имена и условия.
Контекст: деловая переписка о договоре.
Не добавляй комментарии, пояснения или вступление — верни только перевод.

$source
"@
} | ConvertTo-Json -Depth 10

$response = Invoke-WebRequest `
    -Method Post `
    -Uri 'https://api.openai.com/v1/responses' `
    -Headers @{ Authorization = "Bearer $env:OPENAI_API_KEY" } `
    -ContentType 'application/json; charset=utf-8' `
    -Body ([Text.Encoding]::UTF8.GetBytes($body))

Write-Output "HTTP status: $($response.StatusCode)"
$response.Content | Set-Content -Encoding utf8 .\response.json

Перед запуском проверьте, что source.txt действительно сохранён в UTF-8, а переменная ключа не пуста:

if ([string]::IsNullOrWhiteSpace($env:OPENAI_API_KEY)) {
    throw 'OPENAI_API_KEY не задан'
}

При ошибке HTTP PowerShell может выбросить исключение вместо обычного ответа. Сохраните текст ошибки и проверьте код, модель, права проекта и лимиты, не публикуя сам ключ.

Где искать перевод в JSON

У curl нет SDK-свойства output_text. Сырой ответ Responses API — это JSON-объект с полями вроде id, status и массива output; текст нужно извлечь из фактических элементов ответа. Поэтому после запроса полезно разобрать именно полученный JSON.

В Linux и macOS:

jq -r '
  [.output[]?.content[]? | select(.type == "output_text") | .text]
  | join("")
' response.json

Проверка с ненулевым кодом завершения, если текст не найден:

translation=$(jq -r '
  [.output[]?.content[]? | select(.type == "output_text") | .text]
  | join("")
' response.json)

if [ -z "$translation" ] || [ "$translation" = "null" ]; then
  echo 'Перевод не найден в output' >&2
  exit 1
fi

printf '%s\n' "$translation"

В PowerShell:

$json = Get-Content -Raw -Encoding utf8 .\response.json | ConvertFrom-Json
$translation = @(
    foreach ($item in $json.output) {
        foreach ($content in $item.content) {
            if ($content.type -eq 'output_text') { $content.text }
        }
    }
) -join ''

if ([string]::IsNullOrWhiteSpace($translation)) {
    throw 'Перевод не найден в output'
}

$translation

Если структура отличается, сначала посмотрите небольшой фрагмент response.json и сверяйте его с описанием Create a model response. Не подменяйте сырой ответ SDK-удобством: для командной строки важны реальные поля JSON.

Как проверить, что перевод полный

HTTP-код 2xx означает, что сервер принял запрос, но ещё не доказывает качество перевода. Проверьте как минимум четыре вещи:

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

Для нашего примера вручную найдите в английской версии:

  • срок by Friday — «до пятницы»;
  • условие If the deadline changes — «если срок изменится»;
  • просьбу сообщить заранее — let me know in advance;
  • вежливые Please и please, а не приказ без смягчения.

Фраза «пришлите договор до пятницы» и фраза «успеете прислать договор до пятницы?» могут вести к похожему действию, но это разные реплики: во второй есть место для ответа. В переводе нельзя незаметно заменить просьбу вопросом или убрать условие о переносе срока.

Если пропущен фрагмент, изменилось число или исчезло отрицание, не исправляйте смысл наугад. Сначала проверьте кодировку source.txt, затем уточните инструкцию: «Переведи весь текст без сокращений; сохрани порядок предложений и все числа». После повторного запроса снова сравните оригинал и результат вручную.

Если для оплаты нужен отдельный маршрут

Перевод через curl и пополнение OpenAI API — разные задачи. Amber Market может быть отдельным вариантом для читателя из России, которому нужно оплатить зарубежный цифровой сервис через посредника: посмотреть каталог услуг Amber Market. По рабочей карточке каталога заказ оплачивается через СБП, но это не означает пополнение OpenAI API или покупку API-баланса. Перед заказом проверьте актуальные условия карточки.

Итак, воспроизводимый маршрут состоит из простых проверяемых частей: UTF-8-файл, ключ в переменной окружения, POST /v1/responses, явные язык и контекст, разбор массива output и ручная сверка смысла. Модель помогает перевести текст, а полноту результата всё равно подтверждает человек.

Источники

Есть следующая задача?Ещё по теме «Перевод» →