bilibili

A2A 协议介绍

A2A(Agent-to-Agent,智能体间通信协议)是专门用于不同 AI 智能体(Agents)之间进行身份认证、能力协商、任务分发与数据交换的标准网络协议。

如果说 HTTP 是人类与网页通信的桥梁,API 是软件与软件对齐的规则,那么 A2A 就是 AI 与 AI 之间进行复杂协作的“通用语言”。

  • 调度 Agent 被称为 A2A Client 或者 Client Agent
  • 被调度 Agent 被称为 A2A Server 或者 Remote Agent

特点和使用场景

核心要点与特点

:::color1

  1. 能力宣告(Discovery & Handshake): 智能体可以向外“自我介绍”,广播自己擅长什么(如“精通机票预订”或“擅长代码分析”)。
  2. 上下文透传(Context Sharing): 在跨 Agent 协同传递任务时,保持短期记忆和上下文会话不丢失。
  3. 状态与回调(State Management): 支持长流程任务的异步回调、进度轮询与中断恢复。
  4. 统一鉴权(Auth & Security): 解决 Agent 代表用户去调用另一个 Agent 时的身份绑定与权限限制问题。

:::

典型使用场景

:::color2

  • 多智能体复杂任务协作(Multi-Agent System): 例如用户喊“帮我策划一次东京旅行”,主 Agent 将拆解后的任务分别分发给“机票 Agent”、“酒店 Agent”、“景点规划 Agent”协同完成。
  • 跨平台/跨厂商服务调用: 你的个人助理(如苹果 Siri 或 Google Gemini)需要调用第三方企业(如携程、滴滴)的专有 AI Agent 来完成具体交易。
  • 自动化企业工作流: 研发 Agent 编写完代码后,自动触发测试 Agent 进行 Code Review,通过后再通知部署 Agent 执行上线。

:::


A2A 协议协作流程

以下以一个“自动化旅游出行规划”场景,展示主智能体通过 A2A 协议与其他专业 Agent 的交互过程:

启动 Agents

启动 A2A Server

  1. 克隆马克的技术工作坊仓库,并进入 A2A 协议深度解析(1)\weather目录
  2. 执行 uv run .命令启动 Agent_(每一个 Agent 本质是一个内容符合 A2A 协议的 http 服务器)_

启动失败?

在这里插入图片描述

如果发生这种情况,则说明端口被占用 Agent 启动失败。这里的启动端口为 10000,要么更改端口,要么让端口空闲,重新启动 Agent。

启动 Host Agent

  1. 前往Google AI Studio获取 Google 的 API Key

  2. 克隆Google的a2a-samples仓库并进入 a2a-samples\demo\ui目录

  3. 创建 .env文件,并写入刚获取的 API Key

  4. 执行 uv run main.py启动 Agent

  5. 访问http://localhost:12000进入平台。

抓包分析 A2A 协议

抓包注册 A2A Server

  1. 启动 wireshark进行抓包

  1. 注册 A2A Server

  1. 过滤数据包并得到注册流
    在这里插入图片描述


在这里插入图片描述
在这里插入图片描述

  1. 分析注册流

请求包详细分析

GET /.well-known/agent-card.json HTTP/1.1
Host: localhost:10001
User-Agent: python-requests/2.34.2
Accept-Encoding: gzip, deflate
Accept: */*
Connection: keep-alive

  • 目标路径**/.well-known/agent-card.json**:符合 A2A 协议规范。A2A 规定 Server 应在此 URI 暴露其配置名片,以便外部 Client 或 Registry 进行自动化发现。
  • **客户端 ****User-Agent: python-requests/2.34.2**:表明发起发现请求的是一个基于 Python(如使用了 A2A Python SDK 或自定义脚本)的 Agent 客户端。
  • **主机与端口 ****localhost:10001**:说明目前处于本地开发或微服务容器间网络调测阶段。

响应包与 AgentCard JSON 数据结构解析

HTTP/1.1 200 OK
date: Wed, 22 Jul 2026 06:42:40 GMT
server: uvicorn
content-type: application/json

  • **服务器引擎 ****uvicorn**:说明该 A2A Server 是基于 Python 异步框架(如 FastAPI、Starlette、A2A Python SDK 内置 Web 服务)搭建的。
  • 响应负载分析(JSON Payload)
    响应体遵循了 A2A Spec v0.3 / v1.0 规范的 AgentCard 字段定义
{
    "capabilities": { "streaming": false },
    "defaultInputModes": ["text"],
    "defaultOutputModes": ["text"],
    "description": "提供天气相关的查询功能",
    "name": "天气 Agent",
    "preferredTransport": "JSONRPC",
    "protocolVersion": "0.3.0",
    "skills": [
        {
            "description": "给出某地的天气预告",
            "examples": ["给我纽约未来 7 天的天气预告"],
            "id": "天气预告",
            "name": "天气预告",
            "tags": ["天气", "预告"]
        },
        {
            "description": "给出某地当前时间的空气质量报告,不做预告",
            "examples": ["给我纽约当前的空气质量报告"],
            "id": "空气质量报告",
            "name": "空气质量报告",
            "tags": ["空气", "质量"]
        }
    ],
    "url": "http://127.0.0.1:10001",
    "version": "1.0.0"
}
字段名 当前抓包中的值 协议语义解释
protocolVersion "0.3.0" 声明遵循的 A2A 协议版本号为 0.3.0。
version "1.0.0" 该 Agent 业务逻辑或服务自身的软件版本号。
name "...... Agent" (示例脱敏) Agent 的可读名称,向人类或调度器展示。
description "..................." Agent 的整体功能简介。
url "[http://127.0.0.1:10001](http://127.0.0.1:10001)" 该 Agent 接收实际 Task / Message 请求的基础 Endpoint。
preferredTransport "JSONRPC" 告诉 Client 后续的任务调用优先选择 JSON-RPC 2.0 协议进行传输。
capabilities {"streaming": false} 声明 Agent 的全局能力。当前 streaming: false 表示不支持流式响应(如 SSE),仅支持同步/异步完整返回。
defaultInputModes ["text"] 默认支持的输入 MIME 类型/模式(文本输入)。
defaultOutputModes ["text"] 默认支持的输出 MIME 类型/模式(文本输出)。
skills [ { "id": "...", "name": "...", "tags": [...], "examples": [...] }, ... ] 能力/技能列表。列出了该 Agent 暴露的具体子功能(Skill),包括 Prompt 示例 (examples) 和检索标签 (tags),供主控 Agent 判别是否协同。
响应体无数据?
{
    "capabilities": { "streaming": false },
    "defaultInputModes": ["text"],
    "defaultOutputModes": ["text"],
    "description": ".................................",
    "name": "...... Agent",
    "preferredTransport": "JSONRPC",
    "protocolVersion": "0.3.0",
    "skills": [
        {
            "description": "...........................",
            "examples": [".................. 7 .................."],
            "id": "............",
            "name": "............",
            "tags": ["......", "......"]
        },
        {
            "description": "............................................................",
            "examples": ["......................................."],
            "id": "..................",
            "name": "..................",
            "tags": ["......", "......"]
        }
    ],
    "url": "http://127.0.0.1:10001",
    "version": "1.0.0"
}

如果抓到的响应体是这样子的,说明数据脱敏,访问http://127.0.0.1:10001/.well-known/agent-card.json得到响应体

也可以将显示格式进行转换为 RAW 或者 UTF-8

在这里插入图片描述

抓包分析 Host Agent 调度 A2A Server

  1. 保持 wireshark 开启状态
  2. 发送天气相关请求

  1. 过滤数据包并得到调度流

  1. 分析数据包

请求包解析

POST / HTTP/1.1
Host: 127.0.0.1:10001
Content-Type: application/json
User-Agent: python-httpx/0.28.1

JSON-RPC Payload 核心字段分解:

{
  "id": "744647dc-3b51-4e64-b688-6d552ee6ef0e",
  "jsonrpc": "2.0",
  "method": "message/send",
  "params": {
    "configuration": { "acceptedOutputModes": [], "blocking": true },
    "message": {
      "contextId": "0ccdfd0c-7204-42fb-9ec4-fc9beb0b926b",
      "kind": "message",
      "messageId": "e432ce4c-c641-4502-a009-0681d507788e",
      "parts": [
        {
          "kind": "text",
          "text": "纽约明天(请以明天日期)的天气情况如何?"
        }
      ],
      "role": "user"
    }
  }
}

:::color1

  • **jsonrpc**** & ****id**:标准的 JSON-RPC 2.0 格式(ID 为 744647dc-3b51-4e64-b688-6d552ee6ef0e),用于匹配异步或同步的请求与响应。
  • **method**: "message/send":A2A 协议规范中定义的标准 API 方法,用于向 Agent 提交一条用户消息。
  • params.configuration
  • "blocking": true:客户端显式要求阻塞式等待(同步响应),即 Server 必须等任务完全执行结束后再返回响应,而不是立即返回一个 Pending 状态的 Task。
  • params.message
  • contextId0ccdfd0c-7204-42fb-9ec4-fc9beb0b926b(会话/上下文 ID),用于多轮对话的追踪。
  • parts:包含了标准的多模态消息结构(此处为单段文本 text: “纽约明天(请以明天日期)的天气情况如何?”)。

:::


响应包解析

HTTP/1.1 200 OK
date: Wed, 22 Jul 2026 07:57:03 GMT
content-type: application/json

JSON-RPC Result 核心字段分解:

{
  "id": "744647dc-3b51-4e64-b688-6d552ee6ef0e",
  "jsonrpc": "2.0",
  "result": {
    "artifacts": [
      {
        "artifactId": "1d3939c1-4c88-420c-a0b7-f61dff19652d",
        "name": "天气查询结果",
        "parts": [
          {
            "kind": "text",
            "text": "未来 3 天的天气如下:1. 明天(2025年6月1日):晴天;2. 后天(2025年6月2日):小雨;3. 大后天(2025年6月3日):大雨。"
          }
        ]
      }
    ],
    "contextId": "0ccdfd0c-7204-42fb-9ec4-fc9beb0b926b",
    "history": [
      {
        "contextId": "0ccdfd0c-7204-42fb-9ec4-fc9beb0b926b",
        "kind": "message",
        "messageId": "e432ce4c-c641-4502-a009-0681d507788e",
        "parts": [
          {
            "kind": "text",
            "text": "纽约明天(请以明天日期)的天气情况如何?"
          }
        ],
        "role": "user",
        "taskId": "674ed6af-dd27-4c9d-abfa-bdffab019603"
      }
    ],
    "id": "674ed6af-dd27-4c9d-abfa-bdffab019603",
    "kind": "task",
    "status": { "state": "completed" }
  }
}

:::color2

  • status.state: "completed":表明服务端已顺利处理完该任务。
  • id** (TaskId)**:674ed6af-dd27-4c9d-abfa-bdffab019603,服务端为本次生成任务分配的全局唯一标识。
  • artifacts** (产出物)**:
    A2A 协议中用于承载 Agent 最终输出结果的核心字段:
  • name: "天气查询结果"
  • parts: 返回了具体的查询文本内容。
  • history:回传并确认了本次触发该 Task 的原始消息上下文。

:::

核心概念

结合前面两个阶段的报文数据,我们可以清晰地还原出 A2A(Agent-to-Agent)协议 的核心领域模型。

在 A2A 协议中,AgentCard、Task、Message、Part、Artifact 构成了 Agent 之间相互发现、协作和交付结果的基础骨架。

概念 层次/定位 相当于经典 HTTP/Web 概念 核心职责
AgentCard 服务级 (Service Level) OpenAPI Specs / WSDL 告诉别人“我是谁、能干啥、怎么调”
Task 实例级 (Instance Level) 线程/后台 Job (Async Job) 控制“事情处理得怎么样了(生命周期)”
Message 交互级 (Interaction Level) 聊天记录 (Chat Item) 传递“对话与交互指令”
Artifact 成果级 (Output Level) 导出文件 / 最终 Response Body 交付“最终干出来的实体成果”
Part 原子级 (Data Level) MIME Type Body / 多模态 Block 承载“具体的文本/图片/二进制数据”

AgentCard(Agent 名片)

📌 定义:AgentCard 是 Agent 向外暴露的静态自描述元数据元组。它放置在符合 RFC 5785 规范的固定路径 /.well-known/agent-card.json 下,类似于 API 界的 OpenAPI/Swagger 文档或微服务中的服务注册信息。

🔍 详解与实战映射

  • 核心作用:服务发现与能力协商。客户端在发起任何调用前,必须先拉取 AgentCard,以此决定使用什么协议通信、传入什么格式的数据、调用哪些技能。
  • 报文对应
  • 传输与接口协商url ([http://127.0.0.1:10001](http://127.0.0.1:10001)) + preferredTransport (JSONRPC),告诉客户端后续通过该 URL 发送 JSON-RPC 请求。
  • 能力声明capabilities.streaming: false 说明该 Agent 不支持流式输出,客户端必须使用阻塞/同步方式(blocking: true)获取结果。
  • 技能列表skills 数组,包含了该 Agent 能处理的具体任务(如天气查询),每个 Skill 包含 iddescriptionexamples

Task(任务)

📌 定义:Task 是 A2A 协议中有状态的执行单元与生命周期容器。当客户端通过 message/send` 发起一个需要 Agent 计算或处理的请求时,服务端会为其分配或关联一个 Task。

🔍 详解与实战映射

  • 核心作用:追踪一次调用的处理状态、上下文关系及最终产出。
  • 报文对应
  • 在阶段二响应的 result 根节点中,kind: "task" 表明返回的核心对象就是一个 Task。
  • id (674ed6af-...):Task 的唯一标识,用于异步轮询或后续状态查询。
  • status.state ("completed"):表示任务当前的生命周期状态(常见的状态包括:workingcompletedfailedinput_required 等)。
  • contextId (0ccdfd0c-...):将 Task 绑定到某条特定的会话上下文链条上。

Message(消息)

📌 定义:Message` 是客户端与服务端之间、或 Agent 与 Agent 之间的单次对话交互载体。它记录了“谁(role)在什么上下文(contextId)里说了什么(parts)”。

🔍 详解与实战映射

  • 核心作用:表达交互意图或提供对话上下文,是触发 Task 状态更新的“输入”。
  • 报文对应
  • 请求端params.message 中包含 kind: "message", role: "user", messageId: "e432ce4c-..."
  • 响应端:在 result.history 数组中,服务端会将本次接收到的 Message 原样归档,并补充关联的 taskId

Artifact(产出物 / 构件)

📌 定义:Artifact` 是 Task 执行完成后生成的结构化最终业务成果。它不同于中间的对话过程,代表了可以直接交付给用户或其他 Agent 使用的“确定性产物”(如生成的代码文件、查询到的天气结果、渲染的图表数据等)。

🔍 详解与实战映射

  • 核心作用:将 Agent 的“思考/执行过程”与“交付成果”进行解耦,方便上层业务直接提取结果。
  • 报文对应
  • 阶段二响应中的 result.artifacts 数组:
"artifacts": [{
  "artifactId": "1d3939c1-4c88-420c-a0b7-f61dff19652d",
  "name": "天气查询结果",
  "parts": [...]
}]
  • 一个 Task 可以产生 0 个或多个 Artifact。此处成功生成了一个名为“天气查询结果”的构件。

Part(数据分块 / 多模态原子)

📌 定义:Part 是 A2A 协议中承载具体内容的最小数据单元。不管是 Message(输入)还是 Artifact(输出),其具体的内容都是由一个或多个 Part 组成的。

🔍 详解与实战映射

  • 核心作用:支持多模态(Multimodal)交互。一个 Message 或 Artifact 可以同时包含 text(文本)、image(图片)、file(文件)等多个 Part
  • 报文对应
  • 在 Message 中
    "parts": [{"kind": "text", "text": "纽约明天...的天气情况如何?"}]
  • 在 Artifact 中
    "parts": [{"kind": "text", "text": "未来 3 天的天气如下:..."}]

运行链路流程图

Agent 注册阶段

用户问答阶段

Logo

这里是“一人公司”的成长家园。我们提供从产品曝光、技术变现到法律财税的全栈内容,并连接云服务、办公空间等稀缺资源,助你专注创造,无忧运营。

更多推荐