Palantir Lab · 引擎设计

OMS 拆解 — Ontology Metadata Service

编译器前端 + 类型系统 + Schema Registry + Governance

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、低代码平台都“不太一样”。