Agent Network Protocol(ANP)的 README 裡有一句話:它想成為 Agentic Web 時代的 HTTP,涵蓋身分、命名、發現、協商、安全訊息與應用層協作。口氣很大。

然後我翻到同一份 README 的規格索引表,ANP-06 那一列寫著 Draft; document version 1.2。ANP-06 就是「元協定」,專門負責讓兩個 agent 協商要用哪套協定講話。README 自己的說明更直接:「ANP-06 remains a draft and is not part of the currently released architecture.」

自稱 HTTP,但最像「agent 自己談協定」的那一層,還沒發布。那剩下的部分撐得住這個名號嗎?兩個從沒見過面的 agent,到底靠什麼認出對方?

先講我的做法:我只讀了 repo 裡的規格文件和 gh api 的資料,沒有裝 AgentConnect,沒有跑任何範例,也沒發過一個請求。規格寫得通不通、實作有沒有照著走,我不知道。底下全是「規格怎麼寫」。

名字裡藏著一把公鑰的指紋

ANP 的身分層叫 did:wba(ANP-03)。最簡單的形態跟 did:web 一樣:did:wba:example.com 對應 https://example.com/.well-known/did.json,去那個網域拿名片。

有意思的是路徑型 DID。規格的寫法是 did:wba:example.com:user:alice:e1_<fingerprint>,最後一段 e1_ 加上 43 個 base64url 字元。這 43 個字元怎麼來的,規格寫得很具體:拿 Ed25519 公鑰,轉成只保留 crv、kty、x 三個欄位的 JWK(RFC 7638 的做法),欄位按字典序排、不留空白,用 UTF-8 做 SHA-256,再 base64url 去掉 padding。

換句話說,名字的最後一段就是公鑰的指紋。DID 文件裡至少要有一把 Ed25519 的金鑰,它的 RFC 7638 thumbprint 必須跟 DID 最後那段一模一樣,而且要列在 authentication 裡。預設 e1_ 這個 profile 的 DID 文件,proof 欄位是必填。

這個設計逼出一個結果:名字和金鑰綁死了。別人沒辦法在不換名字的情況下偷換金鑰。

可是金鑰總有一天要換。

金鑰換了,人還是同一個嗎

名字既然是指紋,換金鑰就等於換名字。那「同一個 agent 換了金鑰」要怎麼證明?

規格的答案是 stable subject path,也就是 DID 去掉最後那段指紋之後剩下的前綴,例如 example.com:user:alice。這條路徑一旦拿來識別一個持續存在的主體,原文要求它「MUST remain permanently immutable, non-recyclable, and non-reassignable」,永遠不變、不回收、不重新指派。

照直覺,接著就是「路徑相同就是同一個人」。規格反過來把門關上了:「A verifier MUST NOT conclude that two DIDs belong to the same subject solely because they have the same stable subject path」。路徑一樣不算數。連續性靠另一條鏈:舊 DID 文件要保持可取得,標 deactivated = true,再用 successorDid 指向新 DID,整份文件還要有 proof。而且 successorDid 只能指向直接的下一代,不准跳過中間任何一代。

這條鏈在實際請求裡長什麼樣?被取代的舊 DID 收到請求,伺服器可以回 409,JSON 裡有 "code": "did_superseded",附上 requestedDid、currentDid、stableSubjectId。但規格特別寫了一句:回應裡的 currentDid 只是未驗證的提示,客戶端不准直接照著重試。客戶端得自己去抓舊文件,驗 deactivated、successorDid 和 proof,一代一代解析到現行的 DID,還要限制鏈長、偵測循環。

在我讀到的部分裡,這是最有分量的地方。伺服器說的話不可信,連它指給你的新地址也不可信,一切回到簽章。這種設計的代價是客戶端要多做很多事,換來的是沒有誰能靠「回一個看起來合理的 409」把你導去別處。

第一次敲門:簽章在標頭,名片在對方網域

身分有了,請求怎麼證明?ANP-02 的做法很樸素,用的是現成的 HTTP 標準:RFC 9421 的 Signature-Input 和 Signature 標頭,有 body 就再加 RFC 9530 的 Content-Digest。簽章最少要涵蓋 @method、@target-uri,有 body 時加上 content-digest。

規格範例的 Signature-Input 裡,keyid 是完整的 DID URL(範例是 did:web:identity.example:alice#key-1),created 必填,expires 建議填,nonce 可選。範例的 created 是 1733402096、expires 是 1733402156,差 60 秒(這是我自己算的)。

伺服器收到之後,規格列了十步驗證。大意是:驗格式、驗 Content-Digest、從 keyid 找到 DID、去對方網域抓 DID 文件並驗證、確認那把金鑰真的列在 authentication、重建 signature base、檢查時間窗(建議 1 到 5 分鐘)、擋重放,最後還要另外確認這個 DID 有沒有權限存取這個資源,沒有就回 403。失敗回 401,並附上挑戰。

通過之後可以發 access token,而且規格要求放在 Authentication-Info 回應標頭,不能放 Authorization。後續請求帶 Authorization: Bearer <access_token>,伺服器只驗 token,不必每次重驗 DID。

這一節有兩句坦白話,我覺得比功能本身更值得記。第一句:「authentication alone does not imply business authority」,認證通過不代表有業務權限。第二句關於 token:這一版保留了 sender-constrained token 的擴充能力,但「does not yet fully define the specific profile」,token 綁金鑰的做法還沒定義。所以預設就是一般的 Bearer token。Bearer 的老問題是誰拿到誰就能用,這一版規格還沒替它補上綁定。

還有一個值得單獨提的設計:規格說這套認證流程跟 DID method 無關,did:wba 和原生 did:web 共用同一套,而且一般的 HTTP API 可以只採用這一層,不必實作 ANP 的訊息、WNS 或裝置 Manifest。照規格的說法,想試水溫的人不用整套搬過去。

找得到人,才談得上握手

最後是發現(ANP-08)和描述(ANP-07)。主動發現的入口是 https://{domain}/.well-known/agent-descriptions,回傳 JSON-LD,型別是 CollectionPage,有 items 和 next,客戶端要一路翻頁翻到沒有 next 為止。每個 item 是一份 ad:AgentDescription,帶 name 和指向描述文件的 @id。

被動發現就鬆多了:agent 先拿到搜尋服務 agent 的描述文件,從裡面找註冊 API,送出自己的描述 URL,搜尋服務驗證後抓取並建索引。規格明說這些註冊 API 由各搜尋 agent 自己定義,也就是不統一。我讀 ANP-08 全文的感覺是,主動那條路很清楚,被動那條路只定了流程,介面留給各家。

描述文件本身(ANP-07)被比喻成網站首頁,裡面的 interfaces 有 NaturalLanguageInterface 和 StructuredInterface 兩種,也說能和 OpenAPI、JSON-RPC 互通。

到這裡先把狀態攤開。前面講的是身分、握手、發現三層,其中描述(ANP-07)和發現(ANP-08)我併成一層說,所以下表是四條已發布的規格加兩條草案。狀態取自 README 規格索引表。我只有 ANP-08 讀了全文,ANP-02、03、06、07 讀的是部分段落,ANP-04、05、09 沒讀全文:

層 規格 解的問題 索引表狀態
身分 ANP-03 did:wba 名字與公鑰綁定、換金鑰的連續性 Released v1.2
認證握手 ANP-02 首次請求簽章、DID 文件驗證、發 token Released v1.2
描述 ANP-07 agent 的入口文件 Released v1.2
發現 ANP-08 .well-known 列表與搜尋服務註冊 Released v1.2
授權 ANP-05 (我沒讀,索引表只標「授權」) Draft / not released; v0.6
協商(元協定) ANP-06 兩個 agent 談出共用的協定 Draft; document version 1.2

上面四條是 Released。標 Draft 的是授權和協商,再加 ANP-10(AP2 付款適配),索引表寫的是 Draft / not released。表裡沒列的 ANP-01、04、09,這篇不展開。

這個專案走到哪了

下面是 release 的時序,日期取自 gh api(截至 10 月 20 日,最新 release 是 9 月 24 日的 v1.2,距離 10 月 20 日 26 天):

ANP 的發版與最近動靜

2024-10-24 v0.0.1

repo 在 2024 年 10 月 23 日建立,隔天出第一個 release。

2025-02-28 v0.0.2

第二個 release。

2025-05-19 V1.0

第一個 1.0 版本。

2026-06-27 v1.1

距離 V1.0 約 13 個月。

2026-09-24 v1.2

release 名稱是「ANP 1.2 Release」,距離 v1.1 89 天。

2026-10-14 合併 release/0929

commit 訊息寫「Merge release/0929 into main for the October 14 release」。

2026-10-15 update auth draft

最近一次 push,commit 訊息是「update auth draft」,動到的是 ANP-05 授權規格的檔案。

那次 commit 只有刪除行、沒有新增行,我沒追下去那些內容搬去了哪裡。授權草案才剛被動過,和上面表格裡 ANP-05 還在 Draft 對得上。至於採用量,我查不到:repo 的星數只代表關注度,我手上沒有任何「多少服務真的在跑 ANP」的資料。

我的立場:先看已發布的那幾層,協商那層先不押

元協定那層我讀了開頭和流程:Agent Discovery、Agent Description、MetaProtocolInterface、anp.get_capabilities、anp.negotiate,然後選出介面、profile、security profile、schema。規格自己說得很節制:這層是選用的,不是 agent 協作的必要條件;舊版加密訊息內部的二進位協商模型標為 deprecated;anp.negotiate 的結果「is not an identity credential, authorization credential, access token」,什麼憑證都不是。

連它自己都把協商的權責切得這麼小,我就不把「agent 自己談協定」當成 ANP 現在能做到的事。我的判斷是:想評估 ANP,該看的是身分、握手和發現這三層加上它們怎麼接到現有的 HTTP API,這幾層已經 Released,而且握手那層可以單獨採用。

會讓我改變想法的條件有兩個。一是 ANP-06 從 Draft 變成 Released。二是出現我能讀到的、獨立於官方 SDK 的第二份實作,證明這份規格在別人手上也走得通。目前官方 SDK 在另一個 repo AgentConnect,AWiki 是標示為開源實作的專案,這兩個我都沒打開看過,所以這一條我沒辦法替它們背書。

名字和金鑰綁死之後

我最想留下的不是 ANP 本身,是那個設計:名字和金鑰綁死,換金鑰時留一條可以逐代驗證的鏈,伺服器告訴你的「新地址」一律只當提示。想讓陌生方互相認證、又不靠中央註冊,金鑰輪替早晚要面對。這份規格給的答案,讀起來比協商那層的願景踏實。

至於那句「Agentic Web 的 HTTP」,等 ANP-06 和 ANP-05 的狀態欄換字,再回來看一次吧。