1. 先搞清楚A2A 和 MCP 到底各管什么刚接触 Agent 协作协议的同学最容易踩的坑就是把 A2A 和 MCP 当成竞品。我一开始也这么以为直到自己动手把两个协议都接进 Cline 跑了一遍才发现它们根本不在一个层面上干活。MCP 全称 Model Context Protocol解决的是「Agent 怎么调用工具和数据源」——比如让模型去查数据库、调 GitHub API、读本地文件。它是纵向的Agent 往下连能力。A2A 全称 Agent-to-Agent Protocol解决的是「多个 Agent 之间怎么互相通信协作」——比如一个编排 Agent 把任务拆给代码 Agent、测试 Agent、文档 Agent。它是横向的Agent 之间互相连。打个比方MCP 像是你给每个员工配的办公工具箱A2A 像是员工之间的即时通讯和工单系统。工具箱再好也不能替代同事之间的协作流程协作流程再顺也不能替代工具箱里的螺丝刀。两者缺一不可。这篇面向刚入门的小白程序员我会先讲清楚 A2A 的核心概念Agent Card、Task、Message再对比 MCP 的定位差异最后给出一套可复制的 TaoToken 统一 Key 配置骨架让你在 Cline 和 CC Switch 里把 A2A 与 MCP 的链路都跑通。全程不需要你有多深的分布式经验跟着配就行。适合谁看正在学 Agent 开发、准备面试被问到 A2A/MCP、或者想在自己项目里搭多 Agent 协作链路的同学。读完你能自己判断「这个场景该用 MCP 还是 A2A」并且有一套能直接跑的配置。2. 前置准备TaoToken 统一 Key 与配置骨架在动手接 A2A 和 MCP 之前先把模型调用的入口统一掉。不然你会在每个 Agent、每个工具里重复填 Key改一次要改十个地方。我用 TaoToken 做统一入口一个 Key 管所有模型调用配置集中管理。2.1 拿到统一 Key先去 TaoToken 控制台创建一个 API Key。地址是 https://taotoken.net/api 登录后在 API Keys 页面新建一个复制出来备用。这个 Key 后面会同时用在 Cline 的模型配置和 MCP Server 的模型调用里。注意Key 只显示一次复制后存到密码管理器里。不要直接硬编码进 Git 仓库。2.2 理解配置骨架的两层结构整个配置分两层第一层是「模型调用层」Cline、CC Switch 这些客户端通过 TaoToken 的统一 Key 调模型第二层是「协议接入层」MCP Server 和 A2A Agent 各自声明自己的能力。两层解耦换模型不用改协议配置换协议不用改模型配置。2.3 环境变量统一管理我习惯把所有敏感信息放环境变量配置文件里只引用变量名。这样 settings.json 和 config.toml 可以放心提交到团队仓库。# ~/.agent_env (加到 shell 的 source 里) export TAOTOKEN_API_KEYsk-你的统一Key export TAOTOKEN_BASE_URLhttps://taotoken.net/api export A2A_AGENT_B_URLhttp://localhost:8001 export MCP_SERVER_PORT3000在~/.zshrc或~/.bashrc里加一行source ~/.agent_env重开终端生效。验证一下echo $TAOTOKEN_API_KEY | head -c 8 # 输出 sk-xxxxx 前8位即正常3. 可复制配置settings.json 与 config.toml这一节给两份能直接抄的配置。settings.json 用于 Cline 这类 VS Code 插件config.toml 用于 CC Switch 和命令行工具。两份配置都指向 TaoToken 统一入口。3.1 Cline 的 settings.jsonCline 的配置在 VS Code 设置里也可以直接编辑 settings.json。核心是把模型 provider 指向 TaoToken 的兼容端点。{ cline.apiProvider: openai, cline.openAiApiKey: ${env:TAOTOKEN_API_KEY}, cline.openAiBaseUrl: ${env:TAOTOKEN_BASE_URL}/v1, cline.model: claude-sonnet-4-20250514, cline.mcpServers: { filesystem: { command: npx, args: [-y, modelcontextprotocol/server-filesystem, /Users/you/projects], env: { TAOTOKEN_API_KEY: ${env:TAOTOKEN_API_KEY} } }, github: { command: npx, args: [-y, modelcontextprotocol/server-github], env: { GITHUB_TOKEN: ${env:GITHUB_TOKEN}, TAOTOKEN_API_KEY: ${env:TAOTOKEN_API_KEY} } } } }这里cline.mcpServers就是 MCP 的接入点——每个 Server 是一个工具集。filesystem 让 Agent 能读写本地文件github 让 Agent 能操作仓库。注意 baseUrl 后面要加/v1这是 OpenAI 兼容格式的约定。3.2 CC Switch 的 config.tomlCC Switch 用 TOML 格式管理多个模型配置和 Agent 定义。下面这份同时配了模型入口和一个 A2A Agent 的声明。# ~/.cc-switch/config.toml [providers.taotoken] type openai-compatible base_url https://taotoken.net/api/v1 api_key ${TAOTOKEN_API_KEY} default_model claude-sonnet-4-20250514 [agents.code_agent] provider taotoken role 代码生成与单元测试 mcp_servers [filesystem, github] [agents.review_agent] provider taotoken role 代码审查与安全扫描 mcp_servers [filesystem] # A2A 协作声明编排 Agent 通过 A2A 调用下面两个 Agent [a2a.orchestrator] provider taotoken peers [code_agent, review_agent] task_timeout_sec 300[agents.*]段定义每个 Agent 的角色和它挂的 MCP Server[a2a.orchestrator]段声明编排 Agent 的协作对象。这样一份配置里MCP 的纵向连接和 A2A 的横向协作都表达清楚了。3.3 A2A Agent Card 的最小实现A2A 的核心是 Agent Card——每个 Agent 在/.well-known/agent.json暴露自己的能力声明。下面是一个最小可用的 Agent Card用 Python 的 FastAPI 起一个。# agent_b.py from fastapi import FastAPI from pydantic import BaseModel import uuid app FastAPI() AGENT_CARD { name: Code Review Agent, description: 专门做代码审查支持安全扫描和风格检查, url: http://localhost:8001, capabilities: {streaming: False, pushNotifications: False}, skills: [ { id: security-scan, name: Security Scan, description: 扫描 SQL 注入、XSS 等安全问题, inputSchema: { type: object, properties: { code: {type: string}, language: {type: string} } } } ] } app.get(/.well-known/agent.json) def get_agent_card(): return AGENT_CARD class TaskRequest(BaseModel): skill: str input: dict TASKS {} app.post(/tasks) def create_task(req: TaskRequest): task_id str(uuid.uuid4()) TASKS[task_id] {status: working, result: None} # 实际执行逻辑省略这里模拟完成 TASKS[task_id][status] completed TASKS[task_id][result] f已扫描 {req.input.get(language)} 代码未发现高危问题 return {task_id: task_id, status: submitted} app.get(/tasks/{task_id}) def get_task(task_id: str): return TASKS.get(task_id, {status: not_found})启动uvicorn agent_b:app --port 8001。这个 Agent 暴露了 Agent Card 和 Task 接口编排 Agent 就能通过 A2A 发现它、给它派任务。4. 验证请求跑通 A2A 与 MCP 链路配置写完不算完得实际发请求验证。这一节分三步先验证 MCP 工具能调通再验证 A2A 的 Agent Card 能发现最后验证 Task 能提交并拿到结果。4.1 验证 MCP 工具调用在 Cline 里打开一个项目直接问它「列出当前目录下的文件」。如果 MCP 的 filesystem Server 配好了Cline 会调用list_directory工具并返回结果。这一步验证的是纵向链路——Agent 通过 MCP 连到了本地文件系统。如果没反应检查 Cline 的 MCP 面板里 Server 状态是不是绿色。红色说明启动失败多半是 npx 路径或权限问题。4.2 验证 A2A Agent Card 发现用 curl 直接拉 Agent Cardcurl -s http://localhost:8001/.well-known/agent.json | python -m json.tool正常返回{ name: Code Review Agent, description: 专门做代码审查支持安全扫描和风格检查, url: http://localhost:8001, capabilities: {streaming: false, pushNotifications: false}, skills: [ { id: security-scan, name: Security Scan, description: 扫描 SQL 注入、XSS 等安全问题 } ] }看到 skills 列表就说明能力发现通了。这一步对应微服务里的服务注册——调用方不需要提前知道接口文档GET 这个标准路径就能拿到能力声明。4.3 验证 A2A Task 提交与结果模拟编排 Agent 给 review_agent 派一个任务# 提交任务 TASK_ID$(curl -s -X POST http://localhost:8001/tasks \ -H Content-Type: application/json \ -d {skill:security-scan,input:{code:SELECT * FROM users WHERE id1,language:sql}} \ | python -c import sys,json;print(json.load(sys.stdin)[task_id])) echo Task ID: $TASK_ID # 查询结果 curl -s http://localhost:8001/tasks/$TASK_ID | python -m json.tool返回{status: completed, result: 已扫描 sql 代码未发现高危问题}就说明 A2A 的 Task 状态机跑通了。真实场景里 Task 会经历 submitted → working → completed 的流转这里为了演示简化了。4.4 在 CC Switch 里串起两个 AgentCC Switch 的 config.toml 里已经声明了 orchestrator 和两个 peer。启动 CC Switch 后它会读取配置把 code_agent 和 review_agent 注册为可协作对象。你在命令行里发一个任务orchestrator 会先通过 MCP 调 filesystem 读代码再通过 A2A 把代码派给 review_agent 扫描最后汇总结果。这一步是整个链路的核心验证MCP 负责纵向取数据A2A 负责横向派任务TaoToken 统一 Key 负责所有模型调用。三者各司其职。5. 本篇常见错排查配置过程中最容易卡住的几个点我按出现频率排一下。5.1 Agent Card 返回 404.well-known/agent.json这个路径是固定的不能改。如果你用 FastAPI路由要写成app.get(/.well-known/agent.json)注意.well-known前面没有斜杠前缀问题。用 Nginx 反代的话要确保.well-known目录不被 rewrite 规则吞掉。5.2 MCP Server 启动失败Cline 里 MCP Server 显示红色先看输出面板的报错。最常见的是 npx 找不到包加-y参数自动确认安装。其次是路径权限filesystem Server 的路径参数必须是绝对路径且当前用户有读写权限。5.3 Task 状态一直卡在 workingA2A 的 Task 是异步的如果你的 Agent B 执行逻辑是同步阻塞的Task 会一直不返回。检查 Agent B 的任务执行是不是放到了后台线程或异步任务里。生产环境还要加超时机制working 超过设定时间自动标记 failed避免永远卡住。5.4 TaoToken Key 报 401先确认环境变量有没有生效echo $TAOTOKEN_API_KEY。如果为空说明~/.agent_env没 source 成功。其次确认 baseUrl 拼对了OpenAI 兼容格式要带/v1即https://taotoken.net/api/v1。最后确认 Key 没有多余空格复制时容易带上换行。5.5 A2A 和 MCP 配置互相干扰有人把 A2A Agent 的地址填进了 MCP Server 的配置里导致 Cline 试图用 stdio 去连一个 HTTP 服务。记住MCP Server 用 command args 启动本地进程A2A Agent 用 URL 走 HTTP。两者配置字段完全不同不要混。6. 下一步把链路用到真实项目跑通 demo 之后你可以把这套骨架往真实场景搬。几个实用的方向第一把 Agent Card 的 schema 做一层抽象。A2A 规范还在早期Agent Card 的字段可能有调整。你在业务代码和 Agent Card 之间加一个适配层schema 变了只改适配层业务逻辑不动。第二给 Task 加持久化。demo 里 Task 存在内存Agent 重启就丢。生产环境把 Task 状态落 Redis 或数据库Agent 启动时恢复 working 状态的 Task 继续执行。第三加鉴权。A2A 规范对安全着墨不多你可以在 HTTP 层加 Bearer TokenAgent Card 里加 auth 字段声明鉴权方式。TaoToken 的统一 Key 管模型调用Agent 之间的鉴权单独做一层。如果你要长期跑多 Agent 编码任务建议用 Coding Plan 把模型调用额度管起来地址是 https://taotoken.net/api 。接入文档在 https://taotoken.net/api 里面有各客户端的详细配置示例。想先验证模型对话效果可以直接在模型对话页面试。API Keys 管理在控制台的 API Keys 页面。最后提醒一句MCP 和 A2A 不是二选一。每个 Agent 内部用 MCP 挂工具Agent 之间用 A2A 协作两层协议各管各的。你把这张「纵向 横向」的图记牢面试和落地都不会翻车。