Каждый включённый этап пайплайна оставляет в задаче отдельную запись, так что вы видите, что именно сработало, а не просто верите, что всё выполнилось.
Вы включили несколько этапов пайплайна — например, pre-edit, чтобы привести исходный текст в порядок, и back-translation, чтобы отследить смысловые расхождения, — а задача вернулась со статусом completed_with_warnings. На каком этапе что-то пошло не так? Подхватил ли её вообще человек для проверки, или время ожидания просто истекло? Во сколько обошлись дополнительные этапы? Пайплайн, где для каждой локали проходят несколько AI- и ручных этапов, легко превращается в чёрный ящик: на выходе есть результат, а всё, что было между входом и выходом, остаётся только принимать на веру.
Но здесь вас не просят верить на слово. Каждый включённый этап пишет одну запись в массив steps[] задачи: какой это этап, какой у него статус, сколько он стоил, когда начался и когда завершился. Вы видите, что сделал каждый этап, а не просто доверяете тому, что он был запущен. В этом и смысл этой страницы.
Если вы только знакомитесь с пайплайном, начните со страницы Обзор пайплайна.
На этой странице
- Где хранятся записи
- Массив steps
- Как сопоставить stepId с этапом
- Статусы этапов: completed, failed, skipped
- Как ошибка этапа превращается в предупреждение задачи
Где хранятся записи#
Массив steps[] — это поле задачи локализации. Запрашивать его отдельно не нужно: он приходит каждый раз, когда вы читаете задачу:
GET /jobs/localization/:jobIdПередайте API-ключ в заголовке X-API-Key. Полный endpoint, значения статуса задачи и payload outputData описаны на странице отдельной задачи; здесь же речь об одном поле этого ответа — истории по этапам — и о том, что она вам показывает.
Правило простое: каждая задача, которую вы читаете, уже содержит собственный журнал аудита. Если пайплайн не включён, в задаче всё равно будет одна запись, потому что базовая локализация выполняется всегда. Включите два дополнительных этапа — получите три записи. Массив растёт вместе с пайплайном: по одной записи на этап, в порядке выполнения.
Массив steps#
Каждый элемент steps[] — это запись об одном этапе. Именно по этим полям вы проверяете выполнение: какой это этап, чем он закончился, сколько стоил и когда отработал:
"steps": [
{
"stepId": "preEdit",
"type": "action",
"status": "completed",
"errorMessage": null,
"costUsd": 0.0012,
"externalRefType": null,
"externalRefId": null,
"externalRefUrl": null,
"createdAt": "2026-03-16T10:30:01.000Z",
"startedAt": "2026-03-16T10:30:01.000Z",
"completedAt": "2026-03-16T10:30:02.000Z"
},
{
"stepId": "localize",
"type": "action",
"status": "completed",
"errorMessage": null,
"costUsd": 0.0184,
"externalRefType": null,
"externalRefId": null,
"externalRefUrl": null,
"createdAt": "2026-03-16T10:30:02.000Z",
"startedAt": "2026-03-16T10:30:02.000Z",
"completedAt": "2026-03-16T10:30:05.000Z"
}
]| Поле | Описание |
|---|---|
stepId | Какому этапу пайплайна соответствует эта запись. См. таблицу соответствий ниже. |
type | Тип шага. action — для автоматизированного этапа. |
status | completed, failed или skipped для этого этапа — независимо от статуса самой задачи. |
errorMessage | Почему этот этап завершился ошибкой. null, если только status не равно failed. |
costUsd | Стоимость этого этапа в USD — число JSON или null. |
externalRefType, externalRefId, externalRefUrl | Ссылка на внешнюю запись для этапов, где работа передаётся третьей стороне, — этапа human review. null — для полностью автоматизированных этапов. |
createdAt, startedAt, completedAt | Когда этап был создан, взят в работу и завершён. |
У каждой записи также есть поле outputData — контент, который создал этот этап, в той же форме, что и outputData задачи. Это payload перевода, а не след аудита, поэтому он описан на странице отдельной задачи рядом с outputData на уровне задачи; поля выше нужны для того, чтобы понять, что именно сделал пайплайн.
Эти записи дают вам две вещи, которых не даст один общий объект outputData. Во-первых, стоимость разбита по этапам, а не только посчитана на уровне всей задачи — поэтому, если после включения back-translation счёт вырос, вы сразу увидите, какой этап на это повлиял. Во-вторых, тайминг тоже даётся по этапам — если у записи humanEdit между startedAt и completedAt проходят часы, значит, задержка была на стороне человека, а не движка.
Читайте steps по stepId, а не по позиции
Записи идут в порядке выполнения, но не привязывайтесь к позиции в массиве: какие этапы сработали, зависит от того, что именно вы включили, поэтому порядок по индексам не будет одинаковым от задачи к задаче. Ищите этап по его stepId (steps.find(s => s.stepId === "humanEdit")). Набор возможных значений stepId фиксирован, а набор значений в конкретной задаче определяется тем, что вы включили.
Как сопоставить stepId с этапом#
Каждый stepId обозначает один этап пайплайна. Ниже — таблица соответствий между значением в записи, этапом, который оно представляет, и страницей с описанием того, что делает этот этап:
stepId | Этап |
|---|---|
preEdit | AI-редактирование перед локализацией |
localize | Базовая локализация |
humanEdit | Проверка человеком после локализации |
postEdit | AI-оценка после локализации |
rephrase | Перефразирование для естественного звучания |
backTranslation | Проверка обратным переводом |
localize — единственный stepId, который есть в каждой задаче, независимо от того, включён пайплайн или нет: это основной этап перевода, и он выполняется всегда. Остальные пять появляются только если вы включили этот этап в движке или в запросе.
Статусы этапов: completed, failed, skipped#
У каждого этапа есть собственный status, который задаётся независимо от задачи и от всех остальных этапов. Всего значений три:
status этапа | Что означает |
|---|---|
completed | Этап выполнился и выдал результат. |
failed | Этап выполнился и завершился ошибкой. errorMessage объясняет причину. |
skipped | На этот раз этап не дошёл до завершения, хотя был включён. |
completed и failed читаются именно так, как вы ожидаете. А вот на skipped стоит остановиться отдельно, потому что это не то же самое, что "disabled". Этап, который вы вообще не включали, не создаёт запись вовсе. Запись skipped означает, что этап был включён, но пайплайн пропустил его по одной из предусмотренных причин. Самый наглядный пример — human review: если окно проверки закрывается без ответа от человека, этап помечается как skipped, а AI-перевод становится финальным. Запись при этом остаётся, так что пропуск виден, а не теряется бесследно.
Статус этапа — не то же самое, что статус задачи
Этап со статусом failed не всегда означает задачу со статусом failed. Большинство дополнительных этапов некритичны: если один из них падает, в его записи будет failed, движок передаст дальше последний корректный результат, а сама задача всё равно завершится с полным outputData. Что означает итоговый статус задачи — completed_with_warnings — разобрано на странице отдельной задачи. Статус этапа показывает, что произошло на одном этапе; статус задачи — получили ли вы перевод вообще.
Как ошибка этапа превращается в предупреждение задачи#
Когда некритичный этап завершается ошибкой, это сразу отражается в двух местах — и оба показывают одно и то же событие с разной степенью детализации. В записи steps[] будет failed с errorMessage — это подробный вид. То же событие появится и как отдельный элемент в массиве верхнего уровня warnings задачи — это краткий вид, по которому обычно ветвится логика обработки статуса:
{
"id": "ljb_A1b2C3d4E5f6G7h8",
"status": "completed_with_warnings",
"outputData": { "title": "Hallo" },
"warnings": [
{ "step": "backTranslation", "message": "Back-translation check did not complete" }
],
"steps": [
{ "stepId": "localize", "type": "action", "status": "completed", "errorMessage": null, "costUsd": 0.0184, "completedAt": "2026-03-16T10:30:05.000Z" },
{ "stepId": "backTranslation", "type": "action", "status": "failed", "errorMessage": "Back-translation check did not complete", "costUsd": 0.0031, "completedAt": "2026-03-16T10:30:11.000Z" }
]
}Каждый элемент warnings имеет вид { step, message }, где step — это тот же stepId, что и в записи с ошибкой. То есть оба массива согласованы: warnings — это короткий список того, что пошло не так, а steps[] — место, где можно посмотреть детали по каждому случаю. Читайте warnings, чтобы решить, нужно ли отправить локаль на проверку человеку; открывайте соответствующую запись steps[], когда вам нужны errorMessage, стоимость и тайминг этого события.
Именно так устроен completed_with_warnings: базовый перевод прошёл успешно, поэтому у вас есть пригодный outputData, но как минимум один некритичный этап оставил запись failed и соответствующее предупреждение. Считайте такой результат готовым к выпуску, а предупреждения — сигналом о качестве, который стоит показывать. Только status задачи со значением failed означает, что перевода нет вовсе, — и это решение, вместе с полной таблицей статусов задачи, описано на странице отдельной задачи.
Сводное состояние этапов — это отдельный слой
steps[] отвечает на вопрос: «что пайплайн сделал в этой задаче?» Если вам нужен тренд по множеству задач — как часто падает pre-edit, как часто back-translation исправляет перевод, — это уже агрегированный вопрос, и ответ на него ищите на странице Reports, а не в ответе по одной задаче. Здесь — записи по отдельной задаче; там — сводная картина.
