06 · 自测题库

自测题库:把五章正文当成一座可检索的题库

前五章建立了 A2A 的概念地图(01)、工作原理与设计取舍(02)、可跑通的 server + client(03)、跨组织系统的失败模式(04),以及把 A2A 与 MCP 叠成两层栈的综合项目(05)。这一章不教新东西——它用三层梯度题逼出检索:概念记不记得住、原理讲不讲得通、场景判别得对不对。

怎么用这一章

合上其他章,每题先把答案写在纸上或编辑器里,再翻到文末那个折叠块对照——直接看答案等于把这一章当成第六遍重读,检索效果归零。

C 应用判别层 · 判别 综合 03–05 · 场景选型选得对 B 原理层 · 理解 对应 02 + 03 · 机制讲得通 A 概念层 · 回忆 对应 01 · 定义与关系记得住 难度 ↑
图 6.1三层梯度把认知动作映到章节:概念层考「回忆」(01)、原理层考「理解」(02+03)、应用判别层考「判别」(03–05),自下而上变难。注意:卡在哪一层就回对应章补哪一层——卡在顶层判别题,往往不是定义没记住,而是「对端是工具还是对等 agent」「该用哪种交互模式」的取舍还没真正打通。

A概念层(对应 01 章 · 考回忆)

原子级的回忆 / 理解题:每题只问一个点,能用一两句话答完。答不上来,回提示里那一节。

  1. A2A 把 agent 层的 M×N 互操作收敛成 M+N,省掉的是哪三类两两重复的工作?它治的是「水平」还是「垂直」方向,跟 MCP 治的方向差在哪?(提示:§1.1)
  2. Agent Card 是什么?固定发布在哪个路径上?别的 agent 靠它发现什么、为什么不需要注册中心?(提示:§1.2)
  3. Agent Card 里的 securitySchemes 有没有装实际凭证(token / 密钥)?这一点为什么决定了 Card 能不能作为公开文档发布?(提示:§1.2)
  4. 用一句话说清 Task / Message / Part / Artifact 四者的嵌套关系。Message 和 Artifact 内容都是 Part[],区别在哪?(提示:§1.3)
  5. 「不透明 agent(opaque)」原则具体指什么不暴露、只暴露什么?它带来的三条收益和那一条代价分别是什么?(提示:§1.4)
  6. A2A 与 MCP 的判别口诀是什么?决定用哪个的,是对端的「名字」还是对端的「性质」?(提示:§1.5)
  7. 为什么说 A2A 与 MCP 是「正交(⊥)」而非竞争?举出同一个 agent 同时用上两者的典型形态。(提示:§1.5)

B原理层(对应 02 + 03 章 · 考理解)

问机制:不是「是什么」,是「wire 上长什么样、为什么这么设计、代价在哪」。这一层最容易被旧博客的 v0.x 形式带偏,逐题核对。

  1. 委托一件事,v1.0 在 wire 上发的 JSON-RPC "method" 字符串到底叫什么?为什么说 message/send 是错的、只能当迁移注记?(提示:§2.3)
  2. Task 的 state 在实际 JSON 载荷里长什么样(写出一个完整取值)?小写的 completed、英式拼写 cancelled 错在哪?(提示:§2.5)
  3. 三种交互模式——请求/响应、SSE 流、webhook 推送——各自何时用?三者的箭头方向有什么不同?(提示:§2.4)
  4. webhook 推送里,谁该验证「这个 POST 真来自 agent」?为什么说这条边的信任方向和直觉是反的?(提示:§2.4 + §4.4)
  5. Task 生命周期里 INPUT_REQUIRED / AUTH_REQUIRED 是中途态还是终态?「中途要凭证」和「一上来就 401」差在哪?(提示:§2.5)
  6. Python SDK 的方法名是 snake_case send_message,它在 wire 上发出的 "method" 却是 SendMessage——这两者是什么关系?这件事提醒你区分什么?(提示:§3.2)
  7. 同一个抽象方法有 JSON-RPC / gRPC / REST 三个对等绑定。既然抽象一致,为什么 v0.x 与 v1.0 的 agent 仍可能 wire 不兼容?(提示:§2.3 + §4.7)

C应用判别层(综合 03–05 · 考判别)

给场景、做选择。每题不只要选项,更要说出理由——选项蒙对而理由说不通,等于没通过。05 已扛了主判别,这里四道强化迁移。

  1. 场景一 · 调工具还是托对等体(涉及 01 / 03 / 05):你的编排 agent 要接入一个「内部跑着 LLM、会自己规划多步、可能反问你要补充信息、一次任务可能跑十几分钟」的远程服务。该把它当 MCP 工具接、还是当 A2A 对等 agent 接?说出判据,并指出它的「反问」在 A2A 里会落到哪个 Task 状态上。(§1.5 口诀 + §2.5 状态机)
  2. 场景二 · 同步 / 流式 / 异步选哪种(涉及 02 / 03):同一个「生成季度财报」的委托,分别在三种产品形态下——(a) CLI 脚本,跑完即退;(b) 网页,要实时显示「正在取数 / 正在汇总」的进度;(c) 手机 App,提交后用户会立刻锁屏、任务要跑 20 分钟。每种各该选请求/响应、SSE 流、还是 webhook 推送?逐一给理由。(§2.4 三种交互)
  3. 场景三 · 该不该验 Card 签名(涉及 01 / 04):你的 host agent 准备把支付相关的任务,委托给一个号称来自某知名银行、从 /.well-known/agent-card.json 取到的远程 agent。这张 Card 默认没有签名。你该不该在选用它之前加一道 Card 签名验证(JWS)?不加会被哪个具体攻击打穿?光验签名够不够?(§4.2 伪造 + §4.1 描述注入)
  4. 场景四 · 两层栈各管哪一段(涉及 01 / 05):一个「差旅编排 agent」要订机票,它先把「订票」托付给某航司的远程 agent,航司 agent 内部再去读自家的库存数据库、调订座接口。把这条链拆成几跳,逐跳标出该用 A2A 还是 MCP,并说明为什么这就是 2026 年企业级的默认两层栈。(§1.5 repair-shop + §5.1 两层栈)
快速一画(可选)

合上教程,在纸上画一次「最小委托」的端到端:从 client 发现 Agent Card 起,到它收回一个带 Artifact 的 Task 止。在每条边上标出 wire 上真正搬的东西——发现那条标 GET /.well-known/agent-card.json、委托那条标 SendMessage、回流那条标 Task 的 status.state 取值(写大写蛇形)。画完回 §2.1 对照:哪几条边你标反了方向、哪个状态值你写成了小写?

§参考答案

展开全部参考答案(三层都做完再看)

概念层(对应 01 章)

  1. 省掉的三类重复工作:怎么发现对端能干什么、用什么线缆格式发请求、对端用什么数据结构回话——A2A 把这三样分别固定成 Agent Card、JSON-RPC/gRPC/REST + SendMessage、Task/Message/Artifact,于是每端只实现一次「说/听 A2A」,总量从 M×N 降到 M+N。它治水平(agent↔agent);MCP 治垂直(agent↓工具)。同源动机,不同层。
  2. Agent Card 是一个 agent 公开发布的能力声明 JSON,固定位于 GET /.well-known/agent-card.json(v0.x 旧路径 agent.json 已弃用)。别的 agent 用一次普通 HTTP GET 就能读到它「能干哪几件事(skills)、走哪个端点(url)、支持哪些可选能力(capabilities)、用哪种认证(securitySchemes)」。因为路径是约定死的、知道域名就能拼出 URL,所以无需中央注册中心——这是去中心发现,像 robots.txt。
  3. 没有。securitySchemes 只声明认证方案的类型(如 OAuth2 / API Key / OIDC / mTLS),绝不包含任何实际 token 或密钥;凭证由调用方带外另行获取,发请求时放进 HTTP 头,不进 Card、也不进 JSON-RPC 载荷。正因为 Card 只说「用哪种锁」而不放「钥匙」,它才能作为公开文档发布而不泄密。
  4. 嵌套关系:Task(有状态的工作单元,含 id/contextId/status)包住 history(一个 Message[])和 artifacts(一个 Artifact[]);每条 Message 由 Part[] 组成(kind 分 text/file/data);Artifact 内容也是 Part[]。Message 与 Artifact 结构几乎一样,区别在语义:Message 是协作过程的逐条往来,Artifact 是这次托付要交付的成果——分两类是为了让调用方一眼区分「过程」与「结果」。
  5. 不透明 = 远程 agent 不暴露内部提示词、记忆、内部工具、推理过程;只暴露 Agent Card 声明的能力 + 显式交换的 Message / Task。三条收益:① IP 保护(藏住提示词/工具/私有数据);② 安全面收缩(攻击面只剩声明的接口 + 消息通道);③ 解耦(双方各换内部实现,只要 Card 契约不变对端无感)。一条代价:调用方无法深度自省或细粒度协调对端,只能在「发消息 / 查 Task 状态」这个粒度上交互。
  6. 口诀:你是在调一个工具(给输入、要结构化结果、一次即结束)还是在托付给一个对等 agent(对方会自己推理、可能多轮、可能跑很久)?前者 MCP,后者 A2A。决定答案的是对端的性质,而不是它叫什么名字——一个名字里带「tool」的服务若其实有状态、会反问,那它该走 A2A。
  7. 正交是因为两者在不同的层各司其职、不在同一条线上抢位置:MCP 垂直(agent→工具,tools/call),A2A 水平(agent→对等 agent,SendMessage + Task)。典型形态:一个 agent 对外用 A2A 暴露成对等体供别人托付,对内用 MCP 调自己的工具去完成那次托付——这正是 2026 年企业级的默认两层栈。

原理层(对应 02 + 03 章)

  1. wire 上的 JSON-RPC "method" 是 SendMessage(PascalCase,抽象名与 wire 字符串在 v1.0+ 完全一致;流式是 SendStreamingMessage,查任务 GetTask,取消 CancelTask)。message/send 那套斜杠名是 v0.x 的形式,v1.0 已改命名约定——它只能作为「迁移注记」出现,照旧博客写就会发错方法名。
  2. 实际 JSON 里是 SCREAMING_SNAKE 风格,例如 "status":{"state":"TASK_STATE_COMPLETED","timestamp":"…Z"}。全集:TASK_STATE_SUBMITTED / WORKING / INPUT_REQUIRED / AUTH_REQUIRED / COMPLETED / FAILED / CANCELED / REJECTED。小写 completed 是 v0.3.0 的形式(已弃用);拼写是美式 CANCELED,v0.x 的英式 cancelled 已移除。
  3. 三种交互按任务时长和客户端形态分:请求/响应——短任务、当场要结果;SSE 流——要实时看进度,服务端用 Content-Type: text/event-stream 逐帧推 TaskStatusUpdateEvent / TaskArtifactUpdateEvent;webhook 推送——长任务 / 断线(serverless、移动)客户端,不必一直挂着连接。箭头方向不同:前两种是客户端发起、结果顺着回;webhook 推送是服务端反向 POST 到客户端的 url——方向反过来了。
  4. 该验证的是客户端。直觉是「客户端调服务端、服务端验客户端」,但 webhook 把方向反了:是服务端反向 POST 到客户端给定的 webhook url。于是来源验证的功课落到客户端——它必须用密码学手段(JWT + JWKS 验签 / HMAC / token + 时间戳防重放)确认入站 POST 真来自那个 agent,否则有人能伪造 POST 冒充 agent 推假结果。(SSRF 的责任则在服务端:它要校验 webhook url、封禁内网地址。一条边上两侧各有一份功课。)
  5. 都是中途态,不是终态——它们是可中断、可恢复的中间状态:Task 在 WORKING 途中可落到 INPUT_REQUIRED(要补信息)或 AUTH_REQUIRED(要补凭证),拿到后再继续往终态走。与「一上来就 401」的区别:AUTH_REQUIRED 是一个已在运行的任务中途提出要新凭证,而非连接建立时的前置鉴权失败——所以一个恶意 agent 能用它在任务跑到一半时钓凭证(§4.6)。
  6. 它们是「SDK 人体工学」与「wire 协议」两个层面的同一个动作:你在 Python 里调的是 snake_case send_message(...),但 SDK 在底层把它编码成 JSON-RPC 时,"method" 字段写的是 PascalCase SendMessage。提醒你区分SDK 的命名风格 ≠ wire 上的协议字符串——别因为 Python 方法是 snake_case 就以为 wire 上也叫 send_message(那其实更接近 v0.x 的斜杠名误区)。
  7. 因为「同一抽象、三种绑定」保证的是同版本内三种传输等价,并不保证跨版本兼容。v0.x 与 v1.0 在方法名(message/send → SendMessage)、状态值(小写 completed → TASK_STATE_COMPLETED)、Content-Type(如 application/json vs text/event-stream / application/a2a+json)上都不是全 wire 兼容。所以即便两端都用 JSON-RPC 这同一种传输,一个 v0.x SDK 的 agent 和一个 v1.0 的 agent 仍可能对不上——选传输不解决版本错配(§4.7)。

应用判别层(综合 03–05)

  1. 当 A2A 对等 agent 接。判据(§1.5 口诀):被调对象有状态、会自己规划多步、可能多轮反问、任务长——符合「被托付一件事的自治对等体」,不符合 MCP「无状态、一次调用即结束的工具」画像。落地:让它发布 Agent Card 声明技能,用 SendMessage + Task 承载这次有状态委托。它的「反问要补充信息」正好落在 TASK_STATE_INPUT_REQUIRED 这个中途态上(要补凭证则是 AUTH_REQUIRED)——这是 MCP 的 tools/call 一次性调用根本表达不了的。
  2. 三种形态各取一种:(a) CLI 脚本——跑完即退、当场要结果,用请求/响应(短链路,不需要进度,也无谓挂长连接)。(b) 网页要实时进度——用 SSE 流,服务端逐帧推 TaskStatusUpdateEvent(正在取数 / 正在汇总)和 TaskArtifactUpdateEvent,页面边收边渲染。(c) 手机 App、提交即锁屏、跑 20 分钟——用 webhook 推送:客户端注册一个回调 url 就可以断开,任务完成后服务端反向 POST 过来;让手机挂 20 分钟 SSE 连接既费电又会因切后台断流。判据始终是「任务多长 + 客户端能不能一直在线」。
  3. 该加,而且这是支付这类高敏场景的硬要求。不加会被 §4.2 的 Agent Card 伪造 / 冒充打穿——Card 默认不签名、没有强制的加密身份绑定,任何人都能在某个域名上摆一张「自称某银行」的 Card,host 无法仅凭 Card 内容确认它真来自那家银行。加一道 JWS 签名验证(配合 JCS 规范化)能挡住伪造。但光验签名不够:① 签名只证明「这张 Card 没被篡改、来自持私钥者」,证明不了「这个 agent 值得托付支付」——信任建立、授权按任务范围限定(§4.6)都还得自己做;② 还要防 §4.1 的描述注入——一张签名合法的 Card 仍可能在 description 里塞诱导文本去赢得基于 LLM 的选路。一句话:验签名是必要条件,不是充分条件,因为「A2A-compliant ≠ secure」。
  4. 这条链拆成三跳:① 差旅编排 agent → 航司 agent=A2A(把「订票」托付给一个会处理、可能反问、要花时间的自治对等体,跨组织黑盒);② 航司 agent → 自家库存数据库 / 订座接口=MCP(航司 agent 往下调自己的工具/数据源,无状态、给输入回结果)。即便把航司内部再拆出一个「定价 agent」,那一跳仍是 agent↔agent 的 A2A,到「读数据库」才落回 MCP。它是企业默认两层栈,因为外层要的是「跨信任边界、把活托付给别家的对等 agent」(水平,A2A 的不透明对等体正好匹配),内层要的是「在自己掌控内调工具拿能力」(垂直,MCP 的无状态原语正好匹配)——两层各自匹配一种对端性质,正交叠用而非二选一。
进阶挑战 · 刚好够不着

把一道判别题反过来:哪种「看起来该用 A2A」其实不该

前面的判别题都在练「该用 A2A」。现在反向迁移——给一个看起来像 A2A、其实不该上 A2A 的真实场景,并说清三件事:① 它表面像 A2A 的哪一点(比如「也是两个组件在通信」);② 它实际缺了对等体的哪个本质特征(回到 §1.4 不透明 + §1.3 有状态 Task),所以更该用 MCP、共享 state 的进程内多 agent 框架、或干脆直接函数调用;③ 如果硬用 A2A,会白白付出哪些代价(回 §2.6 opaque 的代价那一笔账)。

提示(卡住再展开)

一类典型反例:你自己掌控的、跑在同一进程/同一信任域里、需要频繁共享中间状态的两个组件。它表面像 A2A(两个「agent」在通信),但 ① 你掌控两端、能看见内部——「不透明黑盒」这个本质特征根本不存在;② 它们要共享大量中间状态、要细粒度协调——而 A2A 的 opaque 原则恰恰堵死了深度自省与细粒度协调(§2.6 那笔代价),这正是 multi-agent-patterns 教的共享 state 框架擅长的。硬上 A2A 的代价:白白背上跨信任边界才需要的认证 / 发现 / 序列化开销、把本可共享的状态强行切成「发消息 + 查 Task」的粗粒度交互、还丢掉了对内部的可观测性。另一类反例:被调对象其实是个无状态、一次就结束的纯函数 / 数据查询——那是 MCP tools/call(甚至直接函数调用)的活,套上有状态 Task 的生命周期管理纯属浪费。判断的根子始终是 §1.5 的口诀:先问对端到底是不是「跨边界、看不见内部、有状态自治的对等体」。

本章参考

  • A2A Protocol Specification(v1.0.1, 2026-05-28)(方法名 SendMessage、TASK_STATE_* 取值、/.well-known/agent-card.json 路径的权威来源——核对原理层答案的 wire 事实)
  • A2A and MCP — complementary, orthogonal(官方;判别口诀与 repair-shop 两层栈的来源——概念层第 6/7 题、判别层场景四)
  • A2A · Streaming & Async(官方;三种交互模式与 webhook 反向信任——原理层第 3/4 题、判别层场景二)
  • 前五章正文(01–05)——本章是它们的综合检索场;每题的「提示:§X」直指对应小节