Skip to content

资源视图:节点与项目 ​

全局 agent 需要先知道"有哪些节点、各自的负载、每个节点上有哪些项目", 才能决定把任务投给谁。

1. 总览 ​

http
GET /v1/overview
GET /v1/overview?format=compact

完整格式 ​

json
{
  "data": {
    "generatedAt": "2026-11-09T10:00:00Z",
    "nodes": [
      {
        "nodeId": "node_be",
        "label": "node_be",
        "online": true,
        "lastSeen": "2026-11-09T09:59:55Z",
        "platform": "linux",
        "version": "0.3.25",
        "load": { "running": 2, "queued": 17, "stalledQueued": 0 },
        "projects": [
          { "projectId": "proj_order", "name": "订单服务", "running": 1, "queued": 3,
            "sessionCount": 12, "avgDurationMs": 310000, "successRate": 0.97 },
          { "projectId": "proj_user", "name": "用户服务", "running": 1, "queued": 0,
            "sessionCount": 5, "avgDurationMs": 180000, "successRate": 0.99 }
        ]
      }
    ],
    "totals": { "nodes": 1, "online": 1, "projects": 2, "running": 2, "queued": 17 }
  },
  "requestId": "req_..."
}

紧凑格式(?format=compact) ​

json
{
  "data": {
    "nodes": [
      { "id": "node_be", "online": true, "run": 2, "q": 17,
        "projects": [
          { "pid": "proj_order", "run": 1, "q": 3, "avgMs": 310000, "ok": 0.97 },
          { "pid": "proj_user", "run": 1, "q": 0, "avgMs": 180000, "ok": 0.99 }
        ] }
    ]
  }
}

字段压缩到 2–5 个字符,4 个工作区的响应在 1KB 以内。 推荐给 LLM 用作决策输入:每分钟拉一次,成本可忽略。

决策建议 ​

观察动作
queued = 0 且 run = 0立即投递,会马上开跑
queued 大、run 小于并行度正常排队,按 avgMs 估算等待
stalled > 0该节点的任务卡住了(节点离线),别往这里投
ok 明显偏低该项目的任务失败率高,先查 failures 再批量投

2. 节点列表 ​

http
GET /v1/nodes
json
{
  "data": {
    "items": [
      {
        "nodeId": "node_be",
        "label": "node_be",
        "online": true,
        "lastSeen": "2026-11-09T09:59:55Z",
        "platform": "linux",
        "version": "0.3.25",
        "ip": "203.0.113.10",
        "totals": { "projects": 4, "sessions": 37, "running": 2, "waiting": 0 },
        "stats": { "turns": 1820, "toolCalls": 9300, "errors": 21,
                   "tokensIn": 4200000, "tokensOut": 380000,
                   "since": "2026-11-01T00:00:00Z" },
        "queue": { "running": 2, "queued": 17 },
        "projectCount": 4
      }
    ]
  },
  "requestId": "req_..."
}
字段说明
online网关视角的在线态(5 秒缓存;网关不可达时 30 秒后转离线)
stats节点进程内累计统计,重启清零;只适合看量级
queue该节点的实时排队(来自作业表,不受 stats 重置影响)

需要精确的成功率/耗时请用 /v1/overview 的 projects[].successRate / avgDurationMs, 它们算自最近 2000 条已结束作业。

3. 项目列表(投递路由表) ​

http
GET /v1/projects
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_..."
}

这是投递前必须查的表:拿到 projectId 就能提交(服务端会按它反查唯一节点)。 若同一 projectId 出现在多台节点上,提交时必须显式带 nodeId。

3.1 节点详情 ​

http
GET /v1/nodes/{nodeId}

列表字段之外,额外给出该节点上你可见的项目完整视图:

json
{
  "data": {
    "nodeId": "node_be",
    "label": "订单后端",
    "online": true,
    "lastSeen": "2026-11-09T09:59:55Z",
    "platform": "linux",
    "mode": "full",
    "version": "0.3.25",
    "ip": "203.0.113.10",
    "totals": { "projects": 4, "sessions": 37, "running": 2, "waiting": 0 },
    "stats": { "...": "..." },
    "queue": { "running": 2, "queued": 17 },
    "projects": [
      {
        "projectId": "proj_order",
        "name": "订单服务",
        "workspaceRoot": "/srv/repos/backend-order",
        "sessionCount": 12,
        "running": 1,
        "queued": 3,
        "avgDurationMs": 184000,
        "successRate": 0.92
      }
    ]
  },
  "requestId": "req_..."
}

3.2 节点健康 ​

http
GET /v1/nodes/{nodeId}/health
json
{
  "data": {
    "nodeId": "node_be",
    "online": true,
    "lastSeen": "2026-11-09T09:59:55Z",
    "silentMs": 4200,
    "totals": { "...": "..." },
    "stats": { "...": "..." },
    "resourcesAvailable": false,
    "hint": "CPU/内存/磁盘需在节点本机 GET /api/v1/node/host 获取"
  },
  "requestId": "req_..."
}

能力边界:Hub 拿不到节点的 CPU / 内存 / 磁盘。节点是主动出站连接, Hub 没有到节点的入站通道;resourcesAvailable: false 就是在明说这件事。 silentMs 是距上次心跳的毫秒数(节点心跳 60s),超过 180000 就值得告警。

3.3 用量汇总 ​

http
GET /v1/usage?days=30[&keyId=key_xxx]

需要 usage:read scope。

json
{
  "data": {
    "since": "2026-10-10T00:00:00Z",
    "days": 30,
    "totals": { "jobs": 412, "done": 388, "failed": 19, "cancelled": 5,
                "tokensIn": 5320000, "tokensOut": 610000 },
    "byDay":    [{ "date": "2026-11-09", "jobs": 31, "done": 29, "failed": 1,
                   "tokensIn": 420000, "tokensOut": 51000 }],
    "byProject":[{ "projectId": "proj_order", "jobs": 120, "done": 118, "failed": 2,
                   "tokensIn": 1600000, "tokensOut": 190000 }],
    "byKey":    [{ "keyId": "key_abc", "name": "生产-工单系统", "prefix": "zqa_live_WxYz",
                   "jobs": 120, "done": 118, "failed": 2 }]
  },
  "requestId": "req_..."
}

数据源是作业表(保留最近 2000 条已结束作业),不是精确计费账本。 用途是"这个月大概跑了多少"。精确的 token 账本在节点侧的 usage/ledger。

4. 概念对照(避免误用) ​

Hub 账号(API Key 绑定在这一层)
  └── 设备 / 节点(node)      ← 一台跑 agent 服务的机器
        └── 项目(project)    ← 一个工作目录,任务并行以它为界
              └── 会话(session)← 一次任务的执行上下文
你可能听到的说法对应本系统
租户Hub 账号(API Key 的归属)
设备 / 机器节点 nodeId
工作区 / 仓库 / 模块项目 projectId
任务 / 工单作业 jobId(你系统里的 id 放 externalId)
批次batchId(一次批量提交共享)

⚠️ 节点侧还有一个 /api/v1/devices 接口,那是手机 App 配对设备, 与这里的"设备/节点"无关,不要混用。