1. 从两个真实场景说起为什么单靠 MCP 不够用如果你最近在折腾智能体大概率已经踩过这样一个坑用 MCP 把工具接得明明白白单个 Agent 查数据库、读文件、调 API 都很顺可一旦任务需要「多个 Agent 分工」整个链路就散了。比如让一个 Agent 负责收集资料、另一个负责写报告、第三个负责校对你会发现它们之间没有统一的沟通方式只能靠你在代码里硬编码调用顺序改一个环节就得动全身。这正是 Google 在 2025 年 4 月推出 A2AAgent2Agent协议想解决的问题。A2A 是一套开源的智能体通信标准核心是让不同框架、不同厂商开发的 Agent 能互相发现、互相派活、互相回传结果。而 MCPModel Context Protocol解决的是另一个层面的事——单个 Agent 怎么结构化地调用外部工具和数据源。两者不是替代关系而是分层MCP 管「Agent 用手」A2A 管「Agent 开口说话」。这篇内容面向的是已经跑通过 MCP、想进一步做多智能体协作的开发者。我会给你可复制的 A2A Agent Card 配置、MCP 服务端 settings.json 骨架以及通过 TaoToken 统一 Key 通道把两条链路接起来的验证步骤。整套流程实测下来从零到跑通跨智能体任务分发大概 20 分钟前提是你已经有一个能用的模型 API 通道。2. 前置准备用 TaoToken 统一模型通道别让 Key 管理拖后腿多智能体协作最烦的一件事是每个 Agent 可能配了不同的模型供应商Key 散落在各个配置文件里调试时根本分不清哪个请求走了哪条通道。我的做法是先用 TaoToken 把模型调用统一到一个入口这样 A2A 和 MCP 两条链路都走同一个 Key排障时只需要看一个地方。TaoToken 的定位是统一的模型 API 通道兼容 OpenAI 风格的接口格式你可以在控制台生成 Key然后在各个 Agent 的配置里填同一个 base_url 和 api_key。官网入口在 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 地址是 https://taotoken.net/api 注意 API 地址后面不加 UTM 参数直接填就行。具体操作分三步。第一步打开控制台 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite 注册后进入 API Keys 页面点「创建新 Key」复制生成的 sk- 开头的字符串。第二步如果你要跑长期编码或 Agent 任务建议看一下 Coding Plan 页面 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 里面有适合持续调用的套餐说明。第三步把 Key 写进环境变量后面所有配置都引用这个变量避免硬编码泄露。export TAOTOKEN_API_KEYsk-你的Key export TAOTOKEN_BASE_URLhttps://taotoken.net/api这里有个细节A2A 协议本身不规定模型调用走哪条通道它只管 Agent 之间的通信格式。所以你的每个 Agent 内部用什么模型、走什么 API完全由你自己决定。统一走 TaoToken 的好处是当 A2A 任务分发出现问题时你可以快速判断是通信层的问题还是模型层的问题——如果模型对话页面 https://taotoken.net/model-chat?utm_sourcetaotoken_aicg_blog_endutm_contentmodel-chatutm_campaignrewrite 能正常返回说明 Key 和通道没问题问题就在 A2A 配置上。3. 可复制配置A2A Agent Card 与 MCP settings.json 骨架3.1 A2A Agent Card 怎么写Agent Card 是 A2A 协议的核心发现机制每个 Agent 通过一个 JSON 文件声明自己是谁、能干什么、怎么调用。你可以把它理解成 Agent 的「名片」其他 Agent 拿到这张名片就知道该往哪发任务、发什么格式的任务。下面是一个最小可用的 Agent Card 示例我把它放在agents/report-writer/agent-card.json{ name: report-writer-agent, description: 接收资料汇总任务生成结构化报告, url: http://localhost:8001/a2a, version: 1.0.0, capabilities: { streaming: true, pushNotifications: false }, defaultInputModes: [text/plain, application/json], defaultOutputModes: [text/plain, application/json], skills: [ { id: generate-report, name: 生成报告, description: 输入原始资料输出 Markdown 格式报告, inputModes: [application/json], outputModes: [text/plain] } ], authentication: { schemes: [none] } }几个关键字段说明。url是这个 Agent 的 A2A 端点其他 Agent 会往这个地址发 JSON-RPC 请求。capabilities.streaming设为 true 表示支持 SSE 流式返回任务状态调试时很有用。skills数组里每个条目描述一项能力id是任务路由的依据。authentication在本地调试时设为 none生产环境建议换成 API Key 或 OAuth。3.2 MCP 服务端 settings.json 骨架MCP 服务端的配置决定了 Agent 能调用哪些工具。下面这个骨架放在mcp-server/settings.json我把它设计成同时暴露「文件读取」和「HTTP 请求」两个工具方便 A2A 任务分发时做资料收集{ mcpServers: { file-reader: { command: npx, args: [-y, modelcontextprotocol/server-filesystem, ./workspace], env: {} }, http-client: { command: npx, args: [-y, modelcontextprotocol/server-fetch], env: { TAOTOKEN_API_KEY: ${TAOTOKEN_API_KEY}, TAOTOKEN_BASE_URL: ${TAOTOKEN_BASE_URL} } } } }注意env里引用了前面设置的环境变量这样 MCP 服务端在调用外部 API 时也能走 TaoToken 通道。如果你用的是 Claude Code 或类似的编码 Agent接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 有更详细的说明包括 Anthropic 风格的配置示例。3.3 把 A2A 和 MCP 接起来的主控 Agent主控 Agent 的职责是接收用户任务通过 A2A 发现可用的子 Agent把子任务分发出去同时通过 MCP 调用本地工具补充数据。下面是一个 Python 骨架用httpx发 A2A 请求用mcp客户端调工具import httpx import asyncio from mcp import ClientSession, StdioServerParameters A2A_AGENTS { report-writer: http://localhost:8001/a2a, data-collector: http://localhost:8002/a2a } async def send_a2a_task(agent_url, task_payload): async with httpx.AsyncClient(timeout60) as client: resp await client.post( f{agent_url}/tasks/send, json{ jsonrpc: 2.0, method: tasks/send, params: task_payload, id: task-001 } ) return resp.json() async def call_mcp_tool(): params StdioServerParameters( commandnpx, args[-y, modelcontextprotocol/server-filesystem, ./workspace] ) async with ClientSession(params) as session: await session.initialize() result await session.call_tool(read_file, {path: input.md}) return result async def main(): raw_data await call_mcp_tool() task { task: { id: task-001, message: { role: user, parts: [{type: text, text: str(raw_data)}] } } } result await send_a2a_task(A2A_AGENTS[report-writer], task) print(result) if __name__ __main__: asyncio.run(main())这段代码的逻辑是先用 MCP 读取本地文件拿到原始资料再通过 A2A 把资料发给报告生成 Agent。实测下来只要两个 Agent 的 Agent Card 配置正确这条链路一次就能跑通。4. 验证请求确认跨智能体任务分发真的通了配置写完之后别急着上复杂任务先用一个最小请求验证 A2A 端点是否可达。启动你的报告生成 Agent 后用 curl 直接打它的 A2A 端点curl -X POST http://localhost:8001/a2a/tasks/send \ -H Content-Type: application/json \ -d { jsonrpc: 2.0, method: tasks/send, params: { task: { id: test-001, message: { role: user, parts: [{type: text, text: 测试任务返回一句确认}] } } }, id: req-001 }如果返回的 JSON 里有result字段且包含任务状态说明 A2A 通信层没问题。接下来验证 MCP 工具调用单独跑一下 MCP 客户端npx -y modelcontextprotocol/inspector npx -y modelcontextprotocol/server-filesystem ./workspace这个命令会启动 MCP Inspector在浏览器里能看到所有可用工具列表点「read_file」测试一下能否读到文件内容。两步都通过之后再跑第 3.3 节的主控脚本观察控制台输出。正常情况下你会看到报告生成 Agent 返回的 Markdown 文本里面包含从 MCP 读到的原始资料。这里有个验证技巧在 TaoToken 的模型对话页面 https://taotoken.net/model-chat?utm_sourcetaotoken_aicg_blog_endutm_contentmodel-chatutm_campaignrewrite 手动发一条同样的提示词对比返回结果。如果手动对话正常但 A2A 链路报错问题一定在 Agent Card 或 JSON-RPC 格式上跟模型通道无关。5. 本篇常见错排查Agent Card 404、JSON-RPC 格式错、Key 未生效5.1 Agent Card 返回 404最常见的原因是url字段和实际服务监听地址不一致。比如 Agent Card 里写的是http://localhost:8001/a2a但你的服务实际监听在http://localhost:8001/少了一层路径。检查方法直接浏览器访问 Agent Card 的 URL能返回 JSON 就说明路径对。另一个可能是 Agent Card 文件没被服务端正确加载确认文件路径和加载逻辑匹配。5.2 JSON-RPC 格式错误A2A 基于 JSON-RPC 2.0jsonrpc、method、params、id四个字段缺一不可。我踩过的坑是把params直接写成任务对象正确写法是params里面再包一层task。另外id字段必须是字符串或数字不能是对象。如果服务端返回-32600 Invalid Request优先检查这几个字段。5.3 TaoToken Key 未生效症状是 MCP 工具调用返回 401 或模型对话超时。排查顺序第一确认环境变量TAOTOKEN_API_KEY在当前 shell 里能echo出来第二确认 MCP 配置里的env引用语法正确有些 MCP 服务端不支持${VAR}语法需要直接写值第三去控制台 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 确认 Key 状态是「启用」且余额充足。如果还是不通换一个最简单的 curl 请求直接打 API 地址排除网络层问题。5.4 任务状态订阅收不到更新如果你在 Agent Card 里开了streaming: true但客户端没收到 SSE 事件检查客户端是否用了正确的Accept: text/event-stream头。另外有些 HTTP 客户端默认缓冲响应需要手动关闭缓冲才能实时收到事件。6. 下一步把双协议链路接到你的实际项目里跑通最小链路之后你可以按这个顺序扩展。先把报告生成 Agent 换成你实际业务里的 Agent比如客服 Agent 或数据分析 Agent只改 Agent Card 里的skills和url。然后在主控 Agent 里增加任务编排逻辑比如根据任务类型路由到不同的子 Agent。最后把 MCP 工具从文件读取扩展到数据库查询或内部 API 调用注意生产环境不要直连核心库走只读副本或网关。如果你要长期跑编码类 Agent 任务建议把模型通道固定到 Coding Plan https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 避免按次调用带来的成本波动。接入文档 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 里有 Claude Code 和 Anthropic 风格的完整配置示例可以直接复制到你的项目里。整套 A2A MCP 的配置骨架我已经放在上面的代码块里你只需要把 Agent Card 的url和 MCP 的args换成自己的路径就能跑。