Skip to content

Route BYO admin-connected judge models through the project Responses API (prompty judge path)#48002

Merged
shrutiyer merged 27 commits into
mainfrom
shruti/byo-admin-judge
Jul 20, 2026
Merged

Route BYO admin-connected judge models through the project Responses API (prompty judge path)#48002
shrutiyer merged 27 commits into
mainfrom
shruti/byo-admin-judge

Conversation

@shrutiyer

@shrutiyer shrutiyer commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Adds support for admin-connected (BYO) judge models — referenced as "connection/deployment" and served only through the Foundry project Responses API — in the prompty-based LLM-as-a-judge evaluators (coherence, relevance, fluency, groundedness, retrieval, similarity, tool/task judges, ...). Chat Completions cannot route these models (404 DeploymentNotFound); the platform resolves the connection + auth (API key / managed identity / OAuth2) when the call goes through the project Responses API.

Changes

  • azure/ai/evaluation/_byo_judge.py (new): AsyncByoProjectResponsesClient, an async chat.completions-compatible shim that routes judge calls to the project Responses API (AIProjectClient(...).get_openai_client().responses.create). Maps chat messages to Responses input items and curated sampling params, and translates response_format: {type: json_object|json_schema} to the Responses text: {format: {...}} param (restores enforced JSON mode). Adapts the Responses result (input/output_tokens) back to a chat-completions shape (prompt/completion_tokens, choices[0].message, ...). is_byo_model_config detects a BYO config (byo_model + project_endpoint).
  • azure/ai/evaluation/_legacy/prompty/_prompty.py: AsyncPrompty.__call__ branches on is_byo_model_config(...) and uses the shim instead of AsyncAzureOpenAI, so every prompty judge works with an admin-connected model with no evaluator-code change.
  • azure/ai/evaluation/_common/utils.py: validate_model_config passes BYO configs through (they intentionally omit azure_endpoint/azure_deployment).

Caller contract: model_config = {"byo_model": "<connection>/<deployment>", "project_endpoint": ".../api/projects/<project>"} plus a credential; the platform applies the connection auth.

Tests

  • tests/unittests/test_byo_judge.py: 15 unit tests (helpers, _Usage token adapter, async shim routing, validate_model_config passthrough, and response_format -> text.format mapping). All pass.

Validation

Ran the real prompty judges against live admin connections using this branch's source: Coherence/Relevance plus an 18-evaluator x 4-connection matrix (API key, managed identity, ModelGateway API key, OAuth2) -> all returned real scores; an instrumented trace confirmed text.format is sent on the wire and enforced-JSON parsing succeeds.

All SDK Contribution checklist

  • Does not introduce breaking changes (additive; non-BYO AzureOpenAI/OpenAI configs are unaffected).
  • CHANGELOG update pending.
  • Pull request includes test coverage.

Co-authored-by: Copilot 223556219+Copilot@users.noreply.github.com
Copilot-Session: b11202e6-6a52-4777-bed1-9c48730a63c3

… shim

AzureOpenAIGrader routes admin-connected judge models ('connection/deployment') through the Foundry project Responses API using a chat.completions-compatible shim (_byo_judge.py), so the platform resolves the connection. Judges cannot use chat.completions for BYO (404 DeploymentNotFound).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: b11202e6-6a52-4777-bed1-9c48730a63c3
@github-actions github-actions Bot added the Evaluation Issues related to the client library for Azure AI Evaluation label Jul 10, 2026
@shrutiyer shrutiyer closed this Jul 15, 2026
…s API (prompty judges)

Enables the 18 prompty-based LLM-as-a-judge builtin evaluators (coherence, relevance,
fluency, groundedness, intent_resolution, similarity, retrieval, task_adherence,
task_completion, tool_call_accuracy/success, tool_input_accuracy, tool_output_utilization,
tool_selection, response_completeness, customer_satisfaction, deflection_rate, quality_grader)
to use admin-connected models referenced as "connection/deployment".

- _byo_judge.py: AsyncByoProjectResponsesClient shims chat.completions -> project Responses
  API; _Usage adapts Responses token usage to chat shape.
- _common/utils.py: validate_model_config passes BYO configs through (they omit
  azure_endpoint/azure_deployment).
- _legacy/prompty/_prompty.py: __call__ routes BYO configs to the async shim.
- Scope: score_model/label_model (AOAI graders) are NOT supported - reverted the grader
  changes and removed the sync client.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: b11202e6-6a52-4777-bed1-9c48730a63c3
@shrutiyer shrutiyer reopened this Jul 15, 2026
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).
9 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

The BYO prompty-judge shim dropped the chat.completions `response_format`
param, so admin-connected judge models were not held to JSON output mode
(coherence/relevance/etc. prompts request json_object). The Responses API
exposes the same capability under `text.format`, so translate it:

  response_format={'type':'json_object'}  -> text={'format':{'type':'json_object'}}
  response_format json_schema (nested)    -> text.format json_schema (flattened)

This restores enforced-JSON parity with the AzureOpenAI path and prevents
json.loads failures when a BYO model would otherwise drift to prose output.

Added 6 unit tests for _map_response_format and the _map_params wiring.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: b11202e6-6a52-4777-bed1-9c48730a63c3
@shrutiyer shrutiyer changed the title Prototype: BYO admin-connected judge models via project Responses API… BYO admin-connected judge models via project Responses API… Jul 15, 2026
@shrutiyer shrutiyer changed the title BYO admin-connected judge models via project Responses API… BYO admin-connected judge models via project Responses API shim Jul 15, 2026
@shrutiyer shrutiyer changed the title BYO admin-connected judge models via project Responses API shim Route BYO admin-connected judge models through the project Responses API (prompty judge path) Jul 15, 2026
Shruti Iyer and others added 6 commits July 15, 2026 17:34
Collapse a multi-line AsyncByoProjectResponsesClient constructor call onto one
line (fits within the 120-char limit) to satisfy the azpysdk black check.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: b11202e6-6a52-4777-bed1-9c48730a63c3
is_byo_model_config returned True on byo_model alone, but the prompty branch
reads configuration['project_endpoint'] -> a partial config raised KeyError
instead of taking the normal (non-BYO) path. Require both markers, matching the
control-plane contract (BYO active iff both present). Adds coverage for the
byo_model-only and project_endpoint-only cases.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: b11202e6-6a52-4777-bed1-9c48730a63c3
The shim hardcoded finish_reason='stop', so a judge output truncated at
max_output_tokens was reported as complete and then failed json.loads downstream
with no signal. Map the Responses status/incomplete_details.reason to a
chat.completions finish_reason (max_output_tokens -> 'length', else 'stop').

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: b11202e6-6a52-4777-bed1-9c48730a63c3
with_options(timeout=...) was a no-op, so the prompty runner's per-request
timeout was dropped and a hung Responses call could block on openai's default
(~600s). Capture a concrete numeric timeout and forward it to responses.create
(openai's NotGiven sentinel, used when no timeout is set, is ignored).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: b11202e6-6a52-4777-bed1-9c48730a63c3
_Usage reported total_tokens=0 when the Responses usage omits it. Fall back to
prompt_tokens + completion_tokens so token telemetry stays correct.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: b11202e6-6a52-4777-bed1-9c48730a63c3
get_openai_client() is synchronous in some azure-ai-projects versions and a
coroutine in others; the shim assumed sync, so a version bump would assign a
coroutine to self._client and break responses.create. Create the client in an
async helper that awaits it when needed. Also removes the unused 'responses'
property (leftover from the removed grader path).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: b11202e6-6a52-4777-bed1-9c48730a63c3
@shrutiyer
shrutiyer marked this pull request as ready for review July 16, 2026 16:52
@shrutiyer
shrutiyer requested a review from a team as a code owner July 16, 2026 16:52
Copilot AI review requested due to automatic review settings July 16, 2026 16:52
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).
9 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds BYO judge-model routing through the Foundry project Responses API.

Changes:

  • Adds an async chat-completions compatibility shim.
  • Routes prompty evaluators through the shim for BYO configurations.
  • Adds validation passthrough and unit coverage.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
_byo_judge.py Implements Responses API routing and response adaptation.
_prompty.py Selects BYO routing for applicable configurations.
_common/utils.py Allows BYO model configurations through validation.
test_byo_judge.py Tests routing, mapping, usage, and validation behavior.

Comment thread sdk/evaluation/azure-ai-evaluation/azure/ai/evaluation/_byo_judge.py Outdated
Comment thread sdk/evaluation/azure-ai-evaluation/azure/ai/evaluation/_byo_judge.py Outdated
Shruti Iyer and others added 2 commits July 16, 2026 13:12
…absent

azure-ai-projects is an optional dependency (not in install_requires/extras),
so the BYO judge path's lazy `from azure.ai.projects.aio import AIProjectClient`
raised a raw ModuleNotFoundError when it was not installed. Wrap the import in
try/except and raise the SDK's MissingRequiredPackage with an actionable install
message, matching the existing optional-dependency idiom (azure-ai-inference,
promptflow, openai). Adds a unit test that simulates the missing package.

Addresses PR #48002 reviewer comment on _byo_judge.py.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: b11202e6-6a52-4777-bed1-9c48730a63c3
Truthiness alone accepted invalid configs such as {"byo_model": 1,
"project_endpoint": 2}: those markers are truthy, so the config was treated as
BYO, bypassed validate_model_config, and failed deep inside the project/OpenAI
client instead of producing the evaluator's normal validation error. Require
both markers to be non-empty strings before activating the BYO path. Extends the
is_byo_model_config unit test with non-string and empty-string cases.

Addresses PR #48002 reviewer comment on _byo_judge.py.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: b11202e6-6a52-4777-bed1-9c48730a63c3
Copilot AI review requested due to automatic review settings July 16, 2026 22:13
@shrutiyer
shrutiyer force-pushed the shruti/byo-admin-judge branch from 4a0aaa0 to b2ec218 Compare July 16, 2026 22:16
ACA may forward additional request headers (e.g. correlation / telemetry
headers) when running continuous evaluations. Add an optional extra_headers
parameter to AsyncByoProjectResponsesClient that is forwarded on every Responses
API call via responses.create(extra_headers=...). The headers are copied on
construction so later caller mutations do not leak into the client. AsyncPrompty
threads them from the BYO model config (configuration["extra_headers"]) so the
end-to-end path stays unchanged for callers that do not supply headers.

Adds unit tests covering header forwarding and the no-headers default.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: b11202e6-6a52-4777-bed1-9c48730a63c3
@shrutiyer
shrutiyer force-pushed the shruti/byo-admin-judge branch from b2ec218 to c1c6369 Compare July 16, 2026 22:17

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

Comment thread sdk/evaluation/azure-ai-evaluation/azure/ai/evaluation/_common/utils.py Outdated
Copilot AI review requested due to automatic review settings July 20, 2026 17:59

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.

Remove the admin-connected (BYO) Features Added entry from the 1.18.1 section
(the release entry will be added when the feature ships).

Bump the dev/test pin from azure-ai-projects<=1.0.0b10 to >=2.0.0b1: the BYO
judge path uses AIProjectClient.get_openai_client().responses (the Foundry
project Responses API), which the ACA data plane runs on 2.0.0b1, and Red Team
already documents azure-ai-projects>=2.0.0b1 as the minimum in TROUBLESHOOTING.md.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: b11202e6-6a52-4777-bed1-9c48730a63c3
Copilot AI review requested due to automatic review settings July 20, 2026 18:10

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (1)

sdk/evaluation/azure-ai-evaluation/azure/ai/evaluation/_byo_judge.py:176

  • This adds a new evaluator capability, but the package CHANGELOG has no corresponding entry, and the PR checklist still marks that update as pending. Add this BYO judge-model support under the next release's Features Added section so the shipped behavior is discoverable.
class AsyncByoProjectResponsesClient:
    """Async OpenAI-compatible shim that routes ``chat.completions.create()`` to the Foundry project
    Responses API for an admin-connected (BYO) model.

Tighten verbose inline comments across the BYO judge shim, prompty branch,
model-config validation, and their tests to one or two lines each, keeping the
essential rationale. Docstrings/function explanations are unchanged.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: b11202e6-6a52-4777-bed1-9c48730a63c3
Copilot AI review requested due to automatic review settings July 20, 2026 18:20

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.

The bump to >=2.0.0b1 broke the whl leg: (1) tests/e2etests/test_remote_evaluation.py
imports EvaluatorConfiguration/Evaluation/Dataset from azure.ai.projects.models,
which exist only in the 1.x API (removed in 2.x) -> collection ImportError; and
(2) azure-ai-projects 2.x requires openai>=2.8.0 and azure-core>=1.35.0, which
conflict with this SDK's pinned openai==1.108.0 / azure-core==1.31.0, making the
resolve unsatisfiable.

The test environment must stay on azure-ai-projects 1.x. BYO's 2.x runtime
requirement is a data-plane/ACA concern (already documented in TROUBLESHOOTING.md);
BYO unit tests mock azure-ai-projects, so they pass on 1.0.0b10.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: b11202e6-6a52-4777-bed1-9c48730a63c3
Copilot AI review requested due to automatic review settings July 20, 2026 18:42

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (2)

sdk/evaluation/azure-ai-evaluation/azure/ai/evaluation/_common/utils.py:226

  • model_config now includes _BYOModelConfiguration, but the immediately called parse_model_config_type still accepts only the two existing configuration types. This leaves the internal type contract inconsistent and causes an incompatible-argument diagnostic when this package’s type checking is enabled. Widen the helper’s annotation as well; its existing guards already make BYO a no-op.
    model_config: Union[AzureOpenAIModelConfiguration, OpenAIModelConfiguration, _BYOModelConfiguration],

sdk/evaluation/azure-ai-evaluation/azure/ai/evaluation/_byo_judge.py:175

  • This adds user-visible evaluator support, but sdk/evaluation/azure-ai-evaluation/CHANGELOG.md has no BYO/admin-connected model entry, and the PR checklist still marks the CHANGELOG update as pending. Add the feature under the next release before merging so the package release notes describe the new supported model path.
class AsyncByoProjectResponsesClient:
    """Async OpenAI-compatible shim that routes ``chat.completions.create()`` to the Foundry project
    Responses API for an admin-connected (BYO) model.

The 22 TestLogEvents*/TestEmitEvalResultShutdown tests failed on the sk_ CI leg
with ModuleNotFoundError: No module named 'opentelemetry._events'. The App
Insights event-logging code they cover imports opentelemetry._events /
opentelemetry.sdk._events (the OpenTelemetry Events API, added in opentelemetry
1.26), but the MISSING_OPENTELEMETRY guard only checked the top-level
opentelemetry package. On the sk_ leg semantic-kernel pins an older opentelemetry
(<1.26) that lacks the Events API, so the guard reported present, the tests ran,
and the code crashed on the missing submodule.

Guard on the Events API submodules the code actually imports so the tests skip
cleanly where the API is unavailable (sk_ leg) and still run where it is present
(all other legs). Verified locally: 22 pass with the API present, 22 skip when it
is simulated absent.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: b11202e6-6a52-4777-bed1-9c48730a63c3
Copilot AI review requested due to automatic review settings July 20, 2026 19:53

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (3)

sdk/evaluation/azure-ai-evaluation/azure/ai/evaluation/_common/utils.py:226

  • The newly widened union is passed directly to parse_model_config_type, but that helper still accepts only the Azure OpenAI/OpenAI union (utils.py:216-218). This introduces an incompatible-argument error in mypy whenever construct_prompty_model_config is checked. Widen the helper's annotation as well.
    model_config: Union[AzureOpenAIModelConfiguration, OpenAIModelConfiguration, _BYOModelConfiguration],

sdk/evaluation/azure-ai-evaluation/azure/ai/evaluation/_byo_judge.py:215

  • This import succeeds with the package's current development dependency azure-ai-projects<=1.0.0b10, so the missing-package error does not help, but that version cannot support this call: the projects changelog says project-endpoint construction starts in 1.0.0b11 and get_openai_client() is configured for project Responses operations only from 2.0.0b1 (sdk/ai/azure-ai-projects/CHANGELOG.md:485-500,381-395). The BYO path will therefore fail in the repository-supported environment. Require/validate a Responses-capable azure-ai-projects version and update the development dependency and installation guidance accordingly.
                from azure.ai.projects.aio import AIProjectClient
            except ImportError as ex:
                from azure.ai.evaluation._legacy._adapters._errors import MissingRequiredPackage

                raise MissingRequiredPackage(
                    message="Please install the 'azure-ai-projects' package to use admin-connected "
                    "(BYO) judge models."

sdk/evaluation/azure-ai-evaluation/azure/ai/evaluation/_byo_judge.py:4

  • This adds a user-visible evaluator capability, but the package CHANGELOG still has no entry for BYO judge routing, and the PR checklist explicitly leaves the CHANGELOG update pending. Add the release note before merging so the new model-config behavior and optional projects-package requirement are discoverable.
"""Use admin-connected (BYO) models as LLM-as-a-judge evaluator models.

Comment thread sdk/evaluation/azure-ai-evaluation/azure/ai/evaluation/_byo_judge.py Outdated
Address PR review (posaninagendra): construct the Responses API input with the
openai SDK's typed entity (openai.types.responses.EasyInputMessageParam) and
return the SDK's ResponseInputParam, instead of a hand-written dict. This keeps
the shim in sync with the SDK's input schema (type-checked against it) rather
than a hand-authored shape that drifts silently on SDK upgrades.

Runtime output is identical (EasyInputMessageParam is a TypedDict -> plain dict),
so existing input-shape assertions hold. The output side already reads the SDK's
typed Response via its output_text convenience aggregator. openai is a hard
dependency (openai>=1.108.0), so the import is safe. 29 byo tests pass.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: b11202e6-6a52-4777-bed1-9c48730a63c3
Copilot AI review requested due to automatic review settings July 20, 2026 21:05

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (1)

sdk/evaluation/azure-ai-evaluation/azure/ai/evaluation/_byo_judge.py:4

  • This adds a new evaluator capability, but CHANGELOG.md still has no corresponding entry (its latest section is 1.18.1), and the PR checklist also marks the changelog as pending. Add this BYO judge-model support under the next release’s Features Added section before merging.
"""Use admin-connected (BYO) models as LLM-as-a-judge evaluator models.

@shrutiyer
shrutiyer merged commit b4edba7 into main Jul 20, 2026
22 checks passed
@shrutiyer
shrutiyer deleted the shruti/byo-admin-judge branch July 20, 2026 21:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Evaluation Issues related to the client library for Azure AI Evaluation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants