教程中心进阶
进阶

让不同 AI 智能体会「对话」:A2A 协议实战(Agent 与 Agent 通信)

2026.07.19· 6 个步骤 · 20 分钟阅读· 🔗 A2A 协议

你大概率已经会用 MCP 给 Agent 接工具(查天气、读数据库、发消息)。但一个新问题是:当任务复杂到需要多个 Agent 分工时,它们怎么互相「说话」?2025 年 4 月 Google 发布的 A2A(Agent2Agent)协议就是为此而生——它被称为 Agent 世界的「HTTP 协议」。本教程带你搞懂 MCP 与 A2A 的区别,并在本地用 Python 跑通一个「研究 Agent + 写作 Agent」协作的小系统。

🔗 本教程适合:已经接触过 Agent / MCP,想理解「多智能体协作」底层通信机制、并亲手搭一个最小可用 A2A 系统的开发者。需要一点点 Python 基础。

先搞懂:MCP 和 A2A 是什么关系?

一句话记住:MCP 解决「Agent 连接工具」,A2A 解决「Agent 连接 Agent」。它们不是替代关系,而是互补的上下两层基础设施。

维度MCP(模型上下文协议)A2A(Agent2Agent 协议)
解决什么Agent 与工具 / 数据源的连接Agent 与 Agent 之间的通信协作
类比USB-C(设备接配件)HTTP(设备联设备)
发起方AgentAgent
接收方工具 / 服务 / 数据另一个 Agent
状态通常无状态有状态的任务生命周期

典型组合架构:上层用 A2A 做任务编排(谁负责什么),每个 Agent 内部用 MCP 接自己的工具。好比一个公司——A2A 是部门间的协作流程,MCP 是每名员工手里的办公软件。

Step 1:理解 A2A 的四个核心概念

1 认识 Agent Card、任务、消息与工件

A2A 协议围绕几个简单但关键的概念运转,先建立心智模型:

1) Agent Card(Agent 名片)
   每个 A2A Agent 必须暴露一个 JSON「名片」,写清楚:
   - 自己叫什么、能干什么(skills)
   - 服务地址 URL、支持的认证方式
   其他 Agent 靠这张名片「发现」它、了解它的能力。

2) Client / Remote 架构
   Client Agent = 发起任务的「甲方」
   Remote Agent  = 执行任务的「乙方」
   甲方把任务发给乙方,乙方干完把结果回传。

3) Task 生命周期(状态机)
   submitted → working → input-required → completed
                  ↓            ↓
                failed      canceled
   一次任务从「已提交」到「已完成 / 失败 / 取消」全程可追溯。

4) Message & Artifact(消息与工件)
   支持文本、图片、文件;Artifacts 是 Agent 产出的「成果物」
   (一篇报告、一段代码、一份数据表)。
💡 记住一个比喻:Agent Card 像招聘 JD(写明能力与联系方式),Task 像一张工单,Artifact 像交付物。理解了这三样,A2A 就通了。

Step 2:准备环境

2 装好 Python 与 A2A 官方 SDK

Google 官方维护了一个轻量的 a2a Python SDK(开源),本教程用它搭最小系统。先建个干净环境:

# 建虚拟环境(推荐,避免污染全局)
python -m venv .venv
source .venv/bin/activate        # Windows: .venv\Scripts\activate

# 安装官方 SDK 与示例依赖
pip install a2a-sdk httpx uvicorn pydantic

# 确认装好
python -c "import a2a; print('a2a ready')"

没有 a2a-sdk?GitHub 上官方仓库是 google-a2a/A2A。若 PyPI 版本名不同,用 pip install a2a-python 或按官方 README 安装。本教程的调用思路通用,不绑定某一版本。

Step 3:写一个「写作 Agent」并暴露 Agent Card

3 让一个 Agent 成为可被调用的「乙方」

我们先做一个最简单的「写作 Agent」:它收到一段要点,返回一篇润色后的短文。关键是写一个 Agent Card 描述它的能力,并把它跑成一个 A2A 服务。

# writer_agent/card.json  —— 它的「名片」
{
  "name": "Writer Agent",
  "description": "把要点扩写成通顺的中文短文",
  "url": "http://localhost:8001/a2a",
  "version": "2026-07-19",
  "capabilities": { "streaming": false, "pushNotifications": false },
  "skills": [
    { "id": "expand_points", "name": "要点扩写",
      "description": "输入 3-5 个要点,输出一篇 300 字短文" }
  ],
  "authentication": { "schemes": ["None"] }
}
🔑 Agent Card 是整个协议的灵魂:它让「甲方」不用提前知道乙方内部怎么实现,只要读这张名片就能派活。这点和「微服务里的 OpenAPI 文档」一模一样。

Step 4:实现写作 Agent 的任务处理

4 接收任务、返回 Artifact

用 SDK 把 Agent Card 挂起来,并实现「收到要点 → 调 LLM 扩写 → 返回 Artifact」的逻辑(LLM 部分用任意 OpenAI 兼容接口即可):

# writer_agent/server.py(核心思路,伪代码贴近真实 API)
from a2a.server import A2AServer
from a2a.types import AgentCard, TaskStatus, Artifact
import json, openai

card = AgentCard.model_validate(json.load(open("card.json")))
server = A2AServer(agent_card=card)

@server.task_handler()
async def handle(task):
    points = task.message.content           # 甲方发来的要点
    # 调你自己的 LLM(此处用 OpenAI 兼容 SDK 示意)
    resp = openai.chat.completions.create(
        model="gpt-4o-mini",
        messages=[{"role":"user",
          "content": f"把以下要点扩写成通顺短文:\n{points}"}]
    )
    text = resp.choices[0].message.content
    return TaskStatus(state="completed",
                      artifacts=[Artifact(type="text", content=text)])

server.run(port=8001)

为什么用 Artifact 而不是直接返回字符串?因为真实任务里产出可能是文件、表格、图片。用统一的 Artifact 结构,甲方无论收到什么都能规范处理,系统才好扩展。

Step 5:写一个「研究 Agent」当甲方去调用它

5 用 Client 发现乙方、派发任务、回收结果

现在做一个「研究 Agent」:它先产出几个要点,再通过 A2A Client 把要点派给写作 Agent,最后把拿回来的短文打印出来。

# research_agent/client.py
from a2a.client import A2AClient

async def main():
    # 1) 发现乙方:读取它的 Agent Card
    client = A2AClient("http://localhost:8001/a2a")
    card = await client.discover_agent()
    print("发现协作方:", card["name"], "技能:", card["skills"])

    # 2) 研究 Agent 自己先想出要点
    points = "1) A2A 让 Agent 跨框架协作\n2) 与 MCP 互补\n3) 2026 已成事实标准"

    # 3) 派发任务,回收 Artifact
    task = await client.send_task({"message": {"role":"user","content": points}})
    print("写作 Agent 返回:\n", task.result)

import asyncio
asyncio.run(main())
🚀 到此你已经跑通最小多智能体协作:两个独立进程、不同角色、通过标准协议「对话」。把写作 Agent 换成搜索 Agent、数据分析 Agent,就能搭出真正的调研流水线。

Step 6:本地跑通并扩展成多 Agent 流水线

6 启动服务、验证、再加一层
# 终端 1:启动写作 Agent(乙方)
python writer_agent/server.py
# 终端 2:运行研究 Agent(甲方)
python research_agent/client.py

# 成功会看到:打印出「发现协作方」+ 一篇扩写短文

验证通过后,可以照同样套路加更多「乙方」——比如一个搜索 Agent(内部用 MCP 接搜索工具)、一个数据分析 Agent,让研究 Agent 当编排者统一派活:

研究 Agent(编排)
   ├─ A2A → 搜索 Agent  (内部 MCP 接搜索引擎)
   ├─ A2A → 写作 Agent  (本教程已跑通)
   └─ A2A → 数据 Agent  (内部 MCP 接数据库)

生产环境三件事:① 给 Agent Card 加上认证(Bearer / API Key),别用 None;② 把每个 Agent 跑成独立服务并加健康检查;③ 记录 A2A 通信日志做审计——外部 Agent 的输入一律当不可信,做好过滤。

常见问题速查

你遇到的现象大概率原因 & 解决
甲方连不上乙方乙方服务没起 / 端口写错 / 防火墙拦了
discover_agent 返回空Agent Card 路径不对(默认 /.well-known/agent.json 或 /a2a)
任务一直 input-required乙方在等补充信息,检查发的 message 字段格式
多个 Agent 怎么发现彼此小系统用固定 URL;企业级可部署 Agent 目录服务