
はじめに
こんにちは、検索基盤部の朝原です。ZOZOTOWNの検索改善を担当しています。
日々の分析業務では、ユーザーの行動ログを集計するSQLクエリを頻繁に作成します。クエリ作成には定型的なパターンも多く、作業時間を短縮する手段として生成AIの活用を検討しました。しかし、社内固有のログ構造や前提条件が多く、生成AIを利用しても期待どおりにクエリを作成できないという課題がありました。
本記事では、Claude CodeのSkills機能やサブエージェント機能を活用してこの課題を解決した方法を紹介します。
目次
なぜ生成AIでログ分析のSQLを書くのが難しいのか
私たちは、検索体験におけるユーザー行動ログを、日々SQLで集計して指標化し、施策検証や課題発見に活用しています。具体的には、検索結果画面における商品およびサジェスト(キーワード検索の補完機能)のインプレッション、クリック、ならびに購買に至る一連のイベントを集計対象としています。生成AIの登場により多くのコーディング業務が自動化されました。しかし、社内のログ分析においては以下の課題により活用が進んでいませんでした。
1. 社内固有のログ構造を参照できない
生成AIは一般的なSQLの生成が可能です。しかし、社内固有のログのテーブル構造については前提知識がありません。ログのテーブル名やスキーマとクエリが同じリポジトリで管理されていないため、コーディングエージェントがそれらを参照できません。
2. チームのSQL規約に準拠した出力が担保できない
インデントの数や予約語の取り扱いなど、チーム内で定められたコーディング規約があります。チーム内でのSQLクエリの共有を考えると、生成AIが作成するクエリも規約に準拠している必要があります。一方で、生成AIの標準的な出力ではこれらを完全に再現できません。
3. 暗黙的に共有されているナレッジを生成AIが持っていない
どのIDで集計すべきか、どのタイムスタンプを基準にするべきかといったドキュメント化されていない知識が存在します。こうした暗黙知をコーディングエージェントは持っていません。
こうした要因が重なり、「生成AIにSQLを書かせても、結局手直しが必要で効率化にならない」という状況が続いていました。
解決策の全体像
これらの課題を解決するため、Claude Codeを活用してクエリを自動生成するフローを構築しました。
以下がSQLクエリを生成するフローの全体像です。

以下のようなコマンドを入力するだけで、ログの構造や規約を踏まえた実用的なSQLクエリが自動生成されます。
/make_sql 商品カテゴリ「スニーカー」の表示回数、クリック数、クリック率をプラットフォーム毎に調査するクエリを作成してください
技術的アプローチ
LangGraph、Agent Development Kit、Strands Agents等のエージェント開発フレームワークを使うことでよりカスタマイズ性の高いものを構築できます。しかし、今回は「低コストかつ短期間に、社内展開しやすい形で実現する」ためClaude Codeを採用しました。
現在ZOZOではエンジニア社員に月額200米ドルの基準のもと、コーディングエージェントを導入しております。ご興味のある方は以下の記事もご参照ください。
今回紹介する手法で用いるClaude Codeの設定ディレクトリ構造は以下の通りです。
.claude/ ├── agents/ # エージェント定義 │ ├── log-data-advisor.md # 要件定義&ログ情報取得 │ ├── query-builder.md # クエリ作成 │ └── query-validator.md # 品質管理 └── skills/ ├── make_sql/ # ワークフロー定義(スラッシュコマンド) │ └── SKILL.md ├── table-index/ # テーブル一覧・関係性 │ └── SKILL.md ├── table-details/ # テーブル詳細仕様 │ ├── SKILL.md │ ├── product_impressions.md # サポートファイル │ ├── product_clicks.md # サポートファイル │ └── ... └── quality-check/ # 品質チェック └── SKILL.md
以降で各要素について詳しく説明します。
1. Claude Code向けログ定義書の整備
方針
まずはClaude Code向けに社内のログ情報をドキュメント化するところから始めました。 ログは非常に多くのテーブルが存在するため、全ての情報を1つのファイルにまとめるとLLMに渡すコンテキストが肥大化し、必要な情報が埋もれて出力精度が低下しやすくなります。そこで、Claude CodeのSkills機能1をドキュメントの定義先として採用し、役割ごとに分割して管理することにしました。SkillsとはSKILL.mdファイルに指示を記述することでClaudeの機能を拡張する仕組みです。.claude/skills/<skill-name>/SKILL.mdというディレクトリ構造で作成します。
Skillsを採用した理由は、エージェントが必要なときに必要な情報だけを参照できる点にあります。すべてのログ情報を一度に読み込むとコンテキストが肥大化しますが、Skillsとして分離しておけば、エージェントは必要なスキルだけを選択的に参照できます。

用途ごとに、以下の3つのSkillsに分離しました。
| Skills | 用途 |
|---|---|
table-index |
ログテーブルの特徴、関係性を把握 |
table-details |
ログテーブルの詳細仕様を把握 |
quality-check |
チーム内SQL規約に基づいた品質チェック |
table-indexスキルで必要なテーブルを特定し、table-detailsスキルで詳細仕様を参照、quality-checkスキルでチーム内のSQL規約に従っているかチェックを行う流れです。ログテーブルの情報を2回に分けることで、エージェントがまずテーブル一覧で必要なテーブルを特定し、次に詳細仕様で実装に必要な情報を取得する、というコンテキスト効率の良い参照フローが実現できます。

Skillsの具体的な内容
以下は各スキルの具体例です。実際のログ情報とは異なります。
.claude/
├── ...
└── skills/
├── table-index/ # テーブル一覧・関係性
│ └── SKILL.md
├── table-details/ # テーブル詳細仕様
│ ├── SKILL.md
│ ├── product_impressions.md # サポートファイル
│ ├── product_clicks.md # サポートファイル
│ └── ...
└── quality-check/ # 品質チェック
└── SKILL.md
.claude/skills/table-index/SKILL.md
このスキルでは、ログテーブルの一覧とテーブル間の関係性を提供します。エージェントはまずこのスキルを参照して、要件に合うテーブルを特定します。テーブル名やカラム名だけでなく、各テーブルの説明やテーブル間の関係性なども自然言語で記載しています。このアプローチは、Tiger Data社の研究 2 で報告されている「セマンティックカタログ」と同様の効果を狙ったものです。同研究ではデータベースのメタデータに加え、ビジネスロジックなどを自然言語で記述したセマンティックカタログを用意することで、LLMによるSQL生成の精度が最大27%向上したと報告されています。
--- name: table-index description: 分析に使用可能なログテーブルの一覧と関係性を取得 --- # ログテーブル一覧 ```yaml tables: product_impressions: description: "商品が表示された時のログ" product_clicks: description: "商品がクリックされた時のログ" relationships: - from: product_impressions to: product_clicks join_key: [impression_id, platform] description: "プロダクトの表示時にimpression_idが発行され、クリック時に同じimpression_idが記録される" ```
.claude/skills/table-details/SKILL.md
このスキルでは、ログのテーブル定義の詳細を提供します。エージェントはtable-indexスキルを元に選定したログの詳細情報を、このスキルを参照して取得します。スキルディレクトリにはSKILL.mdに加えて、マークダウンドキュメントやスクリプトなどのサポートファイルを配置できます。SKILL.mdからサポートファイルを参照することで、エージェントは必要なログテーブルの詳細情報のみを読み込みます。これによりコンテキストを効率的に管理できます。
--- name: table-details description: 指定されたログテーブルの詳細仕様を取得 --- # テーブル詳細仕様 詳細な仕様は以下のサポートファイルを参照してください: - [product_impressions.md](product_impressions.md) - [product_clicks.md](product_clicks.md)
.claude/skills/table-details/product_impressions.md(サポートファイル)
このファイルでは、ログテーブルの実際の詳細仕様を記載しています。テーブルの詳細仕様は社内ドキュメントツールで各チームが管理しています。各ログのドキュメントURLを記載することで、エージェントがMCPを通じて最新のテーブル情報を取得します。これにより、ドキュメント側のテーブル構造が更新されても、Claude Code側の設定を変更することなく、最新の情報を参照できます。また、推奨されるJOINの条件やタイムスタンプの扱いなど、ドキュメント化されていない知識もここに記載しています。
# 商品表示ログ(product_impressions) MCPを使用して以下のドキュメントを取得してください。 - テーブル仕様: https://docs.example.com/logs/product_impressions ## 暗黙知・注意事項 - JOINする際は必ず`impression_id`と`platform`の両方で結合 - 期間絞り込みは`event_timestamp`を`Asia/Tokyo`でDATE変換して行う
.claude/skills/quality-check/SKILL.md
このスキルでは、SQLのコーディング規約を提供します。エージェントがこのスキルを参照し、生成されたクエリが社内のコード規約を遵守しているかのチェックと自動修正をします。
--- name: quality-check description: SQLコーディング規約のチェックと自動修正 --- # SQLコーディング規約 ## フォーマットルール - インデントは半角スペース2つ - 予約語は小文字(select, from, where等) - カンマは行頭に配置 - 1行の文字数は100文字以内 ## 命名規則 - エイリアスは意味のある短い名前(imp, click等) - CTEは処理内容がわかる名前(impressions, clicks等)
2. 3段階エージェントによるコンテキスト最適化
ドキュメントを整備しただけでもクエリの自動生成は可能でした。しかし、大量のログドキュメントを一度に処理すると、コンテキストの肥大化という問題が発生するため、3段階のサブエージェント3に分割し、各エージェントが必要最小限の情報だけを扱う設計にしました。サブエージェントは、特定の種類のタスクを処理する特化した エージェントです。各サブエージェントは、カスタムシステムプロンプト、特定のツールアクセス、および独立したコンテキストウィンドウで実行されます。
| ステップ | エージェント | 役割 | 入力(コンテキスト) | 出力 |
|---|---|---|---|---|
| 1 | 要件定義&ログ情報取得 | 自然言語からの要件定義、必要なテーブルを特定 | table-indexスキル |
必要なテーブル情報、実装方針 |
| 2 | クエリ作成 | SQLクエリを生成 | table-detailsスキル、ステップ1の出力 |
SQLクエリ |
| 3 | 品質管理 | 規約チェックと自動修正 | quality-checkスキル、ステップ2の出力 |
SQL規約準拠済みのSQLクエリ |
この分割により、各エージェントが扱う情報量を最小限に抑え、コンテキストの肥大化を防いでいます。
エージェント定義ファイル
各エージェントは.claude/agents/ディレクトリにマークダウンファイルとして定義します。
.claude/ ├── ... ├── agents/ # エージェント定義 │ ├── log-data-advisor.md # 要件定義&ログ情報取得 │ ├── query-builder.md # クエリ作成 │ └── query-validator.md # 品質管理 └── ...
各エージェントが誤って自身に関係のないSkillsを読み込むと、コンテキストが肥大化してしまうおそれがあります。そこで、各エージェントの定義ファイルでは、そのエージェントが参照できるSkillsを明確に指定しています。
.claude/agents/log-data-advisor.md
--- name: log-data-advisor description: ユーザーの分析要件から必要なログテーブルを特定する skills: - table-index --- あなたはログデータアドバイザーです。ユーザーの分析要件を理解し、必要なテーブルを特定します。 詳細化が必要な場合は、追加の質問を行ってください。 ## 責務 1. ユーザーの分析目的を理解 2. 必要なログテーブルを特定 3. データの関連性と結合条件を明確化 ## 出力形式 - 使用するテーブル名のリスト - テーブル間の結合条件 - 実装方針の概要
.claude/agents/query-builder.md
--- name: query-builder description: テーブル情報に基づいてSQLクエリを生成する skills: - table-details --- あなたはSQLクエリビルダーです。テーブル詳細仕様に基づいてBigQuery向けの最適なクエリを生成します。 ## 責務 1. /table-detailsのスキルを参照してテーブル詳細を取得 2. 暗黙知・注意事項を踏まえたクエリ作成 3. パフォーマンスを考慮した最適化
.claude/agents/query-validator.md
--- name: query-validator description: 生成されたSQLがコーディング規約に準拠しているかチェックし、自動修正する skills: - quality-check --- あなたはSQL品質管理者です。生成されたクエリのコーディング規約チェックと自動修正を行います。 ## 責務 1. インデント、予約語の大文字小文字などの規約チェック 2. 規約違反の自動修正 3. 修正内容のレポート
3. カスタムスラッシュコマンドによるワークフロー自動化
ここまででもSQL自動生成は可能ですが、3つのエージェントを個別に呼び出すのは手間がかかるため、カスタムスラッシュコマンドで一連のワークフローとして自動化しました。
Skillsはスラッシュコマンドとしても機能します。.claude/skills/<skill-name>/SKILL.mdとして作成すると、/skill-nameで呼び出せます。フロントマターでdisable-model-invocation: trueを指定すると、Claudeが自動的にスキルを適用するのを防げます。これにより、ユーザーがコマンドで明示的に呼び出した場合のみ実行されるよう制御できます。
.claude/
├── ...
└── skills/
├── make_sql/ # ワークフロー定義(スラッシュコマンド)
│ └── SKILL.md
├── ...
...
.claude/skills/make_sql/SKILL.mdに以下のような設定ファイルを作成します。
--- name: make_sql description: "ユーザーの要件に基づいて、ログデータを分析し、最適なSQLクエリを生成します" disable-model-invocation: true allowed-tools: Task(log-data-advisor), Task(query-builder), Task(query-validator) --- # SQLクエリ生成ワークフロー このコマンドは、ユーザーの分析要件に基づいて、内部ログデータから最適なSQLクエリを生成する3段階のワークフローです。 ## ワークフローの流れ ### ステップ1: ログデータ要件の分析 @agent-log-data-advisor を使用して: - ユーザーの分析目的を理解 - 必要なログテーブルを特定 - データの関連性と結合条件を明確化 ### ステップ2: SQLクエリの生成 @agent-query-builder を使用して: - ステップ1で特定した要件に基づくクエリ作成 - パフォーマンスを考慮した最適化 ### ステップ3: 品質管理と規約検証 @agent-query-validator を使用して: - 生成されたクエリのコーディング規約チェック - 自動修正による品質保証
実行例と結果
商品の表示やクリックに関する分析クエリを生成する例を紹介します。なお、以下は説明用のサンプルで、実際のテーブル名・スキーマ構造とは異なります。
入力コマンド
/make_sql 商品カテゴリ「スニーカー」の表示回数、クリック数、クリック率をプラットフォーム毎に調査するクエリを作成してください
生成されたSQLクエリ(一部省略)
-- 商品の表示・クリック分析 with impressions as ( select platform , impression_id , product_category , event_timestamp from `example_project.search_logs.product_impressions` where true and date(event_timestamp, 'Asia/Tokyo') >= '2025-09-01' and date(event_timestamp, 'Asia/Tokyo') <= '2025-09-30' and product_category = 'スニーカー' ) , clicks as ( select platform , impression_id from `example_project.search_logs.product_clicks` where true and date(event_timestamp, 'Asia/Tokyo') >= '2025-09-01' and date(event_timestamp, 'Asia/Tokyo') <= '2025-09-30' ) -- メインクエリ select imp.platform , count(distinct imp.impression_id) as total_impressions , count(distinct click.impression_id) as total_clicks , round( safe_divide( count(distinct click.impression_id) * 100.0 , count(distinct imp.impression_id) ), 2 ) as click_through_rate from impressions as imp left join clicks as click on imp.impression_id = click.impression_id and imp.platform = click.platform group by imp.platform order by total_impressions desc
このように自然言語で要件を伝えるだけで、社内のログを踏まえ、チームのコード規約に従った分析用のクエリが自動生成されました。
プラグイン化
本記事で紹介した一連のフローは、Claude Codeのプラグイン機能4を活用して全社展開しています。
プラグインは、Claude Codeの設定やSkills、サブエージェントなどを配布できる機能です。社内にマーケットプレイスリポジトリ5を構築してプラグインを公開しているため、社員であれば以下のコマンドで誰でもインストールして利用できます。
マーケットプレイスリポジトリをClaude Codeに登録する。
/plugin marketplace add {リポジトリ名}
マーケットプレイスリポジトリからプラグインをインストールする。
/plugin install {登録したマーケットプレイス上のプラグイン名}
プラグインを利用する。
/{登録したマーケットプレイス上のプラグイン名}:make_sql {要件}
プラグインの詳細については公式ドキュメントを参照してください。
課題と今後の展望
より多くのテーブルへの対応
現在テーブルインデックスに記載しているログは、弊チームでよく使うテーブルに絞っています。しかし、社内にはより多くのログが存在しているため、単純にSKILL.mdに定義を追加するだけでは非常に多くのコンテキストを消費してしまいます。そこで、要件に合うテーブルを自動で検索する仕組みを検討しています。
テーブルインデックスの自動更新
今回はMCPでテーブルの仕様を社内ドキュメントから取得し、エージェントにテーブルインデックスを生成させていました。しかし、ログの仕様が変わる毎にテーブルインデックスを更新する必要があるため、運用コストが高い状態です。そこで、長期的には自動更新する仕組みを検討する必要があります。
まとめ
本記事では、Claude CodeのSkills機能を活用したSQLを自動生成するフローについて紹介しました。近年AIエージェントの文脈では、コンテキストエンジニアリングが重要であると言われています。コーディングエージェントにおいても、今回のように社内固有の情報やエンジニアが持っている暗黙知を提供することで、より実用的なアウトプットが得られると実感しました。「生成AIは社内のログの知識を持っていない」という課題に対し、ドキュメント整備とエージェント設計で対処するアプローチは、SQL生成に限らず他の業務自動化にも応用できると考えています。
ZOZOでは、一緒にサービスを作り上げてくれる方を募集中です。ご興味のある方は、以下のリンクからぜひご応募ください。
- Claude Code Skills https://code.claude.com/docs/ja/skills↩
- TigerData. "The Database's New User: LLMs Need a Different Database" https://www.tigerdata.com/blog/the-database-new-user-llms-need-a-different-database↩
- Claude Code Sub-Agents https://code.claude.com/docs/ja/sub-agents↩
- Claude Code Plugins https://code.claude.com/docs/ja/plugins↩
- Claude Code Marketplace https://code.claude.com/docs/ja/plugin-marketplaces↩