AWS AgentCore A2A:托管契约、重试语义与健康状态
AWS AgentCore A2A:托管契约、重试语义与健康状态
结论与深度判断
“透明代理”只说明某一层不改 payload,不代表错误、鉴权、端口和 session 生命周期都透明。 这个案例值得深挖,不是因为又有一个 A2A 平台,而是官方文档与 SDK 给出了可以逐项核查的 host 接缝:Agent Card 的实际地址、协议版本分支、非 2xx 错误体、健康状态和监听端口。
命中知识点轴:A2A / harness-runtime / sandbox-security(身份与执行边界);错误分层也能迁移到 MCP-Gateway-Runtime,但本轮没有验证 MCP 联邦能力。主归属 A2A-Agent2Agent-Protocol、Harness-Engineering。
证据范围与版本
- 官网:协议契约、部署教程,于 2026-09-17 完整抓取并阅读正文;页面未给本轮可核发布日期,不包装成“今日发布”。
- SDK 固定源码:
git ls-remote固定 main=aea20050dd6c47e0ec19dda93694addf3bf7d778;同 commit 的 examples 与 pyproject 已归档。pyproject 写1.23.1,不据此声称 PyPI 最新发布版本。 - API 元数据限流,未取得可靠 star。抓取的 main 与固定 commit 的 a2a.py 字节一致。未部署 AWS、取得真实 Agent Card、运行 OAuth/SigV4、SSE/push/TCK 或上游 pytest。
机制一:wire contract、SDK extra、部署入口分开
AgentCore 的容器契约为 ARM64、0.0.0.0:9000、根路径 POST / 与 GET /.well-known/agent-card.json;外部调用则通过包含编码 ARN 的 runtime invocation URL。Card 必须广告可达的外部入口,而不是容器 localhost。SDK 用 AGENTCORE_RUNTIME_URL 覆盖相应 JSON-RPC 地址。官网 Card 示例的服务 version=1.0.0,协议却是 protocolVersion=0.3.0,两者不能混用。^[raw/articles/aws-agentcore-a2a-host-contract-and-health-semantics-2026-09-17.md]
固定 pyproject 的 a2a extra 要求 a2a-sdk>=0.3,<0.4,a2a-v1 要求 >=1.0.1,<2.0,并声明互斥。代码通过 StreamResponse 能否导入识别 v1 API;v1 分支构建 supported_interfaces、JSONRPC/1.0,并启用 v0.3 compatibility。这是依赖/API 分支,不是远端握手已通过。 官网教程的 client 又明确 streaming=False;Card 声明 streaming 不能将该教程升级为 streaming 验收。^[raw/articles/aws-agentcore-a2a-host-contract-and-health-semantics-2026-09-17.md]
这补充 microsoft-a2a-adapter-host-ownership:同为 A2A,应用 adapter、托管入口、SDK major 和实际能力分别验;对比 foundry-apim-a2a-discovery-and-credential-hops,不要把另一个 provider 的 header 或 Card 路径直接搬来。
机制二:HTTP 错误不能抹掉业务重试语义
官方契约明确返回实际 HTTP 错误码,部分 runtime 错误体仍是 JSON-RPC。ConflictException 和 RetryableConflictException 都可能是 HTTP 409 / JSON-RPC -32054,但后一种消息是 Session operation in progress, please retry,描述 session 正在创建或销毁;文档要求 caller 自己短指数退避,不能假设 A2A client 自动处理。只按 409 或只按 JSON-RPC code 分组会误判。^[raw/articles/aws-agentcore-a2a-host-contract-and-health-semantics-2026-09-17.md]
建议客户端分别保留 http_status / content_type / parsed_error / message / request_id / session_id / retry_reason:对可解析的非 2xx 响应先保留错误体,再决定重试;OAuth 缺认证的 401 + WWW-Authenticate 与 SigV4 的 403/无该头分开处理。不是“所有错误先重试”,更不是写操作超时可盲重放;状态不明时仍回查 task/独立业务状态及幂等键。该规则与 hyper-tau-bench-evidence-recovery-and-agent-construction 的 post-commit timeout 正好形成反例对照。
机制三:health signal 参与资源生命周期,不只是绿色图标
/ping 的 HealthyBusy 会使 session 保持活跃;可选 time_of_last_update 应是状态变化时间,而非每次探测的当前时间。官方警告不断推进该字段会阻止 idle timeout,直到 MaxLifetime,可能耗尽 session quota。这是事件时间与采样时间的区别。^[raw/articles/aws-agentcore-a2a-host-contract-and-health-semantics-2026-09-17.md]
固定 SDK _handle_ping 在自定义 callback 抛异常时记录日志并回退 Healthy,返回体只含 status。因而“收到 Healthy”不能推出 callback 成功,更不能证明 executor 当前没有业务故障;另一方面,回退也丢失 Busy 信号,但是否造成提前回收须结合实际部署计时器验证,不能从静态代码直接下结论。InMemoryTaskStore 默认也不提供跨进程持久化。^[raw/articles/aws-agentcore-a2a-host-contract-and-health-semantics-2026-09-17.md]
BedrockCallContextBuilder 负责抽取/传播 request、session、token 和 headers;该方法并没有自行完成 IdP 验证。直接本地调用该层、注入 header,不等价于穿过 AgentCore 入站鉴权。不要把 session ID 当认证,也不要把原始 headers 写进可公开 trace。
本机实际核查与可执行启发
仅抽取已阅读的函数 AST;uvicorn.run、app builder、JSONResponse 等均用替身,不启动端口、不调用模型:
- ping default → Healthy;busy callback → HealthyBusy;callback exception → Healthy。
PORT=8080被忽略,默认仍 9000;A2A_PORT=9001生效,显式port=9002优先;非法 scoped port 触发 ValueError。传给 app 的本地 Card URL 随所选端口改变。- 文档 JSON/AST 检查确认 service/protocol version 不同,教程同步 client 不请求 streaming。
完整脚本、输入、16 项联合核查回执见 raw/assets/ai-radar-20260917/;其中还包含另一篇论文表格核查,16 项并非本项目 16 个 E2E 测试。
对 Hermes 接入远端 agent 的最小后续验收:固定依赖与有效 Card;让 HTTP status 与 JSON-RPC error 同时进入错误分类;对 callback 故障增加独立日志/告警;对 port、健康状态、task store、认证边界分别测试。以上是接入建议,没有修改当前 Hermes runtime、网关或安全策略。
未解问题
- 真实 OAuth/SigV4 下的 Card 与 invocation 权限、tenant/session 隔离、断流重订阅、push 出站均未运行。
- 示例 LangGraph
cancel只有pass,不可将存在方法当取消成功;实际 executor 需独立审核。 - v1 compatibility、外部 URL 更新及 HTTP 错误行为还需要对应 SDK/服务版本的集成测试;源码快照不替代服务端回执。
写入记录
- 2026-09-17 09:08 CST:新增官方托管契约、固定SDK与离线函数核查;区分协议/服务版本、HTTP重试、ping生命周期和真实部署边界。