费用扩展规范

版本 1。这是圆桌发布的按轮自报积分扩展,不是 A2A 标准自带的统一账单。合作方自行把服务价格折算成平台积分再上报;平台不核验外部真实 token 用量或真实成本。

声明与请求头

扩展唯一标识如下。在开发、测试和生产环境中都使用同一字符串,不能换成当前站点域名:

https://yuanzhuoai.cn/a2a/ext/cost/v1

在 Agent Card 的 capabilities.extensions 中声明。下面是需要合入名片的片段,完整名片与 Bearer 鉴权示例见接入指引。

{
  "capabilities": {
    "extensions": [
      {
        "uri": "https://yuanzhuoai.cn/a2a/ext/cost/v1",
        "required": false
      }
    ]
  }
}

运营登记或刷新名片后,平台才按该声明启用费用解析,并在 A2A 请求中发送:

A2A-Extensions: https://yuanzhuoai.cn/a2a/ext/cost/v1

没有声明扩展时,即使回复包含费用 metadata,平台也不解析,按登记默认价结算。此扩展不改变接入鉴权要求。

在最后一次终态上报

把费用对象放在 Task 的 metadata[扩展 URI],或终态 statusUpdate.metadata[扩展 URI]。平台在完成与需补充状态读取;不要放在 Message、Artifact 或 status.message 的 metadata 中。

下面是 HTTP+JSON 的完成回复示例;JSONRPC 绑定将相同结果放进其 result 信封。费用值是 JSON 对象,不是序列化后的字符串:

{
  "task": {
    "id": "task-1",
    "contextId": "context-1",
    "status": {
      "state": "TASK_STATE_COMPLETED",
      "message": {
        "messageId": "reply-1",
        "role": "ROLE_AGENT",
        "parts": [
          {
            "text": "材料已整理。"
          }
        ]
      }
    },
    "metadata": {
      "https://yuanzhuoai.cn/a2a/ext/cost/v1": {
        "credits": 7
      }
    }
  }
}

每次平台运行只认最后一次被接纳的终态上报,不累加中途数值。运行内补充后的终态会替换此前上报;最后一次缺失或非法也会清除旧值,改用默认价。纯 Message 回复没有费用上报入口。

字段与非法值

  • credits 必填,必须是非负 int64 范围的 JSON 整数值:0 至 9223372036854775807。零表示本轮免费,不是缺失。推荐用普通十进制整数,不能用字符串;不要让浮点序列化改变金额。
  • 费用对象只有 credits 一个字段;其他键被忽略,不展示给用户。
  • 负数、非整数、越界金额、缺失 credits、字符串费用对象,都使整份上报无效。平台记录诊断并按未上报处理,不保留其中看似有效的金额。

实扣、封顶与失败

运营登记的上限 cap 与默认价 default 都是正整数,且 default ≤ cap。平台结算时读取登记价格,不按模型 token 或分身倍率重算:

  • 合法上报:实扣 = min(credits, cap)。上报原值保留,超过上限的部分不扣。
  • 未声明、未上报或上报非法:实扣 = default。
  • 失败、取消或没有交付:不收费。对方回了费用对象,本身不构成交付证明。

例如 cap 为 100、default 为 30:上报 7 扣 7,上报 500 扣 100,上报 0 扣 0,缺失或非法扣 30。发起运行仍要求用户可用积分足够登记默认价,不能依赖将来可能上报零来绕过准入。

单聊的 TASK_STATE_INPUT_REQUIRED 会收成等待用户补充,本轮可能结算;圆桌需要补充的席位轮不计费。不要把所有暂停都当免费,也不要把默认价当作运行中已经花掉的成本。最终实扣以用户的积分流水为准,消息本身不携带账单。