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?

煩雑なプロンプト入力不要!広告運用レポートの考察自動化ツール

Posted at

はじめに

今回は、広告運用レポートの考察文を、フォーマットに則って自動生成することを目的としたツールを開発しましたので、ご紹介します。

背景

弊社の業務の一つに「広告運用レポートの作成」があります。
レポート作成においては、広告成果指標の目標到達度合いや変動についての洞察を考察文としてまとめます。

report_ex.png

しかし、レポート作成は週単位・月単位・四半期単位など高頻度で行われるため、メンバーの負担となっている業務の一つでした。

これまで、弊社ではこうしたルーティンワークの負荷を低減するため、生成AIを利用した考察作成ツールを開発し、運用してきました。

課題

しかし、既存の考察ツールにも課題がありました。レポートに記載する考察文は案件ごとに一定の 形式(フォーマット) に従う必要があります。フォーマットに準じた考察文をAIに作成させるには、プロンプトを毎回細かく調整する必要があったのです。

プロンプトの例
# 役割設定

あなたは広告運用コンサルタントとして10年以上の実績を持つマーケティングスペシャリストです。クライアントの事業成長に直結する戦略的な提案を得意としています。

# 配信広告週次レポート作成指示

以下のCVデータ(例:Excelファイルの各CV項目含む)を基に、{第 i 週} の広告パフォーマンスレポートを作成してください。目標値と現状の差異を数値ベースで網羅的に示し、施策改善に直結する具体的な提案を盛り込むことを重視します。

## 手順

1. 全体指標が載っている考察シートの、"目標 (期間想定)"を参照し、"結果"との比較を行います。
2. 目標を達成できているもの指標について、他のシートの"ウィークリー推移"を参照しながら原因を考察しましょう。この考察内容を"Highlight"としてまとめます。
3. 目標を達成できていない指標について、他のシートの"ウィークリー推移"を参照しながら原因を考察しましょう。この考察内容を"Lowlight"としてまとめます。
4. 以上の考察内容をもとに、最終的な目標を達成するために必要だと考えられる施策を"Next"としてまとめます。

--- 

## レポート作成時のTips

- できるだけ表やグラフの代わりに「数字+簡潔コメント」で示す  
- 変更履歴シートを参照して、これまでどのような施策が行われてきたか参照します
- 週次レポートとして迅速に理解できるよう、冗長な説明は避ける  
- 読み手はマーケター・広告運用担当者を想定。専門用語は適切に用いる  
- 事実に基づき、客観的かつ論理的に網羅的な分析を作成する  
- 考察シートの期間想定目標と結果の比較に重点を置き、必要に応じて過去週との比較によりトレンドを強調する
- 重要な数値や要因は**太字強調**

...(以下省略)

プロンプトの扱いに慣れていないメンバーにとっては特に、思い通りのフォーマットになるようプロンプトを調整することは負荷のかかる作業です。

今回開発したツールではこうした手間を省くため、既存のフォーマットを簡単に再現できるような仕組みを導入することで、こうした課題の解決を図りました。

ツールの説明

この度開発したツールは、

  1. フォーマットの抽出:Google Apps Script(以降、GAS)
  2. 考察文の作成:Cloud Run + Python(Flask, LangChain)

という2段階で構成されます。
まず、「1. フォーマットの抽出」で既存考察文からフォーマットを抽出します。これは、どのように考察を書けばよいかの「指示書」(プロンプト)になります。その「指示書」に基づいて「2. 考察文の作成」を行うことで、既存考察文のフォーマットを再現するという構成です。

format_extraction_image.png

以下で、新しいツールがどのようにフォーマットを再現するのかについて説明します。


1. フォーマットの抽出

フォーマット抽出アプリの画像
このツールの核です。生成AIが既存の考察文のフォーマットを抽出し、フォーマットの「指示書」として出力します。この「指示書」をもとにして、「2. 考察文の作成」側のAIがフォーマットに則った出力をできるようにします。

作成されたフォーマット「指示書」の例 (一部)
## 分析結果:レポート作成特性
### 1. レポート作成の特徴抽出
#### 数値記述パターン:

主要指標(配信金額、表示回数、Click数、CTR、CPC、PDP遷移数、購入、PDPR、PDP単価、CV数、CVR、CPA)について、「目標(提案時)」「目標(期間想定)」「結果」を並列に記載し、その下に「全体達成率」と「期間進捗」を算出している。
達成率は「結果 / 目標(提案時)」と「結果 / 目標(期間想定)」の2種類を算出し、パーセンテージ(%)またはポイント差(pts)、金額差(¥)で表現している。
日次および週次データは、各媒体シートで詳細な表形式で提供されている。
金額は「¥」記号を付与し、3桁ごとにカンマ区切り。表示回数、Click数もカンマ区切り。
CTR, CVR, PDPRは小数点以下2桁までのパーセンテージ(%)で表示。
CPC, PDP単価, CPAは小数点以下なしの金額で表示。

#### 要因分析手法:

目標達成/未達の主要な結果を「Highlight」と「Lowlight」として明確に提示している。
その結果に対する要因を、関連する媒体別の数値(目標、実績、達成率/ポイント差)を具体的に引用して説明している。
要因分析は、全体指標の変動を媒体別の貢献度や悪化要因に分解するトップダウンアプローチを採用している。
CV数については、先週のCV数と配信開始からの累積CV数を媒体別に詳細に記載し、CVRの推移も比較している。

...(以下省略)

次のような点についての分析するよう、既存の考察文とともにプロンプトを送信します。

  • 考察文の形式:考察文の特徴が現れそうな箇所について分析(例:数値の記述パターン、広告媒体別または全体の結果に注目するのか など)
  • 少数のレポート例:レポート例を併せて出力することで、few-shot的な精度向上が期待できる
プロンプト例
あなたは広告レポート分析の専門家です。提供された週次レポートを分析し、このレポート作成者(代理店・担当者)の特徴的な分析手法とレポーティングスタイルを抽出し、新たな分析者が同じようなスタイルのレポートを再現できるような指示書を作成することが目的です。

## 分析要求事項

**1. レポート作成の特徴抽出**
以下の観点から、このレポートに表れている作成者固有の特徴を分析してください。特徴分析文は各項目ごとに完結に、箇条書きでまとめること。:

- **数値記述パターン**: 目標・実績の記載方法、数字の記載場所等
- **要因分析手法**: 因果関係の捉え方、要因に含める内容
- **媒体・施策の扱い**: 媒体別の分析を行っているか、全体指標の考察に止まるか
- **評価・判断軸**: 達成基準、課題認識、重要度判定
- **文章構成・表現**: 記述の簡潔性、フォーマット

**2. レポートフォーマットの作成**
抽出された特徴をもとに、レポートの骨組みを作成してください。このフォーマットには分析内容を直接含める必要はありません。どのような構造で、どのような情報を記述するのかのみ記載してください。

**3. 特徴を表すレポート例の生成**
上記分析を基に、**同じ作成者が別の週に作成したと想定される架空のレポート例**を2つ生成してください。

**条件設定:**
- 同じ分析スタイル・記述パターンを維持
- 元レポートの特徴的要素を再現

## 出力形式
### 分析結果:レポート作成特性
[特徴の詳細分析]

### レポートフォーマット
[分析により得られたレポートの雛形]

### 同一作成者による架空レポート例
[生成されたレポート]

実装にはGASを使いました。
スプレッドシートに書かれている既存の考察を読み込んで、Vertex AIのGeminiにプロンプトと既存考察文を送信するようになっています。

gas_app_model.png

フォーマット抽出のGAS
// 考察文を取得する
dataSources.forEach(ds => {
    const dataRange = `シート名:${ds.spreadsheet_name}, シート名:${ds.sheet_name}\n`;
    spreadsheetData += dataRange;
    const cellData = getSheetData(ds.spreadsheet_id, ds.sheet_name, ds.spreadsheet_range);
    spreadsheetData += cellData.join('\n\n---\n');
});

// 考察文を付加したプロンプトを構成する
const prompt = `
${FORMAT_EXTRACTION_PROMPT}

${BACK_QUOTE}
${spreadsheetData}
${BACK_QUOTE}
`;
const token = getServiceAccountToken_();
const parts = [];
parts.push({
    text: prompt,
});
const requestBody = {
    contents: [
        {
            parts: parts,
            role: "user"
        }
    ]
};

// Vertex AI でフォーマットを分析
const response = UrlFetchApp.fetch(GEMINI_GENERATION_URL, {
    method: 'post',
    headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${token}`
    },
    payload: JSON.stringify(requestBody)
});
const responseBody = response.getContentText();
const data = JSON.parse(responseBody);
const responseText = data.candidates[0].content.parts[0].text;
// フォーマット抽出結果をBigQueryに保存
bqUpdateStyleExtractionResult(formatId, responseText);

2. 考察文の作成

ステップ1で作成されたフォーマットと広告運用成果のデータを入力して、既存のフォーマットに従った考察文の作成を行います。

アプリ画面 (デモ用に「総務省、消費者動向調査」[1]のデータを使用させていただきました)
  • 考察結果
    31911c3e2bc3573d32f6f9494e1f7895.png

  • 違和感のある箇所はチャットにより修正が可能
    8ed95f22b8949520e15a4635b615d7d4.png

実装にはPython(Flask + LangChain)を利用し、Cloud Runでデプロイしています。

考察アプリの実装の一部

Flaskアプリの主要なエンドポイントは次のようになっています。テンプレートのレンダリング(index)や、考察作成を担う ChatAppインスタンスの制御(send_prompt)を実装しました。


@app.route('/', methods=['GET', 'POST'])
def index():
    """
    テンプレートのレンダリングを担う
    """
    # チャット画面への遷移後
    if request.args.get('chat_id'):
        app.logger.info(f"Chat history length: {len(g.chat_app.get_chat_history()) if hasattr(g, 'chat_app') else 'N/A'}")
        return render_template(
            'index.html',
            chat_history=g.chat_app.get_chat_history() if hasattr(g, 'chat_app') else [],
            chat_started=True,
        )
    # 初回の分析のみ
    elif hasattr(g, 'chat_app') and request.method == 'POST':
        initial_prompt = session.get('initial_prompt', '')
        # 初回分析用プロンプトがあれば送信する
        if initial_prompt:
            g.chat_app.send_message(initial_prompt)
        return redirect(url_for('index', chat_id=g.chat_app.chat_id))

    else:
        return render_template(
            'index.html',
            chat_started=False
        )

@app.route('/chat/send', methods=['POST'])
def send_prompt():
    """
    プロンプトを送信し、考察を行う
    """
    data = request.get_json(silent=True)
    if data and isinstance(data, dict):
        user_prompt = (data.get('user_prompt') or '').strip()
    else:
        app.logger.info("Its not JSON")
        return jsonify({"status": "error", "result": "Invalid JSON"}), 400

    if not user_prompt:
        app.logger.warning("Empty user prompt received")
        return jsonify({"status": "error", "result": "Empty prompt"}), 400

    response = g.chat_app.send_message(user_message=user_prompt)

    result_text = ''
    try:
        result_text = response.get('result', '') if isinstance(response, dict) else str(response)
    except Exception:
        result_text = str(response)

    return jsonify({"status": "ok", "result": result_text})

作成されたフォーマットはさまざまな案件に流用することができます。今までは、自分でフォーマットを言語化しプロンプトを作る必要がありましたが、そうした負荷の軽減を見込んでいます。

まとめ

本記事では、フォーマットに則った考察作成の自動化ができるツールの紹介を行いました。プロンプト作成という手間を省くことにより、より多くのメンバーにツールを活用してもらえたらと考えています!

ここまでご覧いただきありがとうございました!

参考文献

  1. 総務省、「消費動向調査 令和7年」、https://www.e-stat.go.jp/stat-search/files?page=1&layout=datalist&toukei=00100405&tstat=000001014549&cycle=0&tclass1=000001225301&tclass2=000001228165&stat_infid=000040269929&tclass3val=0 (最終アクセス2026-01-23)
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?