会話を評価する

会話の評価では、個々のターンではなく、会話セッション全体を評価できます。 これは、ユーザーのフラストレーション パターン、会話の完全性、全体的な会話の一貫性など、複数の対話に対して品質が生まれる会話型 AI システムを評価するために不可欠です。

複数ターンのジャッジは、開発中のオフライン評価 (このページで説明) と 運用環境での継続的な監視の両方に使用できます。

複数ターンの評価は 試験的です。 API と動作は、今後のリリースで変更される可能性があります。

[前提条件]

MLflow 3.10.0 以降をインストールします。

pip install --upgrade 'mlflow[databricks]>=3.10'

エージェントには、トレース上でセッション ID を追跡する機能が実装されている必要があります。 トレースにセッション ID を設定する方法については、「 ユーザーと セッションを追跡する」を参照してください。

2 つの方法

MLflow では、会話を評価するための 2 つの方法がサポートされています。

  • 事前に生成された会話を評価する: 既にトレースされている既存の会話を評価します。 この方法は、次の場合に使用します。

    • 分析対象となる運用の会話データ
    • QA またはユーザー調査からの事前に記録されたテスト会話
    • 比較のための以前のエージェント バージョンからの会話
  • 評価中に会話をシミュレートする: エージェントとのユーザー操作をシミュレートして、新しい会話を生成します。 この方法は、次の場合に使用します。

    • 一貫性のあるシナリオで新しいエージェント バージョンを体系的にテストする
    • 大規模な多様なテスト シナリオを生成する
    • 特定のユーザーの動作とエッジ ケースを使用してエージェントをストレス テストする

セッション レベルで評価する理由

従来のシングルターン評価では、各エージェントの応答が個別に評価されます。 ただし、会話エージェントでは、次の情報をキャプチャするためにセッション レベルでの評価が必要です。

  • ユーザーのフラストレーション: ユーザーは不満を感じませんでしたか? 解決されましたか?
  • 会話の完全性: 会話の最後までに、すべてのユーザーの質問に回答しましたか?
  • ナレッジリテンション期間: エージェントは会話の前の情報を記憶していますか?
  • 会話の一貫性: 会話は自然に流れるのですか?

複数ターンの評価では、トレースを会話セッションにグループ化し、会話履歴全体を分析するジャッジを適用することで、これらのニーズに対応します。

事前に生成された会話を評価する

既にトレースされている会話を評価します。 これは、実稼働データまたは事前に記録されたテスト会話を評価する場合に役立ちます。

手順 1: セッション ID を使用してタグを付けてトレースします

エージェントを構築するときに、トレースにセッション ID を設定して、それらを会話にグループ化します。

import mlflow

@mlflow.trace
def my_chatbot(question, session_id):
    mlflow.update_current_trace(
        tags={"mlflow.trace.session": session_id}
    )
    # ... your chatbot logic

セッションの追跡に関する完全なドキュメントについては、「 ユーザーとセッションの追跡」を参照してください。

手順 2: セッションを取得して評価する

実験からトレースを取得し、 mlflow.genai.evaluateに渡します。 MLflow では、セッション ID によってトレースが自動的にグループ化されます。

from mlflow.genai.scorers import ConversationCompleteness, UserFrustration

# Get traces from your experiment
traces = mlflow.search_traces(
    filter_string="attributes.status = 'OK'",
    return_type="list",
)

# Evaluate the conversations
# MLflow automatically groups traces by their session ID tag
results = mlflow.genai.evaluate(
    data=traces,
    scorers=[
        ConversationCompleteness(),  # Did the agent answer all questions?
        UserFrustration(),           # Did the user become frustrated?
    ],
)

mlflow.search_sessionsを使用して、完全なセッションを直接取得することもできます。

import mlflow

# Get complete sessions (each session is a list of traces)
sessions = mlflow.search_sessions(
    locations=["<your-experiment-id>"],
    max_results=50,
)

# Flatten for evaluation
all_traces = [trace for session in sessions for trace in session]

results = mlflow.genai.evaluate(
    data=all_traces,
    scorers=[ConversationCompleteness(), UserFrustration()],
)

評価中に会話をシミュレートする

ユーザーの操作をシミュレートして、新しい会話を生成します。 これにより、一貫した目標とペルソナを使用して、さまざまなエージェント バージョンをテストできます。

import mlflow
from mlflow.genai.simulators import ConversationSimulator
from mlflow.genai.scorers import ConversationCompleteness, Safety

# Define test scenarios
simulator = ConversationSimulator(
    test_cases=[
        {"goal": "Successfully set up experiment tracking"},
        {"goal": "Identify the root cause of a deployment error"},
        {
            "goal": "Understand how to implement model versioning",
            "persona": "You are a beginner who needs detailed explanations",
        },
    ],
    max_turns=5,
)


# Your agent's predict function
def predict_fn(input: list[dict], **kwargs) -> str:
    # input is the conversation history
    response = your_agent.chat(input)
    return response


# Simulate conversations and evaluate
results = mlflow.genai.evaluate(
    data=simulator,
    predict_fn=predict_fn,
    scorers=[
        ConversationCompleteness(),
        Safety(),
    ],
)

テスト ケース定義、関数インターフェイスの予測、構成オプションなど、会話シミュレーションに関する完全なドキュメントについては、 会話シミュレーションを参照してください。

複数ターンの判定者

組み込みの判定器

MLflow は、会話の品質を評価するための組み込みのマルチターン ジャッジを提供します。 完全な一覧と詳細なドキュメントについては、 MLflow の定義済みスコアラーのドキュメント、スコアラーと LLM のジャッジ のページを参照してください。

カスタマイズされた審査員

make_judgeを使用してカスタムマルチターンジャッジを作成します。 {{ conversation }} テンプレート変数を使用して、会話履歴全体にアクセスします。

from mlflow.genai.judges import make_judge
from typing import Literal

# Create a custom multi-turn judge
politeness_judge = make_judge(
    name="politeness",
    instructions=(
        "Evaluate whether the assistant maintained a polite and professional "
        "tone throughout this conversation:\n\n{{ conversation }}\n\n"
        "Rate as 'consistently_polite', 'mostly_polite', or 'impolite'."
    ),
    feedback_value_type=Literal["consistently_polite", "mostly_polite", "impolite"],
)

# Get traces from your experiment
traces = mlflow.search_traces(
    filter_string="attributes.status = 'OK'",
    return_type="list",
)

# Use in evaluation
results = mlflow.genai.evaluate(
    data=traces,
    scorers=[politeness_judge],
)

{{ conversation }}変数は、判事が分析できるように、読み取り可能な形式で完全な会話履歴を挿入します。

{{ conversation }}変数は、{{ expectations }}{{ inputs }}、または{{ outputs }}ではなく、{{ trace }}でのみ使用できます。

評価の格納方法

複数ターンの評価は、各セッションの 最初のトレース (時系列) に格納されます。 この設計により、以下が保証されます。

  • 会話に新しいターンが追加されても、評価は安定しています
  • セッション開始トレースを見ることで、会話レベルの評価を簡単に見つけることができます
  • セッション UI では、会話メトリックを効率的に表示できます

評価には、会話レベルとして識別されるメタデータが含まれます。

  • session_id: 評価を完全な会話にリンクするセッション ID

特定のセッションの操作

特定のセッションを評価するには、フィルター文字列で mlflow.search_traces を使用します。

import mlflow
from mlflow.genai.scorers import ConversationCompleteness, UserFrustration

# Get traces for a specific session using filter
traces = mlflow.search_traces(
    filter_string="tags.`mlflow.trace.session` = '<your-session-id>'",
    return_type="list",
)

# Evaluate the session
results = mlflow.genai.evaluate(
    data=traces,
    scorers=[ConversationCompleteness(), UserFrustration()],
)

その他のリソース