3
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?

Databricks × MLflow 3で挑む金融データ活用チャレンジ - 提案書自動生成パイプラインの全貌

3
Posted at

はじめに

金融データ活用推進協会(FDUA)と金融庁が共催するSIGNATEの「金融データ活用チャレンジ」は、金融業界のAI・データ活用人材の育成・発掘を目的としたデータ分析コンペティションです。過去には住宅ローン延滞予測やRAG精度を競うタスクが出題されており、回を重ねるごとにテーマが従来型MLから生成AIへとシフトしています。

本記事では、このコンペティションに取り組む中で構築した金融機関向け提案書自動生成パイプラインについて、Databricks上での実装アプローチと活用した機能を解説します。ノートブックはGitHubに公開していますので、ぜひ手を動かしながら読んでみてください。

リポジトリ:

コンペティションの位置付け

金融データ活用チャレンジは、SIGNATEプラットフォーム上で開催される業界横断型のコンペティションです。

項目 内容
主催 金融庁、金融データ活用推進協会(FDUA)
プラットフォーム SIGNATE
目的 金融業界のAI・データ活用人材の育成・発掘
特徴 金融機関の実務課題に即したテーマ設定

第1回は住宅ローン延滞予測(2023年)、第3回はRAG精度を競うタスク(2025年1月)と、回を追うごとに生成AI色が強まっています。今回のテーマは企業データを読み解き、金融機関の営業担当者が使える提案書を生成AI で自動生成するというもので、単なるテキスト生成にとどまらず、財務分析・証券分析・地域経済分析を踏まえた構造化された提案ドキュメントの品質が問われます。

全体アーキテクチャ

本パイプラインは、企業データの読み込みから最終的なWord形式の提案書出力まで、以下のステップで構成されています。

企業データ(テーブル)
    │
    ▼
[1] データ取得・前処理
    │
    ▼
[2] 財務分析(Financial Analysis)
    │  └─ LLMによる財務指標の解釈・課題抽出
    ▼
[3] 証券分析(Securities Analysis)
    │  └─ 有価証券情報に基づく投資提案
    ▼
[4] 地域経済分析(Regional Analysis)
    │  └─ 地域特性を踏まえたビジネス環境評価
    ▼
[5] 提案書生成(Proposal Generation)
    │  └─ 上記3分析を統合した提案書テキスト作成
    ▼
[6] Word文書出力(.docx)
    │  └─ Markdownからフォーマット済みWord文書への変換
    ▼
[7] 評価(Evaluation)
       └─ LLM Judgeによる品質スコアリング

各ステップでMLflow 3のトレーシングが自動的に記録され、パイプライン全体の実行を後から詳細に追跡できます。

Screenshot 2026-02-07 at 8.54.34.png

Databricksの活用機能

このプロジェクトでは、Databricksの複数の機能を組み合わせて活用しました。それぞれの役割と実装のポイントを紹介します。

Foundation Model API

提案書の各分析ステップではLLMを呼び出しますが、DatabricksのFoundation Model API(FMAPI)を使うことで、データをDatabricks環境の外に出すことなくLLMを利用できます。金融データを扱うコンペにおいて、このデータガバナンスの担保は大きなメリットです。

from openai import OpenAI

client = OpenAI(
    api_key=dbutils.notebook.entry_point.getDbutils()
        .notebook().getContext().apiToken().get(),
    base_url=f"{spark.conf.get('spark.databricks.workspaceUrl')}"
             f"/serving-endpoints"
)

response = client.chat.completions.create(
    model="databricks-claude-sonnet-4",
    messages=[
        {"role": "system", "content": system_prompt},
        {"role": "user", "content": user_prompt}
    ],
    temperature=0.7,
    max_tokens=4000
)

OpenAI互換のSDKをそのまま使えるため、既存のコードからの移行も容易です。

Screenshot 2026-02-07 at 8.55.06.png

MLflow 3 Prompt Registry

5種類のプロンプトテンプレート(システム、財務分析、証券分析、地域分析、提案書生成)をMLflow Prompt Registryに登録してバージョン管理しています。

import mlflow

# プロンプトの登録
pv = mlflow.genai.register_prompt(
    name="signate_financial_analysis",
    template=FINANCIAL_ANALYSIS_TEMPLATE
)

# プロンプトのロード(バージョン指定も可能)
prompt = mlflow.genai.load_prompt(name="signate_financial_analysis")
rendered = prompt.format(
    company_name=company_name,
    financial_data=financial_summary
)

プロンプトの改善を繰り返す中で、どのバージョンのプロンプトがどの結果に紐づくかを追跡できる点が非常に有用でした。Prompt Registryを使うことで、プロンプトの変更履歴がMLflowのUI上で可視化され、チームでのプロンプト管理にも役立ちます。

Screenshot 2026-02-07 at 8.56.07.png
Screenshot 2026-02-07 at 8.56.23.png

MLflow Tracing

パイプラインの各ステップに@mlflow.traceデコレータを付与することで、実行の階層構造をMLflow UIで可視化できます。

@mlflow.trace(name="financial_analysis", span_type="CHAIN")
def run_financial_analysis(financial_pv, metrics, code, system_prompt_text, model):
    financial_prompt = financial_pv.format(...)
    return call_llm(financial_prompt, system_prompt=system_prompt_text, model=model)

@mlflow.trace(name="proposal_pipeline", span_type="CHAIN")
def generate_proposal_for_company(code, metrics, report_text, model):
    # 各分析関数を順に呼び出す
    financial = run_financial_analysis(...)
    securities = run_securities_analysis(...)
    regional = run_regional_analysis(...)
    proposal = run_proposal_generation(...)
    return results

proposal_pipelineがroot spanとなり、その下に各分析ステップが子spanとして記録されます。MLflow UIからトレースを開くと、各ステップのプロンプトと応答をそのまま確認できるため、生成品質のデバッグが格段に効率化されました。

提案書の品質が低い場合に「どの分析ステップの入力が不十分だったか」をトレースから遡って特定できるのは、多段パイプラインならではの恩恵です。

Screenshot 2026-02-07 at 9.11.22.png
Screenshot 2026-02-07 at 9.11.36.png

Evaluation & Scorers

生成された提案書の品質を自動評価するため、MLflow 3のScorer機能を活用しました。

from mlflow.genai.scorers import LLMJudge

# 提案書の品質を評価するカスタムスコアラー
proposal_quality_scorer = LLMJudge(
    name="proposal_quality",
    judge_prompt="以下の金融機関向け提案書を評価してください。"
                 "具体性、論理的整合性、実用性の観点から"
                 "1-5のスケールでスコアをつけてください。...",
    score_type=int
)

# 評価の実行
eval_results = mlflow.genai.evaluate(
    data=eval_dataset,
    scorers=[proposal_quality_scorer]
)

LLM-as-a-Judgeパターンにより、人手評価のコストをかけずに提案書の品質を定量化できます。プロンプト改善のイテレーションにおいて、変更の前後でスコアがどう変化したかを即座に確認できる点が重要でした。

Screenshot 2026-02-07 at 9.14.23.png

Word文書(docx)出力

コンペの提出物として、生成されたMarkdownテキストをフォーマット済みのWord文書に変換する処理も実装しました。python-docxを使い、見出し、テーブル、太字・斜体などのMarkdown記法を適切にWordスタイルにマッピングしています。

特にMarkdownテーブル(| cell | cell |形式)をWordの本物のテーブルオブジェクトに変換する処理は、出力品質に直結する部分でした。

Screenshot 2026-02-07 at 9.15.11.png
Screenshot 2026-02-07 at 9.15.00.png

実装のポイントと学び

プロンプト設計の重要性

金融機関向け提案書は、単に情報を羅列するだけでは不十分です。財務指標の解釈、証券市場の動向分析、地域経済の特性評価をそれぞれ専門的な観点で行い、それらを統合した提案ストーリーを構築する必要があります。

プロンプトを「分析」と「生成」の2段階に分離し、各分析ステップの出力を次のステップの入力として渡すチェーン構造にしたことで、最終的な提案書の品質が大きく向上しました。

評価の自動化

コンペにおけるイテレーション速度を上げるためには、生成結果の品質を素早くフィードバックする仕組みが不可欠です。MLflow 3のScorerとEvaluation機能により、プロンプト変更→生成→評価のサイクルを1つのノートブック内で完結させることができました。

活用したDatabricks機能まとめ

機能 用途 メリット
Foundation Model API LLM呼び出し データガバナンス確保、OpenAI互換SDK
MLflow Prompt Registry プロンプトのバージョン管理 変更履歴の追跡、チーム共有
MLflow Tracing パイプライン実行の可視化 多段パイプラインのデバッグ効率化
Scorers / Evaluation 生成品質の自動評価 LLM-as-a-Judgeによる定量化
MLflow Experiment Tracking 実験管理 パラメータ・メトリクスの記録と比較

おわりに

金融データ活用チャレンジのような生成AIコンペティションでは、モデルのファインチューニングよりもプロンプト設計と評価のイテレーション速度が勝負を分けます。Databricks上でMLflow 3の機能群を活用することで、プロンプト管理→トレーシング→評価という一連のLLMOpsサイクルを効率的に回すことができました。

ノートブックはGitHubに公開していますので、金融データ活用チャレンジへの参加を検討している方、あるいはDatabricks上での生成AIパイプライン構築に興味のある方は、ぜひ参考にしてください。

参考リンク

はじめてのDatabricks

はじめてのDatabricks

Databricks無料トライアル

Databricks無料トライアル

3
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
3
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?