fabriciq-ontology-authoring-cli について
fabriciq-ontology-authoring-cli は、Microsoft Fabric のコントロールプレーン API で Ontology のアイテム定義を作成する CLI スキルです。エンティティ型、データバインディング、リレーションを扱い、書き込み前に変更を確認できます。
主な機能
- 01Ontology 定義の作成と更新
- 02エンティティ型とプロパティの作成
- 03Lakehouse と Eventhouse のテーブルをバインド
- 04リレーションとコンテキスト化を定義
- 05書き込み前に変更案をプレビュー
活用シーン
- 01Fabric のテーブルデータからエンティティをモデル化
- 02Eventhouse の時系列バインディングを設定
- 03リレーションでエンティティ型を接続
- 04Ontology アイテムを作成または改訂
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ microsoft/ skills-for-fabric --skill fabriciq-ontology-authoring-cliインストール後、Claude Code で/fabriciq-ontology-authoring-cliを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/authoring-mechanics.mddefinition-script-templates.mdexamples.mdONTOLOGY-AUTHORING-CORE.mdpreview-and-confirm.md詳細
更新チェック — セッションごとに1回(必須) このスキルをセッションで初めて使用する際は、続行する前に check-updates スキルを実行してください。
- GitHub Copilot CLI / VS Code:
check-updatesスキルを呼び出してください(例:/fabric-skills:check-updates)。- Claude Code / Cowork / Cursor / Windsurf / Codex:ローカルの
package.jsonのバージョンを読み取り、git fetch origin main --quiet && git show origin/main:package.json(または GitHub API)を使ってリモートと比較してください。リモートのほうが新しい場合は、変更履歴と更新手順を表示してください。- このセッション中にすでにチェック済みの場合はスキップしてください。
重要な注意事項
- オントロジーは プレビュー です。アイテムタイプの値は
Ontologyです。機能とワイヤ形式は変更される可能性があるため、本番環境で使用する前に最新のドキュメントを確認してください。- ワークスペース名からワークスペースの詳細(ID を含む)を見つけるには、すべてのワークスペースを一覧表示し、JMESPath フィルタリングを使用してください。
- ワークスペース ID、アイテムタイプ(
Ontology)、アイテム名からアイテムの詳細(ID を含む)を見つけるには、そのワークスペース内の該当タイプのアイテムをすべて一覧表示し、JMESPath フィルタリングを使用してください。- 関係タイプを作成するには、オントロジーにすでに存在する2 つの異なるエンティティタイプが必要です。
source.entityTypeIdとtarget.entityTypeIdの値は、アイテム ID ではなく、割り当てたエンティティタイプ IDです。- データバインディングでは、
workspaceId、itemId、sourceTableName、およびレイクハウスソースの場合はsourceSchemaを使ってソーステーブルを指定します。レイクハウス(LakehouseTable)ソースにはレイクハウスのアイテム ID が含まれます。Eventhouse(KustoTable)ソースにはEventhouse のアイテム IDに加えて、clusterUriとdatabaseNameが含まれます。ソース側のキー列は、エンティティタイプのキー プロパティと一致している必要があります。Eventhouse ソースはTimeSeriesのみです。静的(NonTimeSeries)バインディングはレイクハウスから取得する必要があります。
fabriciq-ontology-authoring-cli — CLI による Fabric オントロジーの作成
目次
| タスク | 参照 | 備考 |
|---|---|---|
| Fabric のワークスペースとアイテムの検索 | Fabric のワークスペースとアイテムの検索 | 必須 — 作成前にワークスペース ID/アイテム ID を解決してください |
| Fabric のトポロジーと主要概念 | Fabric のトポロジーと主要概念 | ワークスペース → アイテムの階層 |
| 認証とトークンの取得 | 認証とトークンの取得 | コントロールプレーンには https://api.fabric.microsoft.com のオーディエンスを使用します |
| コアのコントロールプレーン REST API | コアのコントロールプレーン REST API | アイテムの作成、アイテム定義の取得/更新 |
| 長時間実行操作(LRO) | 長時間実行操作(LRO) | アイテムの作成/更新は LRO を返します |
| レート制限とスロットリング | レート制限とスロットリング | |
| 認証の手順 | 認証の手順 | az login、トークンの取得 |
az rest による Fabric コントロールプレーン API | az rest による Fabric コントロールプレーン API | 必ず --resource https://api.fabric.microsoft.com を渡してください |
| 長時間実行操作(LRO)のパターン | 長時間実行操作(LRO)のパターン | Ontology の作成/更新では、Fabric ホスト上の /v1/operations/{x-ms-operation-id} をポーリングします — LRO ヘッダーの取得を参照してください |
| 注意点とトラブルシューティング(CLI 固有) | 注意点とトラブルシューティング(CLI 固有) | トークンのオーディエンス、シェルのエスケープ |
az rest テンプレート | az rest テンプレート | |
| 定義エンベロープ(parts、payloadType) | 定義エンベロープ | Ontology で使用する InlineBase64 parts パターン |
| Ontology 定義リファレンス | Ontology 定義ツリー | ontology アイテムの正式なファイル/フォルダー構成 |
| EntityType と EntityTypeProperty のスキーマ | EntityType ファイル | 使用可能な valueType 値、キー制約、名前の正規表現 |
| DataBinding のスキーマとソースタイプのマッピング | DataBinding ファイル | Lakehouse と Eventhouse の形式、値の型のマッピング、バインド規則 |
| RelationshipType と Contextualization のスキーマ | RelationshipType ファイル | ソース/ターゲットの制約、リンクテーブルの要件 |
| Ontology の概念 | Ontology アイテムの概念 | エンティティタイプ、プロパティ、バインド、リレーションシップタイプ |
| ツールスタック | ツールスタック | |
| 接続 | 接続 | ワークスペース、Lakehouse、Ontology の ID を検出 |
| 作成範囲 | 作成範囲 | サポートされる操作の概要 |
| 作成の仕組み(完全なリファレンス) | authoring-mechanics.md | エンベロープ、ID、作成、エンティティタイプ、バインド、リレーションシップ、更新、検証 |
| 実例 | examples.md | bash によるエンドツーエンドの手順(作成 → バインド → リレーションシップ → 時系列) |
| プレビューと確認(LRO 書き込み前に必須) | preview-and-confirm.md | ASCII 提案(グリーンフィールド)/変更セットの差分(ブラウンフィールド) |
| スクリプトテンプレート | definition-script-templates.md | Bash/PowerShell の取得・変更・送信のひな形 |
| 必須/推奨/回避/トラブルシューティング | 必須/推奨/回避/トラブルシューティング | LLM の判断ルール |
| エージェントワークフロー | エージェントワークフロー | 作成前の探索、スクリプト生成 |
| エージェント統合に関する注意事項 | エージェント統合に関する注意事項 | このスキルがエージェント/他のスキルとどのように連携するか |
オントロジー項目の概念
Fabric オントロジー項目は、項目定義内のJSON ファイルのツリーとして作成します。各ファイルは、Create/Update 定義エンベロープの parts[] 配列内のパーツとして格納されます(payloadType は InlineBase64)。
| 概念 | 定義ファイルのパス | 目的 |
|---|---|---|
| オントロジーエンベロープ | definition.json | 空の {}。必須です |
| プラットフォームのメタデータ | .platform | { "metadata": { "type": "Ontology", "displayName": "<name>" } } |
| エンティティ型 | EntityTypes/{entityTypeId}/definition.json | 名前、名前空間、キー、表示名プロパティ、properties[]、timeseriesProperties[] |
| エンティティ型のデータバインディング | EntityTypes/{entityTypeId}/DataBindings/{guid}.json | レイクハウスまたはイベントハウスのテーブルをプロパティにマッピングします。dataBindingType は NonTimeSeries または TimeSeries です。イベントハウス(KustoTable)のソースが許可されるのは、TimeSeries の場合のみです |
| エンティティ型のドキュメント | EntityTypes/{entityTypeId}/Documents/{name}.json | オプションのドキュメントリンク |
| エンティティ型の概要 | EntityTypes/{entityTypeId}/Overviews/definition.json | オプションのウィジェットレイアウト |
| エンティティ型のリソースリンク | EntityTypes/{entityTypeId}/ResourceLinks/definition.json | オプションの Power BI/項目リンク |
| リレーションシップ型 | RelationshipTypes/{relTypeId}/definition.json | ソースとターゲットのエンティティ型 ID、名前 |
| リレーションシップのコンテキスト化 | RelationshipTypes/{relTypeId}/Contextualizations/{guid}.json | レイクハウスのテーブルへのソース/ターゲットキーのバインディング |
プロパティの valueType に指定できる値(正確な値):String、Boolean、DateTime、Object、BigInt、Double。整数には Int64 ではなく BigInt を使用してください。Guid の値型はありません(モデルの GUID は String として扱います)。時系列バインディングには、タイムスタンプ列(ソース型 datetime/date/timestamp)と、timestampColumnName を指定した TimeSeries バインディングが必要です。ソース列から valueType へのマッピングの詳細については、ONTOLOGY-AUTHORING-CORE.md § EntityTypeProperty を参照してください。
⚠️ プロパティ名は、単一のエンティティ型内の
properties[]とtimeseriesProperties[]の両方を通じて一意である必要があります。レイクハウステーブルと Eventhouse テーブルに同じ名前の列(例:tenant_id)が含まれている場合、衝突を避けるために、一方のオントロジープロパティ名を必ず変更してください。バインディングのsourceColumnNameでは、元の列を引き続き参照できます。一意にする必要があるのは、オントロジープロパティのnameだけです。たとえば、静的プロパティはTenantIdのままにし、時系列プロパティにはTsTenantIdという名前を付けます。⚠️ 異なるエンティティ型間で同じ
nameのプロパティは、同じvalueTypeを共有する必要があります。オントロジーでは、定義全体にわたって名前レベルで型の一貫性が適用されます。あるエンティティ型でSerialNumがStringの場合、別のエンティティ型でBigIntにすることはできません。すべての箇所で同じvalueTypeを使用するか、プレフィックスを付けて区別してください(例:SerialNumStrとSerialNumInt)。⚠️ パーツのパスでは、常にスラッシュ(
/)を使用してください(EntityTypes/{id}/definition.json)。バックスラッシュは使用しないでください。Windows では、PowerShell のパス結合演算子(Join-Path、\)によってバックスラッシュが生成され、Fabric API によってALMOperationBadRequestエラーで拒否されます。パーツのパスは、常に/を使った文字列補間で作成してください。
ツールスタック
オントロジーの作成では、他のすべての CLI スキルと同じ Fabric コントロールプレーンのツールスタックを使用します。標準の一覧(インストールコマンド、前提条件の確認、base64 ヘルパー、JSON ツール)については、COMMON-CLI.md § ツール選択の理由を参照してください。また、az login とトークンの取得については、COMMON-CLI.md § 認証手順を参照してください。
オントロジー固有のツールに関する以下のガイダンスでは、createItem / updateDefinition のペイロードで注意が必要な点のみを説明します。
⚠️ PowerShell の
ConvertTo-Jsonに関する警告:PowerShell のConvertTo-Jsonは、キーの順序を通知なしに変更したり、$nullを JSON のnullとは異なる方法でシリアル化したりすることがあります。その結果、updateDefinitionでALMOperationImportFailedエラーが発生する場合があります。これを避けるには、次の点に注意してください。
- JSON ファイルの書き込みには必ず
[System.IO.File]::WriteAllTextを使用し、[System.Text.UTF8Encoding]::new($false)を指定してください。Out-FileとSet-Contentはペイロードを破損させる BOM を追加します。- 可能な場合は
ConvertTo-Jsonの代わりにjqで JSON を構築してください。jq -ncは、PowerShell のシリアル化に関する問題がなく、決定的でコンパクトな JSON を生成します。$json = '{}' | jq -nc --arg id "$ET_ID" --arg name "Site" '{id:$id,name:$name}'- 送信前に JSON を 検証してください:
Get-Content envelope.json | jq .—jqが失敗した場合、ペイロードの形式が正しくありません。ConvertTo-Jsonには-Depth 10を指定してください。既定の深度は 2 で、ネストされたオブジェクトが通知なしに切り詰められます。
⚠️
InlineBase64のパーツにはcertutil -encodeを使用しないでください。 出力にはヘッダーとフッターが付いて複数行に折り返されるため、使用前に後処理が必要です。Windows では、代わりに PowerShell の[Convert]::ToBase64String([IO.File]::ReadAllBytes($path))を使用してください。
接続
オントロジーの作成では、Fabric コントロールプレーンを対象とします。定義を作成する前に、WS_ID(ワークスペース)、LH_ID(静的バインディングとレイクハウス時系列バインディング用のレイクハウスアイテム ID)、および Eventhouse を使用する時系列の場合は Eventhouse アイテム ID、KQL クラスター URI、KQL データベース名が必要です。
- サインインして Fabric コントロールプレーンのトークンを取得する → COMMON-CLI.md § 認証手順(必ず
--resource https://api.fabric.microsoft.comを指定してください)。 displayNameでワークスペース、フォルダー、レイクハウス、オントロジーのアイテム ID を特定する → COMMON-CLI.md § Fabric でのワークスペースとアイテムの検索(ページネーションと JMESPath によるフィルタリングについて説明しています)。- 汎用の
az rest呼び出しテンプレート → COMMON-CLI.md § az rest による Fabric コントロールプレーン API。
フォルダー GUID とポータルの数値 ID の違い、Eventhouse ID フィールドのマッピング、バインディングのスキーマ検出、プレビューのリダイレクトホストでの LRO ヘッダー取得といった、オントロジー固有の注意点について、以下で説明します。
フォルダー(オントロジー固有の注意点)
オントロジーの作成ペイロードの folderId フィールドには、ポータル URL に表示される数値の subfolderId ではなく、フォルダー GUID が必要です。ポータルの数値を指定すると、400 InvalidParameter … cannot convert "<numeric>" to Guid … Path 'folderId' で失敗します。GET /v1/workspaces/{WS_ID}/folders を呼び出して GUID の一覧を取得し(COMMON-CLI.md § Fabric でのワークスペースとアイテムの検索を参照)、displayName でフィルタリングしてください。
Eventhouse / KQL データベース(TimeSeries バインディング用)
Eventhouse をバックエンドとする TimeSeries のオントロジー バインディングには、KQL データベースのレコード(GET /v1/workspaces/{WS_ID}/kqlDatabases の戻り値)から取得した、次の 3 つのフィールドが KustoTable データ バインディングのペイロードに必要です。
| KustoTable バインディング フィールド | KQL データベース レコードのソース フィールド |
|---|---|
itemId | properties.parentEventhouseItemId — KQL データベース自身の id ではなく、Eventhouse のアイテム ID です |
clusterUri | properties.queryServiceUri |
databaseName | displayName(API が返す正式な大文字・小文字の表記を使用してください) |
Eventhouse のテーブルは、
TimeSeriesバインディングのみに使用できます。 エンティティ型の静的(NonTimeSeries)バインディングには、引き続きマネージド レイクハウス テーブルを使用する必要があります。
よくある間違い:KQL データベース自身の
idをKustoTable.itemIdとして渡してしまうことです。同じレコードにあるparentEventhouseItemIdを使用してください。
汎用の kqlDatabases 一覧取得呼び出し(ページネーションと displayName による JMESPath フィルター)については、COMMON-CLI.md § Fabric でワークスペースとアイテムを検索するを参照してください。
スキーマの検出
バインディングを作成する前に、ソース テーブルのスキーマを検出し、正しい列名を割り当ててください。スキーマの検出には、コンパニオン スキルを使用してください。生の REST 呼び出しより高速で、信頼性も高くなります。
- レイクハウス テーブル →
sqldw-consumption-cliスキルに依頼し、レイクハウスの SQL エンドポイントに対してINFORMATION_SCHEMA.COLUMNSをクエリします(1 回のクエリですべてのテーブルと列が返されます)。利用できない場合は、Fabric Tables REST API と OneLake Table API を使用して Iceberg メタデータを取得します。 - Eventhouse / KQL テーブル →
eventhouse-consumption-cliスキルに依頼し、.show database schema as jsonを実行します(1 回の応答ですべてのテーブルと列が返されます)。単一のテーブルには、.show table <name> schema as jsonを使用します。
ここで返される列の型を使って、各 EntityTypeProperty の valueType を設定してください。ソース列から valueType へのマッピングについては、ONTOLOGY-AUTHORING-CORE.md § EntityTypePropertyを参照してください。
az rest による LRO ヘッダーの取得
az rest は、既定では応答ヘッダーを公開しません。createItem と updateDefinition はどちらも、x-ms-operation-id ヘッダー(および Location ヘッダー)とともに 202 Accepted を返します。--verbose を指定し、標準エラー出力を解析して操作 ID を取得してください。
Ontology の作成/更新では、生の
Locationヘッダーよりもx-ms-operation-idによるポーリングを優先してください。 公開されている Fabric LRO コントラクトでは、Locationヘッダー、またはx-ms-operation-idに基づくhttps://api.fabric.microsoft.com/v1/operations/{operationId}のいずれでもポーリングできます。現在の Ontology プレビューの動作では、観測されたLocationの値はapi.fabric.microsoft.comではなく、analysis.windows.netのリダイレクト ホスト(例:https://df-…-redirect.analysis.windows.net/v1/operations/{id})を指しています。この URL をaz rest --resource https://api.fabric.microsoft.comでポーリングすると、誤った対象に対して再認証され、401/403 で失敗します。その結果、LRO のステータスやエラーが隠れ、状況を確認せずに再試行するループにつながります。そのため、x-ms-operation-idを取得し、https://api.fabric.microsoft.com/v1/operations/{operationId}(Fabric ホスト、Fabric トークン)をポーリングしてください。Locationを使用する場合は、その URL が必要とする対象を使用してください。
# Bash — capture x-ms-operation-id from az rest --verbose stderr
OP_ID=$(az rest --method POST \
--url "https://api.fabric.microsoft.com/v1/workspaces/${WS_ID}/items" \
--resource "https://api.fabric.microsoft.com" \
--headers "Content-Type=application/json" \
--body @envelope.json --verbose 2>&1 \
| grep -oiP "(?<=x-ms-operation-id': ')[^']+")
# Poll the Fabric operations endpoint (stays on api.fabric.microsoft.com)
while :; do
OP=$(az rest --method GET \
--url "https://api.fabric.microsoft.com/v1/operations/${OP_ID}" \
--resource "https://api.fabric.microsoft.com")
STATUS=$(printf '%s' "$OP" | jq -r .status)
case "$STATUS" in
Succeeded) break ;;
Failed|Cancelled)
# Read the error and FIX the payload — never blind-retry the same body.
printf '%s' "$OP" | jq -r '.error | "\(.errorCode // .code): \(.message)"' >&2
exit 1 ;;
*) sleep 5 ;;
esac
done
# PowerShell — capture x-ms-operation-id from az rest --verbose stderr
$result = az rest --method POST `
--resource "https://api.fabric.microsoft.com" `
--url "https://api.fabric.microsoft.com/v1/workspaces/$WS_ID/items" `
--headers "Content-Type=application/json" `
--body "@envelope.json" --verbose 2>&1
$opId = ($result | Select-String -Pattern "x-ms-operation-id': '([^']+)'" |
ForEach-Object { $_.Matches[0].Groups[1].Value })
# Poll the Fabric operations endpoint (stays on api.fabric.microsoft.com)
do {
Start-Sleep -Seconds 5
$op = az rest --method GET `
--url "https://api.fabric.microsoft.com/v1/operations/$opId" `
--resource "https://api.fabric.microsoft.com" | ConvertFrom-Json
} while ($op.status -notin 'Succeeded','Failed','Cancelled')
if ($op.status -ne 'Succeeded') {
# Read .error and FIX the payload — never blind-retry the same body.
throw "createItem LRO $($op.status): $($op.error.errorCode) $($op.error.message)"
}
重要:
createItemは 202 を返し、応答本文はありません。az restはコード 0 で終了し、何も出力しませんが、これは正常です。操作がSucceededになったら、アイテムを一覧表示して新しいアイテム ID を取得してください。statusがFailedの場合、errorフィールドに原因(不正なエンティティ型の部分など)が示されます。ペイロードを修正して、同じ本文を再送するのではなく、修正したリクエストを送信してください。
オーサリングの対象範囲
| 操作 | Fabric REST 呼び出し | 変更する定義パーツ |
|---|---|---|
| 空のオントロジーを作成 | POST /v1/workspaces/{ws}/items with type=Ontology | .platform, definition.json |
| エンティティ型を追加/変更 | POST /v1/workspaces/{ws}/items/{id}/updateDefinition | EntityTypes/{id}/definition.json |
| エンティティ型をテーブルにバインド(非時系列) | updateDefinition | NonTimeSeries を含む EntityTypes/{id}/DataBindings/{guid}.json |
| エンティティ型をテーブルにバインド(時系列) | updateDefinition | TimeSeries と timestampColumnName を含む EntityTypes/{id}/DataBindings/{guid}.json |
| リレーションシップ型を追加 | updateDefinition | RelationshipTypes/{id}/definition.json |
| リレーションシップをバインド(コンテキスト化) | updateDefinition | RelationshipTypes/{id}/Contextualizations/{guid}.json |
| エンティティ/リレーションシップを削除 | 該当するパスをパーツから省略して updateDefinition を実行 | — |
| オントロジーの名前を変更 | updateMetadata=true と新しい .platform を指定して updateDefinition を実行 | .platform |
Update Item Definition は、含まれるパーツのツリー全体を置き換えます。 必ず
Get Item Definitionで現在の定義を取得し、パーツをローカルで変更してから、希望する完全なセットを再送信してください。
作成リファレンス
各操作の完全な JSON 形式、フィールドの仕様、検証手順については、authoring-mechanics.md を参照してください。最初から最後まで実行できる Bash の例については、examples.md を参照してください。以下のセクションをクイックインデックスとしてご利用ください。
| トピック | リファレンス |
|---|---|
定義エンベロープ(parts[]、InlineBase64、base64 ヘルパー) | authoring-mechanics.md § 定義エンベロープ |
ID の生成(64 ビット整数、GUID、name → id マップ) | authoring-mechanics.md § ID 生成パターン |
| 空のオントロジーを作成する | authoring-mechanics.md § オントロジー項目の作成 |
| エンティティ型を追加する | authoring-mechanics.md § エンティティ型の追加 |
| レイクハウス/イベントハウスへのバインド | authoring-mechanics.md § エンティティ型のバインド |
| リレーションシップ型とコンテキスト化 | authoring-mechanics.md § リレーションシップ型の追加 |
| 定義の更新を適用する(取得 → 変更 → 送信) | authoring-mechanics.md § 定義の更新を適用する |
| 検証と確認 | authoring-mechanics.md § 検証と確認 |
| 完全な Bash/PowerShell のひな形 | definition-script-templates.md |
作成時に留意すべき基本的な不変条件(詳細はリファレンスファイルを参照):
- エンベロープの形式:
{ "displayName", "type": "Ontology", "definition": { "parts": [ { "path", "payload", "payloadType": "InlineBase64" } ] } }。definition.jsonは文字どおり{}で、.platformにはmetadata.type: "Ontology"とdisplayNameが含まれます。 - ID:エンティティ/リレーションシップ/プロパティの ID は正の 64 ビット整数、データバインディング/コンテキスト化の ID はGUIDです。
name → idマップをソース管理に保存し、異なる概念に同じ ID を決して再利用しないでください。
ID マップのテンプレート — デプロイスクリプトと一緒に(JSON または YAML で)保存してください。
{
"ontologyName": "SkillTest_Fleet",
"entityTypes": {
"Site": { "id": "1048860412765431174", "properties": { "SiteId": "1428056703884423742", "SiteName": "4251708967918658190" } },
"Equipment": { "id": "3332700945676096991", "properties": { "EquipmentId": "4585483423451989345" } }
},
"relationshipTypes": {
"EquipmentAtSite": { "id": "4242053467032157032" }
},
"bindings": {
"Site_static": "25e3a44a-b62a-40e3-a64a-a43caaa92d19",
"Equipment_static": "5dc4cadd-3700-4c96-bb1e-41e4c909ae4d"
}
}
- バインディング:
NonTimeSeriesはレイクハウス専用で、各エンティティ型に最大 1 つです。同じエンティティ型にTimeSeriesバインディングを設定する前に、NonTimeSeriesバインディングが必要です。TimeSeriesはレイクハウスまたは Eventhouse に設定できます。KustoTableの場合、itemIdは KQL データベース ID ではなく、Eventhouse 項目 IDです。 - リレーションシップ:
source.entityTypeIdとtarget.entityTypeIdは異なる値でなければならず、parts ツリーに存在するエンティティ型を参照する必要があります。 - 更新では、含まれる parts が丸ごと置き換えられます。必ず現在の定義を取得し、ローカルで変更してから送信してください。
必須/推奨/回避/トラブルシューティング
必須事項
- ここに振り分ける前に、オントロジーのコンテキストを明示的に求めます — プロンプトでは、「オントロジー」の作成または変更を依頼するか、オントロジー項目に言及している必要があります。オントロジーのコンテキストを含まない一般的な「Fabric IQ」プロンプトは、オントロジー作成タスクではありません。一致するスキルに振り分けてください。これにより、共有ブランドである「Fabric IQ」が原因でこのスキルが過剰に選択されるのを防ぎます。
- 曖昧なプロンプトは、作業を開始する前に確認します — スキーマやバインドを推測してはいけません。ユーザーが「航空会社データのオントロジーを作成して」と言い、エンティティの種類、キー、またはレイクハウスのテーブルを指定していない場合は、どのエンティティを使うのか、どのキーを使うのか、どのレイクハウスのテーブルを使うのかを尋ねてください。オントロジー定義の置き換えなど、取り消せない副作用が生じる操作には、ユーザーの明示的な意図が必要です。
- バインドを構成する前に、
WS_IDとソース項目の ID を解決します — GUID のハードコーディングは、よくある重大な失敗原因です。レイクハウスのバインドにはレイクハウスのitemIdが必要です。Eventhouse のバインドには、Eventhouse のitemId、クラスター URI、データベース名が必要です。 - 更新前に、現在の定義を取得します —
updateDefinitionは、含まれるパーツをすべて置き換えます。古くなったローカル状態とマージすると、最近の変更が気付かないうちに失われます。getDefinitionで LRO 202 を処理する際は、ポーリングして、オペレーションのresultエンドポイントから取得してください。 - エンティティの種類、リレーションシップの種類、プロパティの
name → idマップを、スキル利用側のリポジトリとともにソース管理に保存します — 実行のたびに ID を再生成すると、重複が作成され、参照が壊れます。 - エンティティの種類に時系列バインドを追加する前に、静的(
NonTimeSeries)バインドを追加します — 各エンティティの種類でサポートされる静的バインドは 1 つまでであり、時系列バインドには、静的キーのプロパティがすでに設定されている必要があります。 - 管理対象のレイクハウステーブルのみにバインドします — 外部テーブル、OneLake セキュリティが有効なレイクハウス、列マッピングが有効な Delta テーブルはサポートされていません。
- 各エンティティの種類内で、
properties[]とtimeseriesProperties[]のプロパティ名が重複しないようにします。レイクハウステーブルと Eventhouse テーブルに同じ列名(例:tenant_id、device_id)がある場合は、sourceColumnNameを元の列に対応させたまま、オントロジーの時系列プロパティ名を変更します(例:TsTenantId)。プロパティ名が重複すると、ALMOperationImportFailedが発生します。 - 確認済みのプレビュー動作として、エンティティキー(
entityIdParts)はvalueTypeがStringまたはBigIntのプロパティに限定します — 現在のプレビュー動作では、ほかの値型はキーとして受け付けられていません。この制限は Microsoft Learn の公開ドキュメントには記載されていません。これを前提とする場合は、テナントで確認してください。 - すべてのパーツパスでスラッシュを使用します —
EntityTypes/{id}/definition.jsonの形式にし、EntityTypes\{id}\definition.jsonは使用しないでください。Windows では、Join-Pathと\によってバックスラッシュが生成され、Fabric API に拒否されます。パスは文字列補間を使って構築してください:"EntityTypes/$ET_ID/definition.json"。 - アクセス許可を確認します — 作成には、ワークスペースで少なくとも
Contributorの権限が必要です。 - アイテムの種類は、エンベロープの
typeと.platformメタデータの両方で、Ontologyとします(OntologyPreviewなどではありません)。 - LRO による書き込みの前に、必ずプレビューと確認のゲートを表示します — ASCII 形式の提案(新規作成の場合)または
getDefinitionとの差分を示す変更セット(既存定義の変更の場合)を表示し、createItemまたはupdateDefinitionを呼び出す前に、ユーザーから明示的なyesを得てください。preview-and-confirm.md を参照してください。yes以外の応答の場合は停止して内容を修正し、部分的な適用は絶対に行わないでください。
推奨事項
- 定義ツリーをディスク上に構築する(論理パーツごとに 1 つの JSON を作成し、
EntityTypes/{id}/...のレイアウトを反映させる)うえで、送信直前に各ファイルを base64 エンコードします。これにより、差分を確認しやすくなります。 - 新規導入時は、既存の正常なオントロジーの
getDefinitionダンプから開始して、そこから変更します。 - 静的バインディングはレイクハウスを優先し、時系列データには Eventhouse を使用する —
NonTimeSeriesバインディングでサポートされるソースは OneLake(レイクハウス)のみです。TimeSeriesバインディングの大量テレメトリには Eventhouse(KustoTable)を使用するか、チームがソースの種類を 1 つに統一したい場合は、データをレイクハウステーブルにミラーリングするか、ショートカットを作成します。 - 冪等性のあるデプロイスクリプト — 入力を変更せずにスクリプトを再実行した場合、オントロジーに変更が生じないようにします。
- エンティティタイプまたは環境が複数ある場合は、UI よりスクリプトによるワークフローを優先する。
- 上流のデータ書き込み後にグラフモデルを手動で更新する — オントロジーが更新されるまで、バインドされたソースの新しい行はプレビュー画面に表示されません。
避けるべき事項
- モノリシックな
.ps1または.shスクリプトファイルの生成 — シェルでコマンドを直接実行します。大きなスクリプトを生成すると、エスケープ処理の不具合や PowerShell の解析エラーが発生しやすく、1 行の失敗をデバッグするのも困難です。jq -ncで JSON を作成し、一時ファイルに書き込んで、az rest --body @fileに渡します。 - base64 のペイロードを直接編集する — 必ずデコードして JSON を編集してから、再エンコードします。
- 別の概念に同じプロパティ/エンティティ/リレーションシップ ID を再利用する。
- オントロジーのスコープ外でもリレーションシップ名が一意であると想定する — 現時点では、リレーションシップ名はオントロジー内で一意であるようです(観察された動作)。必要に応じてプレフィックスで区別できるよう、希望するリレーションシップ名を事前にすべて集めます。衝突する名前は推測で決めず、利用者に確認します。
.platformやそのほかの部分に、シークレット、SAS トークン、ユーザートークンを埋め込む。- ソースおよびターゲットのエンティティタイプがパーツリストに存在する前に、リレーションシップタイプを作成する。
Object/JSON プロパティを完全にクエリ可能なものとして扱う — 現時点で観察されている動作では、Objectプロパティにバインドされたネストされた JSON は、スカラーのようにアドレス指定できず、不透明なペイロードとして表示されます。ネストされたペイロードについては、生データを Eventhouse に保持し、アドレス指定可能なスカラー項目のみをバインドします。下流の利用者に特定のクエリ形式を約束する前に、getDefinitionのラウンドトリップで確認します。- 「省略による削除」に依存する —
updateDefinitionの本文に含まれないパーツは削除されることが確認されていますが、このスキルでは破壊的な操作であることをユーザーに伝え、パーツを削除するエンベロープを生成する前に確認します。
トラブルシューティング
| 症状 | 考えられる原因 | 修正方法 |
|---|---|---|
作成時に 400 Bad Request — 「Invalid item type」 | 項目タイプの文字列が間違っています | .platform で "type": "Ontology" と metadata.type: Ontology を使用します |
type: Ontology を指定した createItem で 400 InvalidItemType | テナント/ワークスペースで Fabric IQ Ontology(プレビュー)が有効になっていません | ユーザーに伝えてください。再試行しないでください。Ontology のプレビューへの登録はテナントレベルで必要です。 |
作成時に 400 InvalidParameter — Error converting value "<number>" to … Guid … Path 'folderId' | フォルダー GUID ではなく、ポータル URL に含まれる数値の subfolderId を渡しています | GET /v1/workspaces/{WS_ID}/folders でフォルダー GUID を解決し(Connection § Folder を参照)、その値を渡します |
400 — プロパティの「Invalid value type」 | valueType に Int64/Guid/Float を使用しています | 使用できる値は正確に String、Boolean、DateTime、Object、BigInt、Double です |
400 — エンティティタイプ/プロパティの「Invalid identifier」 | 名前が正規表現に違反しています | ^[a-zA-Z][a-zA-Z0-9_-]{0,127}$ に一致させます。移植性を保つには、より厳しいポータルのルールである1~26文字にすることを推奨します |
400 — 「Source and target must differ」 | リレーションシップで同じエンティティタイプがソースとターゲットに指定されています | ソースとターゲットに異なるエンティティタイプを指定します |
400 — 「Referenced property not found」 | targetPropertyId がエンティティタイプ内のどのプロパティにも一致しません | ID を確認し、同じ更新でプロパティが追加されていることを確認します |
400 — 「Time series binding requires existing static binding」 | エンティティタイプに静的バインディングを追加する前に時系列バインディングを追加しています | まずキーのプロパティを含む NonTimeSeries バインディングを追加し、その後に TimeSeries バインディングを追加します |
400 — キー列に関する問題 | キープロパティの valueType が String または BigInt ではありません | プロパティを String/BigInt に変更するか、別のキーを選択します |
バインディングで 404 | workspaceId/itemId が間違っているか、ソース項目が削除されています | list items/list lakehouses/list eventhouses で ID を再解決します |
| バインディングは受け付けられたが、インスタンスが表示されない | ソースが外部テーブル、列マッピングされた Delta テーブル、または OneLake で保護されています | 列マッピングを使用せず、マネージド Delta テーブルとしてテーブルを再構築します。レイクハウスの OneLake セキュリティを解除します |
| バインディング後もインスタンスが空 | propertyBindings の列名がソース列と一致していません | ソースのスキーマを確認し、sourceColumnName/sourceSchema を修正します |
| 上流で新しい行が追加されても反映されない | 更新が実行されていません | オントロジー項目でグラフモデルの手動更新をトリガーします |
| 時系列ウィジェットにデータが表示されない | timestampColumnName が設定されていないか、タイムスタンプ列がサポート対象の日付/時刻型ではありません | TimeSeries バインディングで timestampColumnName を設定し、列の型が datetime/date/timestamp であることを確認します |
getDefinition が 200 または 202 を返す | LRO 対応のレスポンスです(インラインのエンベロープまたは操作 ID の場合があります) | 202 の場合は、状態が Succeeded になるまで操作をポーリングしてから GET https://api.fabric.microsoft.com/v1/operations/{operationId}/result を実行します。200 の場合は、返されたエンベロープを直接解析します。LRO Header Capture を参照してください |
LRO のポーリングで 401/403 が返る、または Location ヘッダーのホストが *.analysis.windows.net である | 作成/更新時の Location が Analysis Services ホストにリダイレクトしています。az rest --resource https://api.fabric.microsoft.com でポーリングすると、誤ったオーディエンスに対して再認証されます | Location URL をたどるのではなく、Fabric ホスト上の https://api.fabric.microsoft.com/v1/operations/{x-ms-operation-id} をポーリングします。LRO Header Capture を参照してください。ポーリングが失敗している間は、作成を無条件に再試行しないでください |
updateDefinition で Conflict | ポータルから同時に編集されています | 定義を再取得し、変更を再適用して再送信します |
updateDefinition で ALMOperationImportFailed | JSON ペイロードの形式が正しくありません。多くの場合、PowerShell の ConvertTo-Json のシリアル化の癖($null と null の違い、キーの並べ替え、ファイル内の BOM)が原因です | ConvertTo-Json の代わりに jq -nc で JSON を構築します。BOM を避けるため、[System.IO.File]::WriteAllText と UTF8Encoding($false) を使用してファイルを書き込みます。送信前に jq . で検証します。Tool Stack § PowerShell Warning を参照してください |
createItem または updateDefinition で ALMOperationImportFailed — プロパティ名が重複しています | 同じエンティティタイプの properties[] と timeseriesProperties[] の両方に、同じプロパティ名が含まれています | プロパティ名は両方の配列全体で一意にする必要があります。レイクハウスと Eventhouse のテーブルで列名が重複する場合は、時系列オントロジーのプロパティ名を変更します(例:TenantId → TsTenantId)。バインディングの sourceColumnName では元の列を引き続き参照できます |
ALMOperationImportFailed — 「Property 'X' has conflicting value types」 | 同じプロパティの name が異なる2つのエンティティタイプに存在し、それぞれの valueType が異なります(例:一方が String、もう一方が BigInt) | プロパティ名はオントロジー全体で一意です。2つのエンティティタイプで同じプロパティ名を使用する場合、両方で同じ valueType を使用する必要があります。接頭辞を付けて区別する(例:SerialNumStr と SerialNumInt)か、型を統一します |
ALMOperationBadRequest — 「directory name … is not valid for EntityType」 | パートの path でスラッシュ(EntityTypes\\{id}\\definition.json)ではなくバックスラッシュを使用しています | パートのパスでは必ずスラッシュを使用します:EntityTypes/{id}/definition.json。Windows では、パートのパスに Join-Path や \ を使わず、/ を含む文字列補間を使用します |
createItem が終了コード 0 を返すが、出力がない | 正常です。createItem は本文なしで 202 Accepted を返し、az rest はこれを成功として扱います | LRO の完了後に項目を一覧表示して新しい項目 ID を取得します。LRO のポーリング用に x-ms-operation-id ヘッダーを取得するには --verbose を使用します |
createItem で 409 ItemDisplayNameAlreadyInUse | 同じ displayName を持つオントロジーがワークスペースにすでに存在します | 既存のオントロジーを一覧表示し、既存のものを削除または名前変更するか、別の名前を選択します |
definition.json のペイロードでインポートエラーが発生する | Base64 ペイロードに余分な空白、BOM、または改行が含まれています | definition.json は正確に {} である必要があります。Base64 は e30= です。Windows では、[System.IO.File]::WriteAllText と UTF8Encoding($false) を使用して BOM が含まれないようにします |
エージェント型ワークフロー
⚠️ モノリシックな
.ps1/.shスクリプトファイルを生成しないでください。 各ステップは個別のコマンドとして、シェルで直接実行してください。大きなスクリプトファイルを生成すると、エスケープのバグ、解析エラー、デバッグが難しいプロパティアクセスの問題が発生します。代わりに、次のようにしてください。
- ターミナルで
az rest、jq、PowerShell コマンドを直接実行する- 変数を経由して
jq -ncをパイプし、JSON ペイロードを段階的に作成する- 最終的なエンベロープを一時ファイルに書き込み、それを
az rest --body @fileに渡す- ステップが失敗したら、修正して再実行する。スクリプト全体を再生成しない
作成前の調査
グリーンフィールドとブラウンフィールドの実行戦略:
- グリーンフィールド(新しいオントロジー):エンティティ型、バインディング、リレーションシップ、コンテキスト化、時系列を含む完全な定義を、すべてのパーツを1つのエンベロープにまとめた単一の
createItem呼び出しで作成します。中間状態を避けられるため、より迅速です。createItemペイロードは.platformとdefinition.jsonだけでなく、完全なdefinition.parts[]配列を受け入れます。- ブラウンフィールド(既存のものを更新):段階的に実行します。現在の定義を取得し、変更して送信します。各
updateDefinitionの後にgetDefinitionで検証し、早期にエラーを検出します。途中で失敗しても、すでに完了した変更は保持されます。
スキーマの並列検出
オントロジーが複数のデータソース(レイクハウステーブルと Eventhouse テーブル)にバインドされている場合は、スキーマを順番ではなく並列で検出します。同時に実行する個別の検出タスクを開始してください。
┌─────────────────────────────────────────────────────────────────┐
│ ORCHESTRATOR (this skill) │
│ │
│ Step 0 → Resolve workspace, folder, lakehouse ID, eventhouse ID │
│ │
│ Step 1 → Fan out schema discovery (parallel): │
│ ┌──────────────────────────┐ ┌────────────────────────────┐ │
│ │ TASK A: Lakehouse schemas │ │ TASK B: Eventhouse schemas │ │
│ │ sqldw-consumption-cli │ │ eventhouse-consumption-cli │ │
│ │ or INFORMATION_SCHEMA │ │ or .show database schema │ │
│ │ → all tables + columns │ │ → all tables + columns │ │
│ └──────────┬───────────────┘ └──────────┬─────────────────┘ │
│ │ │ │
│ Step 2 → Merge schemas ◄────────────────────┘ │
│ - Match entity tables (lakehouse) to telemetry (eventhouse) │
│ - Detect property name collisions across sources │
│ - Detect property type conflicts across entity types │
│ - Rename collisions (e.g., TenantId → TsTenantId) │
│ │
│ Step 3 → Propose model → PREVIEW & CONFIRM │
│ │
│ Step 4 → Build full envelope → createItem (single call) │
└─────────────────────────────────────────────────────────────────┘
並列実行の方法(エージェントごと):
- GitHub Copilot CLI / Claude Code:バックグラウンドの
taskエージェントを2つ起動します。1つはレイクハウス用(sqldw-consumption-cliまたはINFORMATION_SCHEMA.COLUMNSクエリ)、もう1つは Eventhouse 用(.show database schema as json)です。両方が完了したら、結果を読み取ります。 - シングルスレッド環境:2つの検出クエリを順番に実行します。それぞれ単一の呼び出しなので、オーバーヘッドは最小限です。
作成時のバグの多くはマージのステップ(ステップ2)で検出されます。プロパティ名を重複排除し、エンティティ間で valueType を統一し、静的プロパティと衝突する時系列プロパティにはプレフィックスを付けてください。
詳細なステップの流れ
Step 0 → Is the request specific? Are the entity types, keys, and lakehouse tables named?
→ NO → Ask: "Which entity types? What is the key of each? Which lakehouse table binds to each?
Any timeseries properties? Any relationships and their link tables?"
STOP — do not proceed until the user answers.
→ YES → Continue.
Step 1 → Resolve IDs: workspace, folder, lakehouse, eventhouse [COMMON-CLI.md]
Step 2 → Discover source schemas (parallel where possible):
a. Lakehouse: invoke `sqldw-consumption-cli` or query INFORMATION_SCHEMA.COLUMNS
b. Eventhouse: invoke `eventhouse-consumption-cli` or run `.show database schema as json`
Step 3 → Merge schemas: detect property name collisions + type conflicts; rename as needed
Step 4 → If ontology exists: getDefinition → decode parts (capture current IDs)
Else: plan `createItem` with the FULL definition (all parts in one call).
Step 5 → For each entity type:
a. Generate/reuse 64-bit IDs for entity + properties
b. Build EntityTypes/{id}/definition.json
c. Build one or two DataBindings/{guid}.json files
Step 6 → For each relationship:
a. Confirm both entity types exist in Step 5 output
b. Generate/reuse relationship type ID
c. Build RelationshipTypes/{id}/definition.json
d. Build RelationshipTypes/{id}/Contextualizations/{guid}.json
Step 7 → Base64-encode all parts; assemble envelope
Step 8 → **PREVIEW & CONFIRM** — render proposal (greenfield) or change-set diff (brownfield)
and obtain explicit `yes` from the user. See [preview-and-confirm.md](references/preview-and-confirm.md).
Do not proceed on anything other than `yes`.
Step 9 → createItem OR updateDefinition (LRO)
Step 10 → Poll LRO until Succeeded; getDefinition; verify IDs and bindings; persist post-write snapshot for next-run diff
スクリプト生成ワークフロー
Step 1 → Capture user intent (entity types, keys, properties, relationships, source tables)
Step 2 → Save intent as a YAML/JSON spec in the consumer's repo — single source of truth
Step 3 → Generate: (a) the ID map, (b) per-file JSON parts, (c) the composite envelope
Step 4 → **PREVIEW & CONFIRM** — render proposal/diff and require explicit `yes`
(see [preview-and-confirm.md](references/preview-and-confirm.md)). The textual
diff against the last-applied envelope snapshot feeds the brownfield change-set.
Step 5 → Apply via az rest --body @envelope.json (createItem or updateDefinition)
Step 6 → Poll LRO; on success, commit the envelope snapshot + ID map
例
エンドツーエンドの実例(空のオントロジーを作成 → エンティティ型と非時系列バインディングを追加 → リレーションシップ型とコンテキスト化を追加 → 時系列プロパティと Eventhouse バインディングを追加)は、examples.md にあります。取得・変更・送信を行う完全な bash および PowerShell スクリプトは、definition-script-templates.md にあります。
エージェント統合に関する注意事項
- このスキルは作成に特化しています。オントロジーをエンドツーエンドで検証するには、利用スキル(Fabric Graph クエリスキルなど)と組み合わせてください。
- オントロジーが複数のソースタイプにバインドされている場合は、スキーマ検出を並列化してください。
- レイクハウスのスキーマ(
INFORMATION_SCHEMA.COLUMNS)を取得するバックグラウンドのsqldw-consumption-cliタスクを起動します。1つのクエリで、すべてのテーブルと列を取得します。 - Eventhouse のスキーマ(
.show database schema as json)を取得するバックグラウンドのeventhouse-consumption-cliタスクを起動します。1回の呼び出しで、すべてのテーブルと列を取得します。 - どちらも同時に実行します。両方が完了したら結果をマージし、オントロジーモデルを作成します。
- レイクハウスのスキーマ(
- マージのステップは重要です。検出後、
properties[]とtimeseriesProperties[]全体でプロパティ名を重複排除し、エンティティ型間で同名のプロパティのvalueTypeを統一してから、衝突するプロパティにプレフィックスを付けてエンベロープを作成します。 - オントロジー、Eventhouse、レイクハウスにまたがる複数ステップの顧客ワークストリームを調整する場合は、スキルを直接つなぐのではなく、エージェント(
FabricDataEngineerなど)を介して処理します。 - 想定してよい妥当な上流依存関係:レイクハウステーブルはすでに存在し、ユーザーが説明したキー列を備えています。そうでない場合は、呼び出し元が先にレイクハウス作成スキルを呼び出してください。