核心命題: 問題通常不在模型,而在缺少一層共享、可計算、可約束的業務語義。 本文角度: 入門到可落地:五個核心零件、12 個設計維度、八步流程,以及 Agent 如何使用本體。
1. 導讀:為什麼要學本體?
如果你做過企業 AI、資料整合或 Agent,下面這個場景應該不陌生:
同一個任務,模型一樣、工具一樣、資料一樣,但結果時好時壞。Agent 有時把「費用單元」和「部門」當成同一個概念,有時把「產品型號」和「物料編碼」混在一起;多個 Agent 一起跑,各自都說自己對,但結論互相矛盾。
問題通常不在模型,而在缺少一層共享、可計算、可約束的業務語義。這層語義,就是本體(Ontology)。
本體不是「畫一張漂亮的關係圖」,也不是「把數據庫表抄成 JSON」。它是一套形式化的領域模型:定義有哪些概念、概念之間有什麼關係、什麼狀態不可能、資料如何對應,以及 Agent 可以怎樣安全地使用它。
這篇文章會由入門講到精通:
- 入門:本體是什麼、不是什麼、五個核心零件
- 中級:12 個設計維度、八步流程、約束與推理
- 高級:時間、身份、版本、多租戶、 provenance
- 落地:Agent 工具契約、RAG vs 本體、成熟度路線圖
2. 入門:本體到底是什麼?
2.1 一句話定義
本體是對某個領域的概念、關係、約束與實例的形式化描述,目的是讓人和機器對這個領域有共享、可推理的理解。
拆開來講:
- 概念(Class):領域中有哪些類型,例如 Account、JournalEntry、Party。
- 關係(Relation):概念之間怎樣連接,例如 JournalEntry posts JournalLine。
- 約束(Axiom / Constraint):什麼必須成立、什麼不可能,例如每張分錄借方合計必須等於貸方合計。
- 實例(Instance):具體的對象,例如 2026-10-21 的租金分錄。
2.2 TBox 與 ABox
本體工程最重要的一組區分:
| 層 | 名稱 | 內容 | 例子 |
|---|---|---|---|
| 概念層 | TBox(Terminology Box) | 類別、關係、公理、約束 | 「JournalEntry 至少有一條 JournalLine」 |
| 實例層 | ABox(Assertion Box) | 具體對象與事實 | 「JE#20261021-001 是一張 JournalEntry」 |
很多團隊失敗,是因為把兩層混在一起:在 schema 裡直接寫死某張發票的金額,或者在資料表裡偷偷加入業務規則。結果是:規則無法重用、資料無法驗證、Agent 無法推理。
2.3 開放世界假設(Open World Assumption)
在 OWL 的語義下,「沒有說過的」不等於「不存在」。
例如:你只知道 ACME 是 Supplier,但沒有說它是不是 Customer。在開放世界下,不能推論「ACME 不是 Customer」;只能說「未知」。
這與資料庫的封閉世界假設(Closed World)相反。數據庫裡「查不到」通常等於「不存在」;本體裡「查不到」可能只是「還沒說」。
實務建議:如果你需要「查不到就報錯」的驗證,用 SHACL 或業務規則;不要依賴 OWL 的開放世界推理來做資料完整性檢查。
2.4 本體不是什麼
- 不是數據庫 schema:schema 描述儲存結構,本體描述語義與約束。
- 不是知識圖譜:知識圖譜是本體的實例化結果(ABox);本體是它的 schema(TBox)。
- 不是分類法:分類法只有上位/下位;本體還有關係、屬性、公理。
- 不是詞彙表:詞彙表只有術語與定義;本體要可計算、可驗證。
- 不是 prompt:prompt 是給模型的指令;本體是給系統與 Agent 的語義契約。
3. 一圖看清:本體、Schema、知識圖譜、分類法、詞彙表
| 概念 | 核心內容 | 能否推理 | 典型用途 |
|---|---|---|---|
| 詞彙表 Glossary | 術語+定義 | 否 | 統一語言、文件 |
| 分類法 Taxonomy | 類別+上位/下位 | 有限 | 導航、標籤、檢索 |
| 數據庫 Schema | 表、欄位、外鍵 | 否 | 儲存、交易 |
| 知識圖譜 KG | 實體+關係+實例 | 是 | 查詢、推薦、關聯分析 |
| 本體 Ontology | 類別+關係+屬性+公理+約束 | 是 | 語義層、Agent 契約、資料整合 |
一個常見的誤解是「有知識圖譜就等於有本體」。其實:
- 沒有本體的知識圖譜,通常只是一堆沒有型別約束的邊,查得到但不可信。
- 沒有實例的本體,只是一個空殼 schema,無法回答真實問題。
- 真正有價值的,是**本體(TBox)+知識圖譜(ABox)+約束(SHACL)+映射(Mapping)**四件套。
4. 本體的五個核心零件
4.1 Class(類別)
類別是領域中的「類型」。例如:
- LegalEntity(法律實體)
- Account(會計科目)
- JournalEntry(日記帳分錄)
- Party(往來單位)
類別可以有上位/下位關係:AssetAccount 是 Account 的子類;CashAccount 是 AssetAccount 的子類。
4.2 Instance(實例)
實例是類別的具體成員。例如 Account#1000 是一個 CashAccount;JE#20261021-001 是一張 JournalEntry。
4.3 Relation(關係)
關係描述概念之間的連結。例如:
- JournalEntry posts JournalLine
- JournalLine debits Account
- Document supports JournalEntry
- Party counterpartyOf JournalEntry
關係要有基數(cardinality):一對一、一對多、多對多、必要/可選。沒有基數的關係,等於沒有語義。
4.4 Property(屬性)
屬性是概念自身的特徵,例如 Account.code、JournalEntry.date、JournalLine.amount。屬性要有:
- 資料型別(string、decimal、date、enum)
- 單位(HKD、USD、CNY)
- 值域(會計科目類型枚舉)
- 必填/可選
4.5 Axiom / Constraint(公理與約束)
公理是「永遠成立」的語義;約束是「資料必須符合」的規則。
例子:
- 每張 JournalEntry 的借方合計必須等於貸方合計。
- JournalLine.account 必須存在且 is_active = true。
- JournalEntry.date 必須落在 open period。
- 外幣分錄必須有 fx_rate > 0。
沒有公理與約束的本體,只是一個高級詞彙表。
5. 設計維度:12 個必須回答的問題
本體設計沒有唯一標準,但可以用 12 個維度做檢查。這 12 個維度不是學術分類,而是實務上最容易漏、也最能影響成敗的問題。
| # | 維度 | 你要回答的問題 | 產出 |
|---|---|---|---|
| 1 | 目的與範圍 | 這個本體要解決什麼?不包含什麼? | Scope statement、非目標 |
| 2 | 能力問題 CQ | 誰會問什麼?Agent 要完成什麼任務? | 10–30 條 competency questions |
| 3 | 概念與分類 | 有哪些類別?上位/下位? | Class taxonomy、定義 |
| 4 | 關係與基數 | 概念如何連接?一對多?必要? | Relations、cardinality |
| 5 | 屬性與值域 | 每個概念有什麼屬性?單位? | Properties、datatypes、enums |
| 6 | 公理與約束 | 什麼必須成立?什麼不可能? | Axioms、SHACL/OWL constraints |
| 7 | 事件與狀態 | 有哪些業務事件?狀態如何轉移? | Event types、state machine |
| 8 | 身份與解析 | 同一實體不同名稱怎樣合併? | Identity rules、canonical ID |
| 9 | 時間與來源 | 何時有效?誰提供? | Temporal validity、provenance |
| 10 | 數據映射 | 如何對應 DB / API / 文件? | Mapping table、ABox |
| 11 | 模組與標準 | 如何重用?跟什麼標準? | Modules、OWL/SKOS/JSON-LD |
| 12 | 治理與演化 | 誰擁有?如何改版? | Owner、versioning、change log |
5.1 為什麼「能力問題」排第二?
因為本體不是藝術創作,而是為了回答問題。先寫 CQ,可以防止你建模一些永遠不會被查詢的概念。
CQ 的例子:
- 這張分錄屬於哪個會計期間?
- 這個科目的借方餘額是多少?
- 這位供應商在過去 12 個月有哪些交易?
- 這筆銀行交易對應哪張分錄?
- 這個客戶的持股結構有幾層?
每一條 CQ,都應該能在本體上寫成一條查詢;如果寫不出來,代表概念或關係缺失。
6. 設計流程:八步由問題到可驗證模型
6.1 第一步:目的與範圍
寫一句話:「這個本體是為了讓 Agent 在會計記賬任務中,正確解析單據、生成分錄、並可審計。」
同時寫非目標:「不包含稅務申報、不包含人事薪酬、不包含多公司合併報表。」
6.2 第二步:能力問題
寫 10–30 條 CQ,覆蓋主要使用者與 Agent 任務。不要一開始寫 200 條;先寫最痛的 20 條。
6.3 第三步:概念與分類
從 CQ、文件、DB schema、API 中抽名詞。每個概念要有:
- 唯一 ID
- 中文名/英文名
- 定義(一句話)
- 上位類
- 同義詞
- 例子與反例
6.4 第四步:關係與基數
對每個關係問:
- 由哪個概念指向哪個概念?
- 一對一、一對多、多對多?
- 必要還是可選?
- 有沒有反向關係?
6.5 第五步:屬性與值域
金額用 Decimal,日期用 ISO 8601,幣種用 ISO 4217。每個屬性要有單位與值域。
6.6 第六步:公理與約束
先寫「不可能狀態」,再寫「必須狀態」。例如:
- 借方不等於貸方 → 不可能
- 分錄落在 closed period → 不可能
- 科目不存在 → 不可能
- 外幣沒有匯率 → 不可能
6.7 第七步:數據映射
把本體概念映射到真實資料:
- Account.code ← DB accounts.code
- JournalEntry.date ← journal_entries.date
- Document.source ← 文件路徑/頁碼/bbox
映射要保留 provenance:每個實例從哪裡來、何時抓取、由誰確認。
6.8 第八步:驗證與版本
用 CQ 與真實任務驗證:
- CQ 查詢命中率
- Agent 任務準確率
- 約束通過率
- 查詢延遲
- 維護成本
然后版本化:v0.1、v0.2,每次變更記錄原因與影響。
7. 動手做:30 分鐘建立最小會計本體
7.1 八個核心實體
- LegalEntity:法律實體
- Account:會計科目
- Party:往來單位
- Document:單據
- JournalEntry:日記帳分錄
- JournalLine:分錄行
- Period:會計期間
- Currency:幣種
7.2 Turtle 骨架(節錄)
@prefix ex: <https://example.com/accounting#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
ex:JournalEntry a owl:Class .
ex:JournalLine a owl:Class .
ex:Account a owl:Class .
ex:posts a owl:ObjectProperty ;
rdfs:domain ex:JournalEntry ;
rdfs:range ex:JournalLine .
ex:debits a owl:ObjectProperty ;
rdfs:domain ex:JournalLine ;
rdfs:range ex:Account .
ex:JournalEntry rdfs:subClassOf [
a owl:Restriction ;
owl:onProperty ex:posts ;
owl:minCardinality 2
] .
7.3 SHACL 約束(節錄)
@prefix sh: <http://www.w3.org/ns/shacl#> .
@prefix ex: <https://example.com/accounting#> .
ex:JournalEntryShape a sh:NodeShape ;
sh:targetClass ex:JournalEntry ;
sh:property [
sh:path ex:date ;
sh:datatype xsd:date ;
sh:minCount 1
] .
ex:JournalLineShape a sh:NodeShape ;
sh:targetClass ex:JournalLine ;
sh:property [
sh:path ex:amount ;
sh:datatype xsd:decimal ;
sh:minExclusive 0
] .
借貸平衡這種跨行約束,建議用 SPARQL 或應用層規則;SHACL 的簡單 property shape 不足以表達「所有行合計相等」。
7.4 給 Agent 的 JSON Schema(工具契約)
{
"type": "object",
"required": ["date", "currency", "lines"],
"properties": {
"date": {"type": "string", "format": "date"},
"currency": {"type": "string", "enum": ["HKD", "CNY", "USD"]},
"lines": {
"type": "array", "minItems": 2,
"items": {"type": "object", "required": ["account_code", "debit", "credit"]}
}
}
}
Agent 在呼叫記賬工具前,先用這個 schema 驗證;這比在 prompt 裡寫「請確保借貸平衡」可靠得多。
8. 中級:約束、推理與本體模式
8.1 OWL 與 SHACL 的分工
| 工具 | 用途 | 世界假設 | 適合 |
|---|---|---|---|
| OWL 2 | 類別推理、等價、子類、屬性特徵 | 開放世界 | 語義推理、分類 |
| SHACL | 資料驗證、必填、值域、基數 | 封閉世界 | 資料品質、Agent 輸入驗證 |
| JSON Schema | API 參數驗證 | 封閉世界 | 工具契約 |
| SPARQL | 查詢與跨行約束 | 視查詢而定 | 報表、對賬、審計 |
實務建議:用 SHACL/JSON Schema 做「必須正確」的驗證,用 OWL 做「可以推論」的語義。不要用 OWL 做資料完整性檢查。
8.2 本體模式(Patterns)
- 上層本體(Upper Ontology):BFO、SUMO、schema.org;提供通用類別,但不要硬套。
- SKOS:詞彙表、同義詞、分類法;適合標籤與檢索。
- 事件模式:Event → Actor → Object → Time;適合交易、審計、日誌。
- 角色模式:Party 可以同時是 Customer、Supplier、Employee;用 Role 而不是多個子類。
- 時間模式:ValidFrom / ValidTo;不要覆蓋歷史。
- ** Provenance 模式**:Entity → Activity → Agent;W3C PROV。
8.3 推理的邊界
推理很強,但不是萬能:
- 推理可以幫你分類、檢查一致性、推導間接關係。
- 推理不能替代業務規則、不能處理模糊語言、不能保證資料真實。
- 大規模推理會慢;Agent 場景通常只需要「取子圖+局部推理」。
9. 高級:時間、身份、版本、多租戶、Provenance
9.1 時間維度
任何會計、合約、持股、匯率都有時間有效性。錯誤做法是只存「當前值」;正確做法是:
- ValidFrom / ValidTo
- AsOf 查詢
- 事件時間 vs 記錄時間
- 版本鏈
9.2 身份解析(Entity Resolution)
同一個供應商可能有多個名稱、多個 ID、多個銀行帳戶。要有:
- Canonical ID
- 別名表
- 匹配規則(名稱、稅號、地址、銀行帳戶)
- 人工確認隊列
沒有身份解析,本體只會把重複實體越建越多。
9.3 版本與模組化
- 本體版本號(v0.1、v0.2)
- 變更日誌(誰改、為何改、影響哪些 CQ)
- 模組拆分(核心、會計、稅務、銀行)
- 向後兼容策略
9.4 多租戶隔離
- TBox 可以共享;ABox 必須按 tenant 隔離。
- 每個 tenant 一個 graph/schema/namespace。
- 查詢層強制 tenant filter;不要只靠應用層。
9.5 Provenance
每個事實要能回答:
- 從哪份文件來?
- 第幾頁/哪個 bbox?
- 由哪個 Agent/人確認?
- 何時寫入?
- 有沒有被修改?
這對會計與審計尤其重要。
10. Agent 與本體:工具契約,不是 Prompt 堆砌
10.1 三個工具
不要把所有本體塞進 prompt。給 Agent 三個工具:
- search_concepts(query):按名稱/同義詞找概念
- get_relations(concept_id, depth):取子圖
- validate_payload(schema_id, payload):驗證工具參數
Agent 需要時才取,取完即用,避免 context 爆炸。
10.2 RAG vs 本體
| 需求 | RAG | 本體 |
|---|---|---|
| 找相關文件 | 強 | 弱 |
| 實體解析 | 弱 | 強 |
| 關係推理 | 弱 | 強 |
| 參數驗證 | 弱 | 強 |
| 可審計 | 中 | 強 |
最佳組合:RAG 找資料,本體約束語義,Agent 做決策。
10.3 多 Agent 共享本體
多個 Agent 如果各自有一份「本體」,等於沒有本體。要有一個共享的 ontology service,所有 Agent 都通過同一套概念 ID、關係、約束來協作。
10.4 評估
- CQ 命中率
- 實體解析準確率
- 工具參數驗證通過率
- Agent 任務成功率
- 查詢延遲
- 維護成本
11. 案例:有本體 vs 沒有本體
假設同一個任務:「從單據生成租金分錄」。
11.1 沒有本體
- Agent 看到「租金」就猜科目。
- 看到「業主」就當成 Supplier,但有時是 Party。
- 金額可能抓到水印或最低結餘。
- 借貸可能不平衡,但 Agent 不會檢查。
- 多個 Agent 給出不同科目,無人仲裁。
11.2 有本體
- Account 有型別與值域;租金只能映射到租金類科目。
- Party 有角色;業主、供應商、客戶分開。
- Document 有 provenance;金額要回到頁碼/bbox。
- JournalEntry 有公理:借方必須等於貸方。
- 多個 Agent 用同一套概念與約束,結論可比較。
差別不是「模型更聰明」,而是語義層把錯誤擋在外面。
12. 十二個常見坑
- 沒有 CQ,為建模而建模。
- 把本體當數據庫 schema。
- 概念沒有定義,只有名字。
- 關係沒有基數。
- 只有 TBox,沒有 ABox 映射。
- 沒有身份解析,重複實體。
- 忽略時間維度。
- 沒有 provenance,無法審計。
- 過度使用 OWL 推理,查詢慢。
- 沒有 owner 與版本。
- 把整個本體塞進 prompt。
- 多 Agent 各自維護本體,語義漂移。
13. 成熟度路線圖
| 等級 | 名稱 | 特徵 | 適合 |
|---|---|---|---|
| L0 | 詞彙表 | 術語+定義 | 統一語言 |
| L1 | 分類法 | 上位/下位 | 導航、標籤 |
| L2 | 本體 | 類別+關係+屬性 | 資料整合 |
| L3 | 約束與推理 | SHACL/OWL | 資料品質、審計 |
| L4 | Agent-ready | 工具契約+版本+審計 | 多 Agent、生產 |
不要一開始追求 L4。先做 L2,解決一個真實任務,再升級。
14. 30/60/90 天落地計劃
14.1 第 1–30 天:定義與原型
- 寫 20 條 CQ
- 建 8–12 個核心類別
- 建 6–10 條關係
- 用一個真實任務做原型
14.2 第 31–60 天:約束與映射
- 加 SHACL/JSON Schema
- 做 DB/API 映射
- 加 provenance
- 建 identity rules
14.3 第 61–90 天:Agent 與治理
- 三個 Agent 工具
- 多 Agent 共享 ontology service
- 版本化與 change log
- 評估 CQ 命中率與任務成功率
15. 結語:本體是「語義的作業系統」
本體不是一張圖,也不是一份文件。它是:
- 人和機器共享的語言
- Agent 的工具契約
- 資料品質的護欄
- 多 Agent 協作的共同基礎
- 審計與追溯的語義層
入門不難:寫 CQ、建類別、加關係。 精通很難:做好身份、時間、版本、治理,並讓它在真實系統裡跑得動。
記住三句話:
- 先問問題,再建概念。
- 先約束,再推理。
- 先小範圍,再擴展。
16. 附錄:標準與工具
- 標準:RDF、RDFS、OWL 2、SHACL、SKOS、JSON-LD、SPARQL、PROV-O
- 方法論:Ontology 101、NeOn、METHONTOLOGY、Competency Questions
- 工具:Protégé、TopBraid Composer、GraphDB、Neo4j、Stardog
- 實務:schema.org、BFO、SUMO、Palantir Ontology
本體設計沒有唯一正確答案;只有「能否回答問題、能否被驗證、能否被維護」。
下一步
把本文的五件產出真的做出來,全部放在一個資料夾:
- CQ 清單:15 條能力問題,每條都要能寫成一條查詢;
- 本體檔:少於 30 個類別的
ontology.ttl; - 約束檔:對應的
shapes.ttl,含 3 條 SPARQL Constraint; - 測試資料:10 筆故意違規的資料,全部要被攔截;
- 工具契約:
search_concepts/get_subgraph/validate_payload三個介面。
完成之後,你就有一層可以被 Agent 安全使用的語義層,而不是一堆名詞定義。