教程

AI Agent 如何自動發現另一個 Agent?從 Agent Registry、A2A Agent Card 到 JSON Capability Discovery 完整解析

發現失敗時,先問走的是哪一跳:搜目錄、拉名片,還是已經握着域名卻 GET 錯了路徑。

上一篇 Agent Card 字段教程 把 1.0 必填表攤開了。今天不重填字段,也不重講 Registry 是目錄。編排者的下一問是:我怎麼從「需要會辦退貨的同事」走到一張可調用的 Card?官方答案在 A2A Agent Discovery:策略有三條,Card 只有一種。規範不規定策展目錄的查詢 API,見同一頁的 Considerations。Google Cloud 的目錄是其中一種落地,形狀對照 Registry JSON schemas。本文按 hop 走查。橫向委託和向下調工具的分層,見 A2A vs MCP,今天不重講。

發現不是協議,Card 纔是被找到的東西

A2A 標準化的是自述,不是電話本。遠程 Agent 把能力寫成 JSON 名片;客戶端用這張卡判斷適不適合、怎麼連、發什麼 Task。發現方法隨環境變:公網、企業目錄、開發機寫死,三條都能到同一份 Card。把「發現」說成又一種對話協議,評審會先走偏。協議仍是 A2A;變的是你從哪一扇門走進 well-known 或目錄。

官方發現頁上的「Role of the Agent Card」仍用 0.3 口氣提到頂層 url。新卡按 1.0:端點在 supportedInterfaces,見 v1.0 變更。發現 hop 讀到舊字段,不要當 1.0 主合同。字段怎麼寫,上一篇已經寫過。今天只問:這張卡是從哪一跳到手裏的,到了之後先核哪幾個鍵。

發現成功,不等於可以 tools/call。對面仍是不透明 Agent。你選出 skill、挑好接口,發送的是 Task。把搜索命中當成函數表,多輪澄清會撐破 arguments。MCP 那一跳怎麼核參數,見站內 Schema 文。今天停在「找到誰、憑什麼認定他會辦這件事」。

策略 你事先知道什麼 下一跳
Well-known URI域名或主機GET /.well-known/agent-card.json
策展目錄技能關鍵詞 / 標籤查目錄,再拉 Card 或引用
直接配置URL 或整張卡跳過搜索,直接讀卡

三條官方策略,先選路再走路

Well-known 適合公開 Agent,或域名受控的發現。路徑跟 RFC 8615:https://{agent-server-domain}/.well-known/agent-card.json。客戶端已經知道或能推出域名,發 HTTP GET,拿到 JSON。實現簡單,自動化友好。名片裏有敏感技能或內網 URL,這個 GET 本身就要鑑權,不能把內網端點裸掛在公網。

策展目錄適合企業或市場:中間服務收一批 Card,客戶端按 skills、tags、provider、capabilities 查詢,目錄返回匹配的卡或引用。好處是治理和按能力搜。代價是你要養這份目錄。A2A 沒有規定目錄 API。Google Agent Registry、社區 registry、自建目錄,查詢形狀各寫各的。不要拿一份「通用 discover JSON」去校驗三家。

直接配置適合緊耦合、私有 Agent、開發機。卡 URL 寫在環境變量、配置文件或專有 API。關係靜態時最省事;Card 一變,客戶端要跟着改。生產裏把「開發機寫死」當成唯一發現面,就是 2025 年通訊錄。三條路可以並存:目錄負責搜到誰,well-known 負責目錄掛了還能讀名片,配置負責啓動時的種子主機。

手裏有域名:GET well-known

最乾淨的 hop 只有三步。① 得到域名,例如 returns.agents.example.com。② GET https://returns.agents.example.com/.well-known/agent-card.json。③ 響應是一張過 1.0 Schema 的 Card。路徑寫錯、HTTP 換成內部別名、證書主機名對不上,故障單上會寫成「發現失敗」,其實 Card 是好的,GET 沒打到。

規範建議 Card 端點帶緩存頭。Cache-Control: max-age=… 讓中間層和客戶端少打滿卡;ETag 可用 version 或內容哈希。過期後先條件請求(If-None-Match),不要每次無條件拉全文。服務器沒給緩存頭,客戶端可以自己設一個合理默認,但不能永久緩存一張會改 skills 的卡。

公開卡夠編排者選型即可。敏感技能、內網第二端點,放到認證後的擴展卡。capabilities.extendedAgentCard 爲真,纔去拉第二份。發現 hop 不要在未認證時假設擴展卡存在。目錄按身份選擇性返回不同 Card,和 well-known 上一張對所有人相同的卡,是兩種披露,評審裏要分開寫。

手裏有目錄:搜 tags,再拉 Card

沒有域名、只有一句「找會分類退貨的同事」時,走策展目錄。查詢喫的是 Card 上的 skills[].tags 和技能名,不是你幻燈片上的拓撲。Google 項目內的編排者、Gemini Enterprise、Agent Gateway 按技能關鍵詞找登記項——這是產品行爲,不是 A2A 標準 RPC。社區或其他雲各有各的 search。評審夾具裏只斷言「查詢 → 命中列表 → 每條帶 cardUrl 或內嵌 Card」,不要把某一家的路徑寫成規範。

目錄返回引用時,下一跳仍是 well-known 或目錄給出的 Card URL。返回內嵌 Card 時,仍要用 1.0 Schema 核一遍:登記成功不等於字段合法。NO_SPEC 那種只有主機、沒有 skills 的條目,搜索面是空的——#5 寫過,今天只提醒:關鍵詞 hop 打在空索引上,不是協議壞了。

目錄掛了,並不自動等於發現結束。手裏若已有域名,客戶端仍應 GET well-known。把目錄當成唯一真相,等於把發現面單點化。種子配置裏留一兩個穩定主機,目錄恢復後再做關鍵詞搜索,比「目錄 500 就停擺」更接近規範寫的三條並存。

命中之後:對 skills,挑接口,發 Task

搜索命中只說明「可能是他」。編排者還要對 skills[]:id 是否就是你要委託的那類事,tags 是否真的命中查詢詞,description 的邊界是否接受。不要用 MCP inputSchema 去套 skill。1.0 的提示是 examples 和 MIME。選錯 skill 再發 Task,失敗發生在委託,不在發現;但夾具要把「命中 ≠ 選定」寫成兩步。

選定之後讀 supportedInterfaces。第一項是首選。客戶端按自己會的綁定挑:JSONRPC、GRPC、HTTP+JSON。挑不到共同綁定,發現成功、通話失敗。0.3 頂層 url 不要當 1.0 主端點。能力旗標也要看:streaming 爲假還訂流式,規範要求回能力錯誤,不是默默改成 unary。

下面是一份走查夾具,不是任何一家目錄的官方 API。它把查詢、命中、首選接口收成 JSON,方便和倉庫裏的 Card 並排 diff。下一步纔是 message/send。校驗清單和簽名留給更後面一篇。

{
  "kind": "discovery-trace",
  "note": "CI/review fixture — not an official A2A or Google Registry API",
  "query": {
    "tags": ["returns", "classify"]
  },
  "strategy": "curated-registry",
  "hits": [
    {
      "name": "Returns Specialist",
      "cardUrl": "https://returns.agents.example.com/.well-known/agent-card.json",
      "matchedTags": ["returns", "classify"],
      "skillId": "classify-return"
    }
  ],
  "selected": {
    "skillId": "classify-return",
    "preferredInterface": {
      "url": "https://agents.example.com/returns/a2a",
      "protocolBinding": "JSONRPC",
      "protocolVersion": "1.0"
    },
    "next": "message/send"
  }
}
這一跳 輸入 你該斷言什麼
搜目錄tags 或技能名命中列表非空,且帶引用
拉 well-known域名或 cardUrlJSON parse,過 1.0 Schema
選型 / 挑接口完整 1.0 Cardskill id 對上,接口客戶端會說

緩存、過期與夾具

Card 改得不勤:加技能、改鑑權纔會動。發現面卻會髒。目錄索引滯後,well-known 已是新 version,搜索還指向舊 tags。夾具至少兩份:目錄命中快照,和剛 GET 到的 Card。keywords 對不上,先查 tags 和索引延遲,再查是不是 1.0 客戶端讀了 0.3 卡。

{
  "hop": "well-known",
  "method": "GET",
  "url": "https://returns.agents.example.com/.well-known/agent-card.json",
  "requestHeaders": {
    "If-None-Match": "1.0.3"
  },
  "response": {
    "status": 304,
    "etag": "1.0.3",
    "cacheControl": "max-age=3600"
  }
}

規範寫:敏感數據必須鑑權,推薦帶外動態憑證,不要把靜態密鑰寫進 Card。發現夾具裏出現 token、內網密碼,評審直接打回。公開卡按會被拉取來寫。擴展卡的緩存跟會話走,不要和公開卡的 max-age 混成一個桶。

也不要把 Plugin SKILL.md 或 MCP tools/list 當成發現源。同一倉庫裏的 Coding Agent 怎麼長技能,是箱子的事;另一個團隊的退貨 Agent 怎麼被找到,是 Card 的事。混進同一份「capability.json」,三跳失敗會算到同一行。

瀏覽器裏即可完成:JSON 格式化看走查夾具和 Card 能否 parse;JSON Schema 校驗核命中後的 1.0 Card;JSON Diff對比目錄快照和剛拉到的 Card,抓 tags / 接口 drift。數據不離開本機。延伸閱讀:Agent Card 字段教程、Registry 總覽。簽名與校驗清單讀下一篇實戰。

相關文章:A2A Agent Card JSON Schema、Google Agent Registry、A2A vs MCP。

常見問題 FAQ

有了目錄,還要不要 GET well-known?

要。目錄消費 Card,不替代 Card。規範把 well-known 寫成公開發現的標準路徑。目錄掛了,拿得到域名的客戶端仍應讀名片。

A2A 有沒有標準的「搜索 Agent」RPC?

沒有。發現頁寫明:當前規範不規定策展目錄的 API。各家目錄自己定義查詢。標準的是 Card 的形狀和 well-known 路徑。

搜到了能不能直接 tools/call?

不能。命中是發現結果。對面是不透明 Agent,走 Task。確定性參數留給 MCP 工具,不要寫進發現 hop。

緩存多久算合理?

先聽服務器的 Cache-Control 和 ETag。沒給頭,用短默認,過期走條件請求。技能或鑑權一變,version 應變,客戶端不該抱着舊 tags 做生產路由。

總結與下一步

2026 年說「自動發現另一個 Agent」,可以收成三跳:選策略、拿到 Card、按 skills 和接口決定要不要委託。目錄是其中一扇門,不是協議本身。

落地順序:公開 Agent 先掛對 well-known;要按關鍵詞找,再接入某一家目錄並自備查詢夾具;命中後核 1.0 Card 再發 Task。字段怎麼寫讀上一篇;目錄是什麼讀 #5;校驗與簽名讀更後面一篇。用 JSONVue 對走查 JSON 和倉庫 Card。