无尘阁日记

无尘阁日记

构建自主AI:它把 A2A 讲清了,却写成了远程调用
silcano

微信读书《构建自主AI:深入A2A协议的智能体开发》· 抓取 431 屏 / 18 章 / 203 节目录条目
逐字核对 10 屏 · p0006 书名条核对为本书 · 抓取日志标注「已确认读到书尾」· 2026-11-09
先把边界说清楚。这本书的抓取是完整的——431 屏,run 日志写着「已确认读到书尾」,最后一屏 p0428 停在「18.4.3 测试 Agent Framework 与 A2A 的集成」的运行截图上,所以我可以放心地说「书里有」和「书里没有」。431 屏对 203 条目录,我只能逐字核对 10 屏,抽样率 2.3%。凡是我说「作者没讲」的地方,请按这个比例打折看;凡是我引用原话的地方,都是我亲眼在截图里读到的。另外,目录条目不等于页码:203 条里有些是篇标题(「第1篇 基础篇」),有些是一级大节(「1.1」「1.4」),有些才是末级小节(「1.3.3」)。按末级小节算,平均一节 2.1 屏——这个密度在国内技术书里算正常,不是注水。

我先给结论:这是我读过的中文 A2A 书里,把协议本体讲得最老实的一本;但它同时把 A2A 最要紧的那件事——两个 Agent 怎么谈事——降格成了「客户端发一条、服务端回一条」。协议讲清了,协商没讲。

A2A 这个协议值得认真对待,原因不在技术优雅,而在它要解决的问题很实在。作者在前言里把这个背景交代得干净:A2A 最初由 Google 开发,现在在 Linux 基金会管理下继续发展,目标是让不同框架、不同开发厂商、不同编程语言实现的 Agent 能够顺畅互操作。他还补了一句我认为是全书写作动机的核心——单平台内的 Agent 之间沟通通常不存在障碍,但多个平台、不同厂商、多种编程语言开发的 Agent 之间,协作仍然存在技术问题;而单纯用对话式的 OpenAI Completions 兼容接口去解决这个问题效果并不理想,因为大模型应用领域广泛使用的 MCP 更侧重文本内容的交换,不太适合多个 Agent 之间的能力发现和精确调用。

这段话是对的,而且是这本书存在的理由。MCP 解决的是「一个 Agent 怎么用工具」,A2A 解决的是「一个 Agent 怎么用另一个 Agent」。这两件事容易被混为一谈,作者一开始就把它们分开了,这一点我要给他记一功。

一、先把账算清楚:18 章里,真正讲「协作」的只有一章

我把 203 条目录全部读了一遍,按三篇归类:基础篇第 1–2 章,开发篇第 3–8 章,应用篇第 9–18 章。这个框架本身是合理的——先讲协议是什么,再讲怎么实现,最后讲怎么接进现成的 Agent 框架。

但一旦把章节数摆出来,问题就浮上来了。第 9 章到第 18 章,整整十章,是「一个框架一章」的结构:ADK、BeeAI、Pydantic AI、CrewAI、LlamaIndex、LangGraph、Semantic Kernel、Agent Framework……内容简介里作者自己写的是「提供 10 个实用案例,涵盖使用 ADK、BeeAI、Pydantic AI、MCP、CrewAI、LlamaIndex、LangGraph、Semantic Kernel、A2A 和 Agent Framework 等框架开发 Agent 的方法」。

十章给十个框架,意味着一章大约 20 屏。一个框架能分到多少解释、多少判断、多少坑?答案是:刚好够把一段代码贴完、把终端输出截一张图、然后说「运行结果如图 18-3 所示」。

而真正讲「多个 Agent 怎么协作」的,全书只有第 6 章一章:6.1 应用场景、6.2 协作流程设计(含 WebUI 工作原理分析)、6.3 协作源代码与运行、6.4 其他协作方案探讨,四个大节。相比之下,光是第 1 章讲概念与对比就有 1.1.1–1.1.3、1.2.1–1.2.3、1.3.1–1.3.4、1.4.1–1.4.2 共十二个末级小节。

一本叫「构建自主AI」的书,用十二节讲「A2A 是什么」,用四节讲「多个 Agent 怎么一起干活」。这个比例不是排版失误,是写作取向:作者更愿意解释协议,不太愿意处理协作。而协作恰恰是这个协议唯一的存在理由。

二、它最扎实的地方:Agent Card 被当成一张名片,逐个字段讲

要说这本书好在哪,p0028 是我第一个想举的例子。

这一页在讲 Agent Card。绝大多数同题材料会告诉你「Agent Card 是描述 Agent 能力的 JSON 文件」,然后跳到代码。这本书没有。它把 JSON 里十几个字段一个一个注释出来:name、description、url、provider、version、capabilities、skills、default_input_modes、default_output_modes、documentation_url、icon_url、preferred_transport(注释写着「首选传输协议,默认为JSONRPC」)、protocol_version(「Agent 支持的 A2A 协议版本」)、additional_interfaces、security、security_schemes、signatures(「为此 Agent Card 计算的 JSON Web 签名」)、supports_authenticated_extended_card(「是否支持扩展的认证Card」)。

然后它给了一句我觉得很准的话:

Agent Card 相当于Agent的一张名片,上面的信息既可以让人读取,也可以让与之交互的Agent读取,主要包含Agent所具备的技能列表、输入与输出消息的格式,以及认证……

「名片」这个比喻好,好在它同时解释了 Agent Card 的两个读者:人和 Agent。这个双读者结构是 A2A 设计里最容易被忽略的一点,因为大部分人只想到「让对方 Agent 读」,忘了它还得让运维的人看懂、让安全的人能审。而这一页的字段表里,signatures 和 security_schemes 恰好是给人看的——它们的存在说明这张名片要能被验证,不只是被解析。

我为什么愿意为这一页多说两句?因为「字段级摊开」是有成本的。你要么真的读过规范,要么真的跑过一遍,否则写不出 supports_authenticated_extended_card 这种字段——它不是能从直觉里编出来的名字。这是我判断一本技术书是否「真的动过手」的土办法:看它敢不敢列那些长得难看、但确实存在的字段名。

三、p0040 那句分工,是全书最值钱的一句话

第 1 章的「本章小结」在 p0040,作者在这里做了一个很克制的划界,我认为值得单独拎出来:

Function-Calling 更适用于模型需要借助外部工具完成特定计算或查询的场景,如获取实时天气、调用计算器等。
A2A 则适用于需要多个Agent协同处理复杂任务的场景,如智能客服系统中负责意图识别的Agent与负责业务办理的Agent之间的协作处理流程。

这句话的价值在于它给了判据,而不是定义。「获取实时天气、调用计算器」对「意图识别 Agent 与业务办理 Agent 协作」——两边都是具体场景,读者可以拿自己的系统往里套:我这个需求,是要查一个东西,还是要一个会自己判断的实体来接手一段流程?前者 Function-Calling 就够了,后者才需要 A2A。

同一页的小结还顺带把第 1 章的骨架报了一遍:核心概念、主要特性、社区生态和发展历程;Agent Card、Message、Part、Task 和 Artifact 五个结构;身份认证与授权机制,并且特别点明「其依赖 Web 安全实践,将身份信息置于 HTTP 传输层,并通过动态 Token 等方式保障通信安全」。

「依赖 Web 安全实践」这七个字是全书技术判断力最高的一处。它承认了 A2A 在安全上不是一个新东西——它把身份问题交回给 HTTP 那套已经打了三十年补丁的机制,而不是自己另造一套。这是个成熟的选择,很多新协议死在「我这里有一套全新的信任模型」上。作者能把这句写进小结,说明他明白自己在讲什么。

四、但从第 3 章起,这套协议就被写成了 RPC

问题出在开发篇。

第 3 章叫「实战基础应用:单次、任务与流式处理」,三节分别是:3.3 消息单次返回模式、3.4 异步任务处理模式、3.5 流式响应模式。这三个名字本身没问题,它们确实是 A2A 的三种交互形态。但落到代码上,三种形态都变成了同一件事:Client 构造一个 Message,塞进 Part,发出去;Server 收到,跑一个 Agent,把结果推回来。

p0060 讲 execute 方法,拆了三点,我抄下来:

(1) 客户端传过来的消息通过 context.get_user_input() 获取。通过 context 还可以得到 context_id 等代表消息上下文的信息……
(2) TimeAgent 的 invoke 是异步方法,这里通过 await 简单地将其作为同步调用来获取返回值。事实上,在大部分 Agent 的实现中,由于需要与大语言模型交互,通常会逐步生成增量内容的异步调用方式实现。在 execute 中,往往也需要采取异步的方式接收 Agent 的返回结果,再将其推送给客户端。
(3) 与常规的 HTTP 请求应答模式不同,A2A 在客户端和服务端之间采用异步方式传递消息,机制上是基于事件驱动。本例中的体现是:将生成的文本消息推送到事件队列中,供后续异步传输给客户端。

第 (3) 点说得很清楚,而且是对的:事件驱动,不是请求应答。但请注意它说的是「异步方式传递消息」——异步的是传输,不是协商。整段代码里,没有一处是服务端对客户端说「这个任务我不接,你换一个 Agent」,也没有一处是客户端问「你能不能做这件事、大概要多久、要多少钱」。

这就是我说的「写成了 RPC」。RPC 的模型是:我知道你有这个函数,我调它,它返回。A2A 的模型本该是:我不知道谁有这个能力,我先去发现,然后我请求,对方可能接、可能拒、可能接一半、可能中途把子任务转给别人。这本书把前半段讲了——Agent Card 就是发现机制——但后半段几乎全跳过了。

而且「发现」这一半本身也有个坑,书里没点破:Agent Card 里的 skills 字段,注释是「Agent 可以执行的技能或不同能力集合」。这句话的关键词是「可以」——它是自我申报,不是第三方认证。一个 Agent 在名片上写自己会做财务报表分析,没有任何机制能保证它真的会。这在单机 demo 里不是问题,在多组织协作里就是全部问题:你怎么知道对面那张名片没有吹牛?你怎么知道它昨天还能做、今天模型换了就不行了?

这个问题在书里其实被碰到过一次——第 4 章叫「构建A2A验证器:服务治理与验证」,4.2.1 是「Agent Card 的获取与兼容性处理」,4.2.2 是「A2A 返回消息的解析」,4.4 是「A2A 验证器的产品化探讨」。从目录看,这个验证器验证的是格式:名片能不能拿到、字段能不能解析、返回的消息结构对不对。这不叫验证能力,这叫验证语法。真正需要的是「发一个探针任务过去,看它交付得怎么样」——而这一层,目录里没有。

构建自主AI:深入A2A协议的智能体开发 知识图谱
四列:骨架 / 讲对的 / 错位 / 短板

我不认为这是作者偷懒。更可能的解释是:A2A 规范本身在这块就留白。任务拒绝、能力协商、子任务转派这些语义,在协议里只有状态码级别的支持,没有流程级别的规定。书写到这一层,作者如果硬写,就得自己发明一套,那就不再是「讲协议」而是「提方案」了。问题在于——他没有告诉读者这个留白存在。读者读完六章实战,会以为「A2A 就是这么用的」,然后在真实的多 Agent 系统里第一次遇到「对方 Agent 突然不响应了」,才发现书里没有这一页。

五、p0060 那个 cancel,是全书最诚实也最致命的一处

同一页还有一段,我读的时候停了一下:

cancel 方法在本示例中暂未实现具体逻辑,而是直接抛出「不支持取消操作」的异常。实际应用中可根据业务需求补充状态清理、任务终止等处理逻辑。当客户端主动调用 cancel_task 时,cancel 方法会被触发执行。

我要为这句话鼓掌,也要为这句话扣分。

鼓掌是因为它诚实。国内技术书里,遇到自己没实现的接口,最常见的处理是不写——删掉,读者看不见,就当不存在。作者写了,而且明说「暂未实现」「直接抛出异常」,还补了一句「实际应用中可根据业务需求补充」。这是把缺口标出来的写法,比闷声跳过强得多。

扣分是因为,这个缺口的严重性被严重低估了。「取消」在 A2A 里不是一个可选功能,它是这个协议之所以需要「任务(Task)」这个对象的根本原因。如果一次交互是同步的、秒回的,你根本不需要 Task,一次 HTTP 请求就够了。之所以要有 Task、要有状态机、要有 TaskStatusUpdateEvent,就是因为有些活要跑几分钟、几十分钟,中途可能不要了。取消语义是长任务模型的另一半,缺了它,Task 就只是一个「慢一点的请求」。

而这本书在最需要展开的地方,用一句话带过了。它没有告诉读者:取消之后服务端应该把任务置成什么状态?已经产生的部分产物怎么处理?取消和「已完成」撞车了怎么办?客户端取消超时了怎么办?这几个问题,任何一个在真实系统里都会把人卡住。

我把这一处当成整本书的隐喻:作者知道哪里是空的,他标了出来,但他没有填。这不是能力不足——他显然懂协议——这是取舍:填这几个问题要花二十屏,而二十屏可以再讲一个框架。

六、一章一个框架:广度买到了,深度没买到

应用篇那十章,我抽样看了第 7 章、第 14 章和第 18 章,基本可以确认它们的共同结构:先说这个框架是什么、和 A2A 什么关系,再贴一段封装代码,再跑一遍,最后贴终端截图。

p0168 是第 7 章「开发多模态 A2A 应用:视频下载与传输」的 7.3.4。这一节是全书我第二喜欢的地方,因为它讲了一个别处没讲的东西——怎么把服务端的进度推到客户端:

我们重点介绍 task_consumer 部分。task_consumer 采用了「订阅-消费」的方式处理 Server 返回的消息。当接收到 Server 推送的数据时,首先判断数据类型是否为元组,以确保正确解析任务和事件对象。在处理 TaskStatusUpdateEvent 事件时,通过提取任务状态消息中的进度百分比,并利用 tqdm 动态更新下载进度条,使用户能够直观感知任务的执行状态。当接收到 TaskArtifactUpdateEvent 事件时,表明文件下载已完成,此时从任务工件中提取文件 URI 并关闭进度条,最终输出下载完成的文件名信息。

这一段讲的是真正的工程细节:两种事件、两种处理、一个进度条。这才是我希望在一本讲协议的实战书里看到的东西——不是「A2A 支持流式」,而是「流式回来的是两种事件,你得分开处理,一种是状态,一种是产物」。

但这样的页太少了。第 14 章讲 LlamaIndex 集成,p0330 的 14.2.2 讲 ReAct Agent 原理,写的是「联网搜索与向量搜索这两个工具构成了智能体的执行组件,而大模型则为智能体提供了规划与文本整合能力。原始数据文件被切分为若干文本段落,在嵌入模型的支持下生成索引并写入向量数据库」——这段是对的,但它跟 A2A 没有关系,它是 ReAct 和 RAG 的通用介绍,任何一本讲 Agent 的书都有。真正属于这一章的问题是「LlamaIndex 的 Agent 怎么被包成 A2A Server、它的事件流怎么映射到 A2A 的 Task 事件」——而这个,恰恰被略过了。

还有一处细节,我不确定该怎么评价,但值得记下来。p0428 的运行截图里,终端显示的是:

(Chapter18) E:\program\little5\a2a-course\chapter18\python a2a_af_server.py
INFO: Started server process […]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: Uvicorn running on http://0.0.0.0:9999

这是作者自己机器上的路径 E:\program\little5\a2a-course\chapter18。一方面它证明这些代码是真跑过的——路径、端口、conda 环境名都是活的。另一方面它说明读者拿不到一个能直接 clone 下来跑的仓库:所有代码得按章一个个抄,环境得按章一个个建(p0045 明确写「本书将为每一章创建独立的虚拟环境」)。18 章 18 个 conda 环境,这个工程量对「初学者实践指南」的定位来说,有点重。

七、它的短板

第一,失败路径整体缺席。这是最硬的一条。全书讲了三种交互模式、十种框架集成、几种安全配置,但没有一节讲「当对方 Agent 挂了/超时/只返回半个结果/中途换了实例」怎么办。多 Agent 系统在真实环境里的绝大多数麻烦,都出在这四种情况上。p0060 那句「cancel 暂未实现」是这个缺口最明显的证据,但它不是孤例——第 4 章「A2A 验证器」讲的是怎么验证对方 Agent Card 能不能解析,不是验证对方 Agent 能不能干活。协议层面的「能通信」被验证了,业务层面的「能交付」没有。

第二,安全只做到「进门」。第 8 章「构建企业级安全框架:认证与通道保护」覆盖了 Bearer 认证、动态 Token 认证、HTTPS 配置,这三样都对,也都必要。但企业级安全的另一半是进门之后:这个 Agent 能读哪些数据、能调哪些下游、它的调用要不要留痕、出事了怎么追溯。第 1 章小结里那句「依赖 Web 安全实践」如果贯彻到底,后面就该有一节讲 OAuth 的作用域怎么映射到 Agent 的能力边界——没有。所以「企业级」三个字,在这本书里指的是企业级传输安全,不是企业级授权治理。

第三,深度被框架数量摊薄了。十章十个框架,一章 20 屏,扣掉框架介绍和 ReAct 原理这类通用段落,真正属于「A2A 与这个框架怎么对接」的内容大概五六屏。这五六屏能干什么?刚好够贴一段能跑通的代码。而读者真正会卡住的地方——「我这个框架的回调怎么映射成 TaskStatusUpdateEvent」「它的多轮记忆怎么和 context_id 对齐」——一句都没有。这种写法在宣传里很好看(「覆盖 10 大主流框架」),在使用中很不耐用。

第四,篇幅账没算对。第 1 章十二个末级小节讲概念与对比,第 6 章四个大节讲协作。如果把「基础篇」整章和「协作章」放在天平上,前者重得多。我理解作者的考虑:读者可能不熟悉 A2A,概念要多讲。但一本讲「构建」的书,最贵的应该是「怎么搭起来、怎么搭坏了、怎么修」。现在的重心在「这是什么」。

第五,代码的可迁移性没有交代。十八个 conda 环境、本机 E 盘路径、每章独立依赖——这套安排对作者是方便的(写完一章不污染下一章),对读者是负担(想跑第 12 章得重建第 12 章的环境,而依赖版本在书里是散的)。p0045 讲了怎么用 Miniconda 隔离,讲了「将项目迁移到其他机器时,只需导出虚拟环境的依赖配置文件」——但它没有给出一份完整的依赖清单。这是一本实战书最不该缺的一页。

第六,状态管理的「优化措施探讨」被放在最后一节。第 5 章叫「实现多轮交互:状态管理与上下文保持」,5.1 场景设计、5.2 原理与架构、5.3 三段源代码(带状态维护的 Agent、A2A Server、A2A Client)、5.4 才是「存储与消息交互优化措施探讨」。这个顺序意味着:前三节先把内存里的状态跑通,最后一节才谈「放哪儿、怎么清、要不要持久化」。可多 Agent 系统一旦上线,状态放哪儿恰恰是第一个要定的事——放进程内存,重启就丢;放 Redis,就要处理并发写;放数据库,就要处理事务边界。把这件事放在章末当「探讨」,等于承认它没进设计。

八、这本书该给谁看,以及一个更省时间的读法

最合适的一类人:已经能写出单个 Agent、现在要让两个 Agent 互相调的人。你已经知道什么是工具调用、什么是 ReAct、什么是流式输出,你缺的是「怎么把 A 包成服务、怎么让 B 找到 A、A 和 B 之间传什么结构」。这本书的第 1 章(Agent Card 与 Message/Part/Task/Artifact 五个结构)、第 3 章(三种交互形态)、第 8 章(三种认证)正好补这三块,而且补得干净。

不太合适的两类人。第一类是零基础:第 2 章上来就要装 Ollama、建 conda 环境、跑 A2A SDK,没有 Python 异步编程底子会卡在 async with httpx.AsyncClient 那一行。第二类是想要「照着搭一套生产系统」的人:生产要的是失败重试、幂等、审计、配额、灰度,这五样在书里都没有。

给一个具体读法,我觉得比「推荐指数」有用:把第 1 章当规范读,第 3、4、5、6、8 章当参考书读,第 9–18 章只挑你正在用的那个框架读一章。理由很简单:第 1 章是真材实料(字段级),第 3–8 章是协议的骨架(案例虽浅,但结构完整),而第 9–18 章的全部价值只有一条——让你知道「原来我这个框架也能包成 A2A Server」。为了这一条去读十章,性价比太低。

另外,读第 1 章的时候建议做一件事:把 p0028 那张 Agent Card 字段表抄下来,旁边加一列,写「我这个 Agent 这一项该填什么」。十七个字段填完,你对 A2A 的理解会比读完后面十七章都深。因为填表这件事会逼你回答一个书里没问的问题:我的 Agent 到底有什么能力,是值得被别的 Agent 发现的?

第 6 章那二十来屏,反而建议读两遍。第一遍照着跑,看三个 Agent 怎么互相调;第二遍不看代码,只看 6.2 那张流程设计图,然后问自己一句:这套流程里,如果中间那个 Agent 挂了,谁负责重试?如果第一个 Agent 的判断是错的,后面的 Agent 有没有权力拒绝?——这两个问题书里不答,但它们是这套代码真正教你的事:多 Agent 协作的难点不在通信,在归责。

最后一句:这本书把「A2A 是什么」讲到了可以当手册用的程度,把「A2A 怎么用于真事」留在了 demo 的边上。它是这个协议目前最好的中文入门,但它不是一本能让你少踩坑的书——坑它标出来了(cancel 那一句),只是没告诉你坑有多深。

阅读记录 微信读书《构建自主AI:深入A2A协议的智能体开发》· 抓取 431 屏(日志标注「已确认读到书尾」)· 18 章 / 203 条目录 · p0006 书名条核对为本书
抽样核对 10 屏:p0003 内容简介(三篇 18 章、10 个框架案例、定位「A2A及Agent初学者的实践指南」) · p0005 前言(A2A 由 Google 开发、Linux 基金会管理;MCP 侧重文本交换、不适合 Agent 间能力发现与精确调用) · p0028 Agent Card 字段表(十余个字段逐一注释、「Agent 的名片」、preferred_transport 默认 JSONRPC、signatures、supports_authenticated_extended_card) · p0040 1.5 本章小结(Function-Calling 与 A2A 的场景分工;Message/Part/Task/Artifact 五结构;「依赖 Web 安全实践」) · p0045 2.1.3 Python 虚拟化环境(选 Miniconda 的三条理由、「为每一章创建独立的虚拟环境」) · p0060 execute 三点解读与 cancel「暂未实现具体逻辑,直接抛出『不支持取消操作』」 · p0105 Agent Card 转 Markdown 与 httpx.AsyncClient 调用 · p0168 7.3.4 多模态 task_consumer(TaskStatusUpdateEvent 取进度 / TaskArtifactUpdateEvent 取产物) · p0330 14.2.2 LlamaIndex ReAct Agent 原理 · p0428 18.4.3 运行截图(E:\program\little5\a2a-course\chapter18、Uvicorn 0.0.0.0:9999)
说明:抓取完整,末页为 18.4.3 运行截图 · 抽样率 10/431 ≈ 2.3%,「书里没有」的判断请按此折扣 · 章节条数按 meta.json 的 chapters 字段统计 · 笔记与图谱生成于 2026-11-09
关于作者 · 江天(楠哥)
AI 实战导师 / 企业 AI 落地顾问 / 智能体工程师,17 年跨界、15,000+ 小时 AI 实操、20+ 套已交付工作流。 看完整履历海报 → skills 实验室 →