Palantirのオントロジーとは? テーブルとAPIの言葉で置き換える

コードを読まないAIエンジニア
サムネイル

Palantirのオントロジーは、業務システムのテーブルの上に「この行は注文」「注文は顧客につながる」「この条件なら出荷元を変えてよい」という業務の定義を重ねた層です。業務データを渡したAIが、システムに無い操作を平気で提案してくる。オントロジーをテーブル・外部キー・APIの言葉に置き換えると、その原因が足りない定義として見えてきます。同じ業務データをClaudeに渡して試すと、答えを変えたのはデータの説明より、操作の定義のほうでした。

Palantirのオントロジーは、データとアプリの間に置く層

データ層、オントロジー、アプリとAIの3層構造。オントロジーの中は名詞(オブジェクトとリンク)と動詞(アクションと関数)に分かれ、データ層から上向きに同期、下向きに書き戻しの矢印が通る図

Foundry(Palantirの企業向けデータ基盤)では、オントロジーが3層の真ん中に入ります。下にはERPやIoTから取り込んだデータセット(Foundry上のテーブルに当たる単位)があり、上には業務アプリとAIが乗ります。

公式のOntology overviewは、オントロジーが組織のデジタルツイン(現実の業務をデータの上に写した模型)として働くことが多いと書いています。日本語ページの「オントロジーを作成する理由」では、構成要素をデータ、ロジック、アクション、セキュリティの4つとしています。ロジックはサーバー側のコード(関数)や機械学習モデル、セキュリティは人にもAIにも同じ権限制御をかける部分です。

流れは上下の2方向です。オントロジーは元のDBを直接参照するビューではなく、データセットを取り込んで検索できる形のコピーを持ち、データセットが更新されると自動で同期されます。逆方向では、オントロジー上の操作の結果を業務システムへ書き戻します。この書き戻しをライトバック(writeback)と呼びます。

オブジェクト型とリンク型は、テーブルと外部キーの言い換え

架空のEC企業「ノース工房」の注文テーブルT_ORDは、生だとこう見えます。

ORD_NO,CUST_CD,ITM_CD,QTY,WH_CD,ST_CD,ORD_DT
O1001,C1,P1,8,W1,10,2026-10-27
O1004,C1,P1,3,W2,30,2026-10-25

ST_CDの10が何かは、テーブルからは読めません。オブジェクト型(Object Type)「注文」として定義すると、10が「受注済み・未出荷」という業務の言葉になります。

- 注文(T_ORD の1行 = 1注文)。プロパティ: 注文番号、数量、受注日、状態(受注済み・未出荷 / 出荷準備中 / 出荷済み / キャンセル。コードは 10 / 20 / 30 / 90)

自分のシステムのST_CDのような略号、AIが初見で読めると思いますか? コード表を渡していなければ、AIは推測で埋めるしかありません。

外部キーCUST_CDは注文から顧客へのリンク型(Link Type)になり、部材構成の中間テーブルM_BOMは「製品→部材」の多対多のリンク型になります。表でテーブルと書いた行は、公式の対応ではFoundryのデータセットです。

オントロジーの用語
公式docsの原語
DB・APIで近いもの
オブジェクト型
Object Type
テーブル
オブジェクト
Object
行
プロパティ
Property
列
リンク型
Link Type
外部キー、JOIN、中間テーブル
アクション型
Action Type
実行条件と書き戻しが付いた更新API
関数
Function
オブジェクトを入力に取るサーバー側のコード

表のうち「外部キー」「中間テーブル」とアクション型・関数の行は私の読み替えで、残りは公式の対応です。関数はアクションやアプリから呼ばれるTypeScriptやPythonのコードで、4要素の「ロジック」の置き場の1つです。

ここまでは公式が「名詞」と呼ぶデータの側で、データ辞書やセマンティック層(データの意味をまとめて定義しておく層)でも書けます。普通のスキーマとオントロジーが分かれるのは、公式が「動詞」と呼ぶアクションの側なんですよ。

アクション型は、普通の更新APIと何が違うのか?

アクションの実行の流れ。実行の依頼、条件の確認、外部へ書き戻し、オントロジーを編集、通知の順に進み、条件を満たさなければ実行せず、書き戻しが失敗したら何も変えないことを示す流れ図

データを名詞、アクションを動詞と呼ぶのは、公式の「オントロジーを作成する理由」の言い方です。アクション型(Action Type)の定義は「ユーザーが一度に行える、オブジェクト・プロパティ値・リンクへの変更の集合の定義」で、副作用も含みます。

1回の操作に、条件と副作用まで入る

例に挙がる「Assign Employee」は、役職の変更と上司と部下のリンクの作成を1回で行い、実行できるのは人事部の社員だけです(この条件を実行条件、英語ではsubmission criteriaと呼びます)。前の上司と新しい上司への通知が副作用に当たります。

ここは私の読み替えですが、PATCH /employees/{id}が決めるのは変える値までで、アクション型は実行できる人、条件、連動するリンク、副作用まで1つの定義に持ちます。

いまの更新APIは、「実行してよい条件」をAPI仕様から読めるでしょうか。認可のpolicyやバリデーションの中にはあっても、仕様に出ていなければAIからも見えていません。

外部への書き戻しが失敗したら、オントロジーは変えない

実行は条件の確認、外部システムへの書き戻し、オントロジーの編集、通知の順に進みます。書き戻しを担うwriteback webhookは、Foundry側からSAPなどの外部システムを呼ぶ向きのwebhookで、オブジェクトの変更より先に動き、失敗したら何も変更しません。逆は保証されず、外部が成功したあとにオントロジー側の変更が失敗することはあり得ます。後から動くside effect webhook(通知など、変更後に外部を呼ぶwebhook)は順序が保証されず、失敗もユーザーに見えません。

自前でAIを更新APIにつなぐときも、外部への書き込み、DBの更新、通知のどこまでを1つの失敗で巻き戻すかは決めることになります。トランザクションに近いのは外部への書き戻しまでで、通知はその外、というのが私の読み方です。

オントロジーで差が出たのは、名詞より動詞

ノース工房のデータは8テーブル、注文7件、倉庫2つです。仕入先S2(北海木材)の部材供給が止まった設定で、影響範囲の特定、在庫と倉庫振替の判断、取るべき操作をClaude Sonnetに聞きました。依頼文には、データから読めずに仮定したことを最後に列挙するよう添えています。Aは生テーブルだけ、Bはデータ辞書(列の意味)つき、Cはオントロジー相当の定義(オブジェクト型7つ、リンク型7つ、アクション型3つ)をMarkdownで足した条件です。

在庫には手持ち数量と引当済み数量(ほかの注文に確保済みの数)があり、出荷可能数量はその差です。Cに渡したアクション型3つのうち、1と3を抜粋します。

1. 出荷元倉庫を振り替える(対象: 注文、入力: 新しい倉庫)
   - 実行できる条件: 注文の状態が「受注済み・未出荷」であること。新しい倉庫でのその製品の出荷可能数量が注文の数量以上であること
   - 実行されること: 注文の出荷元倉庫が変わる。新しい倉庫の在庫の引当済み数量が注文数量ぶん増える
   - 副作用: 顧客へ出荷元変更の通知メールが送られる
   - 注: 1つの注文を複数の倉庫に分けて出荷する操作は存在しない
3. 代替部材を登録する(対象: 製品、入力: 代替の部材)
   - 実行できる条件: 品質管理担当者の承認が必要。営業担当者やAIエージェントは実行できない(提案のみ)

生テーブルだけでも、影響範囲はたどれた

3条件とも影響を受ける注文4件を過不足なく挙げ、除外すべき3件(別の仕入先の部材だけで作る製品の注文、出荷済み、キャンセル)も正しく外しました。在庫が足りる注文と足りない注文の区別も合っています。AはST_CDの意味を推測で当て、仮定の一覧に書いていました。

違いが出たのは、取るべき操作の中身

データ辞書を足したBは、提案まで良くなったでしょうか? 列の意味の仮定は消えましたが、提案する操作はAとほぼ同じでした。

比べた点
A 生テーブル
B +データ辞書
C +オントロジー
影響を受ける注文の特定
4/4、除外3/3
4/4、除外3/3
4/4、除外3/3
システムに無い操作を実行するものとして提案(筆者の数え方)
4件
3件
0件
AIが実行できない操作を分けたか
分けない
分けない
分けた
列挙した仮定の数
8
8
9

表の提案の件数は私の数え方です。AとBには操作の一覧を渡していないので、Cの定義にある3つの操作(振替、遅延連絡、代替部材の登録)以外を、実行できるものとして挙げた数を数えました。1つの注文を分けて出す分割出荷や、受注の受付停止がそれです。AとBが一覧にない操作を挙げるのは当然で、見たいのは、その操作を実行できるものとして並べるか、人が判断することとして分けるかです。なお、Cの依頼文にだけ操作を「アクション名(対象、入力)」の形で書くよう添えているので、仕分けの形はその指示にも助けられています。

Cの答えだけ、そのまま実行に回せるものと人が判断するものに分かれていました。「実行するアクション」3件(O1001の倉庫振替、O1005とO1006への遅延連絡)、「実行しない」2件、「提案のみ(AIは実行できない)」1件、「システムのアクションにない対応(人が判断)」2種類に仕分けていて、O1001(顧客は青葉デザイン事務所)の振替はこう書かれていました。

1. 出荷元倉庫を振り替える(対象: O1001、入力: 新しい倉庫 = W2 大阪倉庫)
   - 条件1: 注文の状態が「受注済み・未出荷」。O1001 は状態10なので満たしている。
   - 条件2: 新しい倉庫での出荷可能数量が注文数量以上。W2 の P1 は12個で、注文は8個なので満たしている。
   - 実行後: W2 の P1 の引当済みが 0 → 8、出荷可能数量が 12 → 4 になる。
   - 副作用: 青葉デザイン事務所へ出荷元変更の通知メールが自動送信される。
   - 順序: O1005 に先に W2 の在庫を引き当てないよう、このアクションを最初に行う。

仮定の数はほとんど変わらず(8、8、9)、Cでは列の意味の仮定が減り、代わりに「出荷元変更のメールが顧客へ自動で飛んでも問題ない」という、副作用を起こしてよいかの仮定が加わっていました。

AIエージェントには、オントロジーがどう見えるのか?

AIエージェントから見たオントロジー。左に読むためのツール(オブジェクトを探す、リンクをたどる)、右に条件つきで実行できる操作2つ、提案のみの操作1つ、存在しない分割出荷を点線で消した図

公式docsでは、AIP Logic(FoundryでLLMを使う関数をノーコードで作る環境)のLLMに、オントロジーのオブジェクトを検索して調べるツールが渡されます。LLMが出した編集は、そのまま適用するか、人の承認待ちに保留(ステージ)するかを選べます。外のコードから使うSDK(OSDK)でも、できることは主にオブジェクトの読み取り、リンクのたどり、アクションの実行、関数の呼び出しです。

アクションの範囲は、オントロジーの編集だけに限ることも、外部システムへの書き戻しまで広げることもできます。AIについては既定ではステージ(提案)までで、最終レビューは人が行い、十分に検証したAIプロセスにだけ人のレビューなしの実行を許せます。4要素のセキュリティが効いているのがここで、AIも人と同じ権限制御の中で動きます。

つまりAIから見たオントロジーは、読むためのツールと条件付きの操作の束です。ノース工房なら、リンクをたどる読み取り、条件付きの「出荷元を振り替える」「納期遅延を連絡する」、提案しかできない「代替部材を登録する」が並び、「分割出荷」はその中にありません。

function callingのツール定義に、足りないもの

function callingのツール定義に書くのは、名前と説明と引数です。アクション型はそれに加えて条件と副作用と実行できる人を定義に持ち、条件はプラットフォームが実行時に確かめます。

いまAIにつないでいるツールの事前条件、誰が確かめていますか? 説明文に書いただけなら、守るかどうかはモデル次第です。

Foundryなしで真似るときの、アクション型の書き方

Foundryが無くても、Markdownの定義だけで提案は変わりました。AIに触らせたい更新操作ごとに、対象と入力、実行できる条件、実行されること、副作用を書きます。function callingのツール定義に写すと、たとえばこうなります。

{
  "name": "change_ship_warehouse",
  "description": "注文の出荷元倉庫を振り替える。条件: 注文が受注済み・未出荷で、新しい倉庫の出荷可能数量が注文数量以上。実行すると新しい倉庫の引当が注文数量ぶん増え、顧客に通知メールが送られる。1つの注文を複数の倉庫に分けて出荷する操作は無い。",
  "parameters": {
    "type": "object",
    "properties": {
      "order_no": { "type": "string", "description": "注文番号(例: O1001)" },
      "new_warehouse": { "type": "string", "description": "新しい倉庫コード(例: W2)" }
    },
    "required": ["order_no", "new_warehouse"]
  }
}

私の書き方の例で、Foundryが生成するコードではありません。条件を説明文に書くのは提案の質を上げるためで、実行を止める役はこの後に書くAPI側です。

できないことと、AIに許さないことを書く

Cの定義には、分割出荷の操作は存在しないことと、AIは代替部材を登録できないことも書きました。これは試していない私の推定ですが、「存在しない」と書かなければCも分割出荷を提案した可能性があります。AもBも、1つの注文を分けて出す案を選んでいます。

AIに絶対やらせたくない操作も、同じ定義に書いておきます。書いていなければ、AIはそれをほかの操作と同列に扱います。

条件を確かめるのは、プロンプトの外

プロンプトに書いた条件が変えたのは提案の質で、実行を止める仕組みではありません。自前でやるなら、条件の確認は更新APIの中に置き、提案だけの操作はAIに実行ツールを渡さないのが筋だと私は考えています。ノース工房なら「代替部材を登録する」はAIに渡さず、「代替部材の候補を返す」ツールだけを渡して、登録のAPIは品質管理担当者の権限でしか通さない形です。

最初の一歩は小さくて大丈夫です。AIに触らせたい更新APIを1つ選び、条件と副作用、できない操作を書き出すだけです。

このオントロジー検証で、まだ分かっていないこと

Foundry本体(オントロジーを定義するOntology Manager、OSDK、AIP)は触っておらず、Markdownの定義をプロンプトで渡した再現です。各条件1回ずつ、Claude Sonnetだけで、回答のぶれやほかのモデルでの差は測っていません。

依頼文も3条件で同一ではなく、Cだけの書式の指示のほかに、仕入先の呼び方もAとBは「S2」、Cは「北海木材」でした。差のうちどこまでが定義の効果かは、書式をそろえた再実験で切り分ける必要があります。サーバー側で条件を守らせる部分も未検証です。

名詞の側は、テーブルと外部キーがあればAIもたどれました。AIに業務の操作を任せるなら、足すべきは動詞の定義です。