A2A 协作
A2A 协作把设备智能体发布到 EMQX A2A 网络,让其他智能体发现卡片、读取由设备规格命令生成的技能,并通过 MQTT v5 SendMessage 调用设备能力;实际执行仍由设备智能体按已接入设备、设备状态和命令定义完成。
适合什么时候用
A2A 适合让设备智能体参与跨系统或跨智能体协作,例如:
- 其他 A2A 智能体需要调用当前设备智能体的设备能力。
- 多个设备智能体需要组成一个协作流程,例如“传感器判断异常后,让灯光和门锁执行动作”。
- 需要把设备能力放到 A2A 市场里,让其他参与者按卡片发现和复用。
如果只是在当前控制台里对单个设备对话、调试或控制,不需要开启 A2A;普通设备控制走控制台对话、MQTT 或 SDK 即可。
准备条件
开启前先确认三件事:
- EMQX 版本为 6.2.0 或以上,并启用了 A2A 注册表。仓库里的本地开发 EMQX 配置已经包含
EMQX_A2A_REGISTRY__ENABLE=true。 - 设备智能体的设备规格至少定义一个
commands命令。没有命令时不能发布 A2A 卡片,因为卡片里没有可调用技能。 - 设备智能体网关能连接到同一个 MQTT 代理。A2A 发布和请求都复用运行时的 MQTT 配置。
A2A 发布身份由运行时配置决定:
| 配置 | 作用 | 默认值 |
|---|---|---|
A2A_ORG_ID | A2A 注册和发现使用的组织 ID | default |
A2A_UNIT_ID | A2A 注册和发现使用的单元 ID | default |
| MQTT 代理配置 | 写入智能体卡片的 supportedInterfaces[0].url,也是实际通信地址 | 当前 MQTT 运行配置 |
如果要在控制台里看到 A2A 市场入口,还需要在网页控制台环境里开启:
VITE_FF_A2A_MARKETPLACE_ENABLE=true更多配置项见 配置。
启用并发布
创建或编辑设备智能体时,在预览面板确认设备规格后打开 启用 A2A 协作。如果希望这张卡片出现在 A2A 市场,再打开 发布 A2A 卡片。

保存后,系统会根据当前设备智能体生成智能体卡片。如果同时打开 发布 A2A 卡片,这张卡片会出现在 A2A 市场;否则只在当前 A2A 网络中被发现。
| 卡片字段 | 来源 |
|---|---|
name | 使用设备智能体名称 |
description | 使用设备智能体说明;没有说明时使用名称 |
version | 当前固定为 1.0.0 |
supportedInterfaces | 使用 MQTT 代理地址,协议为 MQTT5+JSONRPC |
capabilities | streaming: true |
defaultInputModes / defaultOutputModes | text/plain |
skills | 设备规格里的每个命令生成一个技能,id 和 name 都是命令名,description 来自命令说明 |
发布成功后,设备智能体会保持在线发布状态。EMQX 会根据连接状态判断这张卡片对应的智能体是在线还是离线。
编辑设备智能体时关闭 启用 A2A 协作 会取消发布。如果此前已经发布到 A2A 市场,卡片也会从市场移除。
其他智能体如何发现它
发布后的卡片会写入 EMQX A2A 发现主题:
$a2a/v1/discovery/{org_id}/{unit_id}/{agent_id}agent_id 由设备智能体根据当前命名空间和 productId 生成。你不需要手动拼接它;可以从 A2A 市场或发现主题中获取。
开启 A2A 市场后,进入 A2A 市场 可以看到:
- 卡片名称、说明和技能。
- 公开或私有可见性。
- 在线或离线状态。
市场列表会同时展示已公开登记的卡片,以及当前 EMQX 发现到的私有卡片。
其他智能体如何调用它
调用方使用 MQTT v5,并按 A2A 的 MQTT 通信约定发送 JSON-RPC 请求:
请求主题:$a2a/v1/request/{org_id}/{unit_id}/{agent_id}
回复主题:$a2a/v1/reply/{org_id}/{unit_id}/{caller_agent_id}/{reply_suffix}设备智能体网关当前处理 SendMessage 方法。请求必须设置 MQTT v5 的 responseTopic,否则网关无法回复。correlationData 可选;如果提供,回复时会原样带回。
任意支持 MQTT v5 的客户端都可以调用。先订阅自己的回复主题,再向请求主题发布下面的 JSON;发布时把 responseTopic 设置为回复主题,correlationData 可以设置为同一个任务 ID。
{
"jsonrpc": "2.0",
"id": "task-001",
"method": "SendMessage",
"params": {
"message": {
"role": "user",
"parts": [
{
"type": "text",
"text": "检查当前状态,如果温度过高就把空调切换到制冷模式。"
}
],
"taskId": "task-001"
},
"metadata": {
"sender": "my-a2a-client"
}
}
}请求进入设备智能体网关后,网关会把文本内容交给目标设备智能体处理。目标设备智能体可以查询状态、调用设备命令或使用它已有的工具。回复会发送到 responseTopic:
- 执行中状态返回
statusUpdate,状态通常是TASK_STATE_WORKING。 - 文本结果返回
artifactUpdate,其中artifact.parts包含回复文本。 - 完成时返回
TASK_STATE_COMPLETED。 - 执行失败时返回
TASK_STATE_FAILED。
在市场里组合应用
开启 A2A 市场后,还可以在 A2A 市场 → 应用 中创建组合应用。选择多个已发现的设备智能体,填写应用名称和协作指令,然后创建应用。
组合应用会把所选智能体 ID 和协作指令发送给编排智能体。当前实现依赖名为 skitter 的 A2A 编排智能体;应用变为就绪后,可以在应用对话中发起任务,由编排智能体协调这些设备智能体完成。
例如,可以创建一个“机房环境助手”,选择温湿度设备智能体、空调设备智能体和告警设备智能体,并写入:
持续关注机房温湿度。当温度超过阈值时,先查询空调状态,再切换到制冷模式,并在处理完成后返回简短报告。验证发布是否成功
发布后可以按下面顺序检查:
- 回到设备智能体列表或详情页,确认它显示 A2A 已启用。
- 打开 A2A 市场,确认能看到对应卡片、技能和状态。
- 打开 EMQX Dashboard,进入 A2A 注册表相关页面,按组织、单元或智能体标识查找这张卡片。本地开发环境的 Dashboard 默认地址是
http://127.0.0.1:18083。 - 如果要从 MQTT 层验证,订阅当前组织的发现主题:
$a2a/v1/discovery/{org_id}/+/+- 重启网关后,之前已经发布的卡片会从数据库恢复并重新发布。日志里会出现类似
A2A Sync的恢复信息。
常见问题和限制
| 现象 | 排查方向 |
|---|---|
| 发布失败,提示需要技能 | 设备规格必须至少包含一个 commands 命令;补充命令后重新保存并发布。 |
| A2A 市场入口看不到 | 网页控制台需要开启 VITE_FF_A2A_MARKETPLACE_ENABLE=true。这个开关只影响市场入口显示,不影响 A2A 注册本身。 |
| 卡片看得到但状态是离线 | 发布连接已经断开,或网关没有运行。重启网关后,已发布卡片会尝试自动恢复。 |
| 调用后没有回复 | 确认请求使用 MQTT v5,设置了 responseTopic,并且请求主题里的 org_id、unit_id、agent_id 正确。 |
| 收到失败状态 | 查看网关日志,并确认目标设备在线、命令参数合理。 |
| 请求类型不生效 | 当前主要支持文本类 SendMessage 请求,回复以状态更新和文本结果返回。 |
| 组合应用无法就绪 | 组合应用是预览能力,依赖 skitter 编排智能体在线。 |