Skip to main content
A2A(Agent2Agent)是 Google 提出的智能体通信协议。 AgentScope 通过 A2AAgent 类作为 A2A 协议的客户端,可以连接任意实现了 A2A 1.0 及以上协议的远端智能体(对方只提供 0.3 时,官方 SDK 回退到兼容传输),将远端智能体返回的消息、状态与制品(Artifact)转换成 AgentScope 中的消息与事件;同时将用户输入(包括多模态数据)发送给远端智能体。 A2AAgent 仅仅是远端智能体运行逻辑的本地代理,本身不代表实际的运行逻辑。与 Agent 类相比,两者在接口上保持一致,但有以下区别:
仓库中的 examples/a2a 提供了完整的双端示例:用 AgentScope 智能体搭起 A2A 服务端,再用 A2AAgent 连上去对话。

快速开始

1

安装依赖

A2A 支持依赖官方 SDK,随 a2a 可选依赖安装。
安装依赖
2

取回 Agent Card

Agent Card 是远端智能体的自我描述文件,一份放在固定地址上的 JSON,记录它的名称、简介、能力,以及可用的传输方式与接口地址。A2AAgent 用它识别对方并选择传输方式,因此连接从取回这张卡片开始。
解析 Agent Card
3

创建 A2AAgent 并对话

把卡片交给 A2AAgent。它自己持有 A2A 客户端,退出上下文管理器时关闭,因此一个实例服务一段对话,关闭后不能重开。对话接口与本地智能体一致:reply_stream 实时产出事件,reply 在内部消费完事件后返回最终消息。
A2AAgent.reply_stream 不支持 yield_final_msg 参数:最终消息在流结束后由 A2AAgent 自行组装,需要它时请改用 reply
4

(可选)交给终端 UI

事件流与本地智能体一致,因此远端智能体也可以直接丢进终端 UI 对话调试。
在终端与远端智能体对话
构造参数如下,其中 clientstate 只能以关键字传入:
一段远端会话值得持久化的东西都在 A2AAgentState 里,把它传回构造函数即可续接:
续接同一段远端会话

协议转换

A2AAgent 的全部工作是把 A2A 的概念翻译成 AgentScope 的概念,翻译分三层:会话标识、响应载荷、内容 Part。

会话与任务

A2A 用两个标识组织一段对话,它们与 AgentScope 的概念并不一一对应,是使用中最容易误解的地方: 两者都保存在 A2AAgentState 中。此外该状态还有一个本地的 session_id,只用于给本适配器产出的事件分组,与远端无关。

响应载荷

远端的每一种响应载荷都会被拆成内容 Part 转译,载荷本身只决定这批内容归属哪个 Task、以及本次回复如何收尾:

内容 Part

每个 Part 按类型转成对应的内容块: 因此事件流中只会出现回复起止事件与文本 / 数据块事件,上面的流式对话示例按 TextBlockDeltaEvent 过滤即可覆盖绝大多数文本场景。块结束事件的 metadata["a2a"] 中记录了它来自哪个 A2A 对象(task_idartifact_idmessage_id),最终消息的 metadata["a2a"] 中记录 context_id
思考块、工具调用块、提示块与推送通知都不在转译范围内:A2A 传递的是最终产物,远端智能体的推理过程与工具调用不会出现在事件流里。

回复的结束

远端 Task 挂起在服务端,本地并没有任何东西被挂起,因此每一次响应流结束都意味着本次回复结束。流最后停在哪个 Task 状态,决定这次回复的 finished_reason task_id 只在远端等待输入(INPUT_REQUIRED / AUTH_REQUIRED)时保留,下一条消息续上该 Task;其余状态会清空它,下一条消息在同一个 context_id 内开启新 Task。另有两种边界情况:远端已经忘记的 Task 退化为新 Task;远端仍在运行的 Task 会直接抛出 RuntimeError,因为此时发消息会让它再执行一遍。
A2A 的凭据在协议之外传递,因此 AUTH_REQUIRED 的 Task 无法通过本适配器授权,需要按状态消息中的指引自行完成。

延伸阅读

终端 UI

把远端智能体交给终端,直接开始对话。

消息与事件

了解事件流中每种事件的含义。