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关键字段
startthinking当前执行阶段。
text_block增量文本位于 metadata.status.text
tool_starttool_end工具名、输入、输出或错误。
completeerror当前执行结果。最终完整回复仍以普通消息的顶层 text 返回。

中断或清空会话时,向原输入主题发送空 prompt,并分别设置 metadata.interrupt: truemetadata.clearSession: true。响应是 metadata.status.type: completemetadata.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.statestatus.timestamp、可选 status.message
result.artifactUpdatetaskId、可选 contextId,以及 artifact.artifactIdartifact.partsappendlastChunk

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

启用智能体、使用任务与场景以及排错方式见 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.productIdmetadata.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 事件:

事件数据是否结束
statustypestartthinkingtext_blocktool_starttool_endcompleteerror
message{ "text", "sessionId", "timestamp" }
error{ "error", "sessionId", "timestamp?" }

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

工具授权

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

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

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

视觉帧先通过 /api/vision/frames 上传,再把返回的 frameIdcapturedAt 作为 visionRefs 传给 /api/chatmimeType 支持 image/jpegimage/pngimage/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,包含 frameIdcapturedAtsourcemimeType;请求无效返回 400,视觉帧存储不可用返回 503imageBase64 字符串最大 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查询设备列表;支持 statustags 筛选。
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

设备列表返回 statusstatetagsmodelStatuslastSeenAtstatus 支持 onlineofflineerrorall;多个 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_ONLINEDEVICE_COMMAND_FAILED
504COMMAND_TIMEOUT

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

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

多智能体编排

HTTP 编排 API 只挂载在主 HTTP 端口,用于创建和执行 A2A 场景或一次性任务。调用前请配置可用的大模型,并从 /api/a2a/agents 返回的 cards 中选择 status: online 的真实 agentId;不要手动拼接。visibility 支持 publicprivateall,默认 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 使用与创建场景相同的 nameinstructionsagentIds,保留 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/chatpromptcontinuationIddevices: [{ productId, deviceId }]
/api/a2a/scenes/:sceneId/chatpromptcontinuationIddeviceBindings: { taskId: deviceId }
/api/a2a/tasks只能包含 continuationId 和非空 devices;不能再次携带 texthistory

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

读取 SSE

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

SSE 事件内容
statusworkinginput-requiredcompletedfailedmetadata.typeplan 时,规划文本位于 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查询工作流运行记录,支持 limitoffsetq
GET/api/workflows/:workflowId/runs查询指定工作流的运行记录。
GET/api/workflow-runs/:runId查询一次运行及各步骤结果。

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

定时任务

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

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

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

任务列表返回 { "timers": [...] },默认只查询 activelimit 最大 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,并在 listenstopabort 中使用同一值。

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

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

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

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