← 返回教程库

A2A 协议:让 Agent 之间互相发现与委派

最后更新 2026-06-21
你将学到
  • 搞懂 A2A 要解决的问题:跨 Agent、跨框架的协作与委派
  • 看懂 agent card 是什么、放在哪、声明了哪些关键字段
  • 跑通"拉对方 card → 查兼容 → 发任务"这条发现到委派的链路
  • 彻底分清 MCP(给 Agent 接工具)和 A2A(让 Agent 之间协作)
  • 拿到"什么时候用 A2A、什么时候一个函数调用就够"的判断

上一节我们把一个 Agent 内部的脏活折叠掉了。但真实世界里,你常常需要的不是"我自己的 Agent 多开几个子代理",而是让我的 Agent 去用别人家的 Agent——比如你的客服 Agent 想把一笔退款丢给财务团队那套你完全没参与开发、用的还是另一个框架的报销 Agent。

问题来了:你的 Agent 怎么知道对方会干什么怎么触达它要不要鉴权用什么数据格式A2A(Agent-to-Agent)协议就是为这件事生的:它定义了一套 Agent 之间互相发现、互相委派的通用规矩,让不同团队、不同框架做出来的 Agent 也能搭上话。 这一节我们把它讲透。

这篇适合谁:已经能写单个 Agent、开始要让多个 Agent(尤其是别人做的)协作的人。读完你能看懂一张 agent card,也能写出"发现→委派"的骨架。


钩子:没有 A2A 时,跨 Agent 协作有多难

设想没有统一协议,你的 Agent 要调别人家 Agent,得问一圈:

  • 它部署在哪个地址?走 HTTP 还是别的?
  • 它到底能干哪几件事?参数怎么传?
  • 要不要 token?哪种鉴权?
  • 它回我的是纯文本、JSON、还是流式?

每对接一个 Agent,都要人肉去读文档、写一套专属适配。对接十个 Agent,就是十套互不相通的胶水代码。 这正是当年各种 API 集成的老问题,只不过主角换成了 Agent。

A2A 的解法和"网站有 robots.txt、API 有 OpenAPI 描述"是同一个思路:让每个 Agent 自报家门——发布一张机器可读的"名片",把上面那些问题一次性答清楚。 这张名片就叫 agent card


最小可用:agent card 长什么样

agent card 是一份放在已知 URL 上的 JSON,声明这个 Agent 的身份、能力、怎么触达、怎么鉴权、用什么数据格式。别的 Agent 想找它合作,先去拉这张 card 读一读,就知道能不能、怎么合作。

下面是一张说明性的 agent card 示例(字段命名以官方规范为准,这里重在让你看懂"一张名片该答清哪些问题"):

{
  "name": "报销审批 Agent",
  "description": "处理员工报销单的提交、审批与状态查询",
  "url": "https://finance.example.com/a2a",
  "version": "1.x",
  "capabilities": {
    "streaming": true
  },
  "authentication": {
    "schemes": ["Bearer"]
  },
  "defaultInputModes": ["text", "application/json"],
  "defaultOutputModes": ["application/json"],
  "skills": [
    {
      "id": "submit_reimbursement",
      "name": "提交报销单",
      "description": "提交一笔报销,返回单据号与初步审批结果",
      "tags": ["finance", "reimbursement"]
    },
    {
      "id": "query_status",
      "name": "查询报销状态",
      "description": "按单据号查询当前审批进度"
    }
  ]
}

读这张名片,你的 Agent 一眼就能回答前面那几个问题:它叫报销审批 Agent、走 https://finance.example.com/a2a、要 Bearer token、收 text 或 JSON、回 JSON、会两个技能(提交、查状态)。对接成本从"读一篇文档"降到了"解析一个 JSON"。

⚠️ 字段层面:A2A 仍在演进,具体字段名、card 的标准存放路径、请求/响应的精确结构以官方规范为准。本节给的是骨架与思路,不是逐字段的 API 文档——拿去对接前务必核对官方最新定义。


原理:发现 → 查兼容 → 委派,三步走

A2A 协作的核心链路就三步,记住它你就抓住了主干:

  1. 发现(Discovery):你的 Agent 知道对方的"已知 URL",去把 agent card 拉下来。已知 URL 可以是配置里写死的、注册中心查到的,或对方告诉你的。
  2. 查兼容(Match):解析 card,确认对方有你要的技能(skill id 对得上)、鉴权你能满足(有没有那个 token)、数据格式你能处理(它收/回的模式你接得住)。对不上就别发了。
  3. 委派(Delegate):兼容就按 card 声明的地址和格式,发一个任务请求过去,拿回结果。

类比找外包:先要到对方名片(发现)→ 看看人家会不会这活、收不收你(查兼容)→ 把活派过去并验收(委派)。


进阶:一段"发现→委派"的可读骨架

下面是这条链路的可读代码骨架。请求/响应的精确结构以官方为准,这里聚焦把三步的逻辑串清楚:

import requests  # 演示用;实际请按官方 SDK/规范调整端点与负载结构

def fetch_agent_card(base_url: str) -> dict:
    """第1步 发现:从对方的已知 URL 拉 agent card(确切路径以官方为准)"""
    resp = requests.get(f"{base_url}/.well-known/agent-card", timeout=10)
    resp.raise_for_status()
    return resp.json()

def is_compatible(card: dict, need_skill: str, my_token: str | None) -> bool:
    """第2步 查兼容:要的技能在不在、鉴权我能不能满足"""
    skill_ids = {s["id"] for s in card.get("skills", [])}
    if need_skill not in skill_ids:
        return False
    schemes = card.get("authentication", {}).get("schemes", [])
    if schemes and not my_token:        # 对方要鉴权但我没 token
        return False
    return True

def delegate(card: dict, skill_id: str, payload: dict, my_token: str | None) -> dict:
    """第3步 委派:按 card 声明的地址/鉴权发任务(负载结构以官方为准)"""
    headers = {"Authorization": f"Bearer {my_token}"} if my_token else {}
    resp = requests.post(
        card["url"],
        json={"skill": skill_id, "input": payload},   # 真实字段名以官方协议为准
        headers=headers, timeout=30,
    )
    resp.raise_for_status()
    return resp.json()

# —— 串起来:我的客服 Agent 想把一笔报销委派出去 ——
card = fetch_agent_card("https://finance.example.com")
if is_compatible(card, need_skill="submit_reimbursement", my_token=MY_TOKEN):
    result = delegate(card, "submit_reimbursement",
                      {"amount": 320, "reason": "打车", "user": "老王"}, MY_TOKEN)
    print("委派成功:", result)
else:
    print("对方 Agent 不兼容这次委派,换一个或本地处理")

逐步预期

  • fetch_agent_card 拿回那张 JSON 名片。
  • is_compatible 确认 submit_reimbursement 在它的 skills 里、且你有 token → 返回 True。
  • delegate 按 card 里的 url 和 Bearer 鉴权发任务,拿回单据号一类的结果。
  • 任一步对不上(技能没有、没 token、格式不匹配),就走 else 分支,不硬发——这正是 card 的价值:先看名片再动手,别瞎试。

增量一:MCP(给工具)vs A2A(agent 间),别再混

这俩最容易搞混,一句话钉死区别:

  • MCP 是给一个 Agent 接"工具/数据源"的——比如让你的 Agent 能读数据库、调某个 API、用某个本地能力。它面对的是"死的、被动的能力",你调它、它返回,不会自己思考。
  • A2A 是让"两个 Agent 之间协作"的——对方是一个活的、会自己规划和决策的 Agent,你不是调它的某个函数,而是把一个目标委派给它,让它自己想办法办完
维度 MCP A2A
对接的是 工具 / 数据源(被动) 另一个 Agent(主动、会决策)
你给它的是 一次具体调用 一个待办目标,由它自主完成
类比 给员工配一把电钻 把一摊活外包给另一个团队
典型场景 让 Agent 能查库存 让客服 Agent 把退款甩给财务 Agent

口诀:MCP 给你的 Agent 配工具,A2A 让你的 Agent 找同行搭把手。 两者不打架,常常一起用——你的 Agent 用 MCP 接自己的工具,同时用 A2A 把超纲的活委派给别的 Agent。


增量二:agent card 字段速查 + 什么时候根本不用 A2A

一张 card 该答清的字段(命名以官方为准)

  • name / description:它是谁、干啥的。
  • url:往哪发任务。
  • capabilities:支不支持流式等特性。
  • authentication:要不要鉴权、哪种。
  • defaultInputModes / defaultOutputModes:收什么、回什么格式。
  • skills[]:会哪几件事,每件有 id/name/description/tags——这是查兼容时最关键的字段

什么时候用 A2A:对方是你管不到、可能换框架/换实现、由别的团队维护的 Agent,而且你想委派的是"一个目标"而非"一次函数调用"。跨组织、跨技术栈、对方会自主决策——这是 A2A 的主场。

什么时候一个函数调用就够(别为 A2A 而 A2A):

  • 那段逻辑就在你自己的代码库里,直接 import 调函数最省事。
  • 它本质是一个工具/一次确定的调用,没有"自主决策"成分——那是 MCP 或普通函数的活。
  • 调用方和被调方永远一起部署、一起发版——加一层协议只是徒增复杂度和网络往返。

一句话:A2A 是为"跨边界、对方是个会自己拿主意的 Agent"准备的;同进程里的确定逻辑,老老实实函数调用。


避坑:故障排查表

现象 原因 怎么破
拉 card 404 card 路径/已知 URL 用错了 card 的标准存放路径以官方规范为准,核对后再拉
委派 401/403 鉴权方案没对上 card 声明 先读 card 的 authentication,按它要求带 token
发过去对方不认参数 没按 card 的输入模式/技能 schema 来 委派前查 defaultInputModes 和对应 skill 定义
字段名对不上官方 照搬本文示例字段当真 本文字段为说明性,对接前以官方最新规范核对
明明自己能干却绕一圈 A2A 把同进程逻辑也协议化了 同部署的确定逻辑直接函数调用,别上 A2A
拿工具调用当 Agent 委派 混淆了 MCP 和 A2A 被动工具用 MCP,活的 Agent 才用 A2A

动手挑战

  1. 给你自己的 Agent 写一张 agent card(JSON),把它会的两三件事写成 skills,鉴权、输入输出格式都填上。给一个同事看,他能不能光读这张 card 就知道怎么调你?
  2. 实现本节的 is_compatible:传入一张 card 和你要的 skill,正确判断兼容与否。故意传一个对方没有的 skill,确认它返回 False 且不发请求。
  3. 进阶:查阅官方规范,把骨架里标注"以官方为准"的端点路径和负载结构改成真实的,对着一个示例 Agent 跑通一次真正的发现→委派。

小结 · 你现在掌握了什么

  • 你明白了 A2A 要解决的是跨 Agent、跨框架、跨团队的协作——让别人家的 Agent 也能搭上话。
  • 你看懂了 agent card:一份放在已知 URL 的 JSON 名片,声明身份/能力/触达/鉴权/数据格式。
  • 你能跑通"发现→查兼容→委派"三步,并且懂得对不上时不硬发。
  • 你彻底分清了 MCP(给 Agent 配工具)A2A(让 Agent 之间协作)
  • 你拿到了"跨边界且对方会自主决策才用 A2A,同进程确定逻辑就函数调用"的判断。

记住:card 的意义是"先看名片再动手",把跨 Agent 对接从读文档降级成解析 JSON。 至于精确字段和端点,永远以官方规范为准

下一步:Agent 之间能协作了,下一节我们把 Agent 接到用户真正在用的渠道——微信、飞书、Slack。看 多渠道接入;想看全貌就对照三支柱路线图。基础没打牢先补 AI Agent 是什么

👉 看看 AI 数字员工落地指南,或了解 数字员工搭建实战课。需要为企业落地方案,欢迎找我们聊 企业服务

📄 来源 / 自校链接

本文为学习整理,关键步骤与代码请结合下列官方来源验证。

内容有错、看不懂、或想看下一期?告诉我们 →

本文为学习与落地整理,AI 工具与平台更新较快,关键步骤请结合官方最新资料验证。见免责声明