Skip to main content
Batches

创建 Batch

POST /api/v1/forward/batches Forward 在请求内读取输入文件、解析 JSONL 结构并持久化初始任务计数,然后返回 validating。文件资源等外部依赖在后台预校验;只有预校验通过的任务才会进入等待调度状态。Batch 默认只在闲时窗口内具备调度资格;可通过 ignore_idle_window=true 让它不受该时间窗口限制。完成后生成 output.jsonl,存在失败行时同时生成 error.jsonl。

请求头

Header是否必填说明
AuthorizationBearer <PAT 或 SAT>
Content-Typeapplication/json
Idempotency-Key有副作用请求可选的幂等键。

前置准备:上传输入文件

创建 Batch 需要先准备 JSONL 格式的输入文件,然后通过 CAS Files API 上传获得 file_id JSONL 格式:每行一个 JSON 对象,代表一个独立任务:
{"custom_id":"task-001","template_id":"tmpl_example001","identity_id":"idn_example001","body":{"input":"分析报告","resources":[{"type":"file","file_id":"opaque-report-id","mount_path":"/data/input/report.pdf"}]}}
{"custom_id":"task-002","template_id":"tmpl_example001","identity_id":"idn_example001","body":{"input":"总结会议记录","resources":[{"type":"file","file_id":"opaque-notes-id"}]}}
字段类型必填说明
custom_idstring调用方自定义标识,单 Batch 内唯一,用于结果文件行对应。
template_idstringForward Template ID,指定执行模板。
identity_idstringForward Identity ID,指定执行身份。
bodyobject传给 Session 的请求体。当前包含必填的 input,以及可选的 resources
body.inputstring该任务发送给 Agent 的输入。
body.resourcesarray当前任务追加的文件资源。省略或传空数组表示不追加行级文件。
body.resources[].typestring资源类型,当前只能为 file。缺失或传入其他值会使该行成为 invalid_line
body.resources[].file_idstringFiles API 返回的文件 ID。按不透明字符串处理,不要求固定前缀;trim 后不能为空。
body.resources[].mount_pathstringAgent 容器内的挂载路径。必须是规范的绝对路径;省略时根据文件名生成 /data/workspace/<filename>
每个 resources 元素必须是 JSON object,并且只能包含 typefile_idmount_path。字段类型错误、未知字段、相对路径、包含 .. 的非规范路径或控制字符都会使整行成为 invalid_line,不会静默忽略该资源。 行级文件会追加到 Template 和 Identity 的有效资源中,不会替换已有资源。重复 file_id、重复挂载路径,以及与 Template、Identity 或仓库资源发生路径重叠,都会使对应任务以 config_error 失败。
文件必须由当前 Batch 调用身份可访问,并处于可挂载的 ready 状态。Batch 不会复制、锁定文件或延长文件生命周期;文件在预校验后被删除、失效或变更时,Session 创建阶段仍会再次校验并可能使该任务失败。
上传文件
curl -X POST 'https://api.qoder.com.cn/api/v1/cloud/files' \
  -H "Authorization: Bearer $QODER_ACCESS_TOKEN" \
  -F "file=@batch_input.jsonl" \
  -F "purpose=session_resource"
purpose=session_resource 是 Batch 输入文件的强制约束。省略该字段时 Files API 会按 user_upload 保存,CAS 禁止服务端下载此类文件,创建 Batch 将返回 400 invalid_input_file
返回的 id 即为 创建 Batch 请求中的 input_file_id

请求体参数

参数类型是否必填说明
input_file_idstring通过 Files API 上传的 JSONL 文件 ID。
completion_windowstring完成窗口:24h48h72h。超时后 Batch 自动进入 expired 状态。
metadataobject调用方业务元数据,最多 16 个 key;value 可为任意 JSON 类型;整体序列化后 ≤ 2KB,key ≤ 64 字符,且不得包含 NUL(U+0000)。
ignore_idle_windowboolean是否无视闲时窗口;省略默认为 false。只接受 JSON boolean truefalse,不会将字符串或数字隐式转换。
ignore_idle_window 为严格布尔字段。null"true"1[]{} 均会返回 HTTP 400 invalid_request_error / invalid_request,错误消息为 ignore_idle_window must be a boolean

示例请求

普通 Batch(默认遵循闲时窗口)

省略 ignore_idle_window 等价于显式传入 false
curl -s -X POST 'https://api.qoder.com.cn/api/v1/forward/batches' \
  -H "Authorization: Bearer $QODER_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "input_file_id": "file_input001",
  "completion_window": "24h"
}'

无视闲时窗口的 Batch

curl -s -X POST 'https://api.qoder.com.cn/api/v1/forward/batches' \
  -H "Authorization: Bearer $QODER_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: idem_batch_001" \
  -d '{
  "input_file_id": "file_input001",
  "completion_window": "24h",
  "metadata": {
    "source": "data_pipeline",
    "job_id": "12345"
  },
  "ignore_idle_window": true
}'

示例响应

HTTP 200 OK
{
  "id": "batch_example001",
  "object": "batch",
  "status": "validating",
  "input_file_id": "file_input001",
  "completion_window": "24h",
  "ignore_idle_window": true,
  "created_at": "2026-07-07T07:25:01Z",
  "expires_at": "2026-07-08T07:25:01Z",
  "request_counts": {
    "total": 2,
    "pending": 2,
    "running": 0,
    "completed": 0,
    "failed": 0,
    "cancelled": 0,
    "expired": 0
  },
  "usage": null
}
创建 Batch 在同步完成 JSONL 结构解析、既有 Template/Identity 无人值守策略检查和任务持久化后返回 validating 快照,因此 request_counts 是真实初始计数,不是全 0 占位值。逐文件查询和合并资源冲突检查在后台进行,通过后 Batch 才能转为 queuedoutput_file_id / error_file_id 在任务终态后才出现,创建响应中省略。 若 100 行中有 3 行在同步结构解析阶段失败,创建响应计数应为 total=100pending=97failed=3。之后后台资源预校验还可能把部分 pending 任务转为 failed,但计数恒等式始终成立。

全局容量已满时

全局 processing Batch 已达到容量上限时,Create 仍返回 HTTP 200 OKvalidating,当前等待原因通过动态快照表达:
{
  "id": "batch_capacity_waiting001",
  "object": "batch",
  "status": "validating",
  "input_file_id": "file_input001",
  "completion_window": "24h",
  "ignore_idle_window": true,
  "queue_reason": "global_capacity",
  "created_at": "2026-07-07T07:25:01Z",
  "expires_at": "2026-07-08T07:25:01Z",
  "request_counts": {
    "total": 2,
    "pending": 2,
    "running": 0,
    "completed": 0,
    "failed": 0,
    "cancelled": 0,
    "expired": 0
  },
  "usage": null
}

响应字段

字段类型说明
idstringBatch ID,前缀 batch_
objectstring固定为 batch
statusstringBatch 状态,见状态说明。
input_file_idstring输入 JSONL 文件 ID。
completion_windowstring完成窗口:24h48h72h
ignore_idle_windowboolean始终返回。是否无视闲时窗口;历史数据和创建时省略该字段的 Batch 均为 false
queue_reasonstring可选的动态排队原因快照;只在 validatingqueued 时可能返回。
created_atstring创建时间,RFC 3339。
expires_atstring过期时间,created_at + completion_window
request_countsobject任务计数聚合。
usageobject/null创建响应为 null;后续 Batch 详情、列表和取消响应中,至少一个子任务已有合法 CAS Session 用量时返回 Credit 汇总。
usage.total_creditsnumber已持久化子任务 total_credits 之和;单位为 CAS Credit,不代表 token 数或货币金额,显式零值保留。
metadataobject调用方业务元数据。

Batch 状态

状态说明类型
validatingJSONL 行及同步配置检查结果已持久化,正在后台预校验有效配置和文件资源;此时任务尚未进入执行队列。非终态
queued资源预校验已完成,存在可执行任务,等待 Scheduler 按闲时窗口、容量和 owner 互斥规则调度激活。非终态
processing正在执行任务。非终态
cancelling取消中,等待 running task 结束。非终态
expiring过期中,等待 running task 结束。非终态
finalizing正在生成输出文件。非终态
completed所有任务执行完毕,输出文件已生成。终态
failed输入文件无法读取、持久化失败或资源校验流程无法恢复等 Batch 级错误。终态
cancelled用户取消完成。终态
expiredcompletion_window 到期。终态

调度与排队原因

owner 表示鉴权凭据对应的业务归属范围:PAT 按当前用户判定,管理员 SAT 按其 organization + workspace 判定。 ignore_idle_window=true 只改变 Batch 的时间窗口资格,不代表立即执行,也不提高优先级。以下规则仍然生效:
  • 同一 owner 同时最多一个 processing Batch。
  • 全局 Batch 容量和全局 Task 容量不变。
  • 只有完成资源校验并从 validating 进入 queued 的 Batch 才可能被激活。
  • 闲时窗口内,普通 Batch 与无视窗口的 Batch 按 created_at / ID 共享 FIFO 顺序。
  • completion_window 仍从 created_at 起算;校验、排队和执行时间都计入,不会因无视闲时窗口而延长或重置。
queue_reason 是读取时的动态快照,可能在响应后立即变化,且快照加载失败时会省略,不影响主接口成功。取值按以下顺序判定,命中第一个即返回:
优先级含义
1idle_window当前不在闲时窗口,且该 Batch 没有设置无视窗口。
2owner_processing同一 owner 已有其他 processing Batch。
3global_capacity全局 processing Batch 数已达容量上限。
4scheduler_pendingBatch 已是 queued,前三类都未阻塞,正等待 Scheduler 激活。
queue_reason 只适用于 validatingqueuedvalidating 只返回前三类已确定的外部阻塞,没有外部阻塞时省略,不返回 scheduler_pendingprocessingfinalizingcancellingexpiring 和所有终态均省略。 全局 Batch 容量已满时,创建 Batch 仍可成功返回 validating;Batch 完成校验后继续排队,并通过 global_capacity 表达当前等待原因。

Request Counts

字段类型说明
totalinteger总行数(含校验失败行)。
pendinginteger尚未开始执行的行数。Batch 为 validating 时表示已接受、仍在等待资源预校验;此时尚未进入执行队列。
runninginteger正在执行的行数。
completedinteger执行成功的行数。
failedinteger永久失败的行数(含校验失败)。
cancelledinteger因取消而终止的行数。
expiredinteger因过期而终止的行数。
total = pending + running + completed + failed + cancelled + expired 始终成立。

校验与入队门禁

创建 Batch 请求内同步完成以下工作:
  • 读取输入文件并解析每一行 JSON;
  • 校验必填字段、custom_id 唯一性和 body.resources 结构;
  • 解析 Template/Identity,并执行既有的无人值守工具权限策略检查;
  • 将同步校验通过的行保存为 pending,将失败行按 invalid_lineconfig_errorpermission_denied 保存为 failed
  • 持久化真实的 totalpendingfailed 初始计数。
响应返回后,Forward 在后台以创建 Batch 时的调用身份解析 Template/Identity 的有效资源,并执行文件查询、默认路径生成及合并冲突检查。预校验期间 Batch 保持 validating,不得进入执行队列或创建 Session。预校验完成后:
  • 仍有合法任务:validating → queued → processing
  • 所有任务均失败:validating → finalizing → completed,并生成结果文件;
  • 取消或过期先发生:资源校验不会再激活或入队该 Batch。
单行校验失败不会阻塞其他行。失败行仍保留在 output.jsonl,并进入 error.jsonl;若 Session 尚未创建,该行省略 session_id,且 body.resources 保留原始请求内容。

任务错误分类

Code含义是否重试资源查询
invalid_lineJSONL 结构、资源字段、typefile_id 或显式挂载路径非法。
config_error文件返回 404/410、非 ready、不可挂载,或合并后的资源冲突。
permission_denied上游明确返回 401/403。
transient_error文件查询超时、429 或 5xx,最多 3 次退避重试后仍失败。最多 3 次
出于防枚举考虑,上游可能同时用 404 表示“文件不存在”或“当前调用方不可见”。Forward 不通过 404 推断文件所有权或是否真实存在,统一返回不泄露资源元数据的 config_error;只有明确的 401/403 才分类为 permission_denied

错误

HTTPTypeCode触发条件
400invalid_request_errorinvalid_requestinput_file_id 缺失、completion_window 非法、metadata 超限,或 ignore_idle_window 不是 JSON boolean。
400invalid_request_errorinvalid_input_file输入文件不可供 Batch 下载;上传时必须指定 purpose=session_resource
409conflict_errorbatch_already_processingignore_idle_window=true 且同一 owner 已有状态精确为 processing 的 Batch。
429rate_limit_errorrate_limit_exceeded用户未完成 Batch 数量达到上限。
401authentication_errorauthentication_requiredPAT 或 SAT 无效或已过期。

同 owner 正在处理的冲突

仅当请求为 ignore_idle_window=true 且同一 owner 已有精确的 processing Batch 时,创建 Batch 返回 HTTP 409
{
  "type": "error",
  "request_id": "req_example001",
  "error": {
    "type": "conflict_error",
    "code": "batch_already_processing",
    "message": "Another Batch is already processing for this owner.",
    "batch_id": "batch_existing001"
  }
}
error.batch_id 是同一 owner 当前正在处理的 Batch ID。该冲突检查早于未完成 Batch 配额检查以及所有文件和持久化副作用:被拒绝的请求不会创建 Batch 或 Task,不会读取、解析或校验输入文件,也不会发送过期消息。validatingqueuedfinalizingcancellingexpiring 和终态不触发此 409。

备注

  • 单批次最大 10,000 行 JSONL。
  • 全局并发上限 50 个 task。
  • 默认调度在闲时窗口(默认 22:00~08:00,后台可配)内执行;ignore_idle_window=true 只放宽该时间资格。
  • 客户端创建 Batch 后,应通过 GET /api/v1/forward/batches/{batch_id} 轮询到终态。

相关