虾折腾大赛+让你的OpenClaw多bot多Agent相互通信:我开源了OpenClaw A2A Gateway插件
AI超元域
2026年03月12日 15:16

我 Mac 上跑着一个 OpenClaw Agent 写代码,云服务器上另一个做搜索分析——但它们互相不认识。所以我写了 openclaw-a2a-gateway,把 Google 的 A2A v0.3.0 协议落地到 OpenClaw,让不同机器上的 Agent 能双向通信。


先搞清楚:A2A 到底是什么?

在讲部署之前,我们先用 30 秒理解一下 A2A。

一句话总结:MCP 让 Agent 能用工具,A2A 让 Agent 能找 Agent。

MCP 大家应该不陌生了,它解决的是"Agent 怎么调用外部工具和数据"的问题。而 A2A 解决的是另一个层面——"Agent 怎么找到另一个 Agent,并把任务委派给它"。

A2A 协议由 Google 在 2025 年 4 月发布,目前版本 v0.3.0,已经被 Linux Foundation 接管,背后有 150+ 组织站台(Salesforce、SAP、微软、AWS 等等都在里面)。

它的核心其实就三样东西:

① Agent Card —— 每个 Agent 的"名片",告诉别人我是谁、我会什么、怎么联系我。一个 JSON 文件,放在固定路径 /.well-known/agent-card.json。

② Task —— Agent 之间协作的基本单位。有完整的生命周期:提交 → 处理中 → 需要更多输入 → 完成/失败。

③ Message & Parts —— 消息载体。支持文本(TextPart)、文件(FilePart)、结构化数据(DataPart)。

底层用的全是老朋友:HTTP + JSON-RPC + SSE。没有花哨的私有协议,任何能发 HTTP 请求的语言都能接入。


这个插件做了什么?

装上之后,你的 OpenClaw 实例就变成了一个 A2A 节点。具体来说,它干了这几件事:

对外暴露 A2A 端点:别的 Agent 可以通过标准的 JSON-RPC 接口向你的 Agent 发消息。

发布 Agent Card:让对端能发现你、知道你能做什么。

安全认证:支持 Bearer Token,不是谁都能跟你的 Agent 说话。

双向通信:不仅能接收消息,你的 Agent 也可以主动调用对端。

文件传输:支持发送文件给对端 Agent(URI 或 base64)。

架构长这样:

代码块
PlainText
自动换行
复制代码
  Server A (你的 Mac)              Server B (云服务器)
┌─────────────────────┐        ┌─────────────────────┐
│  Agent: MacBot       │  A2A   │  Agent: CloudBot     │
│  Port: 18800         │◄─────►│  Port: 18800         │
│  Peer: Server-B      │       │  Peer: Server-A      │
└─────────────────────┘        └─────────────────────┘
       Tailscale / LAN / 公网
复制成功

两个端点需要记住:

  • /.well-known/agent-card.json(GET)—— Agent Card 发现

  • /a2a/jsonrpc(POST)—— 消息收发


部署前的准备

开始之前,确认你的环境满足这些条件:

代码块
Shell
自动换行
复制代码
# OpenClaw >= 2026.3.0
openclaw --version

# Node.js >= 22
node --version

# Gateway 正在运行
openclaw gateway status

# 至少配置了一个 AI Provider
openclaw config get auth.profiles
复制成功

如果 OpenClaw 还没装,先跑一下:

代码块
Shell
自动换行
复制代码
npm install -g openclaw@latest
openclaw onboard --install-daemon
复制成功

另外,两台机器之间要能互相访问(后面会讲网络方案)。


八步完成安装(如果不想自己操作,将下面的内容发给你的小龙虾自主操作就行)

第一步:克隆插件

代码块
Shell
自动换行
复制代码
mkdir -p ~/.openclaw/workspace/plugins
cd ~/.openclaw/workspace/plugins
git clone https://github.com/win4r/openclaw-a2a-gateway.git a2a-gateway
cd a2a-gateway
npm install --production
复制成功

装完之后目录结构是这样的:

代码块
PlainText
自动换行
复制代码
a2a-gateway/
├── index.ts                 # 插件入口
├── openclaw.plugin.json     # 插件描述文件
├── src/                     # 核心源码
├── skill/                   # Agent Skill(后面会讲)
│   ├── SKILL.md
│   ├── scripts/
│   │   └── a2a-send.mjs    # 发送脚本
│   └── references/
│       └── tools-md-template.md
└── tests/
复制成功

第二步:注册插件

这一步要做三件事——加白名单、设路径、启用:

代码块
Shell
自动换行
复制代码
# 1) 添加到允许的插件列表
# 注意:保留你已有的插件,比如 telegram
openclaw config set plugins.allow '["telegram", "a2a-gateway"]'

# 2) 告诉 OpenClaw 去哪里加载这个插件
# ⚠️ 必须用绝对路径!用 ~ 或相对路径会静默失败!
openclaw config set plugins.load.paths \
  '["<FULL_PATH_TO>/plugins/a2a-gateway"]'

# 3) 启用插件
openclaw config set plugins.entries.a2a-gateway.enabled true
复制成功

把 <FULL_PATH_TO> 替换成你的实际路径,比如:

  • Linux:/home/ubuntu/.openclaw/workspace/plugins/a2a-gateway

  • macOS:/Users/你的用户名/.openclaw/workspace/plugins/a2a-gateway

踩坑提醒:plugins.load.paths 里面写 ~ 是不行的,必须写完整的绝对路径。这是新手最容易栽的地方。另外 plugins.allow 数组里要保留你已有的插件名,别只写一个 a2a-gateway 把别的覆盖掉了。

第三步:配置 Agent Card

这一步是告诉外界"你的 Agent 是谁":

代码块
Shell
自动换行
复制代码
openclaw config set plugins.entries.a2a-gateway.config.agentCard.name 'MacBot'

openclaw config set plugins.entries.a2a-gateway.config.agentCard.description \
  '我的 OpenClaw A2A Agent'

openclaw config set plugins.entries.a2a-gateway.config.agentCard.url \
  'http://<YOUR_IP>:18800/a2a/jsonrpc'

openclaw config set plugins.entries.a2a-gateway.config.agentCard.skills \
  '[{"id":"chat","name":"chat","description":"Bridge chat/messages to OpenClaw agents"}]'
复制成功

把 <YOUR_IP> 换成对端能访问到的 IP(Tailscale IP、局域网 IP 或公网 IP)。

这里有个很容易搞混的点

agentCard.url 指向你的 JSON-RPC 端点,路径是 /a2a/jsonrpc

后面配 Peer 时的 agentCardUrl 指向对端的 Agent Card,路径是 /.well-known/agent-card.json

一个是"怎么发消息给我",一个是"去哪里了解对方"。别搞反了。

第四步:配置服务器

代码块
Shell
自动换行
复制代码
openclaw config set plugins.entries.a2a-gateway.config.server.host '0.0.0.0'
openclaw config set plugins.entries.a2a-gateway.config.server.port 18800
复制成功

0.0.0.0 表示监听所有网卡接口。端口默认 18800。

第五步:配置安全认证

强烈建议开启 Token 认证,不然谁都能跟你的 Agent 说话:

代码块
Shell
自动换行
复制代码
TOKEN=$(openssl rand -hex 24)
echo "你的 A2A Token: $TOKEN"

openclaw config set plugins.entries.a2a-gateway.config.security.inboundAuth 'bearer'
openclaw config set plugins.entries.a2a-gateway.config.security.token "$TOKEN"
复制成功

这个 Token 一定要保存好,后面对端连你的时候需要它。

建议把 Token 放到环境文件里,不要写进任何 Git 仓库:

代码块
Shell
自动换行
复制代码
mkdir -p ~/.config/openclaw
chmod 700 ~/.config/openclaw
echo "OPENCLAW_A2A_TOKEN=$TOKEN" >> ~/.config/openclaw/gateway.env
chmod 600 ~/.config/openclaw/gateway.env
复制成功

第六步:配置路由

代码块
Shell
自动换行
复制代码
openclaw config set plugins.entries.a2a-gateway.config.routing.defaultAgentId 'main'
复制成功

如果你的 OpenClaw 跑了多个 Agent(比如 main、coder、researcher),这里设的是默认把 A2A 消息路由给谁。发送方也可以用 --agent-id 参数指定。

第七步:重启 Gateway

代码块
Shell
自动换行
复制代码
openclaw gateway restart
复制成功

第八步:验证

代码块
Shell
自动换行
复制代码
# 看 Agent Card 能不能正常返回
curl -s http://localhost:18800/.well-known/agent-card.json | python3 -m json.tool

# 确认插件已加载
openclaw plugins list

# 确认端口在监听
ss -tlnp | grep 18800   # Linux
lsof -i :18800           # macOS
复制成功

如果 curl 返回了带 name、skills、url 的 JSON,恭喜,单机配置完成。


配置对端 Peer

单机跑通只是第一步。要实现 Agent 间通信,还得把对方加为 Peer。

单向连接

代码块
Shell
自动换行
复制代码
openclaw config set plugins.entries.a2a-gateway.config.peers '[
  {
    "name": "CloudBot",
    "agentCardUrl": "http://<PEER_IP>:18800/.well-known/agent-card.json",
    "auth": {
      "type": "bearer",
      "token": "<对端的 TOKEN>"
    }
  }
]'

openclaw gateway restart
复制成功

双向连接

如果你想让两边都能互相发消息,两台机器都要把对方加为 Peer

代码块
PlainText
自动换行
复制代码
Server A 的操作:
  - 生成自己的 A_TOKEN
  - 把 Server B 加为 Peer(用 B 的 TOKEN)

Server B 的操作:
  - 生成自己的 B_TOKEN  
  - 把 Server A 加为 Peer(用 A 的 TOKEN)
复制成功

简单说就是:**各自生成 Token,互相交换。**跟两个人互加微信好友一个道理。

添加多个 Peer

peers 是个数组,可以同时加好几个:

代码块
Shell
自动换行
复制代码
openclaw config set plugins.entries.a2a-gateway.config.peers '[
  {"name":"Server-B","agentCardUrl":"http://100.10.10.2:18800/.well-known/agent-card.json",
   "auth":{"type":"bearer","token":"B_TOKEN"}},
  {"name":"Server-C","agentCardUrl":"http://100.10.10.3:18800/.well-known/agent-card.json",
   "auth":{"type":"bearer","token":"C_TOKEN"}}
]'
复制成功

发消息的几种姿势

姿势一:命令行直接发

插件自带了一个基于 @a2a-js/sdk 的脚本,可以直接在终端发消息:

代码块
Shell
自动换行
复制代码
PLUGIN=~/.openclaw/workspace/plugins/a2a-gateway

node $PLUGIN/skill/scripts/a2a-send.mjs \
  --peer-url http://<PEER_IP>:18800 \
  --token <PEER_TOKEN> \
  --message "你好,我是 Server A!"
复制成功

脚本会自动发现对端的 Agent Card,处理认证,打印响应。

姿势二:异步模式(长任务推荐)

如果你的 Prompt 需要对端处理很久(比如多轮推理、深度分析),用同步模式可能会超时。这时候用异步模式:

代码块
Shell
自动换行
复制代码
node $PLUGIN/skill/scripts/a2a-send.mjs \
  --peer-url http://<PEER_IP>:18800 \
  --token <PEER_TOKEN> \
  --non-blocking \
  --wait \
  --timeout-ms 600000 \
  --poll-ms 1000 \
  --message "分析 A2A 协议的优缺点,写一份 3000 字报告"
复制成功

原理是先发送任务(立即返回 Task ID),然后持续轮询 tasks/get 接口直到任务完成。

  • --non-blocking:不阻塞,立即返回

  • --wait:自动轮询等待结果

  • --timeout-ms:超时时间,默认 10 分钟

  • --poll-ms:轮询间隔,默认 1 秒

姿势三:指定目标 Agent

如果对端跑了多个 Agent,你可以指定消息发给哪一个:

代码块
Shell
自动换行
复制代码
node $PLUGIN/skill/scripts/a2a-send.mjs \
  --peer-url http://<PEER_IP>:18800 \
  --token <PEER_TOKEN> \
  --agent-id coder \
  --message "帮我跑一下健康检查"
复制成功

注意:--agent-id 是这个插件的扩展功能(非 A2A 标准),只在 JSON-RPC 传输上可靠。

姿势四:发文件

代码块
Shell
自动换行
复制代码
# 发本地文件
node $PLUGIN/skill/scripts/a2a-send.mjs \
  --peer-url http://<PEER_IP>:18800 \
  --token <PEER_TOKEN> \
  --file-path /path/to/document.pdf \
  --message "请分析这份文档"

# 发 URL 引用
node $PLUGIN/skill/scripts/a2a-send.mjs \
  --peer-url http://<PEER_IP>:18800 \
  --token <PEER_TOKEN> \
  --file-uri https://example.com/report.pdf \
  --message "看看这份报告"
复制成功

姿势五:让 Agent 自己去调(最优雅的方式)

上面的方式都是人在终端里敲命令。但我们的终极目标是:用户跟 Agent 说一句自然语言,Agent 自己去调 Peer。

要实现这个,你需要在 Agent 的 TOOLS.md 里加一段 A2A 说明。插件提供了模板 skill/references/tools-md-template.md,把它塞到你的 TOOLS.md 里:

代码块
markdown
自动换行
复制代码
## A2A Gateway (Agent-to-Agent Communication)

You have an A2A Gateway plugin running on port 18800.

### Peers

| Peer | IP | Auth Token |
|------|-----|------------|
| CloudBot | 100.10.10.2 | <B_TOKEN> |

### How to send a message to a peer

Use the exec tool to run:

bash
node <PLUGIN_PATH>/skill/scripts/a2a-send.mjs \
  --peer-url http://100.10.10.2:18800 \
  --token <B_TOKEN> \
  --message "YOUR MESSAGE HERE"
复制成功

配完之后,你就可以这样用了:

  • "帮我问一下 CloudBot 服务器的状态"

  • "让 CloudBot 跑一下代码检查"

  • "Send to CloudBot: summarize today's logs"

Agent 会自动解析意图、拼接命令、调用 Peer、返回结果。这才是 Agent-to-Agent 的正确打开方式。


网络方案怎么选?

两台机器要互相访问,有三个方案:

方案一:Tailscale(最推荐)

Tailscale 会在你的设备之间建立一个加密的 Mesh 网络,不用配防火墙、不用端口转发。

代码块
Shell
自动换行
复制代码
# 两台机器都装
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up  # 用同一个账号登录

# 看各自的 IP
tailscale status  # 会分配 100.x.x.x 的地址

# 测试连通
ping 100.x.x.x
复制成功

然后在 A2A 配置里用 Tailscale 的 100.x.x.x IP 就行了。

优势很明显:零配置、NAT 穿透、端到端加密、跨地域(家 ↔ 云 ↔ 办公室都行)。

方案二:局域网

两台机器在同一个网络里?直接用局域网 IP,确保 18800 端口没被防火墙挡住就行。

方案三:公网 IP

用公网 IP + Token 认证。建议加防火墙规则只放行已知 IP:

代码块
Shell
自动换行
复制代码
sudo ufw allow from <PEER_PUBLIC_IP> to any port 18800
复制成功

实战:两台机器从零到通信

下面是一个完整的双机部署流程,假设用 Tailscale 组网:

Server A(IP: 100.10.10.1)

代码块
Shell
自动换行
复制代码
# 生成 Token
A_TOKEN=$(openssl rand -hex 24)
echo "Server A token: $A_TOKEN"

# Agent Card
openclaw config set plugins.entries.a2a-gateway.config.agentCard.name 'Server-A'
openclaw config set plugins.entries.a2a-gateway.config.agentCard.url \
  'http://100.10.10.1:18800/a2a/jsonrpc'
openclaw config set plugins.entries.a2a-gateway.config.agentCard.skills \
  '[{"id":"chat","name":"chat","description":"Chat bridge"}]'

# 服务器 + 安全 + 路由
openclaw config set plugins.entries.a2a-gateway.config.server.host '0.0.0.0'
openclaw config set plugins.entries.a2a-gateway.config.server.port 18800
openclaw config set plugins.entries.a2a-gateway.config.security.inboundAuth 'bearer'
openclaw config set plugins.entries.a2a-gateway.config.security.token "$A_TOKEN"
openclaw config set plugins.entries.a2a-gateway.config.routing.defaultAgentId 'main'

# 添加 Server B 为 Peer(需要 B 的 Token)
openclaw config set plugins.entries.a2a-gateway.config.peers \
  '[{"name":"Server-B",
     "agentCardUrl":"http://100.10.10.2:18800/.well-known/agent-card.json",
     "auth":{"type":"bearer","token":"<B_TOKEN>"}}]'

openclaw gateway restart
复制成功

Server B(IP: 100.10.10.2)

代码块
Shell
自动换行
复制代码
B_TOKEN=$(openssl rand -hex 24)
echo "Server B token: $B_TOKEN"

openclaw config set plugins.entries.a2a-gateway.config.agentCard.name 'Server-B'
openclaw config set plugins.entries.a2a-gateway.config.agentCard.url \
  'http://100.10.10.2:18800/a2a/jsonrpc'
openclaw config set plugins.entries.a2a-gateway.config.agentCard.skills \
  '[{"id":"chat","name":"chat","description":"Chat bridge"}]'

openclaw config set plugins.entries.a2a-gateway.config.server.host '0.0.0.0'
openclaw config set plugins.entries.a2a-gateway.config.server.port 18800
openclaw config set plugins.entries.a2a-gateway.config.security.inboundAuth 'bearer'
openclaw config set plugins.entries.a2a-gateway.config.security.token "$B_TOKEN"
openclaw config set plugins.entries.a2a-gateway.config.routing.defaultAgentId 'main'

openclaw config set plugins.entries.a2a-gateway.config.peers \
  '[{"name":"Server-A",
     "agentCardUrl":"http://100.10.10.1:18800/.well-known/agent-card.json",
     "auth":{"type":"bearer","token":"<A_TOKEN>"}}]'

openclaw gateway restart
复制成功

验证

代码块
Shell
自动换行
复制代码
# A 看 B 的名片
curl -s http://100.10.10.2:18800/.well-known/agent-card.json

# B 看 A 的名片
curl -s http://100.10.10.1:18800/.well-known/agent-card.json

# A → B 发消息
node $PLUGIN/skill/scripts/a2a-send.mjs \
  --peer-url http://100.10.10.2:18800 \
  --token <B_TOKEN> \
  --message "Hello from Server A!"

# B → A 发消息
node $PLUGIN/skill/scripts/a2a-send.mjs \
  --peer-url http://100.10.10.1:18800 \
  --token <A_TOKEN> \
  --message "Hello from Server B!"
复制成功

看到对端的回复了?恭喜,你的两个 Agent 已经学会互相"打电话"了。


Skill 安装:让 AI 帮你配置 A2A

上面那一堆命令看着头疼?其实这个项目还自带了一个 Skill,可以让 AI Agent 自己来执行配置流程。

为什么需要 Skill?

因为手动配置有太多容易搞错的地方:

  • 把 agentCard.url 和 peers[].agentCardUrl 搞反

  • plugins.load.paths 写了相对路径(必须用绝对路径)

  • 忘了更新 TOOLS.md(Agent 不知道怎么调 Peer)

  • 只配了单向 Peer(两边都得互相加)

Skill 把这些全编码成了标准流程。

怎么装?

根据你用的工具选一种:

代码块
Shell
自动换行
复制代码
# OpenClaw
cp -r ~/.openclaw/workspace/plugins/a2a-gateway/skill \
  ~/.openclaw/workspace/skills/a2a-setup

# Codex CLI
cp -r ~/.openclaw/workspace/plugins/a2a-gateway/skill \
  ~/.codex/skills/a2a-setup

# Claude Code
cp -r ~/.openclaw/workspace/plugins/a2a-gateway/skill \
  ./skills/a2a-setup
复制成功

装好后直接跟 Agent 说"配置 A2A"或"Add an A2A peer",它就会按流程自动走。


出了问题怎么办?

❌ "Request accepted (no agent dispatch available)"

A2A 请求到了网关,但 Agent 没处理。两个常见原因:

原因 1:没配 AI Provider

代码块
Shell
自动换行
复制代码
openclaw config get auth.profiles
# 空的话,先配一个 Provider
复制成功

原因 2:Agent 处理超时

解法一:发送方用异步模式 --non-blocking --wait

解法二:加大超时时间

代码块
Shell
自动换行
复制代码
openclaw config set \
  plugins.entries.a2a-gateway.config.timeouts.agentResponseTimeoutMs 600000
复制成功

❌ Agent Card 返回 404

插件没加载成功。挨个检查:

代码块
Shell
自动换行
复制代码
openclaw config get plugins.allow         # 白名单里有没有
openclaw config get plugins.load.paths    # 路径对不对(绝对路径!)
cat /tmp/openclaw/openclaw-$(date +%Y-%m-%d).log | grep a2a  # 看日志
复制成功

❌ 端口 18800 连不上

代码块
Shell
自动换行
复制代码
ss -tlnp | grep 18800        # 在不在监听
openclaw gateway restart       # 重启试试
sudo ufw status               # 防火墙有没有挡
复制成功

❌ Peer 认证失败

九成是 Token 没对上。检查这几个点:

  • 复制 Token 时有没有多余空格或换行

  • 对端改了 Token 但你这边没同步

  • 对端 inboundAuth 是 none 但你配了 Token(或反过来)

💻 macOS 专属提醒

macOS 上 Gateway 是通过 launchd 管理的,确保用正确的方式操作:

代码块
Shell
自动换行
复制代码
openclaw gateway install    # 注册 launchd 服务
openclaw gateway restart    # 重启
复制成功

写在最后

A2A 协议现在还很年轻,这个插件我也还在持续迭代(持久化任务存储、SSE 流式输出、健康检查、审计日志等都在 Roadmap 上,欢迎 PR),但核心的双向通信链路已经跑通了。

如果你也在自己的机器上跑着 OpenClaw,想让不同机器上的 Agent 协作起来,可以试试。Tailscale + A2A Gateway,十分钟就能让两个 Agent 互相说上话。

更重要的是,A2A 是一个开放标准。你的 OpenClaw Agent 不只能跟另一个 OpenClaw 通信——理论上任何实现了 A2A 协议的 Agent(不管是 Google ADK 写的、LangGraph 写的、还是 CrewAI 写的)都可以成为你的 Peer。

这才是 Agent 网络的起点。有问题欢迎在 GitHub 提 Issue。


📦 项目:https://github.com/win4r/openclaw-a2a-gateway