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?

Databricksにおける生成AIアプリケーションとプロンプトのバージョン管理

Last updated at Posted at 2025-10-02

引き続き、MLfow 3を勉強中です。

これらの続きと言えます。

LoggedModelがわかってくると理解が捗ります。今度はこちら。

このガイドでは、プロンプトとアプリケーションの両方のバージョンを一緒に追跡しながら、MLflow プロンプト レジストリのプロンプトを 生成AI アプリケーションに統合する方法について説明します。レジストリからのプロンプトで mlflow.set_active_model() を使用すると、MLflowはプロンプトバージョンとアプリケーションバージョンの間にリネージを自動的に作成します。

サンプルノートブックを動かしていきます。

プロンプトバージョンとアプリケーションのバージョンを同時に追跡する

このノートブックでは、MLflowプロンプトレジストリからプロンプトを生成AIアプリケーションに統合し、プロンプトとアプリケーションのバージョンを一緒に追跡する方法を紹介します。mlflow.set_active_model()をプロンプトと組み合わせて使うことで、MLflowはプロンプトバージョンとアプリケーションバージョンの間に自動的にリネージを作成します。

このノートブックで学べること:

  • MLflowプロンプトレジストリからプロンプトを読み込み、アプリケーションで利用する方法
  • LoggedModelsを使ったアプリケーションバージョンの管理
  • プロンプトバージョンとアプリケーションバージョンの自動的なリネージの確認
  • プロンプトを更新し、その変更がアプリケーションにどのように反映されるかの追跡

必要なパッケージのインストール

%pip install --upgrade "mlflow[databricks]>=3.1.0" openai
# Python環境を再起動します
# (パッケージのインストール後は再起動が必要です)
dbutils.library.restartPython()

ステップ1. プロンプトの作成

事前に以下で指定するカタログとスキーマを作成しておきます。

import mlflow

# CREATE FUNCTION、EXECUTE、MANAGE権限を持つUnity Catalogスキーマ名に置き換えてください
uc_schema = "takaakiyayoi_catalog.prompts"
prompt_name = "customer_support_prompt"

# 変数付きのプロンプトテンプレートを定義
initial_template = """\
あなたは{{company_name}}の親切なカスタマーサポート担当者です。

お客様からのご質問内容: {{topic}}

お客様の質問: {{question}}

お客様の懸念に丁寧かつプロフェッショナルに対応してください。
"""

# 新しいプロンプトを登録
prompt = mlflow.genai.register_prompt(
    name=f"{uc_schema}.{prompt_name}",
    template=initial_template,
    commit_message="初期カスタマーサポートプロンプト",
    tags={
        "author": "support-team@company.com",
        "use_case": "customer_service",
        "department": "customer_support",
        "language": "ja"
    }
)

print(f"プロンプト '{prompt.name}'(バージョン {prompt.version})を作成しました")
プロンプト 'takaakiyayoi_catalog.prompts.customer_support_prompt'(バージョン 1)を作成しました

上を実行したら、右側のフラスコアイコンをクリックしてMLflowエクスペリメントを表示、赤枠のアイコンをクリックしてエクスペリメントページに移動します。
Screenshot 2025-10-02 at 14.07.05.png

プロンプトタブをクリックします。何も表示されていないと思いますが、右上のスキーマを選択をクリックして、上で指定したスキーマを指定します。すると、記録されたプロンプトにアクセスできるようになります。
Screenshot 2025-10-02 at 14.08.44.png

Screenshot 2025-10-02 at 13.42.11.png
Screenshot 2025-10-02 at 13.42.18.png

ステップ2. プロンプトを利用したバージョン管理付きアプリケーションの作成

このステップでは、レジストリからプロンプトを読み込んで利用する生成AIアプリケーションを作成します。mlflow.set_active_model()を使うことでアプリケーションのバージョンを追跡できます。

mlflow.set_active_model()を呼び出すと、MLflowはこのアプリケーションバージョンを表すLoggedModelを作成します。LoggedModelは実際のアプリケーションコードを保存するのではなく、外部コード(Gitコミットなど)や設定パラメータへのリンク、そしてアプリケーションが利用したプロンプトのバージョンを自動的に記録します。アプリケーションバージョン管理の詳細はドキュメントをご覧ください: (AWS)。

import subprocess
from openai import OpenAI

# MLflowの自動ロギングを有効化(トレース取得)
mlflow.openai.autolog()

# MLflowと同じ認証情報でDatabricks LLMにOpenAI経由で接続
# 独自のOpenAI認証情報も利用可能
mlflow_creds = mlflow.utils.databricks_utils.get_databricks_host_creds()
client = OpenAI(
    api_key=mlflow_creds.token,
    base_url=f"{mlflow_creds.host}/serving-endpoints"
)

# アプリケーション名とバージョン識別子を定義
app_name = "customer_support_agent"

# Gitコミットハッシュでバージョン管理
try:
    git_commit = (
        subprocess.check_output(["git", "rev-parse", "HEAD"])
        .decode("ascii")
        .strip()[:8]
    )
    version_identifier = f"git-{git_commit}"
except subprocess.CalledProcessError:
    version_identifier = "local-dev"  # Gitリポジトリ外の場合のフォールバック
logged_model_name = f"{app_name}-{version_identifier}"

# アクティブモデルの設定(このアプリバージョンを表すLoggedModelを作成)
active_model_info = mlflow.set_active_model(name=logged_model_name)
print(
    f"アクティブなLoggedModel: '{active_model_info.name}', モデルID: '{active_model_info.model_id}'"
)

# アプリケーションのパラメータを記録
app_params = {
    "llm": "databricks-claude-sonnet-4-5",
    "temperature": 0.7,
    "max_tokens": 500
}
mlflow.log_model_params(model_id=active_model_info.model_id, params=app_params)

# レジストリからプロンプトを読み込む
# ※ set_active_model()の後でプロンプトを読み込むことで、
# プロンプトバージョンとLoggedModelの自動的な系譜が記録されます
prompt = mlflow.genai.load_prompt(f"prompts:/{uc_schema}.{prompt_name}/1")
print(f"プロンプトバージョン {prompt.version} を読み込みました")

# アプリケーションのエントリポイントをトレースで記録
# この関数で作成される各トレースは、上記で設定したLoggedModel(アプリバージョン)に自動的に紐づきます。
# さらに、LoggedModelはレジストリから読み込んだプロンプトバージョンにも紐づきます。
@mlflow.trace
def customer_support_app(company_name: str, topic: str, question: str):
    # 変数でプロンプトを整形
    formatted_prompt = prompt.format(
        company_name=company_name,
        topic=topic,
        question=question
    )

    # LLMを呼び出し
    response = client.chat.completions.create(
        model="databricks-claude-sonnet-4-5",  # ご利用のモデル名に置き換えてください
        messages=[
            {
                "role": "user",
                "content": formatted_prompt,
            },
        ],
        temperature=0.7,
        max_tokens=500
    )
    return response.choices[0].message.content

# アプリケーションのテスト
result = customer_support_app(
    company_name="TechCorp",
    topic="請求",
    question="先月サブスクリプション料金が二重請求されました。対応してもらえますか?"
)
print(f"\n回答: {result}")
fatal: not a git repository (or any parent up to mount point /)
Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set).
2025/10/02 04:50:07 INFO mlflow.tracking.fluent: Active model is set to the logged model with ID: m-878c1fecd98f4d0e9d2b58c595bf48c2
アクティブなLoggedModel: 'customer_support_agent-local-dev', モデルID: 'm-878c1fecd98f4d0e9d2b58c595bf48c2'
プロンプトバージョン 1 を読み込みました

回答: お問い合わせいただき、ありがとうございます。TechCorpカスタマーサポートの者でございます。

サブスクリプション料金の二重請求につきまして、ご不便とご心配をおかけしており、大変申し訳ございません。この件、早急に確認させていただきます。

**今後の対応について**

1. **ご請求内容の確認**
   - お客様のアカウント情報と先月のご請求履歴を詳しく調査いたします
   - 二重請求が確認できましたら、速やかに返金手続きを進めさせていただきます

2. **必要な情報**
   お手数ですが、以下の情報をご提供いただけますでしょうか:
   - ご登録のメールアドレスまたはアカウントID
   - 請求された日付(2回分)
   - 請求金額

3. **返金までの流れ**
   - 通常、確認後3〜5営業日以内に返金処理を完了いたします
   - 処理完了後、メールにてご連絡させていただきます

このような事態が発生しましたこと、重ねてお詫び申し上げます。お客様に安心してご利用いただけるよう、迅速に対応させていただきます。

ご不明な点やご心配な点がございましたら、いつでもお気軽にお問い合わせください。

どうぞよろしくお願いいたします。

Screenshot 2025-10-02 at 14.11.16.png

これでLoggedModelが作成されます。エクスペリメントのバージョンタブで確認できます。
Screenshot 2025-10-02 at 13.45.27.png

LoggedModelページにアクセスして、プロンプトを参照するとバージョン1が確認できます。
Screenshot 2025-10-02 at 13.45.37.png

ステップ3. プロンプトの更新と変更履歴の追跡

# 改良版プロンプトを作成
improved_template = """\
あなたは{{company_name}}の親切で共感力のあるカスタマーサポート担当者です。

お客様のトピック: {{topic}}
お客様の質問: {{question}}

以下の点に注意して回答してください:
1. お客様の懸念に共感を示す
2. 明確な解決策や次のステップを提示する
3. 必要に応じて追加サポートを提案する
4. 親切かつプロフェッショナルな口調を保つ

注意事項:
- お客様の名前があれば必ず使う
- 簡潔かつ丁寧に回答する
- 不要な専門用語は避ける
"""

# 新バージョンを登録
updated_prompt = mlflow.genai.register_prompt(
    name=f"{uc_schema}.{prompt_name}",
    template=improved_template,
    commit_message="共感ガイドラインと回答構成を追加し、顧客体験を向上",
    tags={
        "author": "support-team@company.com",
        "improvement": "共感ガイドラインと回答構成を追加"
    }
)

print(f"'{updated_prompt.name}' のバージョン {updated_prompt.version} を作成しました")
'takaakiyayoi_catalog.prompts.customer_support_prompt' のバージョン 2 を作成しました

プロンプトレジストリではバージョン2のプロンプトが確認できます。
Screenshot 2025-10-02 at 13.46.20.png

ステップ4. 更新したプロンプトをアプリケーションで利用

このステップでは新しいプロンプトバージョンを利用し、アプリケーションの新バージョンを作成して変更を追跡します。プロンプトバージョンはMLflowの実験ページの「バージョン」タブで確認できます。詳細はドキュメントをご覧ください: (AWS)。

# 新しいアプリケーションバージョンを作成
new_version_identifier = "v2-improved-prompt"
new_logged_model_name = f"{app_name}-{new_version_identifier}"

# 新しいアクティブモデルを設定
active_model_info_v2 = mlflow.set_active_model(name=new_logged_model_name)
print(
    f"アクティブなLoggedModel: '{active_model_info_v2.name}', モデルID: '{active_model_info_v2.model_id}'"
)

# 更新したパラメータを記録
app_params_v2 = {
    "llm": "databricks-claude-sonnet-4-5",
    "temperature": 0.7,
    "max_tokens": 500,
    "prompt_version": "2"  # 利用するプロンプトバージョンを記録
}
mlflow.log_model_params(model_id=active_model_info_v2.model_id, params=app_params_v2)

# 新しいプロンプトバージョンを読み込む
prompt_v2 = mlflow.genai.load_prompt(f"prompts:/{uc_schema}.{prompt_name}/2")

# 新しいプロンプトを使うようアプリを更新
@mlflow.trace
def customer_support_app_v2(company_name: str, topic: str, question: str):
    # 変数でプロンプトを整形
    formatted_prompt = prompt_v2.format(
        company_name=company_name,
        topic=topic,
        question=question
    )

    # LLMを呼び出し
    response = client.chat.completions.create(
        model="databricks-claude-sonnet-4-5",
        messages=[
            {
                "role": "user",
                "content": formatted_prompt,
            },
        ],
        temperature=0.7,
        max_tokens=500
    )
    return response.choices[0].message.content

# 同じ質問で違いを確認
result_v2 = customer_support_app_v2(
    company_name="TechCorp",
    topic="請求",
    question="先月サブスクリプション料金が二重請求されました。対応してもらえますか?"
)
print(f"\n改良版の回答: {result_v2}")
2025/10/02 04:47:45 INFO mlflow.tracking.fluent: LoggedModel with name 'customer_support_agent-v2-improved-prompt' does not exist, creating one...
2025/10/02 04:47:47 INFO mlflow.tracking.fluent: Active model is set to the logged model with ID: m-5bafa3c866eb4b0ba92ddb9753d57d66
アクティブなLoggedModel: 'customer_support_agent-v2-improved-prompt', モデルID: 'm-5bafa3c866eb4b0ba92ddb9753d57d66'

改良版の回答: お問い合わせいただき、ありがとうございます。

二重請求が発生してしまったとのこと、大変ご不便とご心配をおかけして申し訳ございません。すぐに対応させていただきます。

**次のステップ:**

1. **確認作業**:お客様のアカウントを確認し、二重請求の詳細を調査いたします
2. **返金処理**:誤請求が確認でき次第、速やかに返金手続きを開始いたします(通常3〜5営業日でご指定の口座に返金されます)
3. **再発防止**:今後このようなことが起こらないよう、アカウント設定も確認いたします

**お手続きに必要な情報:**
- ご登録のメールアドレス
- 請求日または請求金額
- 可能であれば、請求明細のスクリーンショット

上記の情報をご提供いただけましたら、すぐに調査を開始いたします。

ご不明な点やその他ご心配なことがございましたら、いつでもお気軽にお問い合わせください。お客様のご満足が私たちの最優先事項です。

どうぞよろしくお願いいたします。

TechCorpカスタマーサポート

new_logged_model_nameを変更しているので別のLoggedModelが作成されます。
Screenshot 2025-10-02 at 13.49.42.png

はじめは上を見て「なんで今登録されたLoggedModelだけprompt_versionが?」と思ったら、app_params_v2prompt_versionを指定していただけでした。上のセルでもパラメータにプロンプトバージョンを指定すれば、一覧に表示されるようになります。
Screenshot 2025-10-02 at 13.50.34.png

これで、LoggedModelをメタデータハブとして生成AIアプリケーションとプロンプトが管理されるということがわかってきました。ここにさらに評価が絡んでくるということですね。

あと、プロンプトレジストリでバージョン間の比較ができることに今気づきました。
Screenshot 2025-10-02 at 14.53.39.png

はじめてのDatabricks

はじめてのDatabricks

Databricks無料トライアル

Databricks無料トライアル

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?