谷歌的ADK(Agent Development Kit)最近暴露了一个让人哭笑不得的问题:用官方提供的一行代码部署AI代理,上线后自家客户端居然连不上自家服务器。更离谱的是,报错信息还把真正的原因给藏了起来。
一行代码的诱惑与陷阱
ADK提供了一个叫to_a2a()的方法,能把一个AI代理变成A2A(Agent-to-Agent)服务器。这确实是目前从LlmAgent到能被其他厂商代理调用的最短路径,也是很多开发者选择它的原因。
但问题出在部署环节。这个方法会把host:port直接写进代理卡片的接口URL里。在Cloud Run上运行时,进程绑定的是0.0.0.0:8080,于是部署后的代理卡片就变成了这样:
一个公开的HTTPS端点,却在广播一个无法路由的明文地址。这在本地开发时完全看不出来——因为本地运行时绑定地址和拨号地址是同一个字符串,所以问题被完美隐藏到了生产环境。
自家代码连自家服务器,失败
最讽刺的是,ADK自己的客户端连不上ADK自己部署的服务器。谷歌自家的测试全部通过,因为本地测试时两个地址是相同的。唯一完全由第一方代码组成的配对,恰恰是无法完成一次通信的那一对。
而且失败信息报错了层级。拨号0.0.0.0:8080失败后,RemoteA2aAgent抛出的错误是:
AttributeError: 'A2AClientError' object has no attribute 'status_code'
错误处理器假设所有A2AClientError都带有状态码,但传输失败并不携带。真正的原因——"所有连接尝试均失败"——被单独记到了另一行日志里。两个缺陷叠加:第一个把客户端送到无法路由的地方,第二个删掉了它去哪里的证据。
同一个回复,被送了两遍
如果你现在用to_a2a()部署服务,建议先抓取自己的代理卡片看看。如果修不了卡片,至少确保调用方在解析后重写接口URL,而不是直接按它路由。
另一个坑在回复传递上。ADK的执行器会把回复作为任务工件附加,同时也在任务历史里留一份副本。这在ADK内部使用时没问题,但跟别人对接时就出事了。
微软的A2AExecutor驱动完整的任务生命周期,但只在历史里留回复,工件是空的。所以一个只读工件的客户端——这是最直观的实现方式,也是跟ADK配合完美的方案——在对接Agent Framework时会返回空字符串。不是错误,不是超时,而是一次成功调用但没有内容。
解决办法是读取规范允许的所有载体,这样ADK的回复就会到达两次。这个项目的早期版本里,代理返回的是汇率数据,重复投递的问题就已经存在了。
热门跟贴