Skip to main content
The Microsoft Azure AI Evaluation library ships LLM-as-a-judge evaluators (groundedness, relevance, coherence, fluency, content safety) along with deterministic NLP scorers (BLEU, F1, ROUGE, METEOR). This guide shows two ways to use them with Phoenix:
  • Flow 1 grades existing Phoenix traces with GroundednessEvaluator and logs the scores back as span annotations.
  • Flow 2 uploads a small dataset, runs a Phoenix experiment with the same evaluator, and records a score for each run.
Both flows share the same setup. Run the code blocks below in order in a single Python session, because each block builds on imports and variables from earlier ones.

Prerequisites

  • Python 3.11+
  • An OPENAI_API_KEY from the OpenAI Platform. It’s used for both the model under trace and the judge model for GroundednessEvaluator.
  • A running Phoenix instance. See Phoenix setup.

Install

Configure credentials

Define the evaluator

The shared setup creates a Microsoft GroundednessEvaluator backed by gpt-4.1-mini, the two-row dataset that both flows score, and a Phoenix client. The judge model is pinned to gpt-4.1-mini because azure-ai-evaluation sends the legacy max_tokens parameter, which the GPT-5 and o-series reasoning models reject. gpt-4.1-mini accepts max_tokens natively.

Flow 1: Evaluate existing traces

Trace some LLM calls

Register Phoenix tracing with OpenAI auto-instrumentation, make two calls that each echo a known answer so the trace contains predictable text, then pull the resulting spans back from Phoenix.

Run the evaluator

GroundednessEvaluator is synchronous, so call it once per span with the question, the response from the span, and the reference context. The OpenAI instrumentor records the full response as JSON in attributes.output.value, so the code reads the message text out of it. The raw groundedness value is a 1–5 score from the judge model and can drift by one point between runs. This guide grades on groundedness_result (pass or fail against the default threshold of 3) and normalizes it to 1.0 or 0.0 so the score is stable across runs. To keep the raw 1–5 number, use float(result["groundedness"]) instead.

Log evaluations to Phoenix

log_span_annotations_dataframe reads a dataframe indexed by span ID with score, label, and explanation columns, and attaches each row to its span as an annotation.
You should see output like:
Open the azure-ai-evaluation-tracing-example-<timestamp> project in Phoenix (the name printed above). Each traced ChatCompletion span now has a groundedness annotation with the score, the grounded or ungrounded label, and the judge’s explanation.
azure-ai-evaluation calls the judge model through the OpenAI SDK, so the auto-instrumentation also traces the judge calls into the same project as additional ChatCompletion spans. Only the two spans fetched before evaluation are annotated.

Flow 2: Run an experiment

Create a dataset

Define the task

The task returns the stored answer for each example so the experiment grades the same two responses as Flow 1. In a real experiment, the task would call your application.

Wrap the evaluator

Phoenix binds experiment evaluator arguments by name: input and metadata are the example’s input and metadata, and output is the task’s result. Return a dictionary with score, label, and explanation.

Run the experiment

You should see output like:
Open Datasets in Phoenix and select azure-ai-evaluation-experiment-example-ds-<timestamp>. The experiment azure-ai-evaluation-experiment-example-<timestamp> lists one run per example, each with its groundedness score, label, and explanation.

Troubleshooting

  • OpenAIConnection.__init__() missing 1 required positional argument: 'base_url'. Azure AI Evaluation requires an explicit base_url in the model_config, even for OpenAI. Set it to https://api.openai.com/v1 as shown in the evaluator setup.
  • Unsupported parameter: 'max_tokens' is not supported with this model. azure-ai-evaluation sends the legacy max_tokens parameter that GPT-5 and o-series models reject. Use a non-reasoning judge model such as gpt-4.1-mini or gpt-4.1.
  • Spans never appear. Confirm PHOENIX_COLLECTOR_ENDPOINT points at your Phoenix instance and, if authentication is enabled, that PHOENIX_API_KEY is set.
  • Using Azure OpenAI for the judge model. Replace the model_config with {"type": "azure_openai", "api_key": "...", "azure_endpoint": "https://<resource>.openai.azure.com", "azure_deployment": "<deployment-name>", "api_version": "2024-10-21"}. The rest of the guide is unchanged.
  • Using safety evaluators (HateUnfairness, Violence, and others). These require an Azure AI Foundry project instead of a model_config. See Microsoft’s risk and safety evaluators.
  • Using a different score scale. Microsoft’s LLM-judged evaluators (Groundedness, Relevance, Coherence, Fluency, Similarity, Retrieval) return scores on a 1–5 scale. To project to 0–1, normalize with score = (raw - 1) / 4.

Resources

Azure AI Evaluation documentation

azure-ai-evaluation on PyPI

Ragas evaluation with Phoenix