跳转至

A2A

A2A 通道插件通过 Linux Foundation 的 Agent2Agent 协议 将 OpenClaw 连接到其他代理。外部代理通过公开的 Agent Card 发现网关,并使用 A2A 1.0 JSON-RPC 绑定提交经过身份验证的文本任务。OpenClaw 还可以向已配置的对等代理发送消息。

快速设置

将捆绑的插件添加到 OpenClaw 配置中,并为每个受信任的对等方定义单独的 bearer token:

{
  channels: {
    a2a: {
      enabled: true,
      advertisedUrl: "https://openclaw.example.com",
      peers: {
        hermes: {
          token: "${A2A_HERMES_TOKEN}",
        },
      },
    },
  },
}

在网关环境中将 A2A_HERMES_TOKEN 设置为强且唯一的密钥,然后重启网关。当网关运行在反向代理后面时,请使用外部可访问的 HTTPS 源作为 advertisedUrl。如果省略,插件将从传入的发现请求中推导通告源。

发现 Agent Card

无需身份验证即可获取公开的 A2A Agent Card:

curl http://127.0.0.1:18789/.well-known/agent-card.json

该卡片会通告网关 JSON-RPC 端点、支持的文本输入和输出,以及每个已暴露 OpenClaw 代理的一项技能。将 channels.a2a.exposeAgents 设置为代理 ID 数组,以限制显示哪些代理。如果未设置或为空,则所有已配置的代理都会被通告。

/.well-known/agent.json 会为旧版 A2A 客户端返回相同的卡片。

发送任务

向 /a2a/v1 发送经过身份验证的 SendMessage JSON-RPC 请求:

curl http://127.0.0.1:18789/a2a/v1 \
  -H "Authorization: Bearer $A2A_HERMES_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": "request-1",
    "method": "SendMessage",
    "params": {
      "message": {
        "messageId": "message-1",
        "role": "ROLE_USER",
        "parts": [{ "text": "Summarize my latest project updates." }]
      }
    }
  }'

默认情况下,请求会等待代理响应。已完成的响应包含一个任务,其回复位于其 artifact 中:

{
  "jsonrpc": "2.0",
  "id": "request-1",
  "result": {
    "task": {
      "id": "<task-id>",
      "contextId": "<context-id>",
      "status": {
        "state": "TASK_STATE_COMPLETED",
        "timestamp": "2026-01-01T12:00:00.000Z"
      },
      "artifacts": [
        {
          "artifactId": "<artifact-id>",
          "parts": [{ "text": "Here are your latest project updates..." }]
        }
      ],
      "history": []
    }
  }
}

在后续请求中包含 message.contextId 以继续同一对话。上下文 ID 可以包含字母、数字、句点、下划线、冒号和连字符,且不得超过 128 个字符。

若要在代理继续工作时立即返回,请在 params 中的 "message" 旁边添加 "configuration": { "returnImmediately": true }。任务最初会报告 TASK_STATE_WORKING。超过 replyTimeoutMs 的请求也会返回当前正在工作的任务,而不是取消它。

旧版客户端可以使用 message/send 作为 SendMessage 的别名。

轮询任务

通过向 GetTask 发送任务 ID 来轮询任务:

curl http://127.0.0.1:18789/a2a/v1 \
  -H "Authorization: Bearer $A2A_HERMES_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": "poll-1",
    "method": "GetTask",
    "params": { "id": "<task-id>" }
  }'

任务会从 TASK_STATE_WORKING 转换为 TASK_STATE_COMPLETED、TASK_STATE_FAILED 或 TASK_STATE_REJECTED。旧版客户端可以使用 tasks/get 作为兼容性别名。

CancelTask 会以 JSON-RPC 错误 -32004 被拒绝,而不是被确认。已分派的代理运行没有面向插件的中止接口,因此报告 TASK_STATE_CANCELED 会告诉对等方工作已停止,而运行仍在继续使用工具。拒绝可确保报告状态真实。

配置出站对等方

当 OpenClaw 需要向另一个 A2A 代理发送消息时,添加对等方 URL。当远程代理需要其自己的 bearer token 时,设置 outboundToken:

{
  channels: {
    a2a: {
      enabled: true,
      peers: {
        hermes: {
          token: "${A2A_HERMES_TOKEN}",
          url: "https://hermes.example.com/a2a/v1",
          outboundToken: "${A2A_HERMES_OUTBOUND_TOKEN}",
        },
      },
    },
  },
}

将出站消息寻址到 a2a:hermes。插件会直接向已配置的 URL 发送 SendMessage,而不会执行 Agent Card 发现。出站消息会为每个对等方复用稳定的对话上下文。未配置 url 的对等方无法接收出站消息。

配置参考

键 类型 默认值 描述
enabled boolean - 启用或禁用 A2A 通道。
advertisedUrl string 请求 用于 Agent Card 的公开网关源。
replyTimeoutMs number 120000 最大阻塞回复等待时间;允许范围为 5000 到 600000 毫秒。
rateLimitPerMinute number 30 每个对等方的滑动窗口请求限制;0 表示禁用限制。
exposeAgents string[] 全部 作为 Agent Card 技能通告的代理 ID。
peers object {} 以最多 64 个字符的小写名称为键的受信任对等方。
peers.<name>.token string 必填 当此对等方向 OpenClaw 发送请求时所需的 Bearer token。
peers.<name>.url string - 用于出站消息的对等方 JSON-RPC 端点。
键 类型 默认值 说明
peers.<name>.outboundToken string - OpenClaw 发送到已配置的 Peer URL 的 Bearer token。

Peer 名称必须以小写字母或数字开头,并且还可以包含句点、下划线和连字符。

会话隔离

每个已认证的 Peer 与 A2A contextId 组合都会拥有独立的 agent 会话。A2A 会固定最隔离的直接消息作用域,而不是继承 session.dmScope,因此远程 Peer 内容永远不会加入操作者的主会话,一个 Peer 也无法读取另一个 Peer 的对话历史。

对于 agent 绑定,请使用已配置的 Peer 名称作为规范的直接 Peer ID,例如 hermes。特定上下文的 hermes:<contextId> 绑定优先于该稳定 Peer 绑定,而稳定 Peer 绑定优先于更广泛的 A2A 账户或频道路由。

安全

Agent Card 发现机制是有意公开的:任何能够访问网关的人都可以读取实例描述和暴露的 agent ID。使用 exposeAgents 限制披露,并在网关可通过不受信任网络访问时,通过 HTTPS 暴露网关。

每个 JSON-RPC 请求都需要已配置的 Peer Bearer token。不存在未认证模式。每个已认证的 Peer 同时也是用于常规 OpenClaw 频道入口策略的发送者身份。为每个 Peer 使用不同的高熵 token,将 token 排除在源代码控制之外,并通过更新网关环境并重启来轮换 token。

A2A Peer 发送的是任务,而不是用户命令。以 / 开头的消息会被拒绝,并返回 TASK_STATE_REJECTED 和说明。普通任务中类似命令的文本会保持字面含义。它无法更改会话设置或处理审批。当 Peer 将协议消息角色设置为 ROLE_USER 时也是如此:该字段不会认证人类用户。

普通任务保留其路由 agent 的工具和权限。需要审批的工作仍需要通过受支持的用户频道或 Control UI 由授权操作者做出决定。现有通过 A2A 发送斜杠命令的集成必须对 agent 工作使用纯文本任务,并对命令使用授权用户界面。没有 Peer 命令选择加入机制。

在 exec 审批待定期间,原始任务保持运行状态。操作者做出决定后,同一 agent 运行会收到结果,并通过其原始回复路径完成任务。入站 Peer 无需出站 url 即可通过 GetTask 接收该完成状态。

请求大小限制为 1 MiB,JSON-RPC 批次限制为 30 个条目,序列化后的 JSON-RPC 响应限制为 1 MiB。提取的消息文本上限为 64 KiB,截断时会包含明确的截断标记。默认滑动窗口限制为每个 Peer 每分钟 30 个请求。不符合 Schema 的请求也计入该限制。仅在单独受保护的网络上将 rateLimitPerMinute 设置为 0。被限流的请求会返回 JSON-RPC 错误,同时保持 HTTP 状态 200。

出站目标仅来自操作者配置的 Peer URL。入站调用方无法提供代理目标,也无法将 OpenClaw 重定向到其他目标。

A2A 1.0 限制

当前插件支持文本消息和结构化 JSON 数据部分,这些部分会作为紧凑 JSON 文本追加。文件 URL 和原始二进制部分会被忽略。流式传输、服务器发送事件、推送通知、任务取消、任务列表、扩展 Agent Card 和多租户路由均不受支持。

任务仅保存在内存中。已完成和其他终止任务最多保留 24 小时,最多保留 500 个条目。重启网关会丢弃所有任务和任务历史。

本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 cl/openclaw