What you will be able to do
- Explain why mlflow.genai.evaluate() is the tool for comparing agent context configurations, and what each of its parameters does in that comparison
- Set up a fair comparison by keeping the evaluation dataset and scorers the same, and changing only the app version under test
- Record which configuration each run used, with LoggedModels, model parameters and prompt lineage
- Choose scorers and an evaluation mode (direct or answer sheet) that also work for production monitoring
Key concept
Controlled configuration comparison — You can only call one context configuration more reliable than another if every configuration ran against the same evaluation dataset and was scored by the same scorers. That way, any difference in scores comes from the configuration and not from the test.
1.Why context configurations are compared with mlflow.genai.evaluate()
A context configuration covers everything you decide about what reaches the model: the prompt template, what gets retrieved and how much, and generation settings such as temperature and max tokens. Change any of these and you have a new version of your agent. The question this objective asks is always the same: across several runs, which version produced the most reliable results on a given task? Reading a handful of outputs by eye can't answer that. MLflow 3 replaces it with a structured harness. You don't have to run the agent and check each output yourself. MLflow Evaluation takes in test data, runs your agent and scores the results automatically. The docs say this "makes it easier to compare versions, track improvements, and share results across teams." They also list "validating prompt or model changes across app versions" as a core use case, and that is exactly what comparing context configurations is.
def mlflow.genai.evaluate(
data: Union[pd.DataFrame, List[Dict], mlflow.genai.datasets.EvaluationDataset], # Test data.
scorers: list[mlflow.genai.scorers.Scorer], # Quality metrics, built-in or custom.
predict_fn: Optional[Callable[..., Any]] = None, # App wrapper. Used for direct evaluation only.
model_id: Optional[str] = None, # Optional version tracking.
) -> mlflow.models.evaluation.base.EvaluationResult:Each parameter plays its own part in a comparison. data and scorers are the measuring stick, so they stay the same from run to run. predict_fn is the configuration being measured, and model_id is an optional label that links the run to a tracked version. The function returns an EvaluationResult, and the results are stored as traces with scorer feedback in the active MLflow experiment. Every configuration you test therefore leaves a record you can come back to and compare.
Checkpoint 1 of 6· Check yourself
In mlflow.genai.evaluate(), which parameter wraps the agent so that MLflow can call it during the evaluation?
predict_fn is the app wrapper. MLflow calls it on each test input to generate outputs, and it is used for direct evaluation only. model_id only labels the version; it does not run anything.
“App wrapper. Used for direct evaluation only.”Source: docs.databricks.com
Sources1
2.Keep the dataset and scorers the same; change only the app
The Databricks guide to comparing prompt versions spells out the rule: evaluate every version against the same data. It also says to "include challenging examples in your evaluation dataset", because two configurations that both handle the easy cases may behave differently on the hard ones. Each record in the dataset has a required inputs dictionary, which is passed to your app, and an optional expectations dictionary, which holds ground truth for the scorers. In the prompt-comparison example, expectations contains a list of expected_facts that a good summary should include. Ground truth like this lets a scorer check correctness and completeness, not just fluency.
| Field | Data type | Required | Role in a configuration comparison |
|---|---|---|---|
| inputs | dict[Any, Any] | Yes | The same inputs are passed to every configuration's predict_fn |
| expectations | dict[str, Any] | No | Ground truth (for example expected_facts) that scorers compare outputs against |
The "Evaluate and improve an agent" tutorial shows the pattern in code. The second version of the app is evaluated inside a named run, using the same dataset and the same judges as the first version. The inline comments say this directly. Naming the run with run_name makes it easy to find in the UI when you compare runs later.
Checkpoint 2 of 6· Fill the gap
This tutorial snippet evaluates a new app version against the same dataset and judges. Which parameter name fills the blank?
with mlflow.start_run(run_name="v2"):
eval_results_v2 = mlflow.genai.evaluate(
data=eval_dataset, # same eval dataset
? =generate_sales_email_v2, # new app version
scorers=email_judges, # same judges as step 4
)The new app version is the only thing that changes, and it is passed as predict_fn. The data and scorers stay the same as in the v1 run so that the two runs can be compared.
Source: docs.databricks.com3.Record which configuration each run used
A score is only useful if you know which configuration produced it. MLflow 3 records this with mlflow.set_active_model(), which creates a LoggedModel for the current version of your application. In the docs' words, this LoggedModel "doesn't store your actual application code - instead, it acts as a central record" that links to things like a Git commit. You attach the configuration settings with mlflow.log_model_params(). In the tutorial these settings are the LLM, a temperature of 0.7 and max_tokens of 500, and the comment above them says they "help you track the configuration of this app version." When the agent loads its prompt from the MLflow Prompt Registry (currently in Beta), MLflow also links the prompt version to the application version. That link appears under the experiment's Versions tab.
Checkpoint 3 of 6· Check yourself
What does the LoggedModel created by mlflow.set_active_model() hold for an application version?
The LoggedModel is a metadata hub, not a copy of the code. It links to your external code, holds the configuration parameters you log, and tracks which registry prompts the app uses.
“This LoggedModel doesn't store your actual application code - instead, it acts as a central record”Source: docs.databricks.com
A code comment in the tutorial explains that loading the prompt after set_active_model() is what turns on automatic lineage tracking between the prompt version and the LoggedModel. If you load the prompt first, nothing links that prompt version to the application version, and you can't tell which prompt produced a given score.
Sources3
4.Choose scorers and an evaluation mode that carry over to production
Scorers decide what "reliable" means for your task. A scorer can return "a pass/fail, true/false, numerical value, or a categorical value." Databricks recommends a progression, beginning with this advice: "Start with built-in judges for quick evaluation." When those stop being enough, you move to custom judges or code-based scorers. You can also score existing traces from the UI. In the Traces tab, select the traces, choose Actions, then Evaluate, and pick judges such as Correctness, Completeness or Fluency. MLflow attaches each result to its trace and records the run under the Evaluation runs tab.
| Approach | Customization | Typical use |
|---|---|---|
| Built-in judges | Minimal (moderate for Guidelines judges) | Quick LLM evaluation with judges such as Correctness and RetrievalGroundedness |
| Custom judges | Full | Domain-specific LLM criteria returning numbers, categories or booleans |
| Code-based scorers | Full | Deterministic checks such as exact matching and format validation |
| Third-party scorers | Full | Specialized metrics from open-source evaluation frameworks |
Checkpoint 4 of 6· Match them up
Match each scorer approach to the job it fits best
Tap a term, then the definition that fits it.
The approaches go from least to most control. Built-in judges are the quick starting point, custom judges add LLM criteria for your domain, code-based scorers handle deterministic logic, and third-party scorers bring in metrics from outside frameworks.
“Start with built-in judges for quick evaluation.”Source: docs.databricks.com
You also choose how outputs are produced. Direct evaluation is the recommended mode. MLflow calls your predict_fn (or a Model Serving endpoint wrapped with to_predict_fn) and captures fresh traces. Because of this, the docs say, "this mode enables you to reuse the scorers defined for offline evaluation in production monitoring since the resulting traces will be identical." Answer-sheet evaluation is for cases where you can't run the agent, or don't want to. For example, you might already have outputs from historical traces or batch jobs. In that mode you supply inputs with pre-computed outputs, or existing trace objects, and MLflow only runs the scorers.
Checkpoint 5 of 6· Check yourself
A team scores two context configurations using an answer sheet built from offline batch outputs. Later they want the same scorers to monitor production traffic. What do the docs warn about?
Answer-sheet traces may have a different structure from the traces the live app produces, so the scorers might not carry over unchanged. Direct evaluation avoids this because it produces traces identical to production.
“If you use an answer sheet with different traces than your production environment, you may need to re-write your scorer functions”Source: docs.databricks.com
Checkpoint 6 of 6· Exam question
A team runs mlflow.genai.evaluate() with a Correctness() scorer against the same evaluation dataset for three system-prompt configurations. Config A averages 0.82 with scores ranging from 0.40 to 1.0 across examples. Config B averages 0.80 with scores tightly clustered between 0.75 and 0.85. Config C averages 0.65 with moderate spread. Based on these MLflow 3 evaluation results, which configuration produced the most reliable outcomes for the task?
Correct answer: B — Config B, because it combines a competitive average with low variance across examples
Exam traps
Each one states something that sounds right. Open it to see what is actually true.
1.It's fine to give each context configuration a slightly different evaluation dataset, as long as the scorers are the same.Why is that wrong?
A comparison is only fair if every version is evaluated against the same data. If the dataset changes, a difference in scores can't be attributed to the configuration.
Covered in Keep the dataset and scorers the same; change only the app
2.Scorers that worked on answer-sheet traces will always work unchanged for production monitoring.Why is that wrong?
Only direct evaluation guarantees traces identical to production. Answer-sheet traces may differ, and the scorers may then need to be rewritten.
Covered in Choose scorers and an evaluation mode that carry over to production
Sources
Every claim above is drawn from one of these pages, quoted as it was written on the date shown.
- 1.
“This makes it easier to compare versions, track improvements, and share results across teams.”
↩︎ Why context configurations are compared with mlflow.genai.evaluate()“Validating prompt or model changes across app versions”
↩︎ Why context configurations are compared with mlflow.genai.evaluate()“Stores results as traces with scorer feedback in the active MLflow experiment.”
↩︎ Why context configurations are compared with mlflow.genai.evaluate()“Optional ground truth for scorers”
↩︎ Keep the dataset and scorers the same; change only the app“Direct evaluation (recommended).”
↩︎ Choose scorers and an evaluation mode that carry over to production“you already have outputs (for example, from external systems, historical traces, or batch jobs) and you just want to score them.”
↩︎ Choose scorers and an evaluation mode that carry over to production“this mode enables you to reuse the scorers defined for offline evaluation in production monitoring since the resulting traces will be identical.”
↩︎ Exam trap 2“App wrapper. Used for direct evaluation only.”
↩︎ Checkpoint“If you use an answer sheet with different traces than your production environment, you may need to re-write your scorer functions”
↩︎ Checkpoint - 2.https://docs.databricks.com/aws/en/mlflow3/genai/prompt-version-mgmt/prompt-registry/evaluate-promptsOfficial docs
“Test edge cases: Include challenging examples in your evaluation dataset.”
↩︎ Keep the dataset and scorers the same; change only the app“Use consistent datasets: Evaluate all versions against the same data for fair comparison.”
↩︎ Key concept“Use consistent datasets: Evaluate all versions against the same data for fair comparison.”
↩︎ Exam trap 1“Use consistent datasets: Evaluate all versions against the same data for fair comparison.”
↩︎ Prediction - 3.https://docs.databricks.com/aws/en/mlflow3/genai/prompt-version-mgmt/prompt-registry/track-prompts-app-versionsOfficial docs
“These parameters help you track the configuration of this app version”
↩︎ Record which configuration each run used“This LoggedModel doesn't store your actual application code - instead, it acts as a central record”
↩︎ Record which configuration each run used“MLflow automatically creates lineage between your prompt versions and application versions.”
↩︎ Record which configuration each run used - 4.
“This could be a pass/fail, true/false, numerical value, or a categorical value.”
↩︎ Choose scorers and an evaluation mode that carry over to production“Start with built-in judges for quick evaluation.”
↩︎ Checkpoint