0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

AIが読めるメタデータ×Streamlit×Claude Code ― ダッシュボードを"対話"で動かすデータ基盤設計

0
Posted at

はじめに

同じDWHから 「人が見る用のマート」「AIが読む用のマート」 を分岐させたら、ダッシュボードの使い方がだいぶ変わった。

人用のダッシュボードで全体を掴んで、LLMで深堀りする。この2つの出力を並べると、片方だけでは見えなかった示唆が出てくる。

デモデータには UCI Online Retail Dataset(英国ECサイト、約54万件)を使った。

アプリそのものを公開する予定はないので、本記事では設計の考え方と、AIライクな開発プロセスで何が変わったかを共有する。

メタデータ設計

従来、テーブル定義書はExcelやConfluenceに書いて人が参照するものだった。今回はこれを LLMが読む入力データ として扱った。

# config/metadata.yaml
tables:
  raw_transactions:
    description: "EC小売サイトの全取引データ(生データ)"
    columns:
      invoice_no:
        type: "VARCHAR"
        description: "請求書番号。6桁の一意な取引識別子。先頭が'C'の場合はキャンセル取引"
        role: "identifier"
      quantity:
        type: "INTEGER"
        description: "取引あたりの商品数量。マイナスはキャンセルまたは返品"
        role: "measure"
      customer_id:
        type: "VARCHAR"
        description: "顧客ID。5桁の一意な顧客識別子。NULLの場合は未登録顧客"
        role: "identifier"

descriptionに業務知識を埋め込み、roleで分析上の役割を明示する。YAMLなのでGitで管理できる。

こうしておくと、メタデータがドキュメントではなくパイプラインの「入力」になる。以降のステップは基本的にここが起点になっている。

人用マートとAI用マート

人用: mart_human_monthly_sales

正常な取引だけを対象にした、月別・国別の売上サマリーである。

SELECT
    TO_CHAR(invoice_date, 'YYYY-MM') AS year_month,
    country,
    SUM(quantity * unit_price)        AS total_revenue,
    COUNT(DISTINCT invoice_no)        AS total_orders,
    COUNT(DISTINCT customer_id)       AS total_customers,
    SUM(quantity * unit_price)
      / NULLIF(COUNT(DISTINCT invoice_no), 0) AS avg_order_value
FROM raw_transactions
WHERE invoice_no NOT LIKE 'C%'
  AND quantity > 0 AND unit_price > 0
GROUP BY year_month, country;

人がグラフで傾向を掴むための設計である。

AI用: mart_ai_enriched

LLMに渡して示唆を出すためのマートである。派生指標を事前に計算して1テーブルに集約した。

追加カラム 意図
prev_month_revenue / revenue_change_pct LLMに前月比を計算させると精度が落ちやすいので事前計算
cancel_orders / cancel_rate_pct 人用マートでは除外したキャンセルデータ
top_customer_revenue_pct 上位1顧客の売上構成比
unique_products 商品ポートフォリオの変化検出

人用マートに cancel_rate_pct のような指標を入れてもグラフが増えるだけで活用されにくい。AI用マートはLLMがパターンを検出するための入力データとして割り切った。

ズレの検知

01_dashboard_full.png

人用ダッシュボードで見えるのは、月別売上推移やKPI(総売上£10.6M / 総注文19,960件 / 総顧客13,058人)、国別構成比といった全体像である。

AI用マートをLLMに渡すと、BIだけでは気づきにくいパターンが出てきた。

オランダの収益が"ほぼ1顧客"に依存
2011年1月〜8月の各月で top_customer_revenue_pct が97〜100%。売上推移グラフでは「売上がある」としか見えないが、構造的には単一顧客依存だった。

キャンセル率と売上の逆相関
スイス: 2011年8月に cancel_rate=62.5%。ドイツ・ポルトガルは慢性的にキャンセル率が高い。BIの売上グラフからは読み取れない。

フィンランドの商品ポートフォリオ急変動
ユニーク商品数が12→210→37と月単位で乱高下していた。

人の目とLLMの示唆を並べると、こういうズレが見える。

Streamlit(人の目) LLM(AIの示唆)
「オランダは安定して売上がある」 「97%が1顧客依存」
「12月に売上急落」 「キャンセル率が28.6%に急騰」
「フィンランドは売上が小さい」 「商品数12→210→37で戦略がブレてる」

BIが「何が起きたか」を見せて、LLMが「なぜ」「何が隠れているか」を拾ってくる。この組み合わせは思った以上に相性が良かった。

プロンプト設計

示唆出しのプロンプトはYAMLで管理した。

# prompts/insight_template.yaml
templates:
  monthly_insight:
    system: |
      あなたはデータアナリストです。
      与えられたデータからビジネス上の示唆を日本語で出してください。
      - 数値の根拠を必ず示す
      - 「異常値」「トレンド変化」「リスク」の3カテゴリで整理
      - 各カテゴリ最大3項目
      - 示唆ごとに確信度(高/中/低)を付ける
    user: |
      ## メタデータ(各カラムの意味)
      {metadata}
      ## データ
      {data}

LLMにはメタデータとデータを両方渡している。メタデータがあると cancel_rate_pct のようなカラムの意味をLLMが正しく解釈してくれる。

開発プロセス

ここが今回やってみて一番よかったところである。

Streamlit agent skills × Claude Code

Streamlitには公式でAgent skillsが配信されており、AIコーディングエージェントがStreamlitアプリの構造を認識・操作できる。https://github.com/streamlit/agent-skills

これとClaude Codeを組み合わせると、以下の流れが1セッションで回る。

metadata.yamlを読ませればマートのスキーマを理解した上でStreamlitコードを生成してくれるし、「キャンセル率の推移をもっと目立たせて」と言えばレイアウトも変わる。メタデータがAIに読める形式で存在するので、ダッシュボードの生成・修正をそのまま任せられた。

Playwright CLIによるGUI検証の自動化

以前はStreamlit上でダッシュボードの表示を手動で確認していた。グラフが正しく出ているか、データが欠落していないか、レイアウトが崩れていないか。地味に手間がかかる作業である。

Playwright CLI を使うと、これがCLI上で自律的にできるようになった。GUIベースのアプリケーションであっても、CLI経由でページの状態を取得してAIに渡せる。

# ページのスクリーンショットを取得
playwright screenshot http://localhost:8501 dashboard.png

# アクセシビリティツリーを取得
playwright pdf http://localhost:8501 dashboard.pdf

Claude Codeがこれを読んで、バグがあれば自分でコードを修正し、再度検証する。このサイクルが自動で回るのが大きかった。

人がブラウザを開いて目視する工程がなくなった。GUIの検証をCLIで完結できるのは、AIエージェントとの相性がとても良い。

開発サイクルの全体像

メタデータの変更を起点に、この一連の流れがかなり自律的に回った。

従来との違い

今回の開発を通して感じた違いを整理した。

観点 従来 今回
メタデータ Excel/Confluenceのドキュメント YAMLでGit管理。パイプラインの入力
マート設計 汎用マートを1つ 人用とAI用で目的別に分岐
深堀り 人がSQLを書く LLMが網羅的にスキャンして示唆
ダッシュボード変更 エンジニアに依頼→開発→デプロイ agent skills経由で対話的に変更
プロンプト (存在しない) YAMLテンプレートで管理
GUI検証 ブラウザで目視確認 Playwright CLIでAIが自律検証・自動修正
開発サイクル 人が各ステップを実行 メタデータ起点で自律的に回る

構成

ai-data-pipeline/
├── config/
│   └── metadata.yaml            ← AIが読むメタデータ
├── prompts/
│   └── insight_template.yaml    ← 示唆出し用プロンプトテンプレート
├── scripts/
│   ├── 01_fetch_data.py         ← データ取得 → PostgreSQL(DWH)
│   ├── 02_create_marts.py       ← DWH → 人用マート + AI用マート
│   └── 03_generate_insights.py  ← AI用マート → LLM示唆
├── streamlit_app/
│   └── app.py                   ← 人用BIダッシュボード
└── requirements.txt

おわりに

メタデータをAIの入力として設計し直したことで、こういう流れができた。

  1. 人用マートとAI用マートを分岐させる
  2. 人が全体を見て、LLMが深堀りする
  3. 両者のズレから示唆が生まれる
  4. Streamlit agent skills × Claude Code でダッシュボードの生成・修正が回る
  5. Playwright CLI でGUI検証から自動修正まで自律的に完結する

ダッシュボードが「見るだけのもの」から「対話で動かすもの」に近づいた感触がある。その起点はメタデータの設計だった。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?