← 返回藏书阁

Microsoft A2A:Agent Card 适配与 host 运行责任分离

wiki/ai/sources/microsoft-a2a-adapter-host-ownership.md
分类:ai / sources · 更新:2026-09-14 09:16

Microsoft A2A:Agent Card 适配与 host 运行责任分离

会生成 Agent Card、会转换消息,不等于已经提供可安全部署的 A2A 服务。 应把 discovery、content conversion、executor、session、task store、auth 和 transport 的所有者逐一列出来。

知识点轴:A2A / harness-runtime / context management / sandbox-security。本页是官方文档与固定源码案例,不是已登录企业实例的部署验证。

为什么这对用户重要

Hermes 将来把外部 agent 作为可委派能力接入时,很容易把 streaming=true、自动生成 skills 或某个 SDK helper 当成完整生命周期保证。本案例提供可复用的组件责任分界,可以与 A2A-Agent2Agent-Protocola2a-jakarta-cross-node-state-and-effective-security 的跨节点案例一起设计接入验收,而不是再建一个只罗列 Card 的目录。

深读范围:Microsoft 官方 A2A overview/server 文档;microsoft/agent-framework commit 926b4ecacdaa95cb909c9d08f77b4fd898f273c0 的 hosting README、adapter、adapter tests,以及另一个包中的 _a2a_executor.py。仓库 13,503 stars(2026-09-14 API);源码固定不代表本机已安装或运行该版本。

一:同仓库两层 API,不能混写责任

对象提供什么不应据此推导什么
agent-framework-hosting-a2a原生 A2A 值转换、AgentA2AAdapter / WorkflowA2AAdapter、常见 Card 字段生成README 明确不提供 executor、task lifecycle、queue/store/routes、session policy、auth 或 deployment
agent_framework_a2aA2AExecutor将 agent 执行和响应转换为 A2A 事件,并使用 session 管理历史不是上面 hosting 包的隐式内置能力;其样例不证明多租户/跨节点部署安全
application-owned native A2A host挂载实际 binding、接收请求、管理 state、发布事件与 artifacts每项生产保证仍要靠应用实现和测试,不能靠 Card 宣告替代

两者可以是不同接入层级,而不是文档互相矛盾。尤其不能把另一个包的 A2AExecutor 功能全部归到轻量 hosting adapter 上。

二:Card 的能力、skills 与运行上下文不是同一个东西

AgentA2AAdapter 从 agent 推断名字/说明,默认保守地给出 text input/output。get_card() 是 async,以便 factory-backed state 解析目标。server capabilities 保持显式:它们描述应用实际提供的服务,不从 agent.run 的存在推断 streaming/push。

默认 infer_skills=True 会从 agent 的 SkillsProvider 发现 Skill,将其 name/description 变成 AgentSkill。文档特别指出:发现发生在 agent run 之外,没有 session。如果技能集合随 tenant/用户/session 改变,应使用显式 skills 或 infer_skills=False,不能让无会话目录变成全租户能力曝光。所读测试明确断言关闭推断后空 skills。

AgentInterface 应只列 host 真实挂载的 URL 和 JSONRPC / HTTP+JSON / GRPC binding。Card 是调用合同,不是自动部署器,也不是授权结果;这与 atlassian-rovo-a2a-live-card-and-enterprise-gates 的公开发现/企业授权分验一致。

三:类型转换有模式合同,也有绕过入口

  • 独立 a2a_to_run / a2a_from_run 默认宽松;传 input_modes / output_modes 才按合同校验。
  • adapter 方法默认按 Card 的配置模式校验,但 validate_modes=False 能关闭;要检查实际调用而非只读默认值。
  • 支持 text、JSON、raw bytes、具体媒体类型及 wildcard。自定义 mode 可被宣告,但没有内置 parser 时,宣告不代表能够凭空合成该表示
  • workflow 的推断模式要先通过 await adapter.get_card() 解析;输出中待人工输入的请求会抛出异常,交由应用实现 continuation,而不是自动获得持久化审批流程。
  • a2a_from_run 返回扁平 part list,并保留 content-level metadata;message/artifact 分组及其 metadata 边界由应用负责。

这与 Context-Engineering 的关系是:history、media、metadata 和身份都不是可随便丢弃的格式细节。转换失败应该显式暴露,不能静默降为一段文本后继续宣称协议等价。

四:历史、任务与流式输出需要不同键和回执

hosting README 的应用样例使用 a2a:{context.tenant}:{context.context_id} 作为 session key,并显式 get/create、run、set。另一个包的 A2AExecutor 所读路径以 task.context_id 建立 session;这只说明该路径的映射方式,不能从片段断言整个系统有或没有外层 tenant 隔离。

该 executor 的 stream 路径保留稳定的 default artifact ID;同一 artifact 后续 chunk 使用 append,避免每个 chunk 变成新文件。只转换面向用户的 text/data/URI,跳过不能映射的中间 function-call/result。这是有用实现证据,但不证明断流重订阅、跨节点恢复、exactly-once 或底层副作用取消成功。

Harness-Engineering 应分别记录 session key、task ID、artifact ID、caller/tenant、last event cursor 与业务幂等键。上下文连续≠task 可恢复,取消状态≠外部副作用被撤销。

给 Hermes 的隔离接入验收建议

  1. 固定 Card 与实际 route:只宣告挂载的 binding;对 streaming/push/HITL 分别列 executed / unsupported / not-tested。
  2. 做双 tenant、同 context ID 的负例;分别检查 session、task、artifact 查询和 registry 可见 skills。
  3. 对比 standalone 默认、adapter 默认、validate_modes=False 三条路径;加入 media 不匹配和未知自定义 mode。
  4. 中途断开 stream,检查稳定 artifact ID、append 去重与重订阅;不要把事件能读取当执行已接管。
  5. 单独验证 token、task ownership、取消副作用与独立业务状态,不从官方样例推出企业保证。

这些是建议,不是本轮已运行的服务。没有调用用户企业 endpoint 或上传会话。

证据边界与下一步

本轮对上述固定代码/测试做 6 项静态检查,全部通过;没有安装 SDK、运行 pytest/TCK、获取部署后的 Agent Card、启动 ASGI、测试鉴权/stream/push 或故障恢复。tests 中存在断言与本机实际通过该测试是不同证据层。

下一轮高价值信号是具体 host 的 task store、授权中间件、取消实现和带 tenant 的实际 trace;仅新增 helper API 名称不再新建来源页。

来源与关联

写入记录

  • 2026-09-14 09:15 CST:新增官方 A2A adapter/host 责任案例;明确两包差异、无 session 的 skill discovery、模式校验 opt-out 及 session/task/artifact 分验;只声明静态证据。