blog

DeNAのエンジニアが考えていることや、担当しているサービスについて情報発信しています

2026.04.10 その他

クエリ集計ミス激減!脱「バイブコーディング」と仕様駆動分析(SDA)のすゝめ

by ryoma hamaoka

#ai #sql #analysis #github-copilot #devin

こんにちは、ゲームサービス事業本部分析部の浜岡です。

生成AIの活用が進み、簡単なSQLであれば「これ集計して」と頼むだけでクエリからレポートまでが作れる時代になりました。

AI に参照させる資料を用意した上で、いわゆるVibe Coding(バイブコーディング)のような雰囲気で進めれば、比較的シンプルなものであればカバーできるようになっています。

ゲームサービス事業本部の分析部では、AI を使った分析体制のスタンダードをこれまでに構築してきました。その詳細は過去のエンジニアリングブログ「 SQL未経験でも即戦力に?アナリスト組織が挑む『AIネイティブ』な働き方改革 」でも紹介しています。

ただ、この体制で実務を回していく中で、Vibe Codingだけではカバーしきれない様々な課題に直面しました。

本記事では、その課題に対して僕たちが取り組んでいる「仕様駆動分析(Spec-Driven Analytics)」というアプローチを紹介します。この仕組みは、Github Copilot から始まりましたが、Devin や Claude でも応用が効くものなので、参考になれば幸いです。

まずは、実際に Vibe Coding の壁にぶつかった浜岡の体験から話を始めます。

本記事の登場人物

浜岡 凌誠

  • データアナリスト(25新卒)
  • SQL や開発環境に触れたことがない状態で配属され、今回のAI活用システムの最初のユーザーとして実証実験に参加

佐々木 亮

  • ゲームサービス事業本部分析部 シニアデータアナリスト / 株式会社DeNA AI Link Devin推進部 部長
  • 「仕様駆動分析」構想の発案。ゲームサービス事業本部の分析部AI推進をリード
  • 浜岡のメンターを務め、SQL未経験からの立ち上がりとAI活用に伴走

1. なぜ「仕様駆動」に至ったのか?(Vibe Codingの限界)

僕(浜岡)は新卒1年目でゲームの分析チームに配属されました。SQL の経験はゼロ。それでも、AIコーディングツールのおかげで、「やりたいこと」をざっくり伝えるだけで、大量のクエリを爆速で生成できるようになりました。いわゆる Vibe Coding ——ノリと勢いで AI にコードを書かせるやり方です。最初は「これはすごい、自分にもできる」と思っていました。

異変に気づいたのは、出来上がったクエリを自分でレビューしようとしたときです。

Vibe Coding でやりたいことを雑多に伝えると、AI は設計から実装まで一気にやってくれます。出来上がったクエリは一見それっぽく動く。でも、自分には書けないレベルの複雑なロジックが入っているので、処理が本当に正しいのか判断できない。設計の良し悪しもわからない。なんとなく「良さそう」としか思えない。これはレビューとは呼べませんでした。

そのまま上長にレビューを依頼するわけですが、飛んでいくのは「レビューしづらく、複雑で、しかも誤りが潜んでいる大量のクエリ」です。
振り返ると、これは上長にとってもかなりの負担だったと思います。

そしてクエリの規模が大きくなると、状況はさらに悪化しました。僕たちのプロジェクトでは、アドホックな分析や複雑な要件の依頼も多いため、500行を超えるような大規模なクエリを書く機会も少なくありません。

このスケールになると、コーディング力に長けた AI でも、データ構造の理解を間違えたり、コンテキスト不足でエラーが増え始めます。

デバッグを試みても、最初の生成時の文脈がどんどん薄れていって、AI は目の前のエラー解消にだけフォーカスし始める。ある箇所を直したら別の箇所が壊れ、それを直したらまた別の箇所が……という泥沼です。

整理すると、当時の僕はこういう状態でした。

  • AI の出力を「なんとなく」でしか理解できず、レビューが機能しない
  • 設計を AI に丸投げしているので、設計上の問題に気づけない
  • クエリが大規模になると AI もミスが増え、デバッグが泥沼化する
  • そして何より、自分自身のスキルが一向に伸びていない

「AI で速くなったはずなのに、なぜかずっと苦しい」。
この感覚がずっとありました。

この悩みを、メンターの佐々木さんに相談しました。そこで教えてもらったのが、「仕様駆動分析(Spec-Driven Analytics)」というアプローチです。

これが、僕の AI との付き合い方を根本から変えることになります。

2. Spec-Driven Analytics (SDA) とは

Vibe Coding の壁は、僕だけの問題じゃなかった

佐々木さんに相談したとき、「その悩みは浜岡くんだけの話じゃない」と言われました。

世の中のエンジニアリングの現場でも、AI でコードを書くハードルが下がった分、同じような壁にぶつかっている人が増えているとのこと。

エンジニアの世界では「仕様駆動開発」が広まりつつあった

そうした課題に対して、ソフトウェア開発の世界で有効なアプローチとして広まりつつあったのが仕様駆動開発(Spec-Driven Development / SDD)でした。
考え方はシンプルで、「AI にいきなりコードを書かせるな。まず仕様書を書け。そして仕様書をAIに渡して実装させろ」というものです。

SDDが AI時代の開発と相性が良い理由は明確でした。

LLMの「仕様理解力」が実用レベルに達し、数ページにわたる仕様書を渡しても文脈を保ったまま実装に変換できるようになった。さらに Claude Code や Cursor Agent のようなエージェント型ツールの登場で、「参照すべきドキュメント」があると AI の出力精度が跳ね上がるようになった。つまり、人間が「仕様」という形で設計を担い、AIが「実装」を担うという分業が、ようやく現実的になったわけです。

開発の共通言語を「コード」から「自然言語」へシフトする。人間は「実装者」から「承認役(Reviewer)」へと役割を変え、AI を「開発の主体」として動かす。これがSDDの核心です。

分析にトレースすると?

佐々木さんの発案で、SDDの分析への応用を検討し始めました。
Vibe Coding の問題は、設計も実装も AI に丸投げしているから、出来上がったクエリがブラックボックスになることでした。

だったら、クエリを書く前に、自然言語で「何を集計するのか」「どのテーブルを使うのか」「どんな粒度で出力するのか」を仕様書として言語化すればいい。この言語化の作業は、そのまま「設計」になります。

設計を自分がやっているから、AI の出力に対して「ここは仕様と違う」と具体的に指摘できる。つまりレビューが機能するようになる。しかも仕様書は自然言語なので、SQLを読み慣れていないレビュアーでも内容を理解できます。500行のクエリを読む代わりに、仕様書をレビューすればいい。

これが Spec-Driven Analytics(SDA)。SDDをデータ分析にトレースしたアプローチです。

「クエリを書くな。仕様書を書け。」

佐々木さんに言われたこの一言の意味が、ようやく腑に落ちました。

これならいけるのではないか。そう思って、実際のタスクに導入してみることにしました。

次のセクションでは、SDA を実際にどう進めるのか—— spec.md と design.md という2つのドキュメントを使った具体的なフローを、実例ベースで紹介します。


3. 【詳細解説】SDA の実践フロー

やってみた:あるタスクでの実例

SDAの具体的なフローを、実際のタスクに近い例で紹介します。

ある日、こんな依頼が来ました。「直近イベントのユーザー行動を分析してほしい。イベント参加者の継続率が通常と比べてどう違うのか、課金セグメント別に見たい」。

以前の僕なら、この依頼をこのまま AI に投げていました。もちろん、Vibe Codingでも優秀な AI は「どのイベントですか?」「継続って何日後のログインですか?」くらいは聞いてくれます。ただ、そこで擦り合わせが終わってしまう。「そのイベントの施策としての狙いは何か」「イベント参加の集計ロジックはどのテーブルからどういう処理で組み立てるか」「何は今回の分析対象から外すべきか」——こうした細かいけれど重要な部分は、AI が勝手に解釈して、勝手に設計して、勝手に実装してしまう。そして、その判断が正しいかどうか、僕には見抜けない。

SDAでは、クエリを書く前に2つのドキュメントを作ります。spec.mddesign.md です。

Step 1:spec.md(何を明らかにしたいのか)

spec.md は「ビジネス要件の言語化」です。

SQLの話は出てきません。何を知りたいのか、どういう定義で測るのか、最終的にどんなアウトプットが欲しいのかを自然言語で書きます。

先ほどの依頼を spec.md に落とすと、こんな感じになります。

# Spec: イベント参加者の継続率分析

## Business Question
直近イベントの参加者は、非参加者と比較して継続率に差があるか。
課金セグメント別に傾向が異なるかを明らかにしたい。

## Non-Goals(対象外事項)
- ❌ イベント内のステージ別分析は今回対象外
- ❌ リアルタイム集計は不要(日次バッチで十分)

## Output
- 粒度: イベント参加有無 × 課金セグメント × 経過日数
- 期間: イベント開催期間(2025-01-10 〜 2025-01-24)
- カラム: `event_participation`, `payment_segment`, `days_since_event`, `retention_rate`, `user_count`

## Metric Definitions
- イベント参加者: 期間中にevent_id = 'EVT_2025_01'のログが1回以上あるユーザー
- 継続率: イベント終了日を起点として、N日後にログインしたユーザーの割合
- 課金セグメント:
  - 無課金: 累計課金額 = 0
  - 微課金: 累計課金額 1〜4,999円
  - 中課金: 累計課金額 5,000〜49,999円
  - 重課金: 累計課金額 50,000円以上

## 出力イメージ
| event_participation | payment_segment | days_since_event | retention_rate | user_count |
|---|---|---|---|---|
| 参加 | 無課金 | 1 | 0.72 | 12,345 |
| 参加 | 無課金 | 7 | 0.45 | 12,345 |
| 非参加 | 無課金 | 1 | 0.58 | 34,567 |

ポイントは、どういう目的で、具体的に何を、どのように集計したいかを自然言語で言語化するということです。「イベント参加者」の定義、「継続率」の計算ロジック、課金セグメントの閾値——これらをコードではなくビジネスの言葉で書き切ることで、僕自身も「何を集計しようとしているか」を正確に把握できるし、レビュアーとの認識合わせもクエリを見る前にできます。

Vibe Coding との違いはここです。AI に丸投げしていたときは、これらの定義決めを AI に委ねていたことで、本当は大事なことにも関わらず、注視できていませんでした。

Step 2:design.md(どうやって集計するのか)

spec.md で「何を」が決まったら、次 は design.md で「どうやって」を設計します。ここで初めてテーブル名やCTE構成といった技術的な話が出てきます。

# Design: イベント参加者の継続率分析

## 使用テーブル
- `user_events`: ユーザーのイベント参加ログ
- `user_logins`: 日次ログインログ
- `user_payments`: 課金履歴

## CTE構成
1. `event_users`: event_id = 'EVT_2025_01' で参加者を抽出
2. `payment_segments`: user_payments から累計課金額を算出し、セグメント分類
3. `base_users`: 全ユーザーにイベント参加フラグと課金セグメントを付与
4. `login_check`: イベント終了日からN日後のログイン有無をチェック
5. `final`: グループ別に継続率を集計

design.mdの重要な要素がMermaid図です。

CTEの依存関係やデータの流れを図で可視化します。

フローチャート フローチャート

ER図 ER図

この図があることで、「どのテーブルからどんな順番でデータが流れるか」が一目でわかります。500行のSQLを上から読むよりも、はるかに全体像を把握しやすい。

レビュアーにとっても、「この設計で仕様を満たせるか?」を判断しやすくなります。

そして何より、この設計を AI と一緒に、でも自分が主導して作っているから、AI が生成したクエリに対して「CTE3 のJOIN条件が仕様と違う」「payment_segments の閾値が spec.md の定義と一致していない」と具体的に指摘できるようになります。

Step 3:AI にクエリを生成させる

spec.md と design.md が揃ったら、この2つのドキュメントを AI に渡して、クエリの生成を依頼します。

ここでの AI への指示は驚くほどシンプルです。「spec.mdとdesign.mdを参照して、SQLクエリを生成してください」——基本的にはこれだけ。仕様と設計が明確に書かれているから、AI が迷う余地がほとんどない。

Vibe Coding のときは、「イベント参加者の継続率を課金セグメント別に出して」という曖昧な指示から、AI が仕様の解釈・設計・実装を一気にやっていました。当然、どこかでズレが生じる。SDA では、仕様と設計を AI と相談しながらも人間主導で固めた上で、AI には「実装だけ」をやらせます。AI が最も得意な部分だけを任せるわけです。

そして生成されたクエリをレビューするとき、手元には spec.md と design.md があります。「出力カラムはspec.mdの定義と合っているか」「CTE構成は design.md の設計通りか」「課金セグメントの閾値は spec.md の Metric Definitions と一致しているか」——チェックポイントが明確だから、レビューが「なんとなく良さそう」ではなくなります。

SDAは「遠回り」なのか?

ここまで読んで、「クエリを書く前にドキュメントを2つも作るのは面倒じゃないか」と思った方もいるかもしれません。正直、最初は僕もそう思いました。

でも、実際にやってみると、トータルの所要時間はむしろ短くなりました
Vibe Coding では、AI が生成したクエリのデバッグで泥沼にはまり、何時間も溶かすことが珍しくありませんでした。

SDAでは、仕様と設計を固める時間はかかりますが、AI が生成するクエリの精度が高いので、デバッグの時間が激減します。作っては直し、直しては壊れ、という泥沼がなくなりました。

副産物もあります。仕様を言語化する過程で「あれ、この定義って曖昧だな」「この条件、依頼者に確認しないとわからないな」と気づけるようになりました。

Vibe Coding では、こうした曖昧さにクエリを書き終わった後——もっと悪い場合はレビューで指摘された後に気づいていました。

次のセクションでは、SDA 導入前後で何が変わったのかを、もう少し具体的に振り返ります。

4. やってみてどうだったか(Before / After)

SDAを導入して数ヶ月。振り返ると、変わったことは大きく3つあります。

クエリの集計ミスが、ほぼなくなった

まず一番インパクトが大きかった変化です。SQL未経験から始めて1年、しかも大規模で複雑な分析が求められるプロジェクトにもかかわらず、クエリの集計ミスが劇的に減りました。「劇的に」というのは控えめな表現で、今ではほぼゼロに近い状態です。

理由は明確で、AI に渡す情報の質が圧倒的に上がったからです。spec.md で指標の定義が明確になっていて、design.md でCTE構成が決まっている。AI はその仕様に沿って実装するだけなので、「何をやりたいか」の解釈でズレることがない。仮にエラーが出ても、design.md を見れば「どのCTEの、どの処理でおかしくなっているか」を特定しやすい。

Vibe Coding のときは、生成→デバッグの工程に全体の7割くらいの時間を使っていました。SDA では仕様・設計に時間をかける分、生成後のデバッグは2〜3割で済んでいます。

レビューが「クエリミス探し」から「分析の議論」に変わった

クエリの精度が上がったことで、レビューの中身が根本から変わりました。

Vibe Coding時代、レビューの大半は「この集計おかしくない?」「このJOIN条件抜けてない?」というクエリミス探しでした。レビュアーにとっても、意図がわからない500行のクエリを読み解くのは相当な負荷だったはずです。

SDA 導入後は、レビュー依頼に spec.md と design.md が添付されます。レビュアーはまず仕様書を見て「この分析の目的と定義は正しいか」を確認し、次に設計を見て「この処理フローで仕様を満たせるか」を確認する。SQL を1行ずつ追う前に、全体像を把握できる。

そして集計ミスがほぼなくなった結果、レビューの場では「このセグメントの閾値、もっと細かく分けた方がいいんじゃないか」「Non-Goals に入れてるけど、これも見た方がよくない?」といった、分析の中身に踏み込んだ議論ができるようになりました。

分析の「本質」にフォーカスできるようになった

これが、SDA で一番大きかった変化です。

Vibe Coding のとき、僕の時間の大半は「クエリを正しく動かすこと」に費やされていました。AI が出したものをデバッグして、なんとか動かして、レビューで指摘されて直して……。

業務に貢献する分析ではなく、分析のための分析をしている状態です。

SDA でクエリの精度が担保されるようになると、その先にある本質的な仕事——「何をどう分析するか」を依頼主と一緒に考え、提案していく——にフォーカスできるようになってきました

仕様書を書く過程で、依頼の背景にあるビジネス課題を深く理解するようになったし、「こういう切り口でも見た方がいいんじゃないですか」と提案できる場面も増えました。

SQL未経験で始めた1年目で、ここまで来られたのは正直自分でも驚いています。SDA は「AIを使いこなすフレームワーク」であると同時に、「分析者としての思考力を鍛えるトレーニング」でもありました。クエリの書き方ではなく、分析の考え方が身についた。この実感が、今の僕にとって一番の収穫です。

5. SDAの運用方法

  • このアプローチは、ゲームサービス事業本部で利用されている Github Copilot, Devin で活用されています。
  • Github Copilot では、「プロトコル」としてワークフローと参照するべきファイルを明確化したパッケージを構築し、分析時にはこれを呼び出して利用しています。
    • そのプロトコルの一部が以下です。
# 第1.5部: Spec-Driven Analyticsプロトコル

### 発動条件
- クエリが200行を超える見込みの場合
- 複雑な要件(3つ以上のファネル、複数セグメント分析など)
- ユーザーが「仕様書を作成して」と依頼した場合

---

### フェーズ進行

| Phase | 成果物 | 承認キーワード | 開始条件 |
| :---: | :--- | :--- | :--- |
| **0** | フォルダ作成 | - | ユーザー依頼 |
| **1** | `spec.md` | "spec.md承認します" | Phase 0完了 |
| **2** | `design.md` | "design.md承認します" | Phase 1承認 |
| **3** | SQL | "作成してください" | Phase 2承認 |

---

### 重要原則
- **推測禁止**: 不明点は必ずユーザーに確認すること。
- **段階厳守**: `spec` → `design` → `SQL` の順序を守ること(同時作成禁止)。
- **Mermaid必須**: `design.md`にER図とフローチャートを必ず含めること。

---

### Phase 1: spec.md作成

**【必須項目】**
1. **Business Question**(分析目的を1文で)
2. **Non-Goals**(対象外事項)
3. **Output**(粒度、期間、カラム)
4. **Metric Definitions**(全指標の計算式)
5. **出力イメージ表**
6. **データ品質要件**

**【確認事項】**
分析目的 / 期間 / セグメント / 粒度 / 出力イメージ / 制約条件
- **不明点確認例**:
  - セグメント定義が不明な場合: 「国別、デバイス別、その他のどれを使用しますか?」
  - テーブル選択で迷う場合: 「`user_profile`、`item_consumption_log` のどちらを使用しますか?」

---

### Phase 2: design.md作成

**前提条件**: `spec.md`承認後のみ開始

**【必須項目】**
1. **ER図**(Mermaid、JOINキーと種別を明記)
2. **フローチャート**(Mermaid、処理順序を明記)
3. **CTE処理フロー表**(番号 / 名称 / 目的 / 入出力)
4. **実装ポイント**(パフォーマンス / 品質対策)
5. **`spec.md`参照明記**

**【ER図記載ルール】**
- リレーション線: `"player_id | INNER JOIN"` のように記載。
- PK / FK を明記する。
- 複合キー: `"key1, key2 | JOIN種別"` のように記載。

**【フローチャート記載ルール】**
- エッジにJOIN条件記載: `"INNER JOIN ON player_id"`
- JOIN種別明記(LEFT / INNER / CROSS)
- 処理内容を簡潔に記載(GROUP BY、WHERE等)

**【整合性チェック(自動実行)】**
1. 出力カラム一致
2. 指標定義の実装
3. 集計粒度一致
4. データソース網羅
5. Non-Goals遵守
*※結果レベル: ERROR(修正必須)/ WARN(確認推奨)/ INFO(参考情報)*

---

### Phase 3: SQL生成

**前提条件**: `spec.md` + `design.md` 承認後のみ開始

**【完了条件】**
- `spec.md` 指標全実装
- `design.md` CTE構造 / JOIN順守
- CTE毎にコメント付与(目的 / 入力 / 出力 / 参照タグ)
- 期間 / BOT除外 / 粒度適合
- ドライラン正常
- 最終整合性チェックOK

**【最終整合性チェック(自動実行)】**
- SELECT出力カラム / 計算式 / GROUP BY粒度 / 期間条件
- CTE名 / 数 / 順序 / JOIN種別 / コメント参照タグ

**【クエリヘッダー形式】**
```sql
# /
# クエリ名 / 作成日 / 作成者 / 目的 / 使用テーブル
# 関連ドキュメント: spec.md, design.md
# \
```

**【CTEコメント形式】**
```sql
-- ==================
-- CTE①: [名称]
-- ==================
-- 目的 / 処理 / 参照: spec.md Section名, design.md CTE#
```

---

### 成果物構造

```text
Spec-Driven-Analytics/YYYYMMDD_分析名_担当者名/
├── 分析仕様書/spec.md
├── 分析仕様書/design.md
├── analysis.md
└── temp_query.sql (任意)
```
  • Devin では、ワークフローを設定できる Playbook に SDA の手法を落とし込んで、分析者はそれを呼び出すことで Devin のエージェント内で SDA が実施できるようにしています。Devin Playbook は Devin の AI と作り、その改善も AI とできるので、これを素案として Devin に渡すと動かせます。
  • Claude Code も Devin 同様で、Skills生成をこれを素案に進めることで、Skills に昇華することが可能です。
  • どちらのアプローチでも、基本的には AI 側から必要な情報のヒアリングがされるため、分析者は AI 主導で受け身の形で分析を実施できるようになっています。

6. SDA活用の正直な現状とこれから

ここまで SDA の効果を書いてきましたが、万能ではありません。正直に限界も書いておきます。

全部のクエリに SDA は要らない

当たり前の話ですが、「DAU を日別で出して」くらいのシンプルな集計に spec.md と design.md を作るのは明らかに過剰です。SDA が威力を発揮するのは、複数テーブルのJOINが必要だったり、セグメント定義が複雑だったり、クエリが200〜300行を超えてくるようなタスクです。

僕たちの体感としては、こんな使い分けをしています。

  • Vibe Coding で十分: シンプルな集計、既存クエリの微修正、アドホックな確認
  • SDA を使う: 複雑なセグメント分析、複数指標の組み合わせ、500行程度の大規模クエリ

蓄積した Spec・Design を活かす仕組みの最適解を探る

SDA で作成した spec.md や design.md は、分析が終わればそのまま残ります。似たような分析依頼が来たとき、過去の仕様書を参照すれば効率的に進められるはず——理屈ではそうなんですが、蓄積した Spec や Design を活用して、AIのフィードバックループを回していく仕組みづくりは道半ばです

ただ、読み返すだけで人の分析がわかるという点では非常に重宝しています。

過去の仕様書をどう整理し、どう AI に参照させるか。ここは今まさに試行錯誤している部分です。

モデルの進化で、SDA が必要な範囲は狭まっているが、継続的に使われ続ける必要がある

正直に書くと、SDA の活用頻度は導入当初より減っています。

理由はシンプルで、AIモデル自体が進化したからです。特にOpusモデルの登場以降、Vibe Coding的なざっくりした指示でも、以前よりはるかに高精度なクエリが返ってくるようになりました。SDA が必要だったレベルのタスクの一部が、Vibe Coding でも十分にカバーできるようになってきている。

これは SDA の否定ではなく、「SDAが本当に必要なライン」が上がったということです。モデルが賢くなった分、SDAの出番はより複雑で大規模なタスクに集約されつつあります。逆に言えば、そういうタスクでは SDA の効果は依然として圧倒的です。

ただ、この手法はモデルが改善されて行っても、チーム内で利用することは重要だと実感しています。僕のような分析初心者が、どこを見て修正すればいいかを学ぶための構造として最適だからです。

加えて、今は有効活用できていませんが、仕様書群は今後分析を振り返っていく上で重要な要素になる原石のため、Vibe Coding で失われてしまうコンテキストをあえて残すことの重要性もあると考えています。

これから

AI の進化は速いので、半年後にはまた違うアプローチが最適になっているかもしれません。SDA が必要なタスクの範囲も、モデルの進化とともに変わり続けるでしょう。

ただ、セクション4で書いたように、SDAは「クエリの精度を上げる手法」であると同時に、AI時代における新卒アナリストのスキルアップの手段としても大きな価値があったと思っています。AI に丸投げしていたら身につかなかった「何をどう分析するかを自分の頭で設計する力」が、仕様書を書く過程で自然と鍛えられた。この経験は、ツールやモデルが変わっても確実に残ります。

SDA を通じて身についた「AI に投げる前に、自分の頭で設計を整理する」という習慣。これが、今の僕にとって一番の財産です。

最後まで読んでいただき、ありがとうございます!
この記事をシェアしていただける方はこちらからお願いします。

recruit

DeNAでは、失敗を恐れず常に挑戦し続けるエンジニアを募集しています。