OMS 拆解:Mini-Palantir 的元数据服务设计
这是 Palantir Ontology 逆向工程序列中“元数据层”的一篇:前序文章拆解了 Ontology 的概念体系与工程级架构,本文把战线推进到支撑这一切的底座——OMS(Ontology Metadata Service)。在本文的框架里,OMS 不是几张 metadata 表,而是 Mini-Palantir 的编译器前端 + 类型系统 + Schema Registry + Dependency Graph + Governance Kernel 的组合。
全文以一套通用的广告业务示例(Game / AdNetwork / Country / Experiment / Revenue)贯穿始终,给出完整的 PostgreSQL 建表、YAML DSL、Type AST 与 Compiler 管线设计——这是一份可以直接进入施工的元数据服务蓝本。
OMS 不是几张 metadata 表,而是 Mini-Palantir 的 编译器前端 + 类型系统 + Schema Registry + Dependency Graph + Governance Kernel。
先声明一个非常重要的边界:
下面是基于 Palantir 公开文档做的逆向工程,不是 Palantir 私有 OMS 源码的复刻。
公开资料明确显示,Object Type、Property、Link Type、Action Type、Function、Interface 都是 Ontology 的类型/语义构件;Palantir 还公开了不少 metadata 字段、接口约束、ObjectSet API 和运行行为。我们据此构造一个“行为等价”的 Mini-Palantir OMS。(Palantir)
设计原则是:故意把 OMS 做得比普通 CRUD Schema Registry 更严格。
一、先看最终目标:OMS 到底是什么
整套架构的总览如下:
┌──────────────────────────┐
│ Ontology DSL │
│ YAML / JSON / TS │
└────────────┬─────────────┘
│
▼
┌─────────────────────────────┐
│ Ontology Compiler │
│ │
│ Parse │
│ Normalize │
│ Resolve References │
│ Type Check │
│ Validate │
│ Dependency Analysis │
│ Version Check │
│ Compile │
└──────────────┬──────────────┘
│
┌──────────────▼──────────────┐
│ OMS Metadata │
│ │
│ Type Registry │
│ Property Registry │
│ Link Registry │
│ Interface Registry │
│ Action Registry │
│ Function Registry │
│ Version Registry │
│ Dependency Graph │
│ Validation Rules │
└──────────────┬──────────────┘
│
┌──────────────▼──────────────┐
│ Ontology Runtime │
│ │
│ Object Store │
│ ObjectSet Engine │
│ Link Resolver │
│ Action Engine │
│ Function Runtime │
│ Permission Engine │
└──────────────┬──────────────┘
│
┌──────────────▼──────────────┐
│ Business Ontology │
│ │
│ Game │
│ AdNetwork │
│ Country │
│ Experiment │
│ Revenue │
│ TrafficAllocation │
└─────────────────────────────┘
这里有一个非常关键的认识:
OMS 不存 Game 的业务数据。
它存的是:
“Game 是什么、Game 有什么属性、Game 和 AdNetwork 怎么连接、Game 能执行什么 Action、哪些 Function 可以操作 Game、哪些 Interface 可以被 Game 实现。”
也就是说:
OMS
=
Ontology 的“宪法”
Runtime
=
Ontology 的“执行机关”
Object Store
=
Ontology 的“世界状态”
这个分层非常重要。
Palantir 官方文档本身也明确区分了 object type definition / metadata 和真正的 ontology data。(Palantir)
二、第一性原理:OMS 管理的到底是什么?
先不急着建表。
整个 Ontology 可以拆成三个层次:
Ontology
│
┌─────────┴─────────┐
│ │
META DATA
│ │
│ │
“世界是什么?” “世界现在是什么?”
│ │
ObjectType Object
Property PropertyValue
LinkType Link
Interface
ActionType
Function
META 之上再叠加六个治理维度:
META
│
├── Definition
├── Constraint
├── Version
├── Dependency
├── Validation
└── Compilation
所以 OMS 的实际骨架是:
OMS
│
├── Definition System
│
├── Type System
│
├── Constraint System
│
├── Version System
│
├── Dependency System
│
├── Validation System
│
├── Compilation System
│
└── Governance System
这就是 OMS 逆向工程的目标模型。
三、OMS 核心 Domain Model
第一版直接建立下面这套内部模型:
OntologyDefinition
│
├── ObjectTypeDefinition
│ ├── PropertyDefinition[]
│ ├── PrimaryKeyDefinition
│ ├── LinkBinding[]
│ ├── InterfaceBinding[]
│ └── ActionBinding[]
│
├── LinkTypeDefinition
│ ├── Source
│ ├── Target
│ ├── Cardinality
│ └── Constraints
│
├── InterfaceDefinition
│ ├── PropertyContract[]
│ ├── LinkContract[]
│ └── ActionContract[]
│
├── ActionTypeDefinition
│ ├── Parameters[]
│ ├── Rules[]
│ ├── Mutations[]
│ ├── Conditions[]
│ └── SideEffects[]
│
├── FunctionDefinition
│ ├── Inputs[]
│ ├── Outputs[]
│ ├── Dependencies[]
│ └── Runtime
│
└── SecurityDefinition
四、第一版 ontology_meta 数据库
第一版的技术选型:
PostgreSQL + JSONB + relational constraints
而不是一开始就引入 Neo4j。
因为:
OMS 本质上首先是一个 强类型元数据系统,不是 Graph Database。
Graph 是 OMS 的一个 projection。
五、Schema 总览
第一版的最终 schema:
ontology_meta
│
├── ontologies
│
├── namespaces
│
├── resources
│
├── object_types
│
├── properties
│
├── property_constraints
│
├── primary_keys
│
├── link_types
│
├── link_type_ends
│
├── interfaces
│
├── interface_properties
│
├── interface_links
│
├── interface_actions
│
├── interface_implementations
│
├── action_types
│
├── action_parameters
│
├── action_rules
│
├── action_mutations
│
├── action_side_effects
│
├── functions
│
├── function_parameters
│
├── function_dependencies
│
├── schema_versions
│
├── schema_changes
│
├── dependencies
│
├── validation_rules
│
├── compilation_units
│
├── compilation_errors
│
└── ontology_events
但 Schema 总览立刻暴露一个设计问题:
如果所有表都有:
id
ontology_id
version
status
created_at
updated_at
会迅速变成重复结构。
解决方式是引入一个统一抽象:
Resource
六、Resource:OMS 的统一资源抽象
CREATE TABLE resources (
id UUID PRIMARY KEY,
ontology_id UUID NOT NULL,
resource_type VARCHAR(64) NOT NULL,
api_name VARCHAR(255) NOT NULL,
display_name VARCHAR(255),
description TEXT,
status VARCHAR(32) NOT NULL DEFAULT 'ACTIVE',
rid VARCHAR(255) UNIQUE NOT NULL,
version BIGINT NOT NULL DEFAULT 1,
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
UNIQUE (
ontology_id,
resource_type,
api_name
)
);
resource_type:
OBJECT_TYPE
PROPERTY
LINK_TYPE
INTERFACE
ACTION_TYPE
FUNCTION
这样 OMS 内部可以统一处理:
Resource
↓
Dependency
↓
Version
↓
Validation
↓
Compilation
这是后续 Compiler 的基础。
七、Ontology
CREATE TABLE ontologies (
id UUID PRIMARY KEY,
api_name VARCHAR(255) UNIQUE NOT NULL,
display_name VARCHAR(255) NOT NULL,
description TEXT,
version BIGINT NOT NULL DEFAULT 1,
status VARCHAR(32) NOT NULL DEFAULT 'ACTIVE',
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
例如:
ontology:
apiName: ad_monetization
displayName: Ad Monetization Ontology
八、Object Type Registry
ObjectType 是整个 Ontology 最重要的实体。
Palantir 对 Object Type 的公开 metadata 至少包括 ID、RID、显示名称、plural display name 等。(Palantir)
OMS 中的定义:
CREATE TABLE object_types (
resource_id UUID PRIMARY KEY
REFERENCES resources(id)
ON DELETE CASCADE,
primary_key_property_id UUID,
icon JSONB,
plural_display_name VARCHAR(255),
searchable BOOLEAN NOT NULL DEFAULT TRUE,
description TEXT,
capabilities JSONB NOT NULL DEFAULT '{}'::jsonb
);
但这里出现一个循环依赖:
ObjectType
↓
Property
↓
PrimaryKey
↓
ObjectType
所以 primary_key_property_id 允许后绑定。
九、Property Registry
CREATE TABLE properties (
resource_id UUID PRIMARY KEY
REFERENCES resources(id)
ON DELETE CASCADE,
object_type_id UUID NOT NULL
REFERENCES object_types(resource_id),
data_type VARCHAR(64) NOT NULL,
is_array BOOLEAN NOT NULL DEFAULT FALSE,
nullable BOOLEAN NOT NULL DEFAULT TRUE,
indexed BOOLEAN NOT NULL DEFAULT FALSE,
searchable BOOLEAN NOT NULL DEFAULT FALSE,
sortable BOOLEAN NOT NULL DEFAULT FALSE,
unique_value BOOLEAN NOT NULL DEFAULT FALSE,
default_value JSONB,
render_hints JSONB NOT NULL DEFAULT '{}'::jsonb,
constraints JSONB NOT NULL DEFAULT '{}'::jsonb,
UNIQUE (
object_type_id,
resource_id
)
);
十、不要把 data_type 做成 VARCHAR 黑盒
这里是 Type System 的核心。
不要:
data_type = "string"
然后所有语义都靠 JSON 承载。
正确做法是定义真正的类型系统。
十一、Mini-Palantir Type System
第一版:
Primitive
│
├── STRING
├── BOOLEAN
├── INTEGER
├── LONG
├── FLOAT
├── DOUBLE
├── DECIMAL
├── DATE
├── DATETIME
├── TIMESTAMP
├── UUID
├── JSON
│
├── GEO_POINT
│
└── VECTOR
Collection:
Array<T>
Ontology Types:
ObjectRef<ObjectType>
ObjectSet<ObjectType>
InterfaceRef<Interface>
以后可以增加:
Map<K,V>
Enum<T>
Union<T1,T2>
Optional<T>
十二、内部 Type AST
类型不能只用字符串表示。
内部表示:
type TypeRef =
| PrimitiveTypeRef
| ArrayTypeRef
| ObjectRefType
| ObjectSetType
| InterfaceRefType
| EnumTypeRef
| OptionalTypeRef;
例如:
interface PrimitiveTypeRef {
kind: "primitive";
name:
| "string"
| "boolean"
| "integer"
| "long"
| "float"
| "double"
| "decimal"
| "date"
| "datetime"
| "uuid";
}
interface ArrayTypeRef {
kind: "array";
elementType: TypeRef;
}
interface ObjectRefType {
kind: "object";
objectType: ResourceRef;
}
interface ObjectSetType {
kind: "objectSet";
objectType: ResourceRef;
}
interface InterfaceRefType {
kind: "interface";
interfaceType: ResourceRef;
}
这样以后 Function:
calculateOptimizationScore(
game: Game
) -> OptimizationScore
Compiler 才能真正理解。
十三、Property Constraint
不要把所有约束都塞进 constraints JSONB。
核心约束单独建表:
CREATE TABLE property_constraints (
id UUID PRIMARY KEY,
property_id UUID NOT NULL
REFERENCES properties(resource_id)
ON DELETE CASCADE,
constraint_type VARCHAR(64) NOT NULL,
constraint_value JSONB NOT NULL,
error_message TEXT,
severity VARCHAR(32) NOT NULL DEFAULT 'ERROR'
);
支持:
REQUIRED
MIN
MAX
MIN_LENGTH
MAX_LENGTH
REGEX
ENUM
UNIQUE
FORMAT
REFERENCE
例如:
{
"constraint_type": "MIN",
"constraint_value": 0
}
十四、Link Registry
Palantir 的 Link Type 本质是:
两个 Object Type 之间的关系定义。
公开 metadata 中也包括 source/target object types、cardinality、API name、visibility 等。(Palantir)
所以:
CREATE TABLE link_types (
resource_id UUID PRIMARY KEY
REFERENCES resources(id)
ON DELETE CASCADE,
cardinality VARCHAR(32) NOT NULL,
relationship_type VARCHAR(32)
DEFAULT 'ASSOCIATION',
directionality VARCHAR(32)
DEFAULT 'DIRECTED',
metadata JSONB NOT NULL DEFAULT '{}'::jsonb
);
然后:
CREATE TABLE link_type_ends (
link_type_id UUID NOT NULL
REFERENCES link_types(resource_id)
ON DELETE CASCADE,
side VARCHAR(16) NOT NULL,
object_type_id UUID NOT NULL
REFERENCES object_types(resource_id),
api_name VARCHAR(255) NOT NULL,
display_name VARCHAR(255),
visibility VARCHAR(32)
DEFAULT 'NORMAL',
required BOOLEAN DEFAULT FALSE,
PRIMARY KEY (
link_type_id,
side
)
);
于是:
Game
│
│ monetizedBy
▼
AdNetwork
数据库表达:
link_type
│
├── SOURCE
│ └── Game
│
└── TARGET
└── AdNetwork
十五、Cardinality
第一版:
ONE_TO_ONE
ONE_TO_MANY
MANY_TO_ONE
MANY_TO_MANY
例如:
link:
apiName: monetizedBy
source: Game
target: AdNetwork
cardinality: MANY_TO_MANY
这和 Palantir 对 1-1、1-many、many-many link 的公开行为是一致的抽象方向。(Palantir)
十六、Interface Registry
从这里开始,设计进入最有意思的部分。
Interface 不是:
class interface
这么简单。
它实际上是:
Capability Contract
Palantir 官方明确把 Interface 定义为描述 Object Type 的 shape 和 capabilities,并用于 polymorphism。(Palantir)
所以:
CREATE TABLE interfaces (
resource_id UUID PRIMARY KEY
REFERENCES resources(id)
ON DELETE CASCADE,
searchable BOOLEAN NOT NULL DEFAULT TRUE,
icon JSONB,
capabilities JSONB NOT NULL DEFAULT '{}'::jsonb
);
十七、Interface Property Contract
CREATE TABLE interface_properties (
interface_id UUID NOT NULL
REFERENCES interfaces(resource_id)
ON DELETE CASCADE,
api_name VARCHAR(255) NOT NULL,
data_type VARCHAR(64) NOT NULL,
required BOOLEAN NOT NULL DEFAULT FALSE,
description TEXT,
PRIMARY KEY (
interface_id,
api_name
)
);
例如:
interface:
apiName: MonetizableAsset
properties:
- apiName: revenue
type: decimal
required: true
- apiName: eCPM
type: decimal
required: true
十八、Interface Link Contract
CREATE TABLE interface_links (
interface_id UUID NOT NULL
REFERENCES interfaces(resource_id)
ON DELETE CASCADE,
api_name VARCHAR(255) NOT NULL,
target_interface_id UUID,
target_object_type_id UUID,
cardinality VARCHAR(32),
required BOOLEAN NOT NULL DEFAULT FALSE,
PRIMARY KEY (
interface_id,
api_name
)
);
十九、Interface Implementation
这个表非常关键。
CREATE TABLE interface_implementations (
interface_id UUID NOT NULL
REFERENCES interfaces(resource_id),
object_type_id UUID NOT NULL
REFERENCES object_types(resource_id),
status VARCHAR(32) NOT NULL DEFAULT 'VALIDATED',
property_mapping JSONB NOT NULL DEFAULT '{}'::jsonb,
link_mapping JSONB NOT NULL DEFAULT '{}'::jsonb,
action_mapping JSONB NOT NULL DEFAULT '{}'::jsonb,
created_at TIMESTAMPTZ DEFAULT now(),
PRIMARY KEY (
interface_id,
object_type_id
)
);
例如:
MonetizableAsset
▲
│ implements
┌──────┼─────────┐
│ │ │
Game App Website
而:
Game.revenue
可能映射到:
Game.adRevenue
Compiler 必须验证:
Interface.revenue : decimal
↓
Game.adRevenue : decimal
OK
否则:
COMPILE ERROR
Palantir 的公开实现流程本身就要求 implementation 对 required properties、links、actions 做 mapping。(Palantir)
二十、Action Registry
现在进入 Ontology 最核心的“动词”。
ActionType 不是:
POST /games
它是:
Intent
+
Input
+
Authorization
+
Validation
+
Mutation
+
SideEffect
Palantir 官方把 Action Type 定义成“一组对象、属性、链接变化以及提交后的 side effects”的 schema。(Palantir)
OMS 中的定义:
CREATE TABLE action_types (
resource_id UUID PRIMARY KEY
REFERENCES resources(id)
ON DELETE CASCADE,
transaction_mode VARCHAR(32)
DEFAULT 'ATOMIC',
execution_mode VARCHAR(32)
DEFAULT 'SYNC',
confirmation_required BOOLEAN
DEFAULT FALSE,
security_policy JSONB
DEFAULT '{}'::jsonb
);
二十一、Action Parameters
CREATE TABLE action_parameters (
id UUID PRIMARY KEY,
action_type_id UUID NOT NULL
REFERENCES action_types(resource_id)
ON DELETE CASCADE,
api_name VARCHAR(255) NOT NULL,
parameter_type JSONB NOT NULL,
required BOOLEAN NOT NULL DEFAULT TRUE,
default_value JSONB,
description TEXT,
ordinal INTEGER NOT NULL,
UNIQUE (
action_type_id,
api_name
)
);
例如:
action:
apiName: IncreaseTrafficAllocation
parameters:
- apiName: game
type:
object: Game
- apiName: country
type:
object: Country
- apiName: percentage
type: decimal
二十二、Action Rules
CREATE TABLE action_rules (
id UUID PRIMARY KEY,
action_type_id UUID NOT NULL
REFERENCES action_types(resource_id),
rule_type VARCHAR(64) NOT NULL,
expression JSONB NOT NULL,
ordinal INTEGER NOT NULL,
error_message TEXT
);
支持:
AUTHORIZATION
PRECONDITION
VALIDATION
CONDITION
例如:
rules:
- type: PRECONDITION
expression:
gt:
- ref: game.currentROI
- 1.0
二十三、Action Mutation
CREATE TABLE action_mutations (
id UUID PRIMARY KEY,
action_type_id UUID NOT NULL
REFERENCES action_types(resource_id),
target_type VARCHAR(32) NOT NULL,
target_ref JSONB NOT NULL,
mutation_type VARCHAR(32) NOT NULL,
field VARCHAR(255),
value_expression JSONB,
ordinal INTEGER NOT NULL
);
支持:
CREATE_OBJECT
UPDATE_PROPERTY
DELETE_OBJECT
CREATE_LINK
DELETE_LINK
例如:
mutations:
- type: UPDATE_PROPERTY
object: "$game"
property: trafficAllocation
value:
add:
- ref: game.trafficAllocation
- ref: percentage
二十四、Side Effects
CREATE TABLE action_side_effects (
id UUID PRIMARY KEY,
action_type_id UUID NOT NULL
REFERENCES action_types(resource_id),
effect_type VARCHAR(64) NOT NULL,
config JSONB NOT NULL,
execution_mode VARCHAR(32)
DEFAULT 'ASYNC',
ordinal INTEGER NOT NULL
);
例如:
Action
│
├── Mutation
│
└── SideEffect
├── emit_event
├── webhook
├── external_api
├── notification
└── function
这就是 Ontology 从“数据模型”跨进“业务操作系统”的关键一步。
二十五、Function Registry
Function 是:
Input → Logic → Output
Palantir 的 Function 可以原生接受 Objects/Object Sets,并访问 Ontology 数据。(Palantir)
OMS 中的定义:
CREATE TABLE functions (
resource_id UUID PRIMARY KEY
REFERENCES resources(id),
runtime VARCHAR(64) NOT NULL,
language VARCHAR(32) NOT NULL,
entrypoint VARCHAR(255) NOT NULL,
source_ref TEXT,
timeout_ms INTEGER DEFAULT 30000,
memory_mb INTEGER DEFAULT 512,
deterministic BOOLEAN DEFAULT FALSE,
security_policy JSONB DEFAULT '{}'::jsonb
);
二十六、Function Parameters
CREATE TABLE function_parameters (
id UUID PRIMARY KEY,
function_id UUID NOT NULL
REFERENCES functions(resource_id),
api_name VARCHAR(255) NOT NULL,
direction VARCHAR(16) NOT NULL,
type_ref JSONB NOT NULL,
required BOOLEAN DEFAULT TRUE,
ordinal INTEGER NOT NULL,
UNIQUE(function_id, api_name)
);
例如:
function:
apiName: calculateOptimizationScore
inputs:
- name: game
type:
object: Game
output:
type: decimal
二十七、Function Dependency
Function 不能是黑盒。
例如:
calculateOptimizationScore
│
├── Game
├── Experiment
├── Revenue
└── AdNetwork
因此:
CREATE TABLE function_dependencies (
function_id UUID NOT NULL
REFERENCES functions(resource_id),
dependency_resource_id UUID NOT NULL
REFERENCES resources(id),
dependency_type VARCHAR(32) NOT NULL,
PRIMARY KEY (
function_id,
dependency_resource_id
)
);
二十八、Dependency Graph
这是 OMS 非常容易被低估的一层。
建立:
CREATE TABLE dependencies (
id UUID PRIMARY KEY,
source_resource_id UUID NOT NULL
REFERENCES resources(id),
target_resource_id UUID NOT NULL
REFERENCES resources(id),
dependency_type VARCHAR(64) NOT NULL,
metadata JSONB DEFAULT '{}'::jsonb,
UNIQUE (
source_resource_id,
target_resource_id,
dependency_type
)
);
例如:
Game
│
├── has property → revenue
│
├── linked by → monetizedBy
│
├── implements → MonetizableAsset
│
├── executable by → IncreaseTrafficAllocation
│
└── used by → calculateOptimizationScore
最终形成:
┌──────────────┐
│ Monetizable │
│ Asset │
└──────┬───────┘
│ implements
▼
┌─────────┐ ┌─────────┐ ┌────────────┐
│ Country │◄──────│ Game │──────►│ AdNetwork │
└─────────┘ └────┬────┘ └────────────┘
│
│ tested by
▼
┌────────────┐
│ Experiment │
└─────┬──────┘
│
▼
┌────────────┐
│ Function │
└─────┬──────┘
│
▼
┌──────────┐
│ Action │
└──────────┘
二十九、Schema Versioning
版本管理是不能省略的部分。
否则:
Game v1
改成:
Game v2
整个 Ontology 就炸掉。
schema_versions
CREATE TABLE schema_versions (
id UUID PRIMARY KEY,
ontology_id UUID NOT NULL
REFERENCES ontologies(id),
version BIGINT NOT NULL,
parent_version BIGINT,
status VARCHAR(32) NOT NULL,
schema_hash VARCHAR(128) NOT NULL,
compiled_at TIMESTAMPTZ,
created_at TIMESTAMPTZ DEFAULT now(),
UNIQUE (
ontology_id,
version
)
);
三十、Schema Change
CREATE TABLE schema_changes (
id UUID PRIMARY KEY,
schema_version_id UUID NOT NULL
REFERENCES schema_versions(id),
resource_id UUID,
operation VARCHAR(32) NOT NULL,
before_schema JSONB,
after_schema JSONB,
breaking BOOLEAN NOT NULL DEFAULT FALSE,
created_at TIMESTAMPTZ DEFAULT now()
);
支持:
CREATE
UPDATE
DELETE
RENAME
DEPRECATE
三十一、Breaking Change Engine
Compiler 必须判断:
Game v1
↓
Game v2
是不是 breaking。
例如:
安全
新增 nullable property
新增 optional interface capability
危险
删除 property
更危险
string → integer
极危险
ONE_TO_MANY
↓
ONE_TO_ONE
灾难级
Game.primaryKey
修改。
所以:
Schema Compiler
│
▼
Compatibility Analyzer
│
├── SAFE
├── WARNING
└── BREAKING
三十二、Validation Engine
Validation 分五层:
Validation
│
├── Syntax Validation
│
├── Type Validation
│
├── Reference Validation
│
├── Semantic Validation
│
└── Compatibility Validation
1. Syntax
apiName 是否合法?
type 是否存在?
YAML 是否正确?
2. Type
Game.revenue : decimal
Action.percentage : string
如果:
decimal ← string
报错。
3. Reference
link.target = AdNetwork
但:
AdNetwork 不存在
报错。
4. Semantic
例如:
primaryKey 必须存在
link source / target 必须是 ObjectType
Interface required property 必须能被 implementation 映射
5. Compatibility
v1 → v2
判断 breaking。
三十三、Validation Rule Registry
CREATE TABLE validation_rules (
id UUID PRIMARY KEY,
rule_code VARCHAR(128) UNIQUE NOT NULL,
resource_type VARCHAR(64),
severity VARCHAR(32) NOT NULL,
expression JSONB NOT NULL,
message_template TEXT NOT NULL,
enabled BOOLEAN DEFAULT TRUE
);
例如:
OBJECT_TYPE_PRIMARY_KEY_REQUIRED
LINK_SOURCE_MUST_EXIST
LINK_TARGET_MUST_EXIST
INTERFACE_REQUIRED_PROPERTY_MISSING
FUNCTION_INPUT_TYPE_INVALID
ACTION_TARGET_TYPE_INVALID
BREAKING_PROPERTY_REMOVAL
三十四、Compilation Unit
现在真正进入 Compiler。
CREATE TABLE compilation_units (
id UUID PRIMARY KEY,
ontology_id UUID NOT NULL,
schema_version_id UUID,
source_hash VARCHAR(128) NOT NULL,
status VARCHAR(32) NOT NULL,
compiler_version VARCHAR(64),
started_at TIMESTAMPTZ,
completed_at TIMESTAMPTZ
);
错误:
CREATE TABLE compilation_errors (
id UUID PRIMARY KEY,
compilation_unit_id UUID NOT NULL
REFERENCES compilation_units(id),
resource_id UUID,
code VARCHAR(128) NOT NULL,
severity VARCHAR(32) NOT NULL,
message TEXT NOT NULL,
path TEXT,
details JSONB
);
三十五、现在进入最重要的部分:Schema DSL
没有 DSL,这套系统最终只是复杂的 Admin 后台。
真正的 Mini-Palantir 应该能够:
写 Ontology
↓
Compiler
↓
Runtime
三十六、第一版 DSL
选型采用:
YAML + JSON Schema + 自己的 Semantic AST
而不是自己从零发明 parser。
例如:
ontology:
apiName: ad_monetization
displayName: Ad Monetization Ontology
types:
- object:
apiName: Game
displayName: Game
primaryKey: id
properties:
- apiName: id
type: string
required: true
- apiName: name
type: string
required: true
- apiName: revenue
type: decimal
- apiName: eCPM
type: decimal
- apiName: trafficAllocation
type: decimal
implements:
- MonetizableAsset
三十七、Link DSL
links:
- apiName: monetizedBy
source:
object: Game
apiName: games
target:
object: AdNetwork
apiName: adNetworks
cardinality: MANY_TO_MANY
三十八、Interface DSL
interfaces:
- apiName: MonetizableAsset
properties:
- apiName: revenue
type: decimal
required: true
- apiName: eCPM
type: decimal
required: true
links:
- apiName: monetizedBy
target:
interface: AdNetwork
三十九、Function DSL
functions:
- apiName: calculateOptimizationScore
runtime:
language: python
inputs:
- apiName: game
type:
object: Game
output:
type: decimal
implementation:
entrypoint: optimization.calculate_score
四十、Action DSL
这里是整个 DSL 最有价值的部分。
actions:
- apiName: IncreaseTrafficAllocation
parameters:
- apiName: game
type:
object: Game
- apiName: percentage
type: decimal
preconditions:
- expression:
gt:
- ref: game.eCPM
- value: 1.0
mutations:
- type: UPDATE_PROPERTY
target:
ref: game
property: trafficAllocation
value:
add:
- ref: game.trafficAllocation
- ref: percentage
sideEffects:
- type: EMIT_EVENT
event: TrafficAllocationChanged
到这里,已经接近真正的 Ontology Language。
四十一、整个 DSL
最终:
ontology:
apiName: ad_monetization
types:
objects: [...]
interfaces: [...]
links: [...]
functions: [...]
actions: [...]
policies: [...]
然后:
ontology.yaml
│
▼
Parser
│
▼
AST
│
▼
Normalizer
│
▼
Reference Resolver
│
▼
Type Checker
│
▼
Semantic Validator
│
▼
Dependency Graph
│
▼
Compatibility Analyzer
│
▼
IR
│
▼
Compiler
│
├─────────────┐
▼ ▼
PostgreSQL Runtime
四十二、Ontology Compiler 不应该直接操作数据库
这是一个非常重要的工程原则。
不要:
YAML
↓
SQL
应该:
YAML
↓
AST
↓
Semantic Model
↓
IR
↓
Artifacts
四十三、Compiler 内部架构
OntologyCompiler
│
├── Lexer / Parser
│
├── AST Builder
│
├── Normalizer
│
├── SymbolTable
│
├── ReferenceResolver
│
├── TypeChecker
│
├── ConstraintChecker
│
├── InterfaceChecker
│
├── LinkChecker
│
├── ActionChecker
│
├── DependencyAnalyzer
│
├── CompatibilityAnalyzer
│
├── SecurityAnalyzer
│
├── IRBuilder
│
├── MetadataCompiler
│
└── RuntimeArtifactCompiler
四十四、Symbol Table
这是编译器真正开始“像编译器”的地方。
例如:
object: Game
Compiler 不能直接查数据库。
它应该:
SymbolTable
Game
├── type = OBJECT_TYPE
├── id = xxx
├── properties
│ ├── id
│ ├── revenue
│ └── eCPM
├── links
└── interfaces
然后:
game.eCPM
Compiler 就能解析成:
Game.eCPM
│
▼
PropertySymbol
│
▼
type = DECIMAL
四十五、Type Checker
例如:
expression:
gt:
- ref: game.eCPM
- value: "hello"
Compiler:
game.eCPM
↓
DECIMAL
"hello"
↓
STRING
gt(DECIMAL, STRING)
↓
ERROR
输出:
E1007 TYPE_MISMATCH
Expected:
DECIMAL
Actual:
STRING
Path:
actions.IncreaseTrafficAllocation.preconditions[0]
这才是“Ontology Language”。
四十六、IR:Intermediate Representation
Compiler 不应该直接从 DSL 跳 Runtime。
定义:
interface OntologyIR {
ontology: OntologyIRDefinition;
types: TypeIR[];
links: LinkIR[];
interfaces: InterfaceIR[];
functions: FunctionIR[];
actions: ActionIR[];
dependencies: DependencyIR[];
}
四十七、ObjectType IR
例如:
{
"kind": "ObjectType",
"name": "Game",
"primaryKey": {
"name": "id",
"type": "string"
},
"properties": [
{
"name": "revenue",
"type": {
"kind": "decimal"
}
}
]
}
四十八、Compiler 最终生成什么?
至少生成五类 Artifact:
Compiler
│
├── Metadata Artifact
│
├── Database Artifact
│
├── Runtime Artifact
│
├── API Artifact
│
└── SDK Artifact
Metadata
ontology_meta
Database
自动生成:
Game
AdNetwork
Experiment
Revenue
Runtime
生成:
ObjectResolver
PropertyAccessor
LinkResolver
ActionHandler
API
自动生成:
GET /objects/Game/{id}
GET /objects/Game/{id}/links/monetizedBy
POST /actions/IncreaseTrafficAllocation
SDK
最终甚至可以生成:
Game
AdNetwork
Experiment
以及:
game.eCPM
game.monetizedBy.get()
这和 Palantir 官方文档描述的“Ontology object types 转成 TypeScript API”这一方向是一致的。(Palantir)
四十九、REST API:OMS 管理面
管理面 API 统一挂在:
/oms/v1
Ontology
POST /oms/v1/ontologies
GET /oms/v1/ontologies
GET /oms/v1/ontologies/{ontology}
PUT /oms/v1/ontologies/{ontology}
Object Types
POST /oms/v1/object-types
GET /oms/v1/object-types
GET /oms/v1/object-types/{type}
PUT /oms/v1/object-types/{type}
DELETE /oms/v1/object-types/{type}
Properties
POST /oms/v1/object-types/{type}/properties
GET /oms/v1/object-types/{type}/properties
PUT /oms/v1/object-types/{type}/properties/{property}
Links
POST /oms/v1/link-types
GET /oms/v1/link-types
GET /oms/v1/link-types/{link}
Interfaces
POST /oms/v1/interfaces
GET /oms/v1/interfaces
GET /oms/v1/interfaces/{interface}
POST /oms/v1/interfaces/{interface}/implementations
Actions
POST /oms/v1/action-types
GET /oms/v1/action-types
GET /oms/v1/action-types/{action}
Functions
POST /oms/v1/functions
GET /oms/v1/functions
GET /oms/v1/functions/{function}
五十、但真正高级的 API 是 Compile API
POST /oms/v1/compile
Request:
{
"source": "...ontology yaml..."
}
Response:
{
"status": "COMPILED",
"ontologyVersion": 12,
"schemaHash": "sha256:...",
"artifacts": {
"metadata": true,
"database": true,
"api": true,
"sdk": true
}
}
错误:
{
"status": "FAILED",
"errors": [
{
"code": "TYPE_MISMATCH",
"path": "actions.foo.parameters.game",
"message": "Expected Game, received AdNetwork"
}
]
}
五十一、Preview API
真正好用的 OMS 必须支持:
POST /oms/v1/compile/preview
也就是:
不真正修改 Ontology,只告诉你这次 Schema Change 会发生什么。
返回:
{
"changes": [
{
"type": "ADD_PROPERTY",
"target": "Game.eCPM",
"breaking": false
},
{
"type": "ADD_LINK",
"target": "Game.monetizedBy",
"breaking": false
}
]
}
这实际上就是:
Ontology Migration Plan
五十二、Dependency API
GET /oms/v1/resources/{id}/dependencies
GET /oms/v1/resources/{id}/dependents
例如:
Game
↓
who depends on me?
Experiment
Action
Function
Interface
Link
这对后面做 Schema Migration 极其重要。
五十三、Graph API
更进一步,OMS 还可以暴露:
GET /oms/v1/graph
返回:
{
"nodes": [...],
"edges": [...]
}
然后 ontao.entos.top 就可以直接把整个 Ontology 画出来。
五十四、真正完整的 OMS Architecture
现在把所有东西合起来:
┌──────────────────────┐
│ Ontology DSL │
│ YAML / JSON │
└──────────┬───────────┘
│
▼
┌─────────────────────────┐
│ Ontology Compiler │
│ │
│ Parser │
│ AST │
│ Symbol Table │
│ Resolver │
│ Type Checker │
│ Validator │
│ Dependency Analyzer │
│ Compatibility Analyzer │
│ IR Builder │
└───────────┬─────────────┘
│
▼
┌──────────────────────────┐
│ OMS │
│ │
│ Type Registry │
│ Property Registry │
│ Link Registry │
│ Interface Registry │
│ Action Registry │
│ Function Registry │
│ Version Registry │
│ Dependency Graph │
│ Validation Registry │
└────────────┬─────────────┘
│
┌────────────────┼────────────────┐
│ │ │
▼ ▼ ▼
Metadata DB Runtime Artifacts SDK/API
│ │ │
▼ ▼ ▼
PostgreSQL Ontology Runtime Applications
│
┌────────────────────────┼───────────────────────┐
│ │ │
▼ ▼ ▼
Object Store ObjectSet Engine Action Engine
│ │ │
└────────────────────────┼───────────────────────┘
│
▼
External World
五十五、一个非常重要的“闭环”
到这里就能看清 Palantir Ontology 为什么不是普通知识图谱。
普通:
Data
↓
Knowledge Graph
↓
Query
Mini-Palantir 的闭环是:
World
↓
Object
↓
ObjectSet
↓
Function
↓
Decision
↓
Action
↓
Mutation
↓
Event
↓
World
即:
┌───────────────────────────┐
│ │
▼ │
Object │
│ │
▼ │
ObjectSet │
│ │
▼ │
Function │
│ │
▼ │
Decision │
│ │
▼ │
Action │
│ │
▼ │
Mutation │
│ │
▼ │
Event ────────────────────────┘
这才是值得研究的 Ontology。
Palantir 官方对 Ontology 的描述也是把 semantic elements 与 kinetic elements 放在同一 operational layer 中,而不只是做数据目录。(Palantir)
五十六、用 Ad Monetization OS 场景跑一遍
这个地方非常关键。
不要做:
Demo Ontology
Game
Player
Weapon
那种玩具。
直接做:
Ad Monetization Ontology
已经有真实业务系统和优化闭环,可以直接用来验证 Ontology 的价值。
第一批 ObjectType:
Game
AdNetwork
Country
AdPlacement
UserSegment
Experiment
TrafficAllocation
Revenue
五十七、然后定义 Interface
MonetizableAsset
拥有:
revenue
eCPM
impressions
fillRate
实现:
Game
Website
App
于是:
MonetizableAsset
▲
│
┌─────┼──────┐
│ │ │
Game App Website
这时 Agent 可以直接问:
Find all MonetizableAssets
where eCPM > 5
and revenueGrowth > 20%
而不是:
SELECT ...
FROM ...
JOIN ...
WHERE ...
这就是 Ontology abstraction 的价值。
五十八、再定义 Function
calculateOptimizationScore
输入:
Game
内部:
Game
│
├── Revenue
├── eCPM
├── Country
├── AdNetwork
├── Experiment
└── TrafficAllocation
输出:
OptimizationScore
五十九、再定义 Action
IncreaseTrafficAllocation
:
Game
+
Country
+
percentage
执行:
Authorization
↓
Validation
↓
Precondition
↓
Mutation
↓
Event
↓
External Ad System
于是整个业务真正变成:
Agent
↓
“哪些游戏值得增加美国流量?”
↓
ObjectSet
↓
Function
↓
OptimizationScore
↓
Decision
↓
IncreaseTrafficAllocation
↓
Action
↓
Ad System
↓
Revenue
↓
Event
↓
Ontology
这就已经不是“AI 查数据库”了。
而是:
AI 在一个可计算、可操作、可治理的世界模型上工作。
六十、研究体系同步升级:逆向工程全景框架
研究 Ontology 不应该按照:
什么是 Object?
什么是 Property?
什么是 Link?
这种百科全书方式学。
而应该建立:
ONTOLOGY REVERSE ENGINEERING
│
├── 01 Ontology Philosophy
│
├── 02 Ontology Language
│
│ ├── ObjectType
│ ├── Property
│ ├── Link
│ ├── Interface
│ ├── Action
│ ├── Function
│ └── ObjectSet
│
├── 03 Ontology Meta Model
│
│ ├── OMS
│ ├── Type System
│ ├── Schema
│ ├── Version
│ └── Dependency
│
├── 04 Ontology Compiler
│
│ ├── DSL
│ ├── AST
│ ├── Type Checker
│ ├── Validator
│ ├── IR
│ └── Code Generator
│
├── 05 Ontology Runtime
│
│ ├── Object Store
│ ├── ObjectSet
│ ├── Link Resolver
│ ├── Action Engine
│ └── Function Runtime
│
├── 06 Security
│
├── 07 AI / Agent
│
├── 08 Operational Applications
│
└── 09 Mini-Palantir
│
└── Ad Monetization Ontology
这比单纯做“Ontology 知识库”更接近工程实践。
六十一、下一阶段:写 Compiler,而不是继续堆 Schema
这一阶段暂停继续扩展表。
当前阶段已经具备:
OMS
Type System
DSL
Compiler
REST API
Versioning
Dependency
Validation
下一步是真正开始写 Compiler。
实施顺序固定为:
Phase 1
Ontology DSL
↓
Phase 2
Lexer / Parser
↓
Phase 3
AST
↓
Phase 4
Symbol Table
↓
Phase 5
Reference Resolver
↓
Phase 6
Type Checker
↓
Phase 7
Semantic Validator
↓
Phase 8
Dependency Graph
↓
Phase 9
IR
↓
Phase 10
PostgreSQL Metadata Compiler
↓
Phase 11
Runtime
第一版甚至不要做 UI。
直接:
ontology compile ontology.yaml
然后:
ontology.yaml
↓
Compiler
↓
ontology.ir.json
↓
ontology.sql
↓
ontology.openapi.json
↓
ontology.sdk.ts
这条链真正跑通后,Mini-Palantir 才算从“架构图”进入“语言/编译器系统”阶段。
结语:这套系统在整个体系中的定位
┌─────────────────────────┐
│ Ontology DSL │
└────────────┬────────────┘
↓
┌─────────────────────────┐
│ Ontology Compiler │
└────────────┬────────────┘
↓
┌─────────────────────────┐
│ OMS │
│ │
│ “What the world is” │
└────────────┬────────────┘
↓
┌─────────────────────────┐
│ Ontology Runtime │
│ │
│ “What the world can do” │
└────────────┬────────────┘
↓
┌─────────────────────────┐
│ AI / Human │
│ │
│ “What should we do?” │
└─────────────────────────┘
OMS 是“世界模型的类型系统”;Compiler 是“把世界模型编译成可运行系统的机器”;Runtime 才是“世界模型真正活起来”的地方。
下一步最值得做的不是再画一张架构图,而是直接把上面的 ontology.yaml → AST → SymbolTable → TypeChecker → IR 做出来。做到这里,才能真正理解 Palantir Ontology 为什么和传统数据库、知识图谱、DDD、低代码平台都“不太一样”。