KAKEHASHI Tech Blog

カケハシのEngineer Teamによるブログです。

公式ドキュメントがないJSON仕様をAIに教え込み、Databricksダッシュボードの生成と編集を自動化するスキルの設計と実装

こんにちは、ソフトウェアエンジニアのkackyです。

私たちのチームでは、AIコーディングアシスタント(Claude Code / Cursor)の「スキル」という仕組みを使い、自然言語でDatabricksのダッシュボードを生成できる環境を構築しました。「○○の推移を可視化してみたい」と指示するだけで、ダッシュボードのたたき台が数分で出来上がる世界です。

しかし、その裏側では「公式に仕様が公開されていないJSON形式を、いかにしてAIに正しく生成させるか」という地味で泥臭い作業がありました。この記事では、その設計判断とノウハウを共有します。

背景:Databricksダッシュボードの課題

私たちはプロダクトの利用状況や品質評価データをDatabricks上のUnity Catalogに蓄積しています。データはあるのに、そこから「可視化」に至るまでのハードルが高い。これが出発点でした。

Databricksの AI/BI Dashboard は、GUIのドラッグ&ドロップで作れるものの、Git管理してCLIでデプロイしたかったため、JSON定義ファイル(.lvdash.json)をコードで管理する方針を取りました。

ところが、この .lvdash.json は Databricks のダッシュボード定義を表すJSONファイルで、UI上の変更を CLI(databricks bundle generate dashboard)や Bundles でローカルに取り込んで管理できるものの、内部JSONスキーマは 公式に公開されていません。DatabricksのLakeview APIは存在しますが、serialized_dashboard の中身は「文字列化されたJSON」としか書かれておらず、その構造のドキュメントはありません。

さらに手書きでJSONを組み立てるのは非現実的です。ウィジェットタイプは20種類以上あり、それぞれエンコーディングの構造が異なります。1つのダッシュボードが数千行のJSONになることも珍しくありません。

一方で、JSONはテキスト形式なので生成AIに読み書きさせることができます。仕様さえ教えられれば、AIに生成・編集を任せられるのではないか。そこで考えたのが、「AIにダッシュボードJSONを生成させるスキルを作ろう」というアプローチです。

AIコーディングアシスタントの「スキル」とは

Claude CodeやCursorには、特定のドメイン知識とワークフローをMarkdownで記述してAIに渡す「スキル」の仕組みがあります。ユーザーが /databricks-dashboard のようなコマンドを呼ぶと、AIはスキル定義を読み込み、その手順に従って対話的にタスクを遂行します。

スキルは基本的に以下の2つから構成されます。

  • SKILL.md: ワークフロー定義(AIがどういう手順で作業するかの指示書)
  • references/: ドメイン知識のリファレンス(AIが参照する仕様書やパターン集)

今回作ったのは、この仕組みを使った databricks-dashboard スキル(約1,500行、リファレンス含む)です。AI/BI DashboardのJSON定義ファイルを対話的に生成します。

公式ドキュメントがないJSON仕様をどう教えたか

ここが今回の記事の核心です。

仕様書がないなら作らせる

AI/BI DashboardのJSON仕様は公開されていないため、以下の方法で情報を集めました。

  1. 既存ダッシュボードのJSON解析: Databricks GUIで作成したダッシュボードをエクスポートして構造を分析
  2. 公式ドキュメントの断片情報: ウィジェットタイプ一覧数値フォーマット仕様から仕様を推測
  3. GitHubのサンプル: bundle-examplesリポジトリにある .lvdash.json の実例

これらを統合して作ったのが widget-catalog.md(820行)です。

widget-catalog.md の設計思想

このリファレンスを設計する際に意識したのは、AIが迷わず正しいJSONを出力できる構造 にすることでした。

「やりたいこと」からの逆引きテーブル

AIは「折れ線グラフを作りたい」ではなく「推移を見たい」という抽象的な指示を受け取ります。そこで、ユーザーの分析ニーズからウィジェットタイプへのマッピングをカタログの冒頭に配置しました。

| ユーザーの分析ニーズ | ウィジェット選定の方針 |
|---|---|
| 時間軸で変化を追いたい | line / area / cohort |
| カテゴリ間で大小を比べたい | bar / waterfall |
| 全体に占める割合を知りたい | pie / funnel / sankey |
| 現在の値をぱっと把握したい | counter |

コピペ可能なJSON断片

各ウィジェットタイプのJSON構造は、動くコードとして掲載しています。説明文だけではAIが構造を正しく推論できないケースがあるため、そのまま使えるJSON断片を書きました。

{
  "version": 3,
  "widgetType": "line",
  "encodings": {
    "x": {
      "fieldName": "daily(evaluated_at_jst)",
      "scale": { "type": "temporal" },
      "displayName": "日付"
    },
    "y": {
      "fieldName": "avg(metric_value)",
      "scale": { "type": "quantitative" },
      "displayName": "平均値"
    }
  }
}

ウィジェットタイプ別のバージョン差異

AI/BI Dashboardの罠の1つに、ウィジェットタイプによって spec.version が異なるという仕様があります。これを間違えるとウィジェットが表示されません。

| widgetType | version |
|---|---|
| line, bar, area, scatter, pie | 3 |
| counter, histogram | 2 |
| table, combo | 1 |

このような「間違えやすいポイント」を明示的にリファレンスに含めることで、AIが生成するJSONの正確性を担保しています。

よくある表示されない原因と対策

ダッシュボードを作る過程で何度もハマったパターンを、トラブルシューティング表としてまとめました。

| 症状 | 原因 | 対策 |
|---|---|---|
| フィルターが効かない | queriesでfieldsを使っている | parameters形式に変更 |
| カウンターが表示されない | expressionに複雑なCASE式 | SQL側で計算済みの値を返す |
| ヒストグラムが表示されない | 大量の生データ行を渡している | SQL側で事前にビニング |

これらは自分がデバッグした実体験に基づいています。AIに「やってはいけないこと」を教えるのは、「やるべきこと」を教えるのと同じくらい重要です。

スキルの構造設計:SKILL.md + references/ の役割分担

1,500行のスキルを1つのファイルに書くと、AIのコンテキストウィンドウを圧迫しますし、メンテナンスも困難です。そこで、skillのベストプラクティスに従ってワークフロードメイン知識を明確に分離しました。

databricks-dashboard/
├── SKILL.md                          # ワークフロー定義(276行)
└── references/
    ├── widget-catalog.md             # ウィジェットJSON仕様(820行)
    ├── data-source-discovery.md      # データソース探索手順(229行)
    └── json-operations.md            # JSON操作パターン集(198行)

SKILL.md:「いつ何をするか」の指示書

SKILL.mdにはAIが踏むべきステップだけを書きます。

Step 1: 目的のヒアリング
Step 2: データソース探索・提示
Step 3: 分析ニーズの深掘り(必要な場合のみ)
Step 4: ウィジェット構成の自動選定
Step 5: JSON生成
Step 6: デプロイ・デバッグ(オプション)

各ステップの記述は「判断基準」に焦点を当てています。たとえば Step 4 では、ユーザーにグラフの種類を聞かずに AIが自動で選定する よう指示しています。

ウィジェット構成を決めたら、何が分かるか を中心に提案する(グラフの種類名ではなく、ダッシュボードで得られるインサイトを伝える)

これは「棒グラフにしますか?折れ線にしますか?」という質問がユーザーにとって負担になるためです。AIがデータの特性を見て判断すべきところです。

references/:「どうやるか」の知識ベース

references/ ディレクトリには3つのファイルがあり、それぞれ独立した役割を持っています。

ファイル 役割 読まれるタイミング
widget-catalog.md ウィジェットのJSON構造とエンコーディング仕様 JSON生成時
data-source-discovery.md テーブルの探索方法と既知データソース一覧 データソース探索時
json-operations.md 既存JSONへの追加・修正のPythonパターン 既存ダッシュボード編集時

この分離には実用上のメリットがあります。

  • 新規作成時: widget-catalog.md は読む必要があるが、json-operations.md は不要
  • 既存追加時: json-operations.md が必要だが、data-source-discovery.md は不要なことが多い
  • テーブルが増えた場合: data-source-discovery.md だけ更新すればよい

AIのコンテキストウィンドウには限りがあるため、必要なときに必要な知識だけを参照する構造にすることが重要です。

json-operations.md:AIに「JSONの触り方」を教える

もう1つ工夫したポイントが json-operations.md です。これは、AIが既存ダッシュボードのJSONを編集する際に「どうやって操作すべきか」をPythonコードのパターン集として教えるリファレンスです。

なぜこれが必要かというと、数千行規模のJSONファイルに対してAIがテキストエディタ的に直接編集すると、構造の壊れやウィジェット同士の重なりといった事故が起きやすいためです。そこで、AIにはJSONを直接書き換えさせず、Pythonスクリプト経由でプログラム的に操作させることにしました。

たとえば「既存ダッシュボードにウィジェットを追加する」というよくある操作は、json-operations.md に以下のようなパターンとして載っています。

# パターン: 既存ページへのウィジェット追加
# 既存ウィジェットの最下部を計算し、重ならない位置に配置する
max_bottom = 0
for item in target_page["layout"]:
    pos = item["position"]
    bottom = pos["y"] + pos["height"]
    if bottom > max_bottom:
        max_bottom = bottom

new_widget["position"]["y"] = max_bottom
target_page["layout"].append(new_widget)

AIはこのMarkdown内のPythonパターンを読み、実際のBashツールからインラインPythonとして実行します。つまり、json-operations.md は「AIが実行するコードのテンプレート集」として機能しています。

他にも「ensure_ascii=False で日本語を保持する」「dataset名を変更したら参照元のウィジェットも一括更新する」といった、手作業では見落としやすいルールをパターンとして明示しています。

「抽象的な指示で動いた」の裏側

冒頭で触れた「○○を可視化してみたい」という指示でダッシュボードが出来上がるのは、裏側で以下が動いているからです。

  1. 目的の解釈: ユーザーの入力キーワードから、必要なデータソースを推測、探索
  2. ウィジェット自動選定: 時系列データには折れ線、カテゴリ比較には棒グラフ、KPIにはカウンターを自動選択
  3. JSON生成: widget-catalog.md のリファレンスに基づき、正しいJSON構造を出力
  4. デプロイ: Databricks CLIでダッシュボードを作成し、表示確認

この一連の流れが、ユーザーの1行の入力から自動で進みます。

とはいえ、一発で完璧なダッシュボードが出来上がるわけではありません。実際には「この軸を追加したい」「フィルターの初期値を変えたい」といったフィードバックを何往復かやりとりします。重要なブレークスルーは、動くダッシュボードが数分で出来上がり、自然言語で修正指示が出せる ことです。

成果と学び

定量的な成果

現在、この仕組みで複数のダッシュボードをGit管理しています。最大のものは10ページ以上・数十ウィジェット・数千行規模のJSONで、手書きで管理するのは現実的ではなく、スキルによる生成・編集が不可欠になっています。

学び

1. AIに教える知識の粒度は「そのまま動くコード」まで落とし込む

「折れ線グラフはlineタイプで、x軸にtemporal、y軸にquantitativeを設定する」という説明だけではエラーになってしまったり、表示できないウィジェットが生成されることがよくありました。widget-catalog.md にはそのまま使えるJSON断片を、json-operations.md にはそのまま実行できるPythonスクリプトを載せています。説明文ではなく動くコードで教えることで、精度が大きく上がりました。

2. 「やってはいけないこと」を教えるのは「やるべきこと」と同じくらい重要

フィルターの queriesfields を使うとフィルターが効かない、というような落とし穴は、正例だけ見ていてもわかりません。トラブルシューティング表を作ってアンチパターンを明示することで、AIが同じミスを繰り返すのを防げます。自動レビューやLinterなどのツールを組み込むとより効率的なチェックが可能になります。

まとめ

公式に仕様が公開されていないJSON形式をAIに正しく生成させるために、以下のアプローチを取りました。

  • 既存データの解析と公式ドキュメントの断片から 仕様書を自作 し、820行のwidget-catalog.mdとしてまとめた
  • ワークフロー(SKILL.md)と知識(references/)を 構造的に分離 し、必要な知識だけを参照する設計にした
  • 「やってはいけないこと」を含む トラブルシューティング表 を明示的にリファレンスに含めた

「AIに抽象的な指示を伝えるだけで動く」体験の裏側には、AIが迷わないための知識のエンコーディングがあります。公式ドキュメントがないツールのAI統合に取り組んでいる方の参考になれば幸いです。