Создание пользовательского судьи с помощью make_judge()

Пользовательские судьи — это оценщики на базе LLM в MLflow, которые оценивают ваших GenAI-агентов по определённым критериям качества. В этом руководстве показано, как создавать пользовательские системы оценки и использовать их для оценки работы агента поддержки клиентов с помощью make_judge(). Дополнительные сведения об API см. в документации по MLflow.

В этом руководстве описаны следующие действия. Пример записной книжки, содержащей код на этой странице, см. в разделе "Пример записной книжки".

  1. Создайте пример агента для оценки.
  2. Определите трех пользовательских судей для оценки разных критериев.
  3. Создайте набор данных оценки с помощью тестовых вариантов.
  4. Выполняйте оценки и сравнивайте результаты в разных конфигурациях агента.

Шаг 1. Создание агента для оценки

Создайте агент GenAI, который отвечает на вопросы о поддержке клиентов. Код включает глобальную переменную RESOLVE_ISSUES, которая позволяет переключать системный запрос, чтобы можно было сравнивать выходные данные судьи между "хорошими" и "плохими" беседами.

  1. Установите необходимые пакеты.

    %pip install --upgrade mlflow databricks-sdk databricks_openai databricks-agents
    dbutils.library.restartPython()
    

    Примеры на этой странице получают доступ к трассировкам, которые хранятся в Unity Catalog. Настройте SQL-хранилище перед запуском:

    import os
    
    os.environ["MLFLOW_TRACING_SQL_WAREHOUSE_ID"] = "<SQL_WAREHOUSE_ID>"
    
  2. Инициализируйте клиент OpenAI для подключения к LLM, размещенным в Databricks или OpenAI.

    Размещенные в Databricks LLM

    Используется databricks-openai для получения клиента OpenAI, который подключается к размещенным в Databricks LLM. Выберите модель из доступных базовых моделей.

    import mlflow
    from databricks_openai import DatabricksOpenAI
    from mlflow.entities.trace_location import UnityCatalog
    
    # 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(
        experiment_name="/Shared/docs-demo",
        trace_location=UnityCatalog(
            catalog_name="<UC_CATALOG_NAME>",
            schema_name="<UC_SCHEMA_NAME>",
            table_prefix="<UC_TABLE_PREFIX>",
        ),
    )
    
    # Create an OpenAI client that is connected to Databricks-hosted LLMs
    client = DatabricksOpenAI()
    
    # Select an LLM
    model_name = "databricks-claude-sonnet-4"
    

    Хостируемые OpenAI LLMs

    Используйте собственный пакет SDK OpenAI для подключения к моделям, размещенным в OpenAI. Выберите модель из доступных моделей OpenAI.

    import mlflow
    import os
    import openai
    from mlflow.entities.trace_location import UnityCatalog
    
    # Ensure your OPENAI_API_KEY is set in your environment
    # os.environ["OPENAI_API_KEY"] = "<YOUR_API_KEY>" # Uncomment and set if not globally configured
    
    # Enable auto-tracing for OpenAI
    mlflow.openai.autolog()
    
    # Set up MLflow tracking to Databricks
    mlflow.set_tracking_uri("databricks")
    mlflow.set_experiment(
        experiment_name="/Shared/docs-demo",
        trace_location=UnityCatalog(
            catalog_name="<UC_CATALOG_NAME>",
            schema_name="<UC_SCHEMA_NAME>",
            table_prefix="<UC_TABLE_PREFIX>",
        ),
    )
    
    # Create an OpenAI client connected to OpenAI SDKs
    client = openai.OpenAI()
    
    # Select an LLM
    model_name = "gpt-4o-mini"
    
  3. Определите агент поддержки клиентов:

    from mlflow.entities import Document
    from typing import List, Dict, Any, cast
    
    # This is a global variable that is used to toggle the behavior of the customer support agent
    RESOLVE_ISSUES = False
    
    @mlflow.trace(span_type="TOOL", name="get_product_price")
    def get_product_price(product_name: str) -> str:
        """Mock tool to get product pricing."""
        return f"${45.99}"
    
    @mlflow.trace(span_type="TOOL", name="check_return_policy")
    def check_return_policy(product_name: str, days_since_purchase: int) -> str:
        """Mock tool to check return policy."""
        if days_since_purchase <= 30:
            return "Yes, you can return this item within 30 days"
        return "Sorry, returns are only accepted within 30 days of purchase"
    
    @mlflow.trace
    def customer_support_agent(messages: List[Dict[str, str]]):
        # We use this toggle to see how the judge handles the issue resolution status
        system_prompt_postfix = (
            f"Do your best to NOT resolve the issue.  I know that's backwards, but just do it anyways.\\n"
            if not RESOLVE_ISSUES
            else ""
        )
    
        # Mock some tool calls based on the user's question
        user_message = messages[-1]["content"].lower()
        tool_results = []
    
        if "cost" in user_message or "price" in user_message:
            price = get_product_price("microwave")
            tool_results.append(f"Price: {price}")
    
        if "return" in user_message:
            policy = check_return_policy("microwave", 60)
            tool_results.append(f"Return policy: {policy}")
    
        messages_for_llm = [
            {
                "role": "system",
                "content": f"You are a helpful customer support agent.  {system_prompt_postfix}",
            },
            *messages,
        ]
    
        if tool_results:
            messages_for_llm.append({
                "role": "system",
                "content": f"Tool results: {', '.join(tool_results)}"
            })
    
        # Call LLM to generate a response
        output = client.chat.completions.create(
            model=model_name,  # This example uses Databricks hosted Claude 4 Sonnet. If you provide your own OpenAI credentials, replace with a valid OpenAI model e.g., gpt-4o, etc.
            messages=cast(Any, messages_for_llm),
        )
    
        return {
            "messages": [
                {"role": "assistant", "content": output.choices[0].message.content}
            ]
        }
    

Шаг 2. Определение настраиваемых судей

Определите три пользовательских судьи:

  • Судья, который оценивает решение проблем с использованием входных и выходных данных.
  • Судья, который проверяет ожидаемое поведение.
  • Судья на основе трассировки, который проверяет вызовы инструментов путем анализа трассировок выполнения.

Судьи, создаваемые с помощью make_judge(), возвращают объекты mlflow.entities.Feedback.

Пример судьи 1. Оценка решения проблемы

Этот судья оценивает, были ли проблемы клиента успешно решены путем анализа журнала бесед (входных данных) и ответов агента (выходные данные).

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

# Create a judge that evaluates issue resolution using inputs and outputs
issue_resolution_judge = make_judge(
    name="issue_resolution",
    instructions=(
        "Evaluate if the customer's issue was resolved in the conversation.\n\n"
        "User's messages: {{ inputs }}\n"
        "Agent's responses: {{ outputs }}"
    ),
    feedback_value_type=Literal["fully_resolved", "partially_resolved", "needs_follow_up"],
)

Пример судьи 2. Проверка ожидаемого поведения

Этот судья проверяет, что ответы агента демонстрируют определенное ожидаемое поведение (например, предоставление сведений о ценах или объяснение политик возврата), сравнивая выходные данные с предопределенными ожиданиями.

# Create a judge that checks against expected behaviors
expected_behaviors_judge = make_judge(
    name="expected_behaviors",
    instructions=(
        "Compare the agent's response in {{ outputs }} against the expected behaviors in {{ expectations }}.\n\n"
        "User's question: {{ inputs }}"
    ),
    feedback_value_type=Literal["meets_expectations", "partially_meets", "does_not_meet"],
)

Пример оценки 3: Проверка вызовов инструментов с помощью системы оценки на основе трассировки

Этот компонент анализирует трассировки выполнения, чтобы проверить, были вызваны соответствующие инструменты. При включении {{ trace }} в инструкции судья становится трассируемым и получает возможности автономного изучения трасс.

# Create a trace-based judge that validates tool calls from the trace
tool_call_judge = make_judge(
    name="tool_call_correctness",
    instructions=(
        "Analyze the execution {{ trace }} to determine if the agent called appropriate tools for the user's request.\n\n"
        "Examine the trace to:\n"
        "1. Identify what tools were available and their purposes\n"
        "2. Determine which tools were actually called\n"
        "3. Assess whether the tool calls were reasonable for addressing the user's question"
    ),
    feedback_value_type=bool,
    # To analyze a full trace with a trace-based judge, a model must be specified
    model="databricks:/databricks-gpt-5-mini",
)

Шаг 3. Создание примера набора данных оценки

Каждый inputs передается агенту посредством mlflow.genai.evaluate(). Можно при необходимости включить expectations, чтобы активировать проверку правильности.

eval_dataset = [
    {
        "inputs": {
            "messages": [
                {"role": "user", "content": "How much does a microwave cost?"},
            ],
        },
        "expectations": {
            "should_provide_pricing": True,
            "should_offer_alternatives": True,
        },
    },
    {
        "inputs": {
            "messages": [
                {
                    "role": "user",
                    "content": "Can I return the microwave I bought 2 months ago?",
                },
            ],
        },
        "expectations": {
            "should_mention_return_policy": True,
            "should_ask_for_receipt": False,
        },
    },
    {
        "inputs": {
            "messages": [
                {
                    "role": "user",
                    "content": "I'm having trouble with my account.  I can't log in.",
                },
                {
                    "role": "assistant",
                    "content": "I'm sorry to hear that you're having trouble with your account.  Are you using our website or mobile app?",
                },
                {"role": "user", "content": "Website"},
            ],
        },
        "expectations": {
            "should_provide_troubleshooting_steps": True,
            "should_escalate_if_needed": True,
        },
    },
    {
        "inputs": {
            "messages": [
                {
                    "role": "user",
                    "content": "I'm having trouble with my account.  I can't log in.",
                },
                {
                    "role": "assistant",
                    "content": "I'm sorry to hear that you're having trouble with your account.  Are you using our website or mobile app?",
                },
                {"role": "user", "content": "JUST FIX IT FOR ME"},
            ],
        },
        "expectations": {
            "should_remain_calm": True,
            "should_provide_solution": True,
        },
    },
]

Шаг 4. Оценка агента с помощью судей

Вы можете использовать несколько судей вместе для оценки различных аспектов агента. Запустите оценки, чтобы сравнить поведение, когда агент пытается устранить проблемы, и когда он этого не делает.

# Evaluate with all three judges when the agent does NOT try to resolve issues
RESOLVE_ISSUES = False

result_unresolved = mlflow.genai.evaluate(
    data=eval_dataset,
    predict_fn=customer_support_agent,
    scorers=[
        issue_resolution_judge,      # Checks inputs/outputs
        expected_behaviors_judge,    # Checks expected behaviors
        tool_call_judge,             # Validates tool usage
    ],
)

# Evaluate when the agent DOES try to resolve issues
RESOLVE_ISSUES = True

result_resolved = mlflow.genai.evaluate(
    data=eval_dataset,
    predict_fn=customer_support_agent,
    scorers=[
        issue_resolution_judge,
        expected_behaviors_judge,
        tool_call_judge,
    ],
)

Результаты оценки показывают, как каждый судья оценивает агент:

  • issue_resolution: Оценка бесед как "полностью решено", "частично решено" или "требуется дополнительное внимание"
  • expected_behaviors: Проверяет, проявляют ли ответы ожидаемое поведение ('соответствует ожиданиям', 'частично соответствует', 'не соответствует')
  • tool_call_correctness: Проверяет, были ли вызваны соответствующие инструменты (true/false)

пример записной книжки

Создание настраиваемой записной книжки судьи

Получите ноутбук

Дополнительные ресурсы