1. 谷歌A2A协议到底是什么,为什么智能体协作绕不开它
你可能已经习惯了让一个 AI 帮你写代码、查资料、做表格,但真实业务里更常见的情况是:一个任务需要好几个 AI 分工完成。比如招聘流程里,一个智能体筛简历,一个约面试,一个做背调,它们之间怎么对话、怎么交接任务、怎么确认对方干完了?这就是谷歌 A2A 协议要解决的问题。
A2A 全称 Agent-to-Agent Protocol,是谷歌在 2025 年 4 月发布的开放协议,核心目标是让不同厂商、不同框架构建的 AI 智能体能够互相通信、安全交换信息、协调行动。你可以把它理解成智能体世界的“HTTP 协议”——它不关心你内部用什么模型、什么框架,只规定智能体之间怎么打招呼、怎么派活、怎么汇报进度。
它建立在 HTTP、SSE、JSON-RPC 这些成熟标准之上,所以企业现有 IT 栈很容易接进去。协议里有几个关键概念:Agent Card(智能体名片,用 JSON 描述自己的能力)、Task(任务对象,有完整的生命周期状态)、Message 和 Artifact(消息与成果)。客户端智能体负责构思和传达任务,远程智能体负责执行,两者通过 A2A 协议完成协作。
适合谁看?如果你在做多智能体系统、企业工作流自动化,或者想把自家 AI 能力封装成可被其他智能体调用的服务,A2A 就是你需要理解的互操作性层。而实际接入时,统一管理多个模型的 Key 和 API 通道会变成一个绕不开的工程问题,这也是我下面要结合 TaoToken 来讲的部分。
2. TaoToken 统一 Key 与 API 通道的前置准备
在真正跑 A2A 调用之前,得先把“通道”铺好。A2A 协议本身是智能体之间的通信规范,但每个远程智能体背后往往挂着不同厂商的模型服务,Key 分散、Base URL 不统一、额度各管各的,调试起来很碎。我的做法是用 TaoToken 做统一入口,把模型调用收敛到一套 Key 和一套 API 地址上。
TaoToken 的定位是统一的大模型 API 通道,官网在 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,API 入口是 https://taotoken.net/api 。你需要先拿到一个 API Key,然后所有模型请求都走这个 Base URL。这样做的好处是:A2A 里每个远程智能体无论背后是哪个模型,客户端侧只需要维护一套鉴权信息,排障时也只需要看一个通道的日志。
具体准备三步。第一步,打开 https://taotoken.net/api-keys 创建 API Key,复制保存,注意它只显示一次。第二步,确认你要用的模型 ID,比如 claude-sonnet-4-20250514、gpt-4o 这类,模型 ID 要和你实际调用的服务一致。第三步,把 Base URL 统一设为 https://taotoken.net/api ,后面所有配置里的 base_url 都填这个。
这里有个容易踩的坑:很多人把 A2A 协议本身和模型 API 混在一起理解。A2A 管的是智能体之间的任务流转,模型 API 管的是单个智能体内部怎么调模型。两者是不同层的东西。TaoToken 解决的是下层模型调用的统一接入,A2A 解决的是上层智能体之间的协作。你把下层通道统一了,上层 A2A 的调试才会干净。
如果你打算长期跑编码类或 Agent 类任务,可以了解下 Coding Plan( https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding-plan&utm_campaign=rewrite ),它更适合持续性的智能体工作负载。接入文档在 https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite ,配置细节可以对照看。
3. 可复制的 A2A 调用配置与 Agent Card 示例
这一节给你可以直接抄的配置。A2A 的核心是 Agent Card,它是一个 JSON 文件,通常放在/.well-known/agent.json路径下,用来声明这个智能体能做什么、怎么鉴权、支持哪些能力。下面是一个最小可用的 Agent Card 示例,注意里面的鉴权部分我用了 TaoToken 的统一 Key 思路:
{ "name": "resume-screener-agent", "description": "负责筛选候选人简历的远程智能体", "url": "https://your-agent-host.example.com/a2a", "version": "1.0.0", "capabilities": { "streaming": true, "pushNotifications": false }, "defaultInputModes": ["text"], "defaultOutputModes": ["text", "data"], "skills": [ { "id": "screen-resume", "name": "简历筛选", "description": "根据岗位要求对简历进行匹配度打分", "inputModes": ["text"], "outputModes": ["data"] } ], "authentication": { "schemes": ["apiKey"], "apiKey": { "headerName": "Authorization", "valuePrefix": "Bearer " } } }客户端智能体拿到这张名片后,就知道该往哪个 URL 发任务、用什么鉴权方式。接下来是客户端侧调用远程智能体的配置片段。如果你用 Python 的 requests 或 httpx,核心是构造 JSON-RPC 请求体,走 TaoToken 统一通道时,模型调用部分这样配:
import httpx import json TAOTOKEN_BASE_URL = "https://taotoken.net/api" TAOTOKEN_API_KEY = "sk-你的TaoToken密钥" MODEL_ID = "claude-sonnet-4-20250514" def call_model(prompt: str) -> str: headers = { "Authorization": f"Bearer {TAOTOKEN_API_KEY}", "Content-Type": "application/json" } payload = { "model": MODEL_ID, "messages": [ {"role": "user", "content": prompt} ], "max_tokens": 1024 } resp = httpx.post( f"{TAOTOKEN_BASE_URL}/v1/messages", headers=headers, json=payload, timeout=60 ) resp.raise_for_status() return resp.json()["content"][0]["text"]如果你用的是 OpenAI 兼容格式,把路径换成/v1/chat/completions,payload 里的messages结构保持一致即可。A2A 的任务派发部分则是另一个 JSON-RPC 调用,发到远程智能体的url上,方法名通常是tasks/send或tasks/sendSubscribe(流式)。下面是一个任务派发的请求体示例:
{ "jsonrpc": "2.0", "id": "task-001", "method": "tasks/send", "params": { "id": "task-001", "message": { "role": "user", "parts": [ { "type": "text", "text": "请筛选这份简历,岗位要求是三年以上后端经验" } ] } } }注意parts里可以放 text、file、data 三种类型,这就是 A2A 支持多模态和结构化数据的地方。远程智能体处理完后,会返回一个 Task 对象,里面包含状态和 artifact。状态流转是submitted -> working -> [input-required] -> completed/canceled/failed,你可以根据状态决定下一步。
配置时把 Base URL、Key、Model ID 三件套对齐:Base URL 用https://taotoken.net/api,Key 用你在 API Keys 页面创建的,Model ID 用实际模型名。这三样在 A2A 的每个远程智能体里可能不同,但客户端侧统一走 TaoToken 后,你只需要维护一套。
4. 验证 A2A 连通性与成功结果的实际步骤
配置写完,下一步是验证。我一般分两层验:先验模型通道通不通,再验 A2A 任务能不能跑通。第一层,用 curl 直接打 TaoToken 的模型接口,确认 Key 和 Base URL 没问题:
curl -X POST https://taotoken.net/api/v1/messages \ -H "Authorization: Bearer sk-你的TaoToken密钥" \ -H "Content-Type: application/json" \ -d '{ "model": "claude-sonnet-4-20250514", "messages": [{"role": "user", "content": "回复ok"}], "max_tokens": 16 }'如果返回里能看到content字段和正常的文本,说明通道是通的。这一步过了,再验 A2A。先请求远程智能体的 Agent Card,确认名片能拿到:
curl https://your-agent-host.example.com/.well-known/agent.json拿到名片后,发一个最小任务:
curl -X POST https://your-agent-host.example.com/a2a \ -H "Content-Type: application/json" \ -d '{ "jsonrpc": "2.0", "id": "task-001", "method": "tasks/send", "params": { "id": "task-001", "message": { "role": "user", "parts": [{"type": "text", "text": "测试任务"}] } } }'成功的结果长这样:返回 JSON 里有result字段,里面包含id、status(状态是completed或working)、以及artifacts数组。如果状态是working且你用了tasks/sendSubscribe,你会通过 SSE 持续收到TaskStatusUpdateEvent和TaskArtifactUpdateEvent,直到任务完成。
实测下来,最容易出问题的是流式部分。SSE 连接需要客户端保持长连接,如果你用 httpx,记得设置timeout=None或足够大的值,否则任务还没跑完连接就断了。另外,Agent Card 里的capabilities.streaming如果是 false,你就不能用sendSubscribe,只能用send轮询状态。
验证通过后,你可以把整个链路串起来:客户端智能体先调模型生成任务描述,再通过 A2A 派发给远程智能体,远程智能体内部再调模型处理,最后把 artifact 回传。这条链路里,TaoToken 负责的是每个智能体内部的模型调用,A2A 负责的是智能体之间的任务流转,两者各司其职。
5. 本篇常见报错排查:401、local proxy failed、reading choices、OAuth
这一节把我在接入过程中真实遇到的报错和排查路径列出来,你对照着看。
401 Unauthorized。这个最常见,九成是 Key 问题。先确认你请求头里的Authorization格式是Bearer sk-xxx,注意 Bearer 后面有一个空格。然后确认 Key 没有过期、没有被删。如果你在 A2A 的 Agent Card 里配了apiKey方案,检查headerName和valuePrefix是否和实际请求一致。还有一种情况是 Base URL 写错了,比如漏了/api或者多写了/v1,导致请求打到了错误的路由,也会返回 401。
local proxy failed。这个报错通常出现在你本地起了代理或者环境变量里配了HTTP_PROXY、HTTPS_PROXY,但代理不可用。排查方法是先检查环境变量,把代理相关变量临时清掉再试。如果你确实需要走网络配置,确保代理地址和端口正确。这个报错和 A2A 协议本身无关,是网络层的问题。
reading choices 相关报错。这个一般出现在 OpenAI 兼容格式的响应解析里,报错信息类似reading 'choices'或Cannot read properties of undefined (reading 'choices')。原因是响应体结构和你预期的不一致,比如你按 OpenAI 格式去取choices[0].message.content,但实际返回的是 Anthropic 格式的content[0].text。解决办法是确认你调用的模型和接口路径匹配:走/v1/messages就用 Anthropic 格式解析,走/v1/chat/completions就用 OpenAI 格式解析。TaoToken 两种格式都支持,但你不能混用。
OAuth 相关报错。如果你在 Agent Card 里声明了 OAuth 鉴权,但客户端没有正确走 token 获取流程,会报 401 或 403。排查时先确认 OAuth 的 token endpoint 是否可达,client_id 和 client_secret 是否正确,scope 是否包含所需权限。如果只是内部调试,建议先用 apiKey 方案跑通,再换 OAuth。
另外提醒一点:A2A 的任务状态如果长时间停在working,先检查远程智能体是否真的在处理,还是卡在了模型调用上。这时候去看 TaoToken 通道的请求日志,确认模型调用有没有正常返回。如果模型调用超时,A2A 任务也会一直挂着。
6. 从统一通道到多智能体协作的接入路径
把上面的步骤串起来,你的接入路径其实很清晰:先用 TaoToken 把模型调用的 Key、Base URL、Model ID 三件套统一,确保单个智能体的模型调用是稳的;然后按 A2A 规范给每个智能体写 Agent Card,声明能力和鉴权方式;接着用 JSON-RPC 的tasks/send或tasks/sendSubscribe派发任务,根据 Task 状态流转做后续处理;最后用 curl 或代码验证整条链路。
如果你要快速验证模型通道,可以直接去模型对话页面( https://taotoken.net/model-chat?utm_source=taotoken_aicg_blog_end&utm_content=model-chat&utm_campaign=rewrite )发一条消息,确认 Key 和模型 ID 能用。接入文档在 https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite ,里面有各语言的配置示例。长期跑编码或 Agent 任务的话,Coding Plan( https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding-plan&utm_campaign=rewrite )会更合适。API Key 管理在 https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api-keys&utm_campaign=rewrite ,控制台在 https://taotoken.net/console?utm_source=taotoken_aicg_blog_end&utm_content=console&utm_campaign=rewrite 。
A2A 协议的价值在于它把智能体之间的协作标准化了,而 TaoToken 这类统一通道的价值在于它把模型调用的碎片化收敛了。两者结合,你才能把精力放在任务编排和业务逻辑上,而不是耗在 Key 管理和格式适配上。