一份 agent 的描述檔躺在目錄裡。名字有了,版本有了,schema 版本有了,作者有了,建立時間照 RFC-3339 寫得工工整整,會做哪些事也列得清清楚楚。

唯一沒寫的是:你要去哪裡拿到它。

然後這份檔案完全合法。不是有人偷懶漏填,是規格本來就允許。

要弄懂這個設計怎麼長成這樣,得先往回退一步,退到一個跟 agent 沒什麼關係的地方。

骨架是從資安圈搬過來的

OASF(Open Agentic Schema Framework)的 README 第一段是這樣定義自己的:

The Open Agentic Schema Framework (OASF) is a standardized schema system for defining and managing AI agent capabilities, interactions, and metadata. It provides a structured way to describe agent attributes, capabilities, and relationships using attribute-based taxonomies.

這種段落你大概會直接滑過去。下一段交代了它是從哪裡抄來的:

OASF is highly inspired from OCSF (Open Cybersecurity Schema Framework) in terms of data modeling philosophy but also in terms of implementation. The server is a derivative work of OCSF schema server and the schema update workflows reproduce those developed by OCSF.

搬過來的有三樣:資料建模的哲學、實作、schema 的更新流程。schema server 直接寫明是 OCSF schema server 的 derivative work,不是「參考了它的想法」,是拿它的東西改的。這句話是 README 自己寫的,不是我從相似度推的。

所以,描述 AI agent 會做什麼的那套骨架,原本是為資安領域的事件正規化長出來的。

這件事其實沒那麼跳。一個要把來源雜亂、格式各異的東西壓成同一種形狀的框架,跟另一個要把各家廠商、各種宣稱的 agent 壓成同一種形狀的框架,要解的是同一個形狀的問題。差別只在格子裡裝什麼。就像超市那套條碼與品類代碼,它一點都不在乎你賣的是牛奶還是螺絲起子,它只在乎每樣東西都有一格可以填、而且大家填的是同一格。

為什麼不乾脆自己另開一套

今天要描述一個 agent,能選的格式不只一種。MCP 有自己的 server schema,A2A 有自己的 card,Oracle 那邊有 Open Agent Spec,SKILL.md 有自己的 frontmatter,AGNTCY 本身也曾經有一套 Agent Connect Protocol。

面對「又一個標準」這種指控,OASF 的回答是不當玩家,當索引。它沒有再生一套 agent card 格式去跟這些搶,而是把它們各建一個 module 收進來,變成 record 底下的一個欄位。

module 的分類只有兩格:core(uid 1)與 integration(uid 2)。整個生態就這樣被塞進兩個格子。integration 底下目前有四個實際的 module,分別對到 MCP、A2A、Oracle 的 Agent Spec,以及 ACP。

這裡有個地方很容易讀歪。agentspec 這個 module 的 reference 指向 Oracle 的 Open Agent Spec 文件站,agentskills 指向 agentskills.io 的規格頁。這只代表 OASF 引用了那些規格、替它們建了格子,不代表兩邊有任何合作、聯手或誰加入了誰。引用就只是引用。

這個定位有代價:完整性永遠落後被收編的那幾份規格一個版本。對方改了,你得跟著改 module,改完還得等自己發版。

第一個被收掉的,是自家的協定

schema/modules/integration/acp_manifest.jsonschema/objects/acp.json,這兩個檔案上掛著逐字相同的一段 @deprecatedmessage 是 “ACP is deprecated, please use A2A instead.”,since0.8.0

這個 ACP 是 Agent Connect Protocol,AGNTCY 自己的協定,acp_manifest.jsondescription 就寫著 “Agent Connect Protocol manifest”。順帶一提,ACP 這三個字母在 agent 生態裡不只指一個東西,看到縮寫先確認全名比較不會出事。

acp.json 的欄位看得出它原本設計得不隨便。capabilities(”Declares what invocation features this agent is capable of.”)、inputoutput 三項都是 required;inputoutputcustom_streaming_updatethread_stateconfig 全部 reference 到 openapi_schema_object,也就是整套蓋在 OpenAPI Schema Object 上面。欄位之間還有條件約束:custom_streaming_update 的規定是「Must be specified if streaming.custom capability is true and cannot be specified otherwise.」,thread_state 是「Cannot be specified if threads capability is false.」

有人認真坐下來設計過這個東西。然後它被自己所屬的 schema 標成 deprecated,訊息要人改用另一條線上的規格。

先把這句話的範圍界定清楚。since: "0.8.0" 的意思只有一個:在 OASF schema 的 0.8.0 版被標記為 deprecated。它不代表那個協定在那個時間點停止運作,也不代表誰對外發過什麼聲明。被 deprecated 的定義就只到「這份 schema 不再建議你用它」為止,再往外推都是腦補。

但這件事出現的位置很值得注意。一個組織收手自家規格、改指向別人的規格,這種事通常會出現在部落格、在 roadmap、在某場活動的 keynote。這一次它出現在一個 JSON 檔案的欄位裡。要看到它,你得打開 repo、找到那個路徑、讀完那個物件,然後注意到多了一個 @deprecated 鍵。

我偏好這種形式的誠實。roadmap 可以重寫,公告可以下架,@deprecated.since 留在 schema 裡會被每一個消費這份 schema 的工具讀到。你不用相信任何人的口頭說法,程式自己會看到。

第二個被收掉的,是把別人整包抄過來

mcp_data.json 裡有一個叫 mcp_data 的欄位,描述寫著 “The complete original MCP server JSON data structure for full fidelity storage.”。意思是把整包原始的 MCP server JSON 內嵌進 record,一個位元組都不漏。

它現在掛著 “Inline original MCP payload is deprecated, please use module.artifact instead.”,since1.0.0

理由不難推。把別人的整包 JSON 抄進自己的 record,等於對方每改一次版,你手上這份就過期一次。而 OASF 自己有一條版本不可變政策:一個 schema 版本發布之後就不再改動,只接受非破壞性的修正(文件更新、小 bug),任何刪除、新增或結構變更都得進下一版。兩件事湊在一起,你會得到一份既不能改、又註定要過期的副本。

這條死路的好處是已經有人走過,而且留下了路標。下次你想在自己的資料模型裡「為了完整性」內嵌別人家的整份文件,可以直接跳過這一步,不用自己再撞一次。

同一個檔案 reference 了 MCP 官方 server schema 的網址,而且是帶日期的那種:https://static.modelcontextprotocol.io/schemas/2025-09-29/server.schema.json。指向一個會動的 latest,跟指向一個釘死的日期,是兩種完全不同的外部依賴態度,前者省事、後者可重現。

OASF 留在 schema 裡的路線修正史

0.8.0

自家的 Agent Connect Protocol 被標 @deprecated,訊息逐字是 “ACP is deprecated, please use A2A instead.”

1.0.0

內嵌整包原始 MCP payload 的 mcp_data 欄位被標 @deprecated,訊息要人改用 module.artifact

v1.1.0(2026-07-10)

目前的最新正式 release。官方託管的 schema server 頁尾標的框架版本也是 1.1.0,server 版本 1.1.1。

1.2.0-dev

main 分支 schema/version.json 現在的值。下一版還沒發出來。

必填清單在說什麼

回到開場那份檔案。record 物件(schema/objects/record.json,main 分支)定義了 11 個 attribute,requirement 那一格照抄如下:

欄位 requirement 這格裝什麼
name required record 的名稱
version required record 的版本(原文寫「MAY conform to a specific versioning schema」)
schema_version required OASF schema 的版本
description required record 的描述
authors required 作者清單
created_at required 建立時間,值 MUST 符合 RFC-3339
skills required 與此 record 關聯的 skills 清單
domains recommended 與此 record 關聯的 domains 清單
modules recommended 更深入描述這個 record 與其能力的 modules
annotations optional 附加 metadata
locators optional 這個 record 可以在哪裡被找到或使用

七個 required、兩個 recommended、兩個 optional。

看一下擠進 required 那一格的是哪些。名字、版本、schema 版本、描述、作者、建立時間,這六個是身分資料,任何一份 metadata 都會要,沒什麼好談。真正做了選擇的是第七個。

skills required,locators optional。

這東西會做什麼,你必須說。這東西去哪裡拿,你可以不說。

開場那份檔案為什麼合法,答案就在這一行。

我的判斷是這個順序在押一個注:目錄先解決媒合,取得排後面。這注要贏,前提是目錄大到「找得到」本身就有價值。一個規模不大的目錄,找到之後拿不到,等於沒找到;一個夠大的目錄,光是知道「原來有人做過這種東西」就值錢,剩下的你自己想辦法聯絡。所以 required 跟 optional 這一格不只是欄位設計,是在賭這個目錄最後會長到多大。

會讓我改口的條件很具體:哪一版把 locators 升成 required,或者 dir 那一側的客戶端開始在 runtime 硬性要求它,就代表這注沒押中,光靠媒合撐不起一個目錄。

對寫客戶端的人來說,這個設計的帳單會在 runtime 才寄到。schema 驗證不會擋一筆沒有 locators 的 record,所以你照著 schema 寫的整合測試也不會擋。等到有人真的想把它拉下來用,才發現那一格是空的。缺的那條 fallback 路徑,不能等到那一刻才開始寫。

locators 自己一旦要寫,規矩其實很嚴。type 是一份封閉列舉,共七個值:unspecifiedhelm_chartcontainer_imagepackagesource_codebinaryurlurls 是 required,值 MUST 符合 RFC 1738、SHOULD 用 http 與 https scheme。有寫就得寫好,只是你可以不寫。

不過 type 的描述用的是「Allowed values MAY be defined for common manifest types.」一份封閉列舉配一句 MAY,讀起來像是這一格還沒想定。

下一層的必填邏輯整個翻過來

MCP module 描述一台 MCP server。name 是 required,descriptionpromptsresourcestools 全部 optional,而 connections(怎麼連上這台 server,本機套件或遠端端點)是 required。

描述的對象 「會做什麼」 「怎麼拿到/怎麼連上」
record(agent 本體) skills required locators optional
MCP module(外接的 server) tools optional connections required

同一份 schema,差一層,兩套剛好相反的必填邏輯。

這不是自相矛盾,是兩種東西在目錄裡扮演的角色不一樣。agent 本體是被「找」的那一方,找的人在乎它會什麼;MCP server 是被「接」的那一方,接的人在乎怎麼接上去,至於它有哪些工具,連上去問一下就有了。必填欄位洩漏的是設計者的假設:誰會來讀這份資料,那個人手上缺什麼。

把 skill 放進哪一格,本身就是主張

module 只有兩個 category,所以每一次歸類都是一次表態。MCP 與 A2A 進了 integration,而從 SKILL.md 來的 Agent Skills 進了 core/language_model

同樣都是「這個 agent 的能力從哪裡來」,一個被當成外接的東西,一個被當成語言模型本體的一部分。

agentskills_manifest 這個物件的 description 只有一句:「Normalized metadata extracted from a SKILL.md file.」欄位共七項,namedescription required,versionlicensecompatibilityallowed_toolsfrontmatter_metadata 都是 optional。

這裡又冒出一個不同調的地方:record 層的 version 是 required,到了 skill manifest 這一層變成 optional。同一個概念在兩層之間鬆緊不一,通常代表這兩層是不同時候、為了不同需求長出來的。

skills 那一側的分類法規模不小,schema/skills/ 底下有 18 個頂層分類目錄,從 software_engineeringcybersecuritydata_engineering_analyticsreasoning_planningtool_use_automation 都有。這個 18 我另外回官方託管的 schema server 對過,schema.oasf.outshift.com/skill_categories 那頁列出的 skill category 同樣是 18 個,名稱一一對得上。要注意這是頂層分類的數量,不是 skill 總數,每個目錄底下還有子項目,我沒有逐層展開數。

走到現在:目錄那一側

Directory(agntcy/dir)是把這套 schema 拿去用的那一半。README 的定義是:

The Directory (dir) allows publication, exchange, and discovery of information about records over a distributed peer-to-peer network.

它列的六項特性裡,最值得停下來的是 Verifiable Claims 那條,因為 README 在那裡承認了一件事:

agent capabilities are often subjectively evaluated

它沒有假裝自己能驗證「這個 agent 真的會做這件事」。它只承諾用密碼學保證這段宣稱確實是某人簽的、路上沒被改過。驗的是出處,不是能力。

架構那一側走的是 content-addressing 拿到全域唯一性、DHT 做內容發現與同步。這跟站上九月初寫的〈從改別人的 README 到證明域名是你的:MCP Registry 的三道驗證〉不在同一層:那邊解的是名字歸誰、命名空間對不對得上;這邊連「名字」都不是主要問題,唯一性交給內容雜湊,發現交給 DHT,「這段話是誰說的」交給簽章。兩邊都在回答「怎麼被找到」,但一個是中心化登錄加所有權驗證,一個是內容定址加分散式雜湊表。走哪條路,取決於你認為目錄本身該不該有一個管理員。

幾個現況的數字,全部是 2026-09-21 當下用 GitHub API 抓的欄位值:agntcy/oasfagntcy/dir 是同一天開的(2025-02-10),都是 Apache-2.0,archived 都是 false,stars 分別是 334 與 190。oasf 最後一次 push 在 2026-09-08,dir 在 2026-09-20。dir 最新 release 是 v1.7.0(2026-08-18),oasf 是 v1.1.0(2026-07-10)。

治理那一側也講清楚,因為這格特別容易讀歪。MAINTAINERS.md 列了五位具名維護者。CONTRIBUTORS.md 只有兩項:Cisco Systems Inc. 與「OASF a Series of LF Projects, LLC」,而且那個檔案自己寫明了它的定義:「CONTRIBUTOR file should only contain list of copyright holder (i.e. employers of maintainers).」版權持有者,不是共同開發者名單,更不是採用者名單。這種檔案很容易被讀成「誰在用」。它不是。

這篇的邊界

全部來自公開文件與原始碼的閱讀。我沒有裝過 dir、沒有發過一筆 record、沒有跑過任何 CLI 或 server。上面每一個欄位名、每一個 requirement 值、每一段 @deprecated 訊息都照抄檔案原文。

口徑也要講清楚。最新的正式 release 是 v1.1.0,但 main 分支的 schema/version.json 已經是 1.2.0-dev。我引的 record.jsonlocator.jsonmcp_data.jsonacp.json 這些細節讀的是 main 分支(2026-09-21),不保證每一條都已經進了某個正式版。

還有一整排我沒查的:有沒有任何實際採用者(完全沒查證)、DHT 用的是哪個實作與什麼 routing 演算法、OASF 跟 OCSF 之間除了 inspired 與 derivative work 有沒有正式的治理關聯。README 沒說組織關係,我就不往下推。

下一個 @deprecated 會蓋在誰身上

這個 repo 把自己的路線修正史,一版一版留在 @deprecated.since 欄位裡。0.8.0 收掉自家的協定,1.0.0 收掉內嵌別人 payload 的做法。兩次都沒有配公告,兩次都寫在一個 JSON 欄位裡。讀 schema 的工具會讀到,讀新聞的人不會。

main 分支現在停在 1.2.0-dev

skills 那條 required 撐不撐得住,locators 會不會被提上來,integration 底下剩下那幾個 module 誰接著被 @deprecated 蓋掉,答案大概不會寫在任何一篇公告裡。它會出現在某個檔案多出來的那幾行。


參考來源