會什麼是必填,去哪裡拿是選填:OASF 把資安圈的 schema 搬來描述 agent
一份 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.json 與 schema/objects/acp.json,這兩個檔案上掛著逐字相同的一段 @deprecated。message 是 “ACP is deprecated, please use A2A instead.”,since 是 0.8.0。
這個 ACP 是 Agent Connect Protocol,AGNTCY 自己的協定,acp_manifest.json 的 description 就寫著 “Agent Connect Protocol manifest”。順帶一提,ACP 這三個字母在 agent 生態裡不只指一個東西,看到縮寫先確認全名比較不會出事。
從 acp.json 的欄位看得出它原本設計得不隨便。capabilities(”Declares what invocation features this agent is capable of.”)、input、output 三項都是 required;input、output、custom_streaming_update、thread_state、config 全部 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.”,since 是 1.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 是一份封閉列舉,共七個值:unspecified、helm_chart、container_image、package、source_code、binary、url。urls 是 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,description、prompts、resources、tools 全部 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.」欄位共七項,name 與 description required,version、license、compatibility、allowed_tools、frontmatter_metadata 都是 optional。
這裡又冒出一個不同調的地方:record 層的 version 是 required,到了 skill manifest 這一層變成 optional。同一個概念在兩層之間鬆緊不一,通常代表這兩層是不同時候、為了不同需求長出來的。
skills 那一側的分類法規模不小,schema/skills/ 底下有 18 個頂層分類目錄,從 software_engineering、cybersecurity、data_engineering_analytics 到 reasoning_planning、tool_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/oasf 與 agntcy/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.json、locator.json、mcp_data.json、acp.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 蓋掉,答案大概不會寫在任何一篇公告裡。它會出現在某個檔案多出來的那幾行。
參考來源
- OASF 規格與 README:agntcy/oasf(Apache-2.0)
- Directory:agntcy/dir(Apache-2.0)
- 官方託管的 schema server:schema.oasf.outshift.com
- 血緣來源:OCSF (Open Cybersecurity Schema Framework)










