0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

PMでもClaude CodeでBigQuery分析できる基盤を作ったらすごかった話

0
Posted at

はじめに

グロービスでエンジニアをしている堀尾です。社内の教育プラットフォーム「ナノ単科」の開発を担当しています。

今回、PMがGitHub Issueに日本語で書くだけで、BigQueryの分析結果が返ってくる仕組みをClaude Codeで構築しました。

「非エンジニアにAI経由でDBを叩かせるの、怖くないですか?」

この質問、社内で紹介した時に必ず聞かれました。この記事では、その懸念にどう向き合い、3段構えの安全設計でどう解決したかをお話しします。

課題:分析依頼が引き起こす「負のループ」

プロダクト開発の現場で、こんなやり取りに心当たりはないでしょうか。

PMから「このデータを見たい」と依頼が来る。エンジニアは今やっている作業を中断し、依頼内容を確認し、SQLを書き、結果を共有する。そしてPMから返ってくるのは——

「データありがとうございます!」
「あ、ちょっとこの条件も追加で見たいんですが…」
「先月のデータと比較するとどうなりますか?」

データ分析は本質的に「反復」です。一度結果を見ると、次の問いが生まれる。でもその度にエンジニアが手を止めていたら、開発工数は奪われ、PMの意思決定も遅れます。リードタイムは数時間から数日。この構造的な問題を仕組みで解決したいと思いました。

解決策:自然言語による「分析の自動化」

作ったのは、GitHub Issueに自然言語で分析依頼を書くと、Claude Codeが自動でBigQueryにクエリを実行し、結果をコメントで返してくれる仕組みです。

GitHub Issue (@claude_analysis で依頼)
  ↓
GitHub Actions ワークフロー起動
  ↓
Claude Code 起動(SKILL.md に基づく制約付き)
  ├── コードベース + スキーマ情報を読み込み
  ├── 依頼内容からSQLを生成
  └── ruby scripts/claude_bq_analysis.rb でクエリ実行
  ↓
Issue にコメントで分析結果を返却

PMの体験はシンプルです。Issueに「@claude_analysis 昨日のDAUを出して」と書く。数分後、集計結果とビジネスインサイトがコメントで返ってくる。SQLには一切触れません。

裏側ではGitHub Actionsが起動し、Claude Codeがバックエンドのコードベースとスキーマ情報を読み込んだ上で、適切なSQLを生成・実行しています。プロダクトの仕様を理解した上で分析するので、単にSQLを投げるだけでなく、結果に対する示唆まで提供してくれます。

最大の懸念:「非エンジニアにAI経由でDB叩かせて大丈夫?」

この仕組みを紹介すると必ず聞かれるのが、セキュリティリスクとコスト爆発の懸念です。AIが予期しないクエリを実行したらどうなるのか。正直、ここが一番時間をかけて設計した部分です。

これは「3段構えの多層防御」で対処することにしました。

Layer 1:インフラ層(GCP側の制御)

BigQueryに接続するサービスアカウントには 読み取り専用の権限(BigQuery Data Viewer) のみを付与しています。万が一アプリケーション層やAI層が突破されても、インフラレベルで書き込みは不可能です。加えて、BigQueryのコストキャップも設定しています。

Layer 2:アプリケーション層(Rubyスクリプト内の制御)

クエリ実行用のRubyスクリプトに validate_query 関数を組み込んでいます。クエリ実行前にバリデーションが走り、危険なSQLキーワードが含まれていれば即座に処理を中断します。

def validate_query(query)
  dangerous_keywords = %w[INSERT UPDATE DELETE DROP CREATE ALTER TRUNCATE MERGE]
  normalized_query = query.upcase.gsub(/\s+/, ' ')

  dangerous_keywords.each do |keyword|
    next unless normalized_query.match?(/\b#{keyword}\b/)

    puts "エラー: 危険なクエリが検出されました: #{keyword}"
    puts 'このスクリプトではSELECT文のみ実行可能です。'
    exit 1
  end
end

Layer 3:AIスキル層(Claude Codeの制御)

Claude Codeの allowedTools 設定で、実行可能なコマンドを ReadEditBash(ruby *) の3つに限定しています。Bash(ruby *) はパターンマッチなので、ruby で始まるコマンドしか実行できません。bqgclouddockercurlmysql ——は全部ブロックされます。

さらに SKILL.md(Claude Codeのスキル定義ファイル)で詳細な禁止事項を明示的に記述しています。「bqコマンドは存在しないものとして扱うこと」「ユーザーに手動実行を依頼することも禁止」と、AIが抜け道を探さないように徹底しています。

この3層は独立して機能する設計です。1つの層が仮に突破されても、別の層で止まります。

Before / After

指標 Before After
分析リードタイム 数時間〜数日 数分
エンジニア工数 依頼のたびに発生 ゼロ
PMの分析頻度 遠慮して控えめ 気軽に何度でも

数字以上に大きかったのは定性的な変化です。PMが「ちょっとこれも見たい」を遠慮せずに実行できるようになりました。データを見て、新しい問いが生まれて、すぐまた分析する。このサイクルが、エンジニアの手を一切借りずに回るようになったのは大きいです。

副次的な効果として、分析のナレッジがGitHub Issueに蓄積されるようになりました。「あの時どんな分析したっけ?」をIssue検索で振り返れます。

まとめ:横展開の可能性

この仕組みは「BigQuery + Claude Code」に限った話ではありません。非エンジニアがAI経由で安全にシステムを操作するという設計パターンとして、さまざまな場面に応用できると考えています。

ポイントは安全設計です。3段構えの多層防御(インフラ → アプリケーション → AIスキル)があるからこそ、非エンジニアに安心して使ってもらえます。Claude Codeの allowedTools と SKILL.md を組み合わせれば、AIにできることを精密にコントロールできます。

エンジニアが「仕組み」を作ることで、チーム全体のデータアクセスを民主化する。その一つの形としてみなさんも試してもらえると嬉しいです。

0
0
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
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?