Skip to content

API 参考 ​

示例使用本地运行时,其中 productId 是设备智能体 ID,deviceId 是真实设备 ID,HTTP 路径里的 products 按设备智能体理解。

txt
HTTP: http://127.0.0.1:3000
Voice WebSocket: ws://127.0.0.1:3001/ws/voice
Voice HTTP: http://127.0.0.1:3001/api/chat, /api/vision/frames

启用直接 HTTPS 后,主 HTTP 地址改用 https://。主 HTTP TLS 不会同时为 MQTT Broker 或语音服务启用 TLS;请分别配置这些端点,浏览器连接时使用 wss://。使用私有 CA 时,应向客户端提供 CA 文件,不要关闭证书校验。

Gateway 不提供用户认证、租户隔离、会话归属或资源级授权。HTTP、SSE 和语音 WebSocket 只应由可信系统或受控客户端访问;多用户或公网接入时,应放在带认证与授权的网关后。HTTPS/WSS 只保护传输,不等于访问控制。

选择协议 ​

使用场景推荐协议说明
真实设备长期在线、上报状态、接收命令MQTT适合设备端连接、状态同步和命令响应。
其他智能体发现并调用已启用 A2A 的设备智能体A2A over MQTT使用 MQTT v5 的发现和请求/回复主题。
业务系统创建或执行多智能体场景与一次性任务HTTP + SSE使用 HTTP 提交请求,通过 SSE 持续接收规划、步骤和最终结果。
业务系统、控制台扩展或自动化脚本调用 Device AgentHTTP适合一次性请求、查询和命令下发。
实时语音交互WebSocket适合连续音频输入、实时识别结果和语音合成输出。
浏览器或设备端通过 WebSocket 连接 MQTT BrokerMQTT over WebSocket这是 MQTT 的传输方式,不是 Device Agent 的语音 WebSocket。

MQTT ​

MQTT 用于设备侧接入。设备通过 MQTT 上线、上报状态、接收命令、返回命令结果和上报事件。MQTT 服务地址、用户名、密码和主题模板以控制台配置为准。

方向主题用途
MQTT 客户端 -> Device Agentdevice-agent/{productId}/in向某个设备智能体发送文本请求。
Device Agent -> MQTT 客户端device-agent/{productId}/out返回设备智能体回复。
MQTT 客户端 -> Device Agentdevice-agent/{productId}/device/{deviceId}/in向某台设备上下文发送文本请求。
Device Agent -> MQTT 客户端device-agent/{productId}/device/{deviceId}/out返回带设备上下文的回复。
Device Agent -> 设备device-agent/{productId}/device/{deviceId}/commands下发设备命令。
设备 -> Device Agentdevice-agent/{productId}/device/{deviceId}/responses返回命令结果。
设备 -> Device Agentv1/{productId}/{deviceId}/telemetry上报在线状态和当前数据。
设备 -> Device Agentv1/{productId}/{deviceId}/event上报设备事件。
设备 -> Device Agentdevice-agent/{productId}/device/{deviceId}/ntp/request发起时间同步。
Device Agent -> 设备device-agent/{productId}/device/{deviceId}/ntp/response返回时间同步结果。

文本请求消息体:

json
{
  "id": "req-001",
  "prompt": "查看当前温度",
  "sessionId": "session-default:thermostat:thermostat-001",
  "metadata": {
    "source": "mqtt-client"
  }
}

设备智能体回复消息体:

json
{
  "sessionId": "session-default:thermostat:thermostat-001",
  "text": "当前温度是 28 度。",
  "metadata": {
    "timestamp": "2026-05-11T10:00:00.000Z"
  },
  "timestamp": "2026-05-11T10:00:00.000Z"
}

一次对话会返回多条消息。过程消息的顶层 text 为空,进度位于 metadata.status:

metadata.status.type关键字段
start、thinking当前执行阶段。
text_block增量文本位于 metadata.status.text。
tool_start、tool_end工具名、输入、输出或错误。
complete、error当前执行结果。最终完整回复仍以普通消息的顶层 text 返回。

中断或清空会话时,向原输入主题发送空 prompt,并分别设置 metadata.interrupt: true 或 metadata.clearSession: true。响应是 metadata.status.type: complete,metadata.replyTo 对应请求 id。

消息体规则、校验方式和 MQTTX 示例见 MQTT 接入。

A2A over MQTT ​

A2A 客户端通过 MQTT v5 发现并调用实时网络中已启用 A2A 的设备智能体:

用途主题
发现智能体卡片$a2a/v1/discovery/{org_id}/{unit_id}/{agent_id}
发现当前组织$a2a/v1/discovery/{org_id}/+/+
发现全部组织$a2a/v1/discovery/+/+/+
发送请求$a2a/v1/request/{org_id}/{unit_id}/{agent_id}
接收回复通过 MQTT v5 responseTopic 指定,通常位于 $a2a/v1/reply/... 下

智能体卡片使用 QoS 1 的 retained 消息;空 retained 消息表示移除卡片。Device Agent 处理 JSON-RPC SendMessage 请求。请求使用 QoS 1,并且必须携带 responseTopic;可选的 correlationData 会原样返回。需要延续同一上下文时使用 params.message.contextId;需要指定设备时使用 params.metadata.deviceId。

请求示例:

json
{
  "jsonrpc": "2.0",
  "id": "task-001",
  "method": "SendMessage",
  "params": {
    "message": {
      "role": "user",
      "parts": [
        {
          "type": "text",
          "text": "检查当前温度。如果温度过高,把空调切换到制冷模式。"
        }
      ],
      "taskId": "task-001",
      "contextId": "server-room-session"
    },
    "metadata": {
      "sender": "my-a2a-client",
      "deviceId": "air-conditioner-01"
    }
  }
}

回复使用 QoS 1,并发送到 responseTopic:

JSON-RPC 结果内容
result.statusUpdatetaskId、可选 contextId,以及 status.state、status.timestamp、可选 status.message。
result.artifactUpdatetaskId、可选 contextId,以及 artifact.artifactId、artifact.parts、append、lastChunk。

完整文本先通过 artifactUpdate.artifact.parts[].text 返回,再以 TASK_STATE_COMPLETED 结束;失败以 TASK_STATE_FAILED 结束。客户端应校验相同的 JSON-RPC id 和 correlationData,并为等待回复设置超时。

启用智能体、使用任务与场景以及排错方式见 A2A 多智能体协作。

HTTP ​

HTTP API 路径都以 /api 开头,目前没有版本号。/api/chat 和多智能体编排执行接口返回 Server-Sent Events,其他对外接口使用 JSON。升级前请查看发布历史。

GET /api/health 只表示 HTTP 进程可响应,不检查大模型、MQTT 或设备是否可用。

对话和视觉 ​

方法路径用途
GET/api/health检查 HTTP API 是否可用。
POST/api/chat发起文本对话,必须设置 stream: true。
GET/api/sessions/:sessionId/history查询会话历史。
POST/api/sessions/:sessionId/interrupt中断当前会话。
DELETE/api/sessions/:sessionId清空会话。
POST/api/sessions/:sessionId/tool-approvals授权或撤销高风险工具。仅限可信管理客户端。
POST/api/vision/frames上传视觉帧,供后续对话使用。
请求字段要求
message必填,非空文本。
stream必须为 true。
sessionId终端接入建议自行生成并保存;历史、中断、清空和工具授权使用同一 ID。
metadata.productId、metadata.deviceId需要设备上下文时传入。
visionRefs可选,引用同一会话上传的视觉帧。

对话示例:

bash
$ curl -N http://127.0.0.1:3000/api/chat \
  -H 'Content-Type: application/json' \
  -H 'Accept: text/event-stream' \
  -d '{
    "message": "查看当前温度,并把目标温度设置为 24 度",
    "stream": true,
    "sessionId": "demo-session",
    "metadata": {
      "productId": "thermostat",
      "deviceId": "thermostat-001"
    }
  }'

SSE 事件:

事件数据是否结束
statustype 为 start、thinking、text_block、tool_start、tool_end、complete 或 error。否
message{ "text", "sessionId", "timestamp" }是
error{ "error", "sessionId", "timestamp?" }是

同一 sessionId 同时只能有一个对话请求,否则返回 429。请求最长等待 5 分钟;超时会返回 error 并中断会话。客户端断开 SSE 也会中断本轮执行;主动中断使用 POST /api/sessions/:sessionId/interrupt。

工具授权 ​

当 status 事件包含 data.approvalRequired: true 时,原 SSE 会等待授权。可信管理客户端确认 toolName 和 toolInput 后,在 5 分钟内提交:

json
{
  "action": "approve",
  "toolName": "write_file",
  "scope": "once",
  "target": {
    "type": "write_file",
    "path": "<toolInput.path>"
  }
}

toolName 支持 write_file、execute_command;scope 支持 once、session,默认 once。execute_command 的 target 使用 { "type": "execute_command", "command": "...", "cwd": "..." }。服务器未启用对应工具时返回 403。优先使用带精确 target 的单次授权。

视觉帧先通过 /api/vision/frames 上传,再把返回的 frameId 和 capturedAt 作为 visionRefs 传给 /api/chat。mimeType 支持 image/jpeg、image/png 和 image/webp。

bash
$ curl http://127.0.0.1:3000/api/vision/frames \
  -H 'Content-Type: application/json' \
  -d '{
    "sessionId": "demo-session",
    "deviceId": "thermostat-001",
    "mimeType": "image/png",
    "imageBase64": "<base64>",
    "source": "camera"
  }'

上传成功返回 201,包含 frameId、capturedAt、source 和 mimeType;请求无效返回 400,视觉帧存储不可用返回 503。imageBase64 字符串最大 6 MiB;每个会话最多保留 20 帧,5 分钟后过期。清空会话时也会删除对应视觉帧。

带视觉帧发起对话:

json
{
  "message": "根据这张图判断设备屏幕是否异常",
  "stream": true,
  "sessionId": "demo-session",
  "visionRefs": [
    {
      "frameId": "frame-001",
      "capturedAt": "2026-05-11T10:00:00.000Z",
      "source": "camera"
    }
  ]
}

设备、命令和事件 ​

方法路径用途
GET/api/products查询设备智能体列表。
GET/api/products/:productId查询设备智能体定义,包括属性、命令、参数和事件。
GET/api/products/:productId/devices查询设备列表;支持 status 和 tags 筛选。
GET/api/products/:productId/devices/:deviceId查询设备详情。
POST/api/products/:productId/devices/:deviceId/commands向在线设备下发命令。
GET/api/products/:productId/devices/:deviceId/events查询设备事件。

先查询真实 ID 和产品定义,不要自行拼接命令名或参数:

bash
$ export BASE=http://127.0.0.1:3000
$ curl "$BASE/api/products"
$ export PRODUCT_ID=your_product_id
$ curl "$BASE/api/products/$PRODUCT_ID"
$ curl "$BASE/api/products/$PRODUCT_ID/devices?status=online&tags=site:lab"
$ export DEVICE_ID=your_device_id

设备列表返回 status、state、tags、modelStatus 和 lastSeenAt。status 支持 online、offline、error、all;多个 tags=key:value,key:value 条件需同时匹配。

命令名和参数必须来自产品定义:

bash
$ curl "$BASE/api/products/$PRODUCT_ID/devices/$DEVICE_ID/commands" \
  -H 'Content-Type: application/json' \
  -d '{
    "command": "set_drive_mode",
    "params": {
      "mode": "eco"
    },
    "timeoutMs": 30000
  }'

timeoutMs 默认 30,000,最大 120,000。命令响应:

HTTP结果
200{ "result": <设备响应> }
400COMMAND_VALIDATION_FAILED
404DEVICE_NOT_FOUND
409DEVICE_NOT_ONLINE 或 DEVICE_COMMAND_FAILED
504COMMAND_TIMEOUT

收到 504 时,设备仍可能稍后执行命令;确认设备状态后再决定是否重试。

设备事件按新到旧返回,limit 默认 50、最大 200。下一页把本页最后一条事件的 id 作为 beforeId。

多智能体编排 ​

HTTP 编排 API 只挂载在主 HTTP 端口,用于创建和执行 A2A 场景或一次性任务。调用前请配置可用的大模型,并从 /api/a2a/agents 返回的 cards 中选择 status: online 的真实 agentId;不要手动拼接。visibility 支持 public、private 和 all,默认 all。需要本地设备时,再用卡片顶层的 productId 查询真实 deviceId。

方法路径用途
GET/api/a2a/agents?visibility=all查询当前 A2A 组织和单元中的智能体卡片及在线状态。
GET/api/a2a/scenes查询已保存场景。
POST/api/a2a/scenes创建场景并异步生成协作流程。
GET/api/a2a/scenes/:sceneId查询场景详情和生成状态。
POST/api/a2a/scenes/:sceneId/input为处于 needs_input 的场景补充信息。
POST/api/a2a/scenes/:sceneId/recreate完整替换场景名称、目标和智能体,并重新生成。
DELETE/api/a2a/scenes/:sceneId删除场景。
POST/api/a2a/chat在已就绪场景中选择一个进行对话或执行,返回 SSE。
POST/api/a2a/scenes/:sceneId/chat将对话限制在指定场景,返回 SSE。
POST/api/a2a/tasks发起一次性多智能体任务,返回 SSE。

创建并等待场景就绪 ​

bash
$ curl "$BASE/api/a2a/scenes" \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "机房响应",
    "instructions": "检查机房温湿度,超过阈值时调节空调并返回处理报告",
    "agentIds": ["<sensor-agent-id>", "<air-conditioner-agent-id>"]
  }'

接口返回 202 { "sceneId": "<scene-id>", "status": "creating" }。保存 sceneId,通过 GET /api/a2a/scenes/:sceneId 轮询状态:

status处理方式
creating继续等待并查询。创建和重新生成都使用此状态。
needs_input读取 pendingInput,提交补充信息后继续查询。
ready场景可以执行。
failed读取 failureReason;根据原因处理后调用 recreate。

需要补充信息时,向 /api/a2a/scenes/:sceneId/input 提交 { "answers": "..." }。recreate 使用与创建场景相同的 name、instructions 和 agentIds,保留 sceneId 并重新生成。

执行场景 ​

共享场景对话使用 /api/a2a/chat。请求中写明场景名称和执行意图,规划器会从已就绪场景中选择至多一个:

bash
$ curl -N "$BASE/api/a2a/chat" \
  -H 'Content-Type: application/json' \
  -H 'Accept: text/event-stream' \
  -d '{
    "prompt": "现在执行机房响应场景,并返回最终处理报告",
    "contextId": "terminal-demo-001"
  }'

如果调用方持有准确的 sceneId,可向 /api/a2a/scenes/:sceneId/chat 提交相同的 prompt,把候选范围限制在该场景。

这两个接口都是对话式执行接口。请求不够明确时,系统可能直接回答或要求补充信息,不会无条件下发设备动作。多轮场景对话的 history 由调用方保存并随请求传回;contextId 用于下游 A2A 上下文,不会保存 HTTP 对话历史。

发起一次性任务 ​

一次性任务不保存场景。devices 可选;需要提前指定设备时,每个 productId 只能出现一次。

bash
$ curl -N "$BASE/api/a2a/tasks" \
  -H 'Content-Type: application/json' \
  -H 'Accept: text/event-stream' \
  -d '{
    "text": "检查所有房间的温度,把高于 28°C 的房间空调设置为 24°C,并返回汇总",
    "devices": [
      {
        "productId": "<sensor-product-id>",
        "deviceId": "<sensor-device-id>"
      },
      {
        "productId": "<air-conditioner-product-id>",
        "deviceId": "<air-conditioner-device-id>"
      }
    ]
  }'

首次请求必须提供 text。任务也可能直接回答或要求补充信息,不保证每次都会执行设备动作。可选的 history 最多包含 12 条 { "role": "user|assistant", "text": "..." } 消息,每条 text 最多 4000 个字符;对话历史由调用方保存,并在后续新的任务请求中传回。

处理设备选择 ​

执行需要具体设备但请求中没有可用选择时,当前 SSE 会先返回 status: input-required,再以 binding_required 事件结束。appId 是场景 ID:

text
event: binding_required
data: {"kind":"scene","appId":"<scene-id>","continuationId":"<id>","prompt":"<prompt>","tasks":[{"taskId":"<task-id>","productId":"<product-id>"}]}

续接请求必须发回原端点,三种请求体不能混用:

原端点续接请求体
/api/a2a/chatprompt、continuationId、devices: [{ productId, deviceId }]。
/api/a2a/scenes/:sceneId/chatprompt、continuationId、deviceBindings: { taskId: deviceId }。
/api/a2a/tasks只能包含 continuationId 和非空 devices;不能再次携带 text 或 history。

continuationId 有效期为 5 分钟且只能使用一次,Gateway 重启后失效。场景的 continuationId 还会在该场景被删除或重新生成时失效。收到事件后应立即完成设备选择。

读取 SSE ​

使用 curl -N 关闭输出缓冲。执行接口可能返回以下事件:

SSE 事件内容
statusworking、input-required、completed 或 failed。metadata.type 为 plan 时,规划文本位于 data.text;为 task_step 时,步骤详情位于 data.metadata。
artifact最终文本位于 data.parts[].text。
binding_required返回需要绑定设备的步骤和一次性 continuationId,并结束当前流。

HTTP 200 只表示 SSE 已建立;运行失败会通过 status 事件的 data.state: failed 返回。正常执行以 status 事件的 data.state: completed 结束。客户端应持续读取到终止事件。

多智能体执行不是持久化任务:接口不返回运行 ID,也不提供运行历史或断线后的状态查询。断开 SSE 会停止尚未下发的步骤,但不会撤销已经发送给智能体或设备的动作。执行接口没有幂等键,不要在结果未知时直接重复请求。

控制台操作见 A2A 多智能体协作。

工作流 ​

工作流可以通过 HTTP 查询、启停和删除。创建和完整更新由设备智能体的工作流工具完成,通常在对话中说明触发条件和处理动作。使用方式见 工作流。

方法路径用途
GET/api/workflows查询已保存工作流。
PATCH/api/workflows/:workflowId启用或停用工作流。请求体为 { "enabled": true } 或 { "enabled": false }。
DELETE/api/workflows/:workflowId删除工作流。
GET/api/workflow-runs查询工作流运行记录,支持 limit、offset 和 q。
GET/api/workflows/:workflowId/runs查询指定工作流的运行记录。
GET/api/workflow-runs/:runId查询一次运行及各步骤结果。

列表返回 { "workflows": [...] };修改返回 { "workflow": {...} };删除成功返回 204。运行列表返回 runs、total、limit 和 offset;传入 q 时还会返回 query。limit 默认 50、最大 100。

定时任务 ​

定时任务通过设备智能体对话创建。HTTP 可以查询、暂停、恢复、修改、取消任务,并读取运行历史。

方法路径用途
GET/api/timers?status=active&limit=50按 active、paused、running、completed 或 deleted 查询任务。
PATCH/api/timers/:timerId设置 enabled,或替换 instruction,也可以同时修改。
DELETE/api/timers/:timerId取消任务。
GET/api/timers/:timerId/runs?limit=25&offset=0分页查询该任务的运行历史。

0.4.0 不提供 HTTP 创建接口。需要修改调度规则时,也要先取消任务,再通过对话重新创建。

任务列表返回 { "timers": [...] },默认只查询 active,limit 最大 100;修改返回 { "timer": {...} },取消成功返回 204。运行历史返回 { "runs", "total", "limit", "offset" }。

控制台中的创建和管理流程见 定时任务。

Webhook ​

方法路径用途
GET/api/webhooks查询已保存连接,不返回 URL、Header 或签名密钥。
POST/api/webhooks创建连接。
PATCH/api/webhooks/:webhookId修改名称、启用状态、凭据、消息体模板或响应条件。
DELETE/api/webhooks/:webhookId删除未被使用的连接;仍被工作流引用时返回 409。
POST/api/webhooks/:webhookId/test发送测试消息并等待投递结果。

创建一个基础自定义连接:

bash
$ curl "$BASE/api/webhooks" \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "operations-alerts",
    "enabled": true,
    "credential": {
      "url": "https://hooks.example.com/device-agent"
    },
    "preset": "custom",
    "bodyTemplate": {
      "message": "{{message}}"
    }
  }'

通过 POST /api/webhooks/:webhookId/test 和 { "message": "Device Agent test" } 测试连接。

JSON 请求体最大 64 KiB。创建成功返回 201 { "webhook": {...} },修改返回 200 { "webhook": {...} },删除返回 204,测试成功返回 200 { "ok": true, "httpStatus": <状态码> }。

预设、签名、模板、投递限制和工作流用法见 Webhook。

WebSocket ​

语音通道使用 /ws/voice。连接时可带 Header:

Header说明
Protocol-Version协议版本,当前为 3。
Device-Id当前设备 ID。
Client-Id客户端 ID,不传时默认使用设备 ID。

语音连接建立后,先发送 hello:

json
{
  "type": "hello",
  "version": 3,
  "audio_params": {
    "format": "pcm",
    "sample_rate": 16000,
    "channels": 1
  },
  "sessionId": "demo-session",
  "productId": "thermostat",
  "deviceId": "thermostat-001",
  "provider": "aliyun"
}

JSON 控制消息可使用 WebSocket 文本帧,也可放入类型 1 的二进制帧。音频使用类型 0 的二进制帧,格式由 audio_params 约定。二进制帧头固定为 4 字节:

字节内容
0类型:0 音频,1 UTF-8 JSON。
1保留位,设为 0。
2..3payload 长度,big-endian uint16。

16 位 PCM payload 应保持偶数字节,单帧不超过 65,534 字节。客户端应为每轮生成 taskId,并在 listen、stop 和 abort 中使用同一值。

一次语音交互的消息顺序通常是:

方向消息说明
客户端 -> Device Agenthello建立语音会话,提交音频参数、设备上下文和语音服务商。
Device Agent -> 客户端hello返回会话 ID 和服务端语音输出参数。
客户端 -> Device Agentlisten发送 `mode: auto
客户端 -> Device Agent音频二进制帧发送语音数据。
Device Agent -> 客户端asr返回 text、definite、utterances 和 taskId。
客户端 -> Device Agentstop发送同一 taskId,可携带 visionRefs。
Device Agent -> 客户端agent_reply返回 text 和 taskId;streaming: true 表示增量文本。
Device Agent -> 客户端语音合成音频二进制帧播放语音回复。
Device Agent -> 客户端tts_complete表示本轮完成或已中断,可带 taskId。
客户端 -> Device Agentabort使用当前 taskId 中断本轮。
客户端 -> Device Agentgoodbye携带服务端 hello 返回的 session_id。

服务端 hello.audio_params 是下行 TTS 音频格式,客户端应按其中的 sample_rate 播放 PCM;即使 listen.mode 为 auto,每轮录音结束时也必须发送 stop。连接以 1000 正常关闭;1011 表示语音服务不可用,1012 表示语音配置已重载,客户端可重新连接。

语音配置见 语音配置,使用方式见 语音交互。