Skip to content

对外 API 接入指南 ​

让第三方系统(任务管理系统、工作流引擎、内部平台)调用本项目的 AI agent: 批量投递任务、跟踪执行、查询节点与项目。

  • 机器可读规范:openapi/zqagent.v1.yaml
  • 适用于:服务端到服务端调用(浏览器直连不支持,见「安全边界」)

1. 五分钟跑通 ​

1.1 创建 Key ​

在控制台 设置 → 集成(/settings/integrations)点「新建 Key」:

  • 名称:生产-工单系统
  • 权限范围:默认 jobs:write + jobs:read + resources:read
  • 限定节点 / 项目:留空表示不限
  • 回调地址:https://team.cd-zq.com/api/zqagent/webhook
  • 每分钟上限:留空用服务端默认(600)
  • IP 白名单:如 203.0.113.10, 198.51.100.0/24;留空不限

创建后页面只显示一次完整 Key 与 webhook 密钥,请立即保存。

生产环境建议同时配 IP 白名单与每分钟上限:Key 泄露时损失可控。

1.2 查可用项目 ​

bash
curl https://hub.example.com/v1/projects \
  -H "Authorization: Bearer $ZQA_API_KEY"
json
{
  "data": {
    "items": [
      {
        "projectId": "proj_order",
        "name": "订单服务",
        "nodeId": "node_be",
        "online": true,
        "workspaceRoot": "/srv/repos/backend-order",
        "sessionCount": 12,
        "running": 1,
        "queued": 3
      }
    ]
  },
  "requestId": "req_8Hq2..."
}

1.3 提交两个任务 ​

bash
curl -X POST https://hub.example.com/v1/jobs \
  -H "Authorization: Bearer $ZQA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: order-20261109-001" \
  -d '{
    "batchId": "sprint-42",
    "items": [
      {
        "kind": "ai",
        "projectId": "proj_order",
        "prompt": "检查 src 下所有 TODO 并生成 reports/todo.md",
        "externalId": "TASK-1024"
      },
      {
        "kind": "script",
        "projectId": "proj_order",
        "command": "pnpm test",
        "timeoutSeconds": 300,
        "externalId": "TASK-1025"
      }
    ]
  }'
json
{
  "data": {
    "batchId": "sprint-42",
    "accepted": 2,
    "items": [
      { "id": "job_9f2c", "externalId": "TASK-1024", "status": "queued", "nodeId": "node_be", "projectId": "proj_order" },
      { "id": "job_9f2d", "externalId": "TASK-1025", "status": "queued", "nodeId": "node_be", "projectId": "proj_order" }
    ]
  },
  "requestId": "req_..."
}

1.4 等结果 ​

两个任务的 projectId 相同,因此串行执行(同一工作区不并发改文件)。 推荐用 webhook 收结果(见 webhooks.md),或轮询:

bash
curl https://hub.example.com/v1/jobs/job_9f2c \
  -H "Authorization: Bearer $ZQA_API_KEY"

2. 认证 ​

http
Authorization: Bearer zqa_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
项说明
格式zqa_live_ + 32 位随机字符
存储服务端只存 sha256,明文仅在创建时返回一次
吊销立即生效(控制台点「吊销」,或 DELETE /api/hub/agent-api/keys/{id})
轮换新 Key 立即生效;可设宽限期让旧 Key 多活一段时间(见下);id 不变,日志仍能对上
过期创建时可设天数;过期后返回 401
限流默认 600 次/分钟(每 Key 独立),超限返回 429 + Retry-After
IP 白名单可限定只允许某些 IPv4 / CIDR 调用;不命中返回 403 ip_not_allowed

轮换与宽限期 ​

换 Key 时如果旧的立刻失效,正在跑的批量任务会中途断掉。轮换接口支持宽限期:

bash
curl -X POST https://hub.example.com/api/hub/agent-api/keys/$KEY_ID/rotate \
  -H "Authorization: Bearer $CONSOLE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"graceHours": 24}'

宽限期内新旧 Key 都可用;到期后旧 Key 自动返回 401。响应里的 previousExpiresAt 就是这个时刻。 graceHours 取值 0–720,缺省 0(立即失效)。

限流响应头 ​

每个成功响应都带:

头含义
X-RateLimit-Limit该 Key 的每分钟上限
X-RateLimit-Remaining当前窗口剩余次数
X-RateLimit-Reset窗口重置的 Unix 秒

超限时额外带 Retry-After(秒)。建议按它退避,别固定 1 秒重试。

权限范围(scope) ​

scope能做什么
jobs:write提交 / 取消 / 重试任务
jobs:read查询任务与批次
resources:read看节点、项目、总览
usage:read查用量汇总 /v1/usage

缺权限返回 403 insufficient_scope。

3. 端点一览 ​

方法路径用途
GET/v1/overview全网负载/排队/耗时(?format=compact 供 LLM 用)
GET/v1/projects项目清单(投递路由表)
GET/v1/nodes节点清单
GET/v1/nodes/{nodeId}节点详情(项目与负载)
GET/v1/nodes/{nodeId}/health节点健康快照
GET/v1/usage用量汇总(按天/项目/Key)
POST/v1/chat/completionsOpenAI 兼容(给现成工具用)
POST/v1/jobs批量提交(≤100)
GET/v1/jobs列表(按状态/节点/项目/批次/外部 id 过滤)
GET/v1/jobs/{id}单任务详情(含 progress)
GET/v1/jobs/{id}/events事件流(SSE,实时跟进度)
POST/v1/jobs/{id}/cancel取消
POST/v1/jobs/{id}/retry重试
GET/v1/batches/{batchId}批次汇总
POST/v1/batches/{batchId}/cancel整批取消

详见 jobs.md 与 resources.md。

3.1 OpenAI 兼容(给现成工具用) ​

如果调用方是 LangChain / Dify / n8n / 自研的 OpenAI SDK 封装,可以不改代码直接接:

bash
curl -X POST https://hub.example.com/v1/chat/completions \
  -H "Authorization: Bearer $ZQA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "zqagent",
    "project_id": "proj_order",
    "messages": [{"role": "user", "content": "6 乘 7 是多少"}]
  }'
json
{
  "id": "chatcmpl-job_9f2c",
  "object": "chat.completion",
  "model": "zqagent",
  "choices": [{ "index": 0, "message": { "role": "assistant", "content": "42" }, "finish_reason": "stop" }],
  "usage": { "prompt_tokens": 12, "completion_tokens": 3, "total_tokens": 15 },
  "zq_job_id": "job_9f2c",
  "zq_session_id": "sess_xxx"
}

要点:

  • 必须提供 project_id(顶层或 metadata 里):本实现要靠它定位工作区。
  • 这是同步接口,默认等 120 秒(x-zq-timeout 头可设 5–600 秒)。
  • 超时返回 504 job_timeout 并带 jobId,任务没有被取消,可改用 /v1/jobs/{id} 继续追。
  • 返回是 OpenAI 标准形状,不套 {data} 信封。

3.2 实时跟进(SSE) ​

长任务不必轮询,直接订阅事件流:

bash
curl -N https://hub.example.com/v1/jobs/$JOB_ID/events \
  -H "Authorization: Bearer $ZQA_API_KEY"
id: 1
event: job.state
data: {"id":"job_9f2c","status":"running","progress":{"toolCalls":3,...}}

id: 2
event: job.progress
data: {...}

id: 3
event: job.completed
data: {"id":"job_9f2c","status":"done","result":{"summary":"..."}}

事件名:job.state(首帧当前状态)、job.progress、job.completed、job.failed、job.cancelled、job.deleted。 到达终态后服务端主动关闭连接;每 15 秒有一次 : ping 保活。

说明:这是服务端轮询作业表推断出来的变化,不是逐 token 的实时流。 Hub 到节点没有入站通道,逐 token 流是控制台的需求;集成方通常只需要"开始/进度/结束"。

4. 并发模型(决定你的预期) ​

一个节点(设备)
├── 工作区 A(项目)  ← 同时只跑 1 个任务
├── 工作区 B(项目)  ← 同时只跑 1 个任务
└── 工作区 C(项目)  ← 同时只跑 1 个任务
      A、B、C 之间并行
  • 同一 projectId 严格串行:agent 会真实改文件,同目录并发会让两份改动互相覆盖。
  • 不同 projectId 并行:上限由节点配置 HUB_JOB_CONCURRENCY 决定(默认 4)。
  • 不同节点天然并行。

对你的影响:100 个任务投给 1 个项目 = 按顺序跑完;投给 4 个项目 = 约 1/4 时间。 如果一个项目就要高吞吐,需要把它拆成多个工作区(每区一个 projectId)。

5. 安全边界 ​

  • 不支持浏览器直连:服务端不发 CORS 头。Key 属于机密,不应下发到浏览器。
  • 回调地址必须 HTTPS,且拒绝内网/回环地址(防 SSRF);可配置站点白名单。
  • Key 只能访问自己的资源:别人的 jobId 一律返回 404,不暴露存在性。
  • 建议给不同系统/环境分别建 Key,便于单独吊销。
  • 生产 Key 建议同时配 IP 白名单 + 每分钟上限:即使泄露,也只能从固定出口调用有限次数。

6. 版本与兼容 ​

  • 路径前缀 /v1,字段只增不改;破坏性变更走 /v2。
  • 弃用流程:先在响应头加 Deprecation,至少保留 12 个月。
  • 每个响应都带 X-Request-Id,排障时提供它即可定位。

7. 文档索引 ​

文档内容
jobs.md提交、查询、批次、幂等、重试、失败类型
webhooks.md签名验签、载荷结构、重试与幂等
resources.mdoverview / nodes / projects 字段说明
errors.md错误码、限流、常见问题
en/README.mdEnglish guide(same scope, condensed)
../../examples/api/可直接运行的 curl / Python / Node 客户端