← 返回文章列表

A2A 中的 Agent Card:完整 JSON 示例与字段解析

Agent Card 是一份 JSON 文档,告诉客户端代理应调用谁、任务发到哪里、有哪些可用技能。在 A2A(Agent2Agent)协议中,卡片通常发布在 /.well-known/agent-card.json:没有它难以发现;描述含糊则难以正确路由。

  • Agent Card - 代理能力的公开契约
  • Discovery - 通过 well-known URL 或 registry 发现卡片
  • skills - 具体能力,而不是笼统的「什么都会」
  • capabilities - streaming、push、扩展卡片
  • security - OpenAPI 风格的认证方案

为什么需要 Agent Card

A2A 连接独立代理:一方是客户端,另一方是执行者。发送任务前,客户端会读取卡片并回答:

  1. 这个代理是否匹配用户意图?
  2. 哪个 endpoint 接收任务?
  3. 输入和输出支持哪些 MIME 类型?
  4. 是否需要认证,以及何种方式?
  5. 是否支持事件流与 webhook 通知?

卡片不是营销文案。编排器与 LLM 路由器会解析它。descriptionskillsexamples 越具体,执行者选择就越稳定。

完整 JSON 示例

下面是一个可运行示例:代理可在网站中搜索商品、计算价格,并在用户确认后创建线索。字段采用 camelCase,与常见 A2A JSON 卡片一致。

{
  "name": "Site Commerce Agent",
  "description": "搜索网站目录、计算价格与交期,并在用户确认后创建线索。处理目录、草稿购物车与订单状态。不处理支付,也不改价。",
  "version": "1.2.0",
  "protocolVersion": "0.3.0",
  "url": "https://api.example.com/a2a",
  "documentationUrl": "https://docs.example.com/a2a/commerce-agent",
  "iconUrl": "https://example.com/icons/commerce-agent.svg",
  "provider": {
    "organization": "Example Shop",
    "url": "https://example.com"
  },
  "capabilities": {
    "streaming": true,
    "pushNotifications": true,
    "stateTransitionHistory": true,
    "extendedAgentCard": false
  },
  "defaultInputModes": [
    "text/plain",
    "application/json"
  ],
  "defaultOutputModes": [
    "text/plain",
    "application/json"
  ],
  "skills": [
    {
      "id": "search-products",
      "name": "商品搜索",
      "description": "按查询、品类、价格与库存搜索商品。返回带 id、名称、价格与简短描述的候选列表。",
      "tags": ["catalog", "search", "products"],
      "examples": [
        "找本周可配送、800 欧元以下的笔记本电脑",
        "显示适合 20 人团队的可用套餐"
      ],
      "inputModes": ["text/plain", "application/json"],
      "outputModes": ["application/json", "text/plain"]
    },
    {
      "id": "calculate-quote",
      "name": "报价计算",
      "description": "为所选条目与数量计算价格、税费、运费与交期。不创建订单。",
      "tags": ["pricing", "quote", "shipping"],
      "examples": [
        "计算 product_id=sku-1042 共 3 件、配送到柏林的费用",
        "比较 50 用户的 Basic 与 Pro 套餐"
      ],
      "inputModes": ["application/json", "text/plain"],
      "outputModes": ["application/json"]
    },
    {
      "id": "create-lead",
      "name": "创建线索",
      "description": "在用户明确确认后创建线索或申请草稿。需要联系方式与数据处理同意。",
      "tags": ["lead", "order-draft", "crm"],
      "examples": [
        "为 ACME 创建 Pro 套餐申请,联系人:ops@acme.example",
        "根据 quote_id=q-7781 生成订单草稿"
      ],
      "inputModes": ["application/json"],
      "outputModes": ["application/json", "text/plain"]
    },
    {
      "id": "get-order-status",
      "name": "订单状态",
      "description": "按已认证用户的 order_id 或公开运单号返回支付与配送状态。",
      "tags": ["orders", "status", "tracking"],
      "examples": [
        "订单 ORD-20441 的状态是什么?",
        "运单号 TRK-998877 的包裹在哪里?"
      ]
    }
  ],
  "securitySchemes": {
    "bearer": {
      "type": "http",
      "scheme": "bearer",
      "bearerFormat": "JWT"
    },
    "oauth2": {
      "type": "oauth2",
      "flows": {
        "clientCredentials": {
          "tokenUrl": "https://auth.example.com/oauth/token",
          "scopes": {
            "catalog:read": "读取目录与报价",
            "leads:write": "创建线索",
            "orders:read": "读取订单状态"
          }
        }
      }
    }
  },
  "security": [
    {
      "oauth2": ["catalog:read"]
    },
    {
      "bearer": []
    }
  ]
}

在 A2A v1.0 中,endpoint 常用 supportedInterfaces 数组描述,而不是单一顶层 url。含义相同:告诉客户端任务发往何处、使用何种 binding(JSONRPCHTTP+JSONGRPC 等)。

v1.0 片段示例:

{
  "supportedInterfaces": [
    {
      "url": "https://api.example.com/a2a",
      "protocolBinding": "JSONRPC",
      "protocolVersion": "1.0"
    }
  ]
}

顶层字段解析

字段 是否必填 作用
name 可读的代理名称
description 具体摘要:做什么、不做什么
version 实现版本(建议 semver)
url / supportedInterfaces 是* 任务 endpoint,不是卡片 URL
skills 至少一个 skill
capabilities 建议 诚实的能力标志
defaultInputModes / defaultOutputModes 建议 默认 MIME
provider 所属组织
documentationUrl / iconUrl 文档与 UI 图标
protocolVersion 取决于 schema 协议版本(v0.3 常在顶层)
securitySchemes / security 客户端如何认证

* 在 v0.3 schema 中通常要求 url。在 v1.0 中由 supportedInterfaces 承担 endpoint 角色。

namedescription

name 给人与日志看。description 给路由器读。差:「有用的网站代理」。好:列出操作、边界与结果形态。

version

这是代理实现版本,不一定是协议版本。skills 或响应契约发生破坏性变更时提升 major。客户端可能缓存卡片,并在版本变化时重新拉取。

url - 常见错误

urlmessage/send / 任务的发送地址。它 不是 /.well-known/agent-card.json 的路径。

错误:

"url": "https://example.com/.well-known/agent-card.json"

正确:

"url": "https://api.example.com/a2a"

capabilities

标志 含义
streaming 支持流式响应(SSE / stream)
pushNotifications 长任务的 webhook 通知
stateTransitionHistory 任务状态变迁历史
extendedAgentCard 认证后可获取扩展/私有卡片

仅在真实实现时设为 true。对不支持 streaming 的代理开启 stream 会得到错误。

defaultInputModesdefaultOutputModes

整个代理的默认 MIME。skill 可覆盖。常见值:text/plainapplication/jsonapplication/pdfimage/png

skills 解析

skill 是路由单元。一个 skill = 一项清晰能力。

字段 是否必填 说明
id 在代理内唯一,kebab-case 便于管理
name UI 短名称
description 接受什么、返回什么、有何限制
tags 搜索与过滤关键词
examples 否但强烈建议 给编排器用的 2-3 个真实提示
inputModes / outputModes 该 skill 的 MIME 覆盖

examples 不是装饰。没有它们,编排器只能根据描述猜测输入,更容易出错。

差的 skill:

{
  "id": "website",
  "name": "Website",
  "description": "处理网站相关事务"
}

好的 skill 应如完整示例:具体 id、明确边界、tags 与 examples。

认证:securitySchemessecurity

方案通常遵循 OpenAPI 方式:

  • apiKey
  • http(Basic / Bearer)
  • oauth2
  • openIdConnect
  • mutualTLS

securitySchemes 描述可用方法。security 设定默认要求:

  • security 数组中多个对象 = 备选(OR);
  • 同一对象中多个键 = 全部需要(AND)。

公开的是认证 方式,不是密钥。不要把 API keyrefresh token 或内部主机名放进 JSON。

Discovery:如何发现卡片

典型流程:

  1. 客户端知道代理的基础域名。
  2. 请求 https://agent.example.com/.well-known/agent-card.json
  3. 校验必填字段。
  4. 按描述、tags、examples 选择 skill。
  5. security 完成认证。
  6. 将任务发到 url / supportedInterfaces

卡片也可发布在 registry 或代理目录中。此时 discovery 走搜索,well-known 仍是所有者的权威来源。

本地检查:

curl -s https://api.example.com/.well-known/agent-card.json

Agent Card 中不要发布的内容

  • API key、密码、私钥;
  • 未受保护的内部管理或 staging URL;
  • 外部客户端不可用的操作;
  • 夸大的 capabilities(未实现却写 streaming: true);
  • 「能做网站上的一切」这类含糊 skills。

公开卡片既是攻击面,也是路由面。保持精确且最小够用。

常见错误

  1. url 与卡片 URL 搞混。
  2. 空的 skills 数组。 代理几乎无法被路由。
  3. 没有边界的描述。 未说明不做什么(支付、删除、改价)。
  4. 缺少 examples 编排器更难理解合法输入。
  5. 生产卡片写 localhost。 客户端无法访问。
  6. 整个产品只有一个 skill。 更好拆成多个权限与 MIME 不同的窄 skills。

发布前小清单

  1. 通过 HTTPS 提供,且 Content-Type: application/json
  2. namedescriptionversion、endpoint 与至少一个 skill。
  3. 描述具体。
  4. 关键 skills 带有 examplestags
  5. capabilities 与真实服务器一致。
  6. JSON 中无密钥。
  7. 卡片中的 endpoint 能响应测试任务。
  8. 破坏性变更时升级版本。

总结

Agent Card 是 A2A 的主要 discovery 契约。带有精确 skills、诚实 capabilities 与明确 security 的完整 JSON,能让客户端代理找到正确执行者,并避免误调用。

若需要协助设计 Agent Card、A2A 服务器,或将代理接入网站 API - 请联系我

常见问题

Agent Card 应该放在哪里?

标准公开路径是代理域名上的 /.well-known/agent-card.json 也可注册到目录或 registry,但 well-known URL 仍是无需单独索引的便捷 discovery 入口。

url 与卡片地址有何不同?

卡片地址用于 discovery;url(或 supportedInterfaces)用于执行任务。 客户端先读取 JSON,再向代理的工作 endpoint 发送消息/任务。

一张卡片应该有多少 skills?

有多少真正不同、输入或权限不同的能力,就写多少。 通常 3-7 个窄 skills 优于一个笼统的「什么都做」。路由需要清晰边界、tags 与 examples。

Agent Card 必须声明认证吗?

不总是。 公开只读代理可以省略 security。涉及写入、个人数据与付费操作时,声明 securitySchemessecurity,并把密钥放在卡片之外。

每次部署都要更新卡片吗?

当 skills、endpoint、capabilities、auth 或代理含义变化时更新。 无契约变更的技术补丁可反映在 version;破坏性变更应提升 major 并配套明确文档。

联系方式