visualize-semantic-model について
visualize-semantic-modelは、Cube.devのYAML定義をダークテーマの有向グラフPNGに変換するスキルです。結合とカーディナリティを解析してファクトスパインを特定し、付属レンダラーで図を生成します。
主な機能
- 01Cube.dev YAML定義の解析
- 02ファクトスパインと結合の検出
- 03結合キーとカーディナリティの表示
- 04ダークテーマのグラフをPNGで生成
- 05生成画像のチャット内表示
活用シーン
- 01Cubeモデル間の関係の確認
- 02ファクトとディメンションの接続の確認
- 03cube YAMLファイルから図を生成
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ revosai/ skills --skill visualize-semantic-modelインストール後、Claude Code で/visualize-semantic-modelを入力して読み込まれたか確認します。
同梱ファイルscripts/render_graph.py
詳細
セマンティックモデルを可視化する
Cube の YAML ファイルを解析してファクトスパインを検出し、同梱のレンダラーを JSON 仕様とともに実行して、ダークテーマの有向グラフを描画します。
レンダラー(scripts/render_graph.py)はレイアウトと描画のみを行います。標準入力からグラフ仕様を受け取り、PNG を書き出します。同梱することで、毎回一貫した見た目で出力でき、matplotlib のコードをその都度書き直す必要がありません。
ステップ 1:cubes フォルダーを特定する
ユーザーがフォルダー引数を渡した場合は、それを使用します。渡されていない場合は、cubes/ をデフォルトとして使用します。フォルダーが存在しない場合は、続行する前に Cube 定義の場所をユーザーに尋ねます。
find <folder> -name "*.yml" -not -name "model-graph.*" | sort
ステップ 2:Cube グラフを解析する
各 .yml ファイルから次の情報を抽出します。
spec.name—${CUBE}と結合で参照される Cube 識別子(metadata.nameはローカルスラッグで、通常は同じ値です。spec.nameがない場合は、代わりに使用します)spec.meta.icon— 存在する場合のアイコンキー(カタログキー、url:…、またはdata:…)。存在しない場合はnullspec.joins—target_cube → { relationship, sql }のマップ- 各結合の
sqlから解析した短い結合キーラベル
結合キーラベルのルール。 ${CUBE}. と ${<target>}. のプレフィックスを取り除きます。単一の等式の場合は、LHS の列を使用します。複合キー(複数の AND)の場合は、LHS の列名を + でつなぎます。
sql: "${CUBE}.user_id = ${users}.user_id"
# → "user_id"
sql: "${CUBE}.traffic_source = ${rev}.traffic_source AND ${CUBE}.order_date = ${rev}.order_date"
# → "traffic_source + order_date"
カーディナリティ(エッジは常に one 側から many 側へ描画します):
| この Cube で宣言された関係 | この Cube 側 | 相手の Cube 側 |
|---|---|---|
many_to_one | ∞ | 1 |
one_to_many | 1 | ∞ |
one_to_one | 1 | 1 |
ファクトスパインの検出。 many_to_one 結合が最も多い Cube(FK を保持する Cube)がスパインです。同数の場合は、名前に enriched、fact、または items を含む Cube を優先します。many_to_one 結合を持つ Cube がない場合(たとえば、モデルがすべてハブからの one_to_many で構成されている場合)は、あらゆる種類の出方向の結合が最も多い Cube を使用します。それでも候補が複数ある場合は、どの Cube をスパインとして扱うかユーザーに尋ねます。
エッジケース — 描画せず、ユーザーに伝えて停止します。
- フォルダー内の Cube が 2 つ未満の場合 → 少なくとも 2 つの Cube が必要です。
joinsがどこにも見つからない場合 → 描画する関係がありません。
ステップ 3:グラフ仕様を作成する
レンダラーが解釈できる JSON オブジェクトを作成します。
{
"title": "Semantic Model — <project_name>",
"fact_spine": {
"name": "<fact_cube>",
"icon": "<catalog_key_or_null>",
"pk": "<pk_col>",
"fks": ["fk_a", "fk_b", "fk_c", "fk_d"]
},
"dimensions": [
{
"name": "<dim_cube>",
"icon": "<catalog_key_or_null>",
"pk": "<pk_col>",
"extras": ["metric1", "metric2"]
}
],
"edges": [
{
"from": "<dim_cube>",
"to": "<fact_cube>",
"label": "<join_key>",
"from_card": "1",
"to_card": "∞"
}
]
}
from_card / to_card は、矢印の各端に描画されるラベルで、"1" または "∞" です。one_to_one 結合の場合は、両端とも "1" です。
icon フィールドは将来のレンダラー対応に備えて仕様に保存します。現在の render_graph.py はまだアイコンを描画しません。レンダラーがアップグレードされたときにデータを利用できるよう、含めてください。
YAML での関係の宣言方法にかかわらず、矢印は常にディメンションからファクトを指します。
ステップ 4:描画する
python3 -c "import matplotlib" 2>/dev/null || python3 -m pip install matplotlib --quiet
python3 .claude/skills/visualize-semantic-model/scripts/render_graph.py \
--output <folder>/model-graph.png \
<<'EOF'
{ ... the JSON spec from Step 3 ... }
EOF
<folder>/model-graph.png がすでに存在し、ユーザーが明示的に再生成を依頼していない場合は、上書きする前に確認します。
ステップ 5:結果を表示する
Read ツールを使用します(Python の Read() 呼び出しではありません。Read は Claude Code のツールです)。PNG のパスを指定すると、チャット内に画像がインライン表示されます。
Read
<folder>/model-graph.png
最終応答のテンプレート
Generated: <folder>/model-graph.png
Cubes visualized: <n>
Fact spine: <cube_name>
Dimensions: <dim1>, <dim2>, ...
Edges: <dim1> → <fact> (<join_key>) [1:∞]
<dim2> → <fact> (<join_key>) [1:∞]
ルール
- 必ず YAML を解析してください。Cube 名や関係をハードコードしないでください。
- エッジの向きは常に ディメンション → ファクト です(矢印の尾がディメンション、先端がファクト)。
1と∞のマーカーの位置は、レンダラーがfrom_card/to_cardに基づいて決定します。上記のカーディナリティ表に従って正しく設定してください。- 確認せずに既存の
model-graph.pngを上書きしないでください。 - 保存した後は、必ず Read ツールを使って画像をインライン表示してください。