OpenClaw A2A 通道实战指南:基于 A2A v1.0 协议的 Agent 互联互通
OpenClaw A2A 通道实战指南基于 A2A v1.0 协议的 Agent 互联互通【免费下载链接】openclawThe AI that really does things. Any OS. Any Platform. The lobster way. 项目地址: https://gitcode.com/GitHub_Trending/cl/openclawOpenClaw 内置的 A2A 通道插件包名openclaw/a2a将 OpenClaw 网关接入 Linux Foundation 的 Agent2AgentA2A v1.0协议外部 A2A 兼容 Agent 可以通过公开的 Agent Card 发现网关并用携带 Bearer 令牌的 JSON-RPC 请求提交文本任务反过来OpenClaw 也能向配置好的远端对等 Agent 发送出站消息。读完本文你将掌握 A2A 通道的完整配置方法、Agent Card 发现机制、任务发送与轮询的调用方式、出站对等点设置以及该通道在认证、会话隔离、限流与安全方面的底层实现细节。A2A 通道概览A2AAgent-to-Agent是 Linux Foundation 主导的跨 Agent 互操作协议。OpenClaw 的 A2A 通道插件插件清单将其落地为一条标准消息通道位于agent-orchestration分类激活方式为onStartup: false按需启动声明通道 id 为a2a。从插件入口看该通道以 Chat 通道插件的形式实现具备完整的入站HTTP JSON-RPC 接收任务、出站向远端对等点发送消息、任务存储与会话路由能力相关实现集中在 extensions/a2a/srchttp.tsHTTP 路由与 JSON-RPC 请求处理protocol.tsA2A 协议方法解析、消息提取与校验inbound.ts入站任务分发与会话隔离outbound.ts出站消息发送task-store.ts任务生命周期与内存存储gateway.ts网关路由注册与生命周期管理。安装与分发方面插件以openclaw/a2a包随 OpenClaw 内置分发无需单独安装package.json声明其peerDependencies为openclaw 2026.9.4。快速配置在 OpenClaw 配置中启用channels.a2a并为每个可信对等点单独定义一个 Bearer 令牌{ channels: { a2a: { enabled: true, advertisedUrl: https://openclaw.example.com, peers: { hermes: { token: ${A2A_HERMES_TOKEN}, }, }, }, }, }要点说明将A2A_HERMES_TOKEN设为网关环境中的强随机唯一密钥然后重启网关生效当网关位于反向代理之后时advertisedUrl应填写外部可达的 HTTPS 源origin。若省略插件会从入站请求推导公布源源码中resolveRequestOrigin依据请求 socket 的encrypted标志与Host头拼接出 origin见 http.ts插件清单还提供了交互式配置入口channel.setup.fields定义了--advertised-url、--peer-name、--peer-token三个 CLI 参数peer-token标记为敏感字段便于通过命令行向导完成首轮配置见 package.json。从配置校验源码config-schema.ts可以看到通道配置使用 zod 严格模式.strict()未知字段会被拒绝advertisedUrl必须是合法的 HTTP/HTTPS URLreplyTimeoutMs必须为5000600000之间的整数即 5 秒到 10 分钟rateLimitPerMinute为不小于 0 的整数peers的键peer 名必须匹配/^[a-z0-9][a-z0-9._-]{0,63}$/以小写字母或数字开头可包含句点、下划线、连字符总长不超过 64 字符peers.name.token至少 1 字符必填url与outboundToken可选。发现 Agent CardAgent Card 是 A2A 协议的名片允许外部 Agent 在无认证的情况下发现网关能力。直接抓取curl http://127.0.0.1:18789/.well-known/agent-card.json卡片会公布网关的 JSON-RPC 端点、支持的文本输入输出以及为每个被公开的 OpenClaw Agent 生成的一个 skill设置channels.a2a.exposeAgents为 Agent ID 数组可以限定哪些 Agent 出现在卡片中未设置或为空数组时所有已配置 Agent 都会被公布/.well-known/agent.json返回同一张卡片用于兼容旧版 A2A 客户端。源码层面的实现细节http.tsAgent 列表通过listAgentIds读取兼容agents.entries与旧版agents.list两种配置形态避免因配置形态不同导致卡片缺 skillexposeAgents作为白名单过滤!exposed?.length || exposed.includes(agentId)即未配置时全部公开卡片supportedInterfaces中protocolBinding: JSONRPC、protocolVersion: 1.0端点统一为advertisedOrigin/a2a/v1卡片默认只公布text/plain输入输出模式明确声明streaming: false、pushNotifications: falseskill 的description固定为OpenClaw agent agentId.刻意不公布操作者编写的 Agent 描述——因为卡片是无认证公开的只让 Agent ID 跨越发现边界。发送任务向/a2a/v1发送携带认证的SendMessageJSON-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. }] } } }默认情况下请求会阻塞等待 Agent 响应完成后的响应包含任务及其回复产物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: [] } } }会话延续与上下文 ID后续请求中带上相同的message.contextId即可继续同一段对话。协议层对上下文 ID 有严格校验protocol.ts只能包含字母、数字、句点、下划线、冒号与连字符长度 1128 字符。未提供contextId时插件会生成ctx-uuid作为新会话的上下文。立即返回模式在params中与message并列添加configuration: { returnImmediately: true }请求会立即返回任务在后台继续执行此时任务状态为TASK_STATE_WORKING。超过replyTimeoutMs的阻塞请求同样会返回当前 working 状态的任务而不会取消它。对应实现中超时由taskStore.wait(taskId, timeoutMs)的定时器驱动见 task-store.ts。兼容别名旧版客户端可使用message/send作为SendMessage的别名。协议解析层resolveA2aRpcMethod仅接受四组显式白名单映射SendMessage、GetTask、message/send、tasks/get见 protocol.ts其余方法要么报Method not found-32601要么走明确不支持路径。轮询任务将任务 ID 发给GetTask即可轮询进度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作为兼容别名。任务不存在时返回-32001 Task not found。为什么 CancelTask 被拒绝CancelTask及tasks/cancel会被 JSON-RPC 错误-32004拒绝而不是假装成功。源码注释给出了明确理由已派发的 Agent 运行在插件层没有可用的中止缝abort seam如果回执TASK_STATE_CANCELED等于向对端谎报工作已停止而实际 Agent 运行仍在继续使用工具。拒绝而非伪确认是为了保持上报状态的真实性。除取消外ListTasks、SendStreamingMessage、SubscribeToTask、各类 PushNotification 配置方法与GetExtendedAgentCard等也全部列入不支持集合见 protocol.ts。配置出站对等点当 OpenClaw 需要主动向另一个 A2A Agent 发送消息时为 peer 添加url远端 Agent 需要它自己的 Bearer 令牌时再加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 发现每个 peer 复用稳定的会话上下文源码中出站请求固定使用ctx-oc-peerName作为contextId见 outbound.ts并在configuration中带returnImmediately: true未配置url的 peer 无法接收出站消息发送时会抛出peer name has no url configured for outbound A2A出站请求超时为 30 秒当远端返回-32601 Method not found时会以 A2A 0.3 时代的message/send方法名自动重试一次兼容 Hermes 一代的旧版对端。出站安全同样有据可查请求经由共享的 SSRF 防护层fetchWithSsrFGuard发出策略绑定为 peer URL 的允许源且maxRedirects: 0——重定向可能把 A2A 任务投递给非预期的 Agent因此被显式禁止见 outbound.ts。配置参考KeyTypeDefaultDescriptionenabledboolean-Enables or disables the A2A channel.advertisedUrlstringrequestPublic gateway origin used in the Agent Card.replyTimeoutMsnumber120000Maximum blocking reply wait; allowed range is5000to600000milliseconds.rateLimitPerMinutenumber30Sliding-window request limit per peer;0disables the limit.exposeAgentsstring[]allAgent IDs advertised as Agent Card skills.peersobject{}Trusted peers keyed by lowercase names up to 64 characters.peers.name.tokenstringrequiredBearer token required when this peer sends requests to OpenClaw.peers.name.urlstring-Peer JSON-RPC endpoint for outbound messages.peers.name.outboundTokenstring-Bearer token OpenClaw sends to the configured peer URL.补充说明所有默认值均可在 http.ts 与配置校验中核验DEFAULT_REPLY_TIMEOUT_MS 120_000、DEFAULT_RATE_LIMIT_PER_MINUTE 30、RATE_LIMIT_WINDOW_MS 60_000速率限制为每 peer 的滑动窗口计数60 秒窗口0表示关闭关闭只在独立受保护网络上才建议启用peer 名规则以小写字母或数字开头可含句点、下划线、连字符最长 64 字符。会话隔离A2A 通道为每个已认证 peer 每个 contextId组合分配独立的 Agent 会话。关键设计是A2A固定使用最隔离的 direct-message 作用域而不是继承session.dmScope——这样远端 peer 的内容永远不会进入操作者的主会话一个 peer 也无法读取另一个 peer 的对话历史。实现上inbound.ts入站路由把 peer 建模为 direct 会话peer { kind: direct, id: peerName:contextId }dmScope固定为per-account-channel-peer会话路由将 peer 名作为规范 direct-peer ID如hermes。绑定优先级从高到低为上下文专属绑定hermes:contextId→ 稳定 peer 绑定hermes→ 更宽泛的 A2A 账户/通道路由入站还经过dmPolicy: allowlistallowFrom: peers 键集合的入站策略过滤被拦截的请求会以TASK_STATE_REJECTED终结。安全机制公开发现与最小化暴露Agent Card 的发现是有意公开的任何能触达网关的人都能读到实例描述与暴露的 Agent ID。因此用exposeAgents收敛披露面网关若在不可信网络上可达必须通过 HTTPS 暴露。全量认证无匿名模式每个 JSON-RPC 请求都必须携带已配置 peer 的 Bearer 令牌不存在未认证模式。认证实现采用常数时间比较服务端将呈现令牌与每个已配置 peer 的令牌分别做 SHA-256 摘要再用timingSafeEqual比对从而抵抗时序侧信道见 http.ts。已认证的 peer 同时也是 OpenClaw 常规通道入站策略中的发送者身份。实践建议每个 peer 使用不同的高熵令牌令牌不进版本库轮换令牌只需更新网关环境变量并重启。任务是任务命令是命令A2A peer 提交的是任务不是用户命令以/开头的消息会被拒绝任务以TASK_STATE_REJECTED终结并附解释普通任务文本中的命令样式内容保持字面量不能改变会话设置或代为批准审批即使 peer 把协议消息role设为ROLE_USER也不代表它认证了一个人类用户——该字段不构成身份认证判断逻辑见 inbound.ts 的斜杠前缀检查与CommandInterpretationSuppressed标记普通任务保留其路由 Agent 的工具与权限需要审批的工作仍须由已授权操作者通过受支持的用户通道或 Control UI 决策曾经通过 A2A 发送斜杠命令的集成现在必须改用纯文本任务做 Agent 工作、用受授权的用户界面执行命令——A2A 没有 peer 命令 opt-in。审批与完成路径当 exec 审批挂起时原任务保持 working 状态操作者决策后同一个 Agent 运行接收结果并通过原回复路径完成任务。入站 peer 即使没有配置出站url也能通过GetTask取回该完成结果——出站 URL 只影响主动推送不影响任务回读。硬性限额限额项数值请求体大小1 MiB超限返回 HTTP 413序列化 JSON-RPC 响应1 MiB超限以-32000错误替代JSON-RPC 批处理条目数最多 30 条即使关闭每 peer 限流也强制生效提取的消息文本64 KiB超出即截断并附显式截断标记默认速率限制每 peer 每分钟 30 次滑动窗口schema 无效请求也计入文本截断实现于 protocol.ts拼接所有文本与 JSON 数据 part 后按字节计数若超限则用TextDecoder(fatal: true)逐字节回退保证不会在 UTF-8 多字节字符中间截断并追加\n[message truncated at 65536 bytes]标记。被限流的请求返回 JSON-RPC 错误但 HTTP 状态保持 200。出站方向不可被劫持出站目的地只来自操作者配置的 peer URL入站调用者无法提供代理目标也无法把 OpenClaw 重定向到其他目的地maxRedirects: 0从传输层也封死了重定向投递。A2A 1.0 能力边界当前插件对 A2A 1.0 协议的支持是务实裁剪的明确边界如下支持的 part文本text与结构化 JSON 数据data会以紧凑 JSON 文本追加到消息。文件 URLurl与原始二进制rawpart 被忽略不支持流式、Server-Sent Events、推送通知、任务取消、任务列表、扩展 Agent Card 以及多租户路由。任务仅保存在内存中A2aTaskStore以 Map 实现见 task-store.ts已完成等终态任务保留最长24 小时最多保留500条终态任务网关重启会丢弃全部任务与任务历史。任务完成按每个 peercontext 会话队列以 FIFO 顺序交付保证并发发送与取消墓碑场景下的回复关联不乱序。网关路由与生命周期插件通过 gateway.ts 在网关注册三条固定路径/.well-known/agent-card.json、/.well-known/agent.json、/a2a/v1注册方式为match: exact且throwOnFailure: true——重复注册意味着存在过期或冲突的持有者会快速失败而不是静默替换活动处理器。关闭时先停止接收新任务再释放被阻塞的响应避免关机窗口期任务已受理、等待者与定时器已被清理的不一致状态。延伸阅读通道总览通道路由网关安全通道插件 SDKA2A 插件参考插件清单、配置与工具入口【免费下载链接】openclawThe AI that really does things. Any OS. Any Platform. The lobster way. 项目地址: https://gitcode.com/GitHub_Trending/cl/openclaw创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考