Route BYO admin-connected judge models through the project Responses API (prompty judge path)#48002
Conversation
… 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
…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
|
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
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
|
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. |
There was a problem hiding this comment.
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. |
…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
4a0aaa0 to
b2ec218
Compare
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
b2ec218 to
c1c6369
Compare
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
There was a problem hiding this comment.
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 Addedsection 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
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
There was a problem hiding this comment.
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_confignow includes_BYOModelConfiguration, but the immediately calledparse_model_config_typestill 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.mdhas 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
There was a problem hiding this comment.
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 wheneverconstruct_prompty_model_configis 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 andget_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-capableazure-ai-projectsversion 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.
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
There was a problem hiding this comment.
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.mdstill 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.
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 asyncchat.completions-compatible shim that routes judge calls to the project Responses API (AIProjectClient(...).get_openai_client().responses.create). Maps chat messages to Responsesinputitems and curated sampling params, and translatesresponse_format: {type: json_object|json_schema}to the Responsestext: {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_configdetects a BYO config (byo_model+project_endpoint).azure/ai/evaluation/_legacy/prompty/_prompty.py:AsyncPrompty.__call__branches onis_byo_model_config(...)and uses the shim instead ofAsyncAzureOpenAI, so every prompty judge works with an admin-connected model with no evaluator-code change.azure/ai/evaluation/_common/utils.py:validate_model_configpasses BYO configs through (they intentionally omitazure_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,_Usagetoken adapter, async shim routing,validate_model_configpassthrough, andresponse_format->text.formatmapping). 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.formatis sent on the wire and enforced-JSON parsing succeeds.All SDK Contribution checklist
AzureOpenAI/OpenAIconfigs are unaffected).Co-authored-by: Copilot 223556219+Copilot@users.noreply.github.com
Copilot-Session: b11202e6-6a52-4777-bed1-9c48730a63c3