メインコンテンツまでスキップ

アプリケーションの評価と改善

このガイドでは、 評価データセット を使用して品質を評価し、問題を特定し、アプリを繰り返し改善する方法を示します。

このガイドでは、デプロイされたアプリの トレース を使用して評価データセットを作成しますが、評価データセットの作成方法に関係なく、この同じワークフローが適用されます。評価データセットを作成するその他の方法については、 評価データセットの作成ガイドを参照してください。

このガイドでは、次の手順について説明します。

  • 実際の使用状況から 評価データセット を作成します。
  • 評価ハーネスを使用して、MLflow の事前定義されたスコアラー で品質を評価します。
  • 結果を解釈して、品質の問題を特定します。
  • 評価結果に基づいてアプリを改善します。
  • バージョンを比較して、改善が機能し、回帰を引き起こさなかったことを確認します。

前提 条件

  1. MLflow と必要なパッケージをインストールする

    Bash
    pip install --upgrade "mlflow[databricks]>=3.1.0" openai
  2. MLflow エクスペリメントを作成するには、環境のセットアップに関するクイックスタートに従ってください。

  3. 評価データセットを作成するには、Unity Catalog のスキーマへのアクセス権と、そのスキーマに対する CREATE TABLE アクセス許可が必要です。

注記

Databricks 試用版アカウントを使用している場合は、Unity Catalog スキーマ workspace.defaultに対する CREATE TABLE 権限があります。

オプション: 並列化の構成

複雑なエージェントの実行には時間がかかる場合があります。MLflow by デフォルト バックグラウンド スレッドプールを使用して評価プロセスを高速化します。 使用するワーカーの数は、環境変数 MLFLOW_GENAI_EVAL_MAX_WORKERSを設定することで構成できます。

Bash
export MLFLOW_GENAI_EVAL_MAX_WORKERS=10

ステップ 1: アプリケーションを作成する

このガイドでは、次のことを行う Eメール 生成アプリの評価手順を説明します。

  1. データベースから顧客情報を取得します。
  2. 取得した情報に基づいてパーソナライズされたフォローアップEメールを生成します。

この手順では、Eメール生成アプリを作成します。 取得コンポーネントは、MLflow の取得固有のスコアラーを有効にするために span_type="RETRIEVER" でマークされています。

  1. OpenAI クライアントを初期化して、Databricks でホストされている LLM または OpenAI でホストされている LLM に接続します。

MLflow を使用して、Databricks でホストされている LLM に接続する OpenAI クライアントを取得します。利用可能な基盤モデルからモデルを選択します。

Python
import mlflow
from databricks.sdk import WorkspaceClient

# Enable MLflow's autologging to instrument your application with Tracing
mlflow.openai.autolog()

# Set up MLflow tracking to Databricks
mlflow.set_tracking_uri("databricks")
mlflow.set_experiment("/Shared/docs-demo")

# Create an OpenAI client that is connected to Databricks-hosted LLMs
w = WorkspaceClient()
client = w.serving_endpoints.get_open_ai_client()

# Select an LLM
model_name = "databricks-claude-sonnet-4"
  1. Eメール生成アプリを作成します。

    Python
    from mlflow.entities import Document
    from typing import List, Dict

    # Simulated customer relationship management database
    CRM_DATA = {
    "Acme Corp": {
    "contact_name": "Alice Chen",
    "recent_meeting": "Product demo on Monday, very interested in enterprise features. They asked about: advanced analytics, real-time dashboards, API integrations, custom reporting, multi-user support, SSO authentication, data export capabilities, and pricing for 500+ users",
    "support_tickets": ["Ticket #123: API latency issue (resolved last week)", "Ticket #124: Feature request for bulk import", "Ticket #125: Question about GDPR compliance"],
    "account_manager": "Sarah Johnson"
    },
    "TechStart": {
    "contact_name": "Bob Martinez",
    "recent_meeting": "Initial sales call last Thursday, requested pricing",
    "support_tickets": ["Ticket #456: Login issues (open - critical)", "Ticket #457: Performance degradation reported", "Ticket #458: Integration failing with their CRM"],
    "account_manager": "Mike Thompson"
    },
    "Global Retail": {
    "contact_name": "Carol Wang",
    "recent_meeting": "Quarterly review yesterday, happy with platform performance",
    "support_tickets": [],
    "account_manager": "Sarah Johnson"
    }
    }

    # Use a retriever span to enable MLflow's predefined RetrievalGroundedness scorer to work
    @mlflow.trace(span_type="RETRIEVER")
    def retrieve_customer_info(customer_name: str) -> List[Document]:
    """Retrieve customer information from CRM database"""
    if customer_name in CRM_DATA:
    data = CRM_DATA[customer_name]
    return [
    Document(
    id=f"{customer_name}_meeting",
    page_content=f"Recent meeting: {data['recent_meeting']}",
    metadata={"type": "meeting_notes"}
    ),
    Document(
    id=f"{customer_name}_tickets",
    page_content=f"Support tickets: {', '.join(data['support_tickets']) if data['support_tickets'] else 'No open tickets'}",
    metadata={"type": "support_status"}
    ),
    Document(
    id=f"{customer_name}_contact",
    page_content=f"Contact: {data['contact_name']}, Account Manager: {data['account_manager']}",
    metadata={"type": "contact_info"}
    )
    ]
    return []

    @mlflow.trace
    def generate_sales_email(customer_name: str, user_instructions: str) -> Dict[str, str]:
    """Generate personalized sales email based on customer data & a sale's rep's instructions."""
    # Retrieve customer information
    customer_docs = retrieve_customer_info(customer_name)

    # Combine retrieved context
    context = "\n".join([doc.page_content for doc in customer_docs])

    # Generate email using retrieved context
    prompt = f"""You are a sales representative. Based on the customer information below,
    write a brief follow-up email that addresses their request.

    Customer Information:
    {context}

    User instructions: {user_instructions}

    Keep the email concise and personalized."""

    response = client.chat.completions.create(
    model=model_name, # This example uses a Databricks hosted LLM - you can replace this with any AI Gateway or Model Serving endpoint. If you provide your own OpenAI credentials, replace with a valid OpenAI model e.g., gpt-4o, etc.
    messages=[
    {"role": "system", "content": "You are a helpful sales assistant."},
    {"role": "user", "content": prompt}
    ],
    max_tokens=2000
    )

    return {"email": response.choices[0].message.content}

    # Test the application
    result = generate_sales_email("Acme Corp", "Follow up after product demo")
    print(result["email"])

評価アプリ トレース

ステップ 2: 本番運用のトラフィックをシミュレートする

この手順では、デモンストレーションの目的でトラフィックをシミュレートします。実際には、実際の使用状況のトレース トレース を使用して評価データセットを作成します。

Python
# Simulate beta testing traffic with scenarios designed to fail guidelines
test_requests = [
{"customer_name": "Acme Corp", "user_instructions": "Follow up after product demo"},
{"customer_name": "TechStart", "user_instructions": "Check on support ticket status"},
{"customer_name": "Global Retail", "user_instructions": "Send quarterly review summary"},
{"customer_name": "Acme Corp", "user_instructions": "Write a very detailed email explaining all our product features, pricing tiers, implementation timeline, and support options"},
{"customer_name": "TechStart", "user_instructions": "Send an enthusiastic thank you for their business!"},
{"customer_name": "Global Retail", "user_instructions": "Send a follow-up email"},
{"customer_name": "Acme Corp", "user_instructions": "Just check in to see how things are going"},
]

# Run requests and capture traces
print("Simulating production traffic...")
for req in test_requests:
try:
result = generate_sales_email(**req)
print(f"✓ Generated email for {req['customer_name']}")
except Exception as e:
print(f"✗ Error for {req['customer_name']}: {e}")

ステップ 3: 評価データセットを作成する

次に、トレースを評価データセットに変換します。評価データセットにトレースを格納すると、評価結果をデータセットにリンクして、データセットの経時的な変更を追跡し、このデータセットを使用して生成されたすべての評価結果を確認できます。

以下の録画に従って、UIを使用して次のことを行います。

  1. 評価データセットを作成します。
  2. ステップ 2 でシミュレートした本番運用トレースをデータセットに追加します。

評価データセットの作成とトレースの追加

ステップ4:事前定義されたスコアラーで評価を実行する

次に、MLflow に用意されている 定義済みのスコアラー を使用して、GenAI アプリケーションの品質のさまざまな側面を自動的に評価します。詳細については、LLM ベースのスコアラーおよび コードベースのスコアラーを参照してください。

注記

必要に応じて、MLflow を使用してアプリケーションとプロンプトのバージョンを追跡できます。アプリとプロンプトのバージョンを追跡するを参照してください。

Python
from mlflow.genai.scorers import (
RetrievalGroundedness,
RelevanceToQuery,
Safety,
Guidelines,
)

# Save the scorers as a variable so we can re-use them in step 7

email_scorers = [
RetrievalGroundedness(), # Checks if email content is grounded in retrieved data
Guidelines(
name="follows_instructions",
guidelines="The generated email must follow the user_instructions in the request.",
),
Guidelines(
name="concise_communication",
guidelines="The email MUST be concise and to the point. The email should communicate the key message efficiently without being overly brief or losing important context.",
),
Guidelines(
name="mentions_contact_name",
guidelines="The email MUST explicitly mention the customer contact's first name (e.g., Alice, Bob, Carol) in the greeting. Generic greetings like 'Hello' or 'Dear Customer' are not acceptable.",
),
Guidelines(
name="professional_tone",
guidelines="The email must be in a professional tone.",
),
Guidelines(
name="includes_next_steps",
guidelines="The email MUST end with a specific, actionable next step that includes a concrete timeline.",
),
RelevanceToQuery(), # Checks if email addresses the user's request
Safety(), # Checks for harmful or inappropriate content
]

# Run evaluation with predefined scorers
eval_results = mlflow.genai.evaluate(
data=eval_dataset,
predict_fn=generate_sales_email,
scorers=email_scorers,
)

ステップ 5: 結果の表示と解釈

mlflow.genai.evaluate()を実行すると、評価データセット内のすべての行のトレースと、各スコアラーからのフィードバックが関連付けられた評価実行が作成されます。

評価ランを使用して、次のことを行います。

  • 集計メトリクスの参照 : 各スコアラーのすべてのテストケースの平均パフォーマンス。
  • 個々の障害ケースをデバッグ する: 障害が発生した理由を理解して、将来のバージョンで行うべき改善点を特定します。
  • 障害分析 : スコアラーが問題を特定した具体的な例。

この評価では、いくつかの問題が見られます。

  1. 不適切な指示フォロー - エージェントは、簡単なチェックインを求められたときに詳細な製品情報を送信したり、熱心なお礼のメッセージを求められたときにサポートチケットの更新を提供したりするなど、ユーザーの要求と一致しない応答を頻繁に提供します。
  2. 簡潔さの欠如 - ほとんどのEメールは不必要に長く、重要なメッセージを薄めるほどの詳細が多すぎて、Eメールを「簡潔でパーソナライズ」に保つように指示されているにもかかわらず、効率的にコミュニケーションをとることができません。
  3. 具体的な次のステップが欠けている - Eメールの大部分は、必須要素として特定された具体的なタイムラインを含む、具体的で実行可能な次のステップで終わらない。

MLflow UI の [評価] タブから評価結果にアクセスし、アプリケーションのパフォーマンスを理解します。

評価結果

ステップ 6: 改良版を作成する

評価結果に基づいて、特定された問題に対処する改善バージョンを作成できます。

注記

新しいバージョンの generate_sales_email() 関数では、最初のステップから retrieve_customer_info() 取得した関数を使用します。

Python
@mlflow.trace
def generate_sales_email_v2(customer_name: str, user_instructions: str) -> Dict[str, str]:
"""Generate personalized sales email based on customer data & a sale's rep's instructions."""
# Retrieve customer information
customer_docs = retrieve_customer_info(customer_name)

if not customer_docs:
return {"error": f"No customer data found for {customer_name}"}

# Combine retrieved context
context = "\n".join([doc.page_content for doc in customer_docs])

# Generate email using retrieved context with better instruction following
prompt = f"""You are a sales representative writing an email.

MOST IMPORTANT: Follow these specific user instructions exactly:
{user_instructions}

Customer context (only use what's relevant to the instructions):
{context}

Guidelines:
1. PRIORITIZE the user instructions above all else
2. Keep the email CONCISE - only include information directly relevant to the user's request
3. End with a specific, actionable next step that includes a concrete timeline (e.g., "I'll follow up with pricing by Friday" or "Let's schedule a 15-minute call this week")
4. Only reference customer information if it's directly relevant to the user's instructions

Write a brief, focused email that satisfies the user's exact request."""

response = client.chat.completions.create(
model="databricks-claude-3-7-sonnet",
messages=[
{"role": "system", "content": "You are a helpful sales assistant who writes concise, instruction-focused emails."},
{"role": "user", "content": prompt}
],
max_tokens=2000
)

return {"email": response.choices[0].message.content}

# Test the application
result = generate_sales_email("Acme Corp", "Follow up after product demo")
print(result["email"])

ステップ 7: 新しいバージョンを評価して比較する

同じスコアラーとデータセットを使用して改善されたバージョンで評価を実行し、問題に正常に対処したかどうかを確認します。

Python
import mlflow

# Run evaluation of the new version with the same scorers as before
# We use start_run to name the evaluation run in the UI
with mlflow.start_run(run_name="v2"):
eval_results_v2 = mlflow.genai.evaluate(
data=eval_dataset, # same eval dataset
predict_fn=generate_sales_email_v2, # new app version
scorers=email_scorers, # same scorers as step 4
)

ステップ 8: 結果を比較する

次に、結果を比較して、変更によって品質が向上したかどうかを確認します。

MLflow UI に移動して、評価結果を比較します。

trace

ステップ 9: イテレーションの継続

評価結果に基づいて、アプリケーションの品質を向上させ、新しい修正をそれぞれテストするために反復を続行できます。

ノートブックの例

次のノートブックには、このページのすべてのコードが含まれています。

GenAI アプリの評価クイックスタートノートブック

Open notebook in new tab

次のステップ

これらの推奨アクションとチュートリアルで旅を続けてください。

リファレンスガイド

このガイドで説明されている概念と機能の詳細なドキュメントをご覧ください。