A2A 协议代理卡怎么写,任务端点怎么调

先理清 A2A 配置到底在配什么

A2A(Agent-to-Agent)协议要解决的是让两个独立部署的 AI 代理能互相发现、互相派活。
配置工作主要落在三处:

  • 代理卡(Agent Card):一个 JSON 文件,声明“我是谁、我能干什么、你该往哪个地址发任务”。
  • 服务端入口:接收任务请求、返回任务对象、支持查询任务状态的 HTTP 端点。
  • 客户端配置:知道去哪里拿到代理卡,并按卡里的地址发起调用。

如果目标是让本地代理被另一个代理调用,先把这三件事分开,再逐项填。
下面用最小示例走一遍,不依赖特定厂商 SDK。

准备一份能读懂的代理卡

代理卡通常放在服务端根路径下,例如 https://your-agent.example.com/.well-known/agent-card.json。
文件内容至少要让调用方知道身份、能力和技能入口:

{
  "name": "weather-agent",
  "description": "提供城市天气查询",
  "url": "https://your-agent.example.com/a2a",
  "version": "0.1.0",
  "capabilities": {
    "streaming": false,
    "pushNotifications": false
  },
  "skills": [
    {
      "id": "query-weather",
      "name": "查询天气",
      "description": "输入城市名,返回当前天气"
    }
  ]
}

几个容易填错的地方:

  • url 是任务请求端点,不是代理卡本身的地址。客户端拿到卡后,会往这个地址 POST 任务。
  • capabilities.streaming 表示服务端是否支持流式返回。如果填了 true 但服务端没实现对应处理,客户端可能一直等不到完整响应。
  • skills 里的 id 建议保持稳定,客户端可能按技能 ID 路由请求。

代理卡本身是公开可读的,不要在里面放密钥、内部 IP 或数据库连接串。

把服务端任务入口跑起来

A2A 的任务请求通常走 JSON-RPC 风格,方法名和消息体格式以你所用的协议版本为准。
下面是一个最小 HTTP 处理逻辑的示意(Node.js,仅用于说明请求形态,不是完整生产代码):

// POST /a2a
// body: { "jsonrpc": "2.0", "id": "1", "method": "tasks/send", "params": { ... } }

app.post('/a2a', (req, res) => {
  const { method, params } = req.body;
  if (method === 'tasks/send') {
    const taskId = crypto.randomUUID();
    // 先返回任务对象,异步处理
    res.json({
      jsonrpc: '2.0',
      id: req.body.id,
      result: {
        id: taskId,
        status: { state: 'submitted' }
      }
    });
    // 后续再通过 tasks/get 查询状态
  }
});

关键点:任务提交和任务完成是两件事。
客户端拿到 submitted 状态后,需要按协议约定轮询 tasks/get,或者由服务端在支持的情况下推送更新。
如果服务端同步处理完才返回,长任务容易触发客户端超时。

如果你的服务端前面有 Nginx,确认 /a2a 路径没有被改写成静态文件,并适当调大 proxy_read_timeout,否则流式返回会被提前切断。

客户端发现代理与发起调用

客户端配置的核心是“卡从哪来、任务往哪发”。
一个最小调用流程:

  1. 请求 /.well-known/agent-card.json 拿到代理卡。
  2. 解析 url 字段,得到任务端点。
  3. 向该端点 POST 任务请求,携带 JSON-RPC 方法名和参数。
  4. 根据返回的任务 ID 轮询状态,直到 completed 或 failed。

用 curl 验证发现阶段是否通:

curl -s https://your-agent.example.com/.well-known/agent-card.json | jq .

返回 200 且 JSON 可解析,说明发现这一步没问题。
再验证任务端点:

curl -s -X POST https://your-agent.example.com/a2a \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":"1","method":"tasks/send","params":{}}'

如果代理卡能拿到但任务端点返回 404,优先检查 url 字段是否写成了代理卡地址,以及反向代理是否把 /a2a 转发到了后端服务。

调不通时按这个顺序查

代理卡返回 404:检查文件是否真的放在 /.well-known/ 路径下,以及 Web 服务器是否允许访问以点开头的目录。
Nginx 常见配置是 location /.well-known/ { root /var/www/agent; },确认 root 拼写和文件权限。

任务一直停在 pending 或 submitted:说明提交成功了,但服务端没有推进状态。
检查后台任务队列是否在消费,以及客户端是否真的在轮询 tasks/get。
有些实现要求客户端带上同一个任务 ID 查询,漏传会查不到。

流式响应超时:先确认 capabilities.streaming 与服务端实现一致。
不一致时把能力声明改为 false,用轮询方式先跑通,再单独调流式链路。

跨域被浏览器拦截:A2A 客户端通常是服务端程序,不涉及浏览器同源策略;
如果确实从网页发起,需要在任务端点和代理卡路径上都返回合适的 CORS 头。

验证配置是否真的生效

配置完成后至少做三项检查:

  • 用 jq 解析代理卡,确认 url 是一个可访问的绝对地址,且与客户端实际请求的地址一致。
  • 提交一个最小任务,确认返回体里有任务 ID 和状态字段。
  • 用同一个任务 ID 查询一次状态,确认服务端能返回该任务,而不是 404 或空结果。

如果服务端日志里能看到任务提交记录,但客户端拿不到结果,问题多半在状态查询环节,而不是代理卡本身。
把提交和查询分开看,能少走很多弯路。

两个常见疑问

代理卡必须放在 .well-known 下吗? 协议约定使用这个路径是为了让发现过程标准化,但客户端也可以配置成从任意 URL 拉取。
如果对方代理只认标准路径,就按标准放。

A2A 和直接调 HTTP API 有什么区别? 直接调 API 需要调用方事先知道每个接口的地址和参数;
A2A 多了一层代理卡来描述能力和入口,适合代理数量多、需要跨团队复用的场景。
单个固定接口没必要为了用协议而加一层。

分享到:
上一篇
MCP 企业级部署前要准备哪些基础设施与安全边界
下一篇
A2A Agent Card 配置怎么写:从字段填写到端点验证
1
系统公告

关于香港云优质服务器IP地址更换的通知

尊敬的客户: 因原IP运营商大幅涨价,为避免成本转嫁至用户,我司决定更换IP服务商。本次更换后,您的续费价格将保持不变,且新IP网络质量与服务标准不受影响。新IP已分配至后台,即刻生效(更换的新IP都是香港原生IPv4)。 涉及 IP 段: 45.192.x.x 旧 IP 停用时间: 2026 年 12 月 1 日
服务中心
客服
在线客服
24小时为您服务
咨询
联系我们
联系我们,为您的业务提供专属服务。
24/7 技术支持
如果您遇到寻求进一步的帮助,请过工单与我们进行联系。
24/7 即时支持
泽御云
售前客服
泽御云
泽御云
售后客服
泽御云
技术支持
评价
您对当前页面的整体感受是否满意?
😞
非常不满意
😕
不满意
😐
一般
🙂
满意
😊
非常满意