---
summary: "通过 A2A 1.0 JSON-RPC 协议将外部代理连接到 OpenClaw"
read_when:
- "您希望 A2A- 兼容代理发现 OpenClaw 并发送消息"
- "您需要配置经过身份验证的 A2A 对等体或出站代理消息"
title: "A2A"
---
A2A 通道插件通过 Linux 基金会 [Agent2Agent 协议 ](https://a2a-protocol.org) 将 OpenClaw 连接到其他代理。外部代理通过公共代理卡发现网关,并使用 A2A 1.0 JSON-RPC 绑定提交经过身份验证的文本任务。 OpenClaw 还可以向配置的对等代理发送消息。
## 快速设置
将捆绑插件添加到您的 OpenClaw 配置中,并为每个受信任的对等点定义单独的承载令牌:
```json5
{
channels: {
a2a: {
enabled: true,
advertisedUrl: "https://openclaw.example.com",
peers: {
hermes: {
token: "${A2A_HERMES_TOKEN}",
},
},
},
},
}
```
在网关环境中将 `A2A_HERMES_TOKEN` 设置为强大的、唯一的机密,然后重新启动网关。当网关在反向代理后面运行时,使用外部可访问的 HTTPS 源作为 `advertisedUrl`。如果省略,插件将从传入的发现请求中派生出通告的来源。
## 发现代理卡
无需认证即可获取公共A2A代理卡:
```bash
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 请求:
```bash
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." }]
}
}
}'
```
默认情况下,请求等待代理响应。已完成的响应包含一个任务,其工件中包含回复:
```json
{
"jsonrpc": "2.0",
"id": "request-1",
"result": {
"task": {
"id": "",
"contextId": "",
"status": {
"state": "TASK_STATE_COMPLETED",
"timestamp": "2026-01-01T12:00:00.000Z"
},
"artifacts": [
{
"artifactId": "",
"parts": [{ "text": "Here are your latest project updates..." }]
}
],
"history": []
}
}
}
```
在后续请求中包含 `message.contextId` 以继续与新任务进行相同的对话。省略 `message.taskId`:不支持继续执行现有任务,包括在该任务正在运行时。上下文 ID 可以包含字母、数字、句点、下划线、冒号和连字符,且不得超过 128 个字符。
如果提供了 `message.taskId`,则未知、过期或其他对等方的任务 ID 将返回 JSON-RPC 错误 `-32001`。具有冲突 `message.contextId` 的自有任务返回 `-32602`;否则,请求将返回 `-32004`,表示任务继续不受支持。这些请求都不会启动新工作或更改引用的任务。
要在代理继续工作时立即返回,请将 `"configuration": { "returnImmediately": true }` 与 `"message"` 一起添加到 `params` 中。该任务最初报告 `TASK_STATE_WORKING`。超过 `replyTimeoutMs` 的请求也会返回当前工作任务,而不是取消它。
较旧的客户端可以使用 `message/send` 作为 `SendMessage` 的别名。
## 轮询任务
通过将 ID 发送到 `GetTask` 来轮询任务:
```bash
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_STATE_WORKING` 转换到 `TASK_STATE_COMPLETED`、`TASK_STATE_FAILED` 或 `TASK_STATE_REJECTED`。较旧的客户端可以使用 `tasks/get` 作为兼容性别名。
`CancelTask` 被拒绝,并出现 JSON-RPC 错误 `-32004`,而不是被确认。调度的代理运行没有用于停止它的插件 API,因此报告 `TASK_STATE_CANCELED` 将告诉对等方工作已停止,而运行仍在使用工具。拒绝可以使报告的状态保持诚实。
## 配置出站对等体
当 OpenClaw 应向另一个 A2A 代理发送消息时,添加对等 URL。当远程代理需要自己的承载令牌时,设置 `outboundToken`:
```json5
{
channels: {
a2a: {
enabled: true,
peers: {
hermes: {
token: "${A2A_HERMES_TOKEN}",
url: "https://hermes.example.com/a2a/v1",
outboundToken: "${A2A_HERMES_OUTBOUND_TOKEN}",
},
},
},
},
}
```
将出站消息地址发送至 `a2a:hermes`。该插件将 `SendMessage` 直接发送到配置的 URL,而不执行代理卡发现。出站消息重用每个对等方的稳定对话上下文。未配置 `url` 的对等体无法接收出站消息。
代理回复(包括排队的后续回复)仅向 A2A 对等方传送终端回复内容。主机状态通知(包括仅元数据诊断)和运行失败消息不会作为新的对等消息或任务工件转发。失败的代理运行会将其原始任务标记为 `TASK_STATE_FAILED`,原因为 `Agent run failed`,包括运行排队的时间。如果收集模式组合请求,则失败的运行将标记每个原始任务失败。这不会改变面向人的渠道上的错误报告。
## 配置参考
| 键 | 类型 | 默认值 | 描述 |
| ---------------------------- | -------- | -------- | ------------------------------------------------------------------------------ |
| `enabled` | 布尔值 | - | 启用或禁用 A2A 通道。 |
| `advertisedUrl` | 字符串 | 要求 | 代理卡中使用的公共网关源。 |
| `replyTimeoutMs` | 数字 | `120000` | 最大阻塞回复等待时间;允许的范围是 `5000` 到 `600000` 毫秒。 |
| `rateLimitPerMinute` | 数字 | `30` | 每个对等点的滑动窗口请求限制; `0` 禁用限制。 |
| `exposeAgents` | 细绳[] | 全部 | 特工 ID 被宣传为特工卡技能。 |
| `peers` | 目的 | `{}` | 受信任的对等点由最多 64 个字符的小写名称键入。 |
| `peers..token` | 字符串 | 必填 | 当该对等方向 OpenClaw 发送请求时需要承载令牌。 |
| `peers..url` | 字符串 | - | 出站消息的对等 JSON-RPC 端点。 |
| `peers..outboundToken` | 字符串 | - | 承载令牌 OpenClaw 发送到配置的对等点 URL。 |
对等名称必须以小写字母或数字开头,还可以包含句点、下划线和连字符。
## 会话隔离
每个经过身份验证的对等点和 A2A `contextId` 对都会获得自己的代理会话。 A2A 固定最隔离的直接消息范围,而不是继承 `session.dmScope`,因此远程对等内容永远不会加入操作员的主会话,并且一个对等点无法读取另一对等点的对话历史记录。
对于代理绑定,请使用配置的对等名称作为直接对等 ID,例如 `hermes`。上下文特定的 `hermes:` 绑定优先于该稳定对等点绑定,并且稳定对等点绑定优先于更广泛的 A2A 帐户或通道路由。
## 安全
代理卡发现有意公开:任何能够到达网关的人都可以读取实例描述和公开的代理 ID。使用 `exposeAgents` 来限制泄露,并在可通过不受信任的网络访问时通过 HTTPS 公开网关。
每个 JSON-RPC 请求都需要配置的对等承载令牌。不存在未经身份验证的模式。每个经过身份验证的对等点也是用于正常 OpenClaw 通道入口策略的发送者身份。为每个对等方使用不同的高熵令牌,使令牌不受源代码控制,并通过更新网关环境和重新启动来轮换令牌。
A2A 对等方发送任务,而不是用户命令。以 `/` 开头的消息将被拒绝,并显示 `TASK_STATE_REJECTED` 和解释。普通任务中类似命令的文本保持原义。它无法更改会话设置或解决批准问题。当对等方将协议消息角色设置为 `ROLE_USER` 时,这也适用:该字段不对人类用户进行身份验证。
普通任务保留其路由代理的工具和权限。需要批准的工作仍然需要授权运营商通过支持的用户渠道或 Control UI 做出决定。通过 A2A 发送斜杠命令的现有集成必须使用纯文本任务进行代理工作,并使用授权用户界面执行命令。没有选择加入的对等命令。
当等待执行批准时,原始任务仍然有效。操作员做出决定后,同一代理运行会接收结果并通过其原始回复路径完成任务。入站对等方不需要出站 `url` 即可通过 `GetTask` 接收该完成。
请求限制为 1 MiB,JSON-RPC 批次限制为 30 个条目,序列化 JSON-RPC 响应限制为 1 MiB。提取的消息文本的上限为 64 KiB,并在缩短时包含显式截断标记。默认滑动窗口限制为每个对等点每分钟 30 个请求。架构无效的请求计入该限制。仅在单独受保护的网络上将 `rateLimitPerMinute` 设置为 `0`。速率限制请求返回 JSON-RPC 错误,同时保持 HTTP 状态 200。
出站目标仅来自操作员配置的对等 URL。入站呼叫者无法提供代理目标或将 OpenClaw 重定向到另一个目标。
## A2A 1.0 限制
当前插件支持文本消息和结构化 JSON 数据部分,这些数据部分作为紧凑的 JSON 文本附加。文件 URL 和原始二进制部分将被忽略。不支持流、服务器发送事件、推送通知、任务取消、任务列表、扩展代理卡和多租户路由。
代理卡标有 `pushNotifications: false`。推送通知配置方法返回 JSON-RPC 错误 `-32003` (`PushNotificationNotSupportedError`),按照 [A2A 1.0 规范 ](https://a2a-protocol.org/v1.0.0/specification/#334-capability-validation) 的要求。其他公认的不支持的方法返回`-32004`;未知方法名称返回 `-32601`。
来自同一经过身份验证的对等方的重复 `messageId` 返回现有任务及其当前状态,同时保留该任务。即使重试忽略 `contextId`,它也不会启动另一个代理轮次。使用新的 `messageId` 进行新的工作。回复与开始轮次的任务相关联,包括当一个上下文中的消息无序完成时。没有回复文本的已完成回合不会出现任何伪影;停止通道会导致未完成的任务失败。
任务仅保留在内存中。已完成的终端任务和其他终端任务最多保留 24 小时,最多保留 500 条条目。重新启动网关会丢弃所有任务和任务历史记录。
## 相关内容
- [渠道概览](/channels)
- [频道路由](/channels/channel-routing)
- [网关安全](/gateway/security)
- [频道插件 SDK](/plugins/sdk-channel-plugins)
- [A2A 插件参考](/plugins/reference/a2a) — 插件的清单、配置和工具参考