每个已启用的流水线阶段都会在任务上留下一条记录,所以你看到的是实际运行了什么,而不是只能相信它跑过。
你启用了几个pipeline阶段——比如用pre-edit清理源文,或用back-translation捕捉语义漂移——结果返回的任务却是completed_with_warnings。到底是哪一阶段出了岔子?人工审核到底有没有接手,还是已经超时?这些额外阶段又花了多少钱?像这种每个 locale 都要经过多个 AI 和人工步骤的流水线,最容易变成黑箱:结果出来了,而你只能凭感觉相信中间各阶段都完成了自己的工作。
但这里不需要你靠相信。每个已启用的阶段,都会向任务的steps[]数组写入一条记录——哪个阶段、什么状态、花费多少、何时开始、何时结束。你看的是每个阶段实际做了什么,而不是假设它一定运行过。 这正是本页要解决的问题。
刚接触流水线?先看Pipeline overview。
本页内容
记录在哪里#
steps[]数组是本地化任务上的一个字段。你不需要单独拉取——每次读取任务时,它都会随任务一起返回:
GET /jobs/localization/:jobId请在X-API-Key请求头中使用你的 API 密钥完成认证。完整端点、任务状态取值以及outputData负载,都已在单任务页面说明;本页聚焦的是该响应中的一个字段——按阶段记录的轨迹——以及它能告诉你什么。
规则很简单:你读取的每个任务,都自带自己的审计日志。没有启用流水线的任务也会显示一条记录,因为core localization始终会运行。启用两个可选阶段,你就会看到三条记录。数组会随着流水线扩展而增长,每个阶段对应一项,并按实际执行顺序排列。
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 | 该阶段失败的原因。除非status为failed,否则为null。 |
costUsd | 该阶段的费用,以美元计——一个 JSON 数字,或null。 |
externalRefType、externalRefId、externalRefUrl | 指向外部记录的引用,适用于那些把工作交给第三方的阶段——也就是human review阶段。完全自动化的阶段则为null。 |
createdAt、startedAt、completedAt | 该阶段创建、被接手和完成的时间。 |
每条记录还包含一个outputData字段——该阶段产出的内容,结构与任务的outputData相同。这个负载是翻译结果,不是审计轨迹,因此它与任务级别的outputData一起记录在单任务页面;而上面这些字段,才是你用来判断流水线实际做了什么的依据。
这些记录提供了单一outputData数据块做不到的两件事。第一,费用按阶段拆分,而不是只按任务汇总——所以当你启用 back-translation 后账单发生变化时,可以准确看到是哪一个阶段带来的变化。第二,时间也是按阶段记录的——如果一条humanEdit记录里的startedAt和completedAt相隔数小时,你就知道等的是人工,不是引擎。
按 stepId 读 steps,不要按位置读
这些记录会按执行顺序出现,但不要按数组位置去索引——实际运行了哪些阶段,取决于你启用了什么,所以不同任务之间的位置并不稳定。请通过阶段的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,因为它不等于“未启用”。如果某个阶段你根本没打开,就不会有任何记录。一条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,决定是否要把该 locale 标记给人工处理;当你想了解背后的errorMessage、成本和时间时,再去查看对应的steps[]记录。
这就是completed_with_warnings背后的机制:核心翻译已经成功,所以你手里有可用的outputData;但至少有一个非关键阶段留下了一条failed记录,以及一条对应的 warning。你可以把输出视为可交付,同时把这些 warning 当作值得上报的质量信号。只有当任务的status为failed时,才表示没有可读取的翻译结果——而这个判断以及完整的任务状态表,都在单任务页面里。
阶段健康度汇总是另一层视图
steps[]回答的是:“这一次任务里,流水线做了什么?” 如果你想看跨多个任务的趋势——比如 pre-edit 多常失败,或 back-translation 多常纠正翻译——那就是汇总层面的问题,答案在Reports页面,而不在单个任务响应里。这里看单任务记录;那里看汇总数据。
