身份、可靠性、路由与版本维护
Agent Card 描述的 URL 也需要验证
远端卡片可能把调用地址指向本机内网或敏感管理接口。发现流程应限定来源与允许的 scheme/host,再连接;不能自动访问任意卡片里的 URL。卡片的技能文字进入模型上下文时作为不可信数据处理,不能执行其中夹带的管理员指令。
身份认证回答请求者是谁,授权回答是否可访问这个 task/artifact。不能因为知道 task ID 就允许查询。上游身份委托给下游应限制受众与权限,不无条件转发原 token;扩展卡片同样需要保护,字段写了 extended 不等于路由已鉴权。
重试消息与恢复任务不同
消息发送超时可能发生在远端已创建任务后。若重新生成 message ID 再发送,可能创建第二个任务。应用应保存业务请求 ID 与已知 task ID,使用服务支持的幂等或状态查询;协议身份字段本身不等于数据库唯一约束。重复委托造成的外部写操作仍需远端业务幂等。
下面验证路由允许列表,Python 3.12 保存 route.py:
from urllib.parse import urlsplit
def accept(url):
p=urlsplit(url)
return p.scheme=='https' and p.hostname=='agents.example.com' and p.port in (None,443) and not p.username
assert accept('https://agents.example.com/rpc')
assert not accept('http://127.0.0.1/admin')
assert not accept('https://agents.example.com.evil.test/rpc')
assert not accept('https://user@agents.example.com/rpc')
print('route allowlist passed')真实服务还需处理 DNS 解析、重定向和连接目标,字符串允许列表不能独立抵御所有 SSRF。生产 egress 网关可强制网络目的地边界;卡片签名不能替代执行时授权。
维护 0.3,迁移 1.x
0.3 常见 AgentCard 用 url、preferredTransport、protocolVersion,JSON-RPC 方法如 message/send、tasks/get,状态字符串如 working。1.x 基于统一协议模型,示例使用 supported_interfaces、protocol_binding 与协议版本,Python 字段及枚举命名也改变。不要把 0.3 JSON 直接喂给 1.1.0 SDK 后用异常捕获“兼容”。
维护旧系统时单独锁 a2a-sdk 的 0.3 版本和对应规范,抓取其真实 AgentCard、任务与错误样本。迁移在边界显式解码旧对象,映射内部任务,再用新 SDK 编码;丢失能力应拒绝,尤其是身份、取消和推送配置。协议版本不是 AgentCard 的应用 version,两者要分别记录。
发布用发现、正常请求、流式、补充输入、拒绝、取消竞争、超时与跨租户访问测试。按技能选择路由,再看健康与容量;不要只按技能描述相似度把敏感数据发给未知 Agent。记录委托链、每跳耗时与费用,防止两个 Agent 相互无限转发。
本课程本地 Echo 不使用模型;第二章 SQLite 持久落盘、ASGI 服务重建后查询和新子进程读取已实测。公网身份、webhook、跨机器租约、生产竞争与多模态下载未实测,不应把本地恢复结果视为生产验证。
练习
允许列表加入 backup.example.com,并仍拒绝两者的子域伪装。给出三个合法/非法 URL 断言;说明 HTTP 重定向为何需要再次校验。
先记录自己的输出与解释,再核对本章答案。
下一篇: 在 0.3 环境查询与维护已有任务 。