Skip to content

Commit d8fa0c8

Browse files
vertex-sdk-botcopybara-github
authored andcommitted
chore: Gate Managed Agent evaluation to supported metrics.
PiperOrigin-RevId: 964769846
1 parent 09acba7 commit d8fa0c8

4 files changed

Lines changed: 130 additions & 5 deletions

File tree

‎agentplatform/_genai/_evals_common.py‎

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1564,13 +1564,63 @@ def _build_interaction_id_dataset(
15641564
return types.EvaluationDataset(eval_cases=eval_cases)
15651565

15661566

1567+
# Metrics supported for Managed Agent evaluation.
1568+
_MANAGED_AGENT_SUPPORTED_METRICS = frozenset(
1569+
{
1570+
"safety_v1",
1571+
"final_response_quality_v1",
1572+
"multi_turn_task_success_v1",
1573+
}
1574+
)
1575+
1576+
15671577
def _has_interactions_data_source(
15681578
eval_cases: list[types.EvalCase],
15691579
) -> bool:
15701580
"""Returns True if any EvalCase has interactions_data_source set."""
15711581
return any(case.interactions_data_source is not None for case in eval_cases)
15721582

15731583

1584+
def _validate_managed_agent_metrics(
1585+
agent: Optional[str],
1586+
metrics: Union[list[types.Metric], list[types.EvaluationRunMetric]],
1587+
) -> None:
1588+
"""Validates metrics are supported for Managed Agent evaluation.
1589+
1590+
When the ``agent`` parameter is a Gemini Agent resource name
1591+
(``projects/{p}/locations/{l}/agents/{id}``), only a subset of
1592+
metrics are supported for Preview. This function raises ValueError
1593+
if any unsupported metrics are requested.
1594+
1595+
Args:
1596+
agent: The agent resource name, or None.
1597+
metrics: The list of metrics to validate. Accepts either
1598+
``types.Metric`` objects (which expose a ``name`` attribute)
1599+
or ``types.EvaluationRunMetric`` objects (which expose a
1600+
``metric`` attribute holding the metric name string).
1601+
1602+
Raises:
1603+
ValueError: If any metric is not in the supported set.
1604+
"""
1605+
if not agent or not _is_gemini_agent_resource(agent):
1606+
return
1607+
1608+
unsupported = []
1609+
for metric in metrics:
1610+
# EvaluationRunMetric uses `.metric` (str); types.Metric uses `.name`.
1611+
name = getattr(metric, "metric", None) or getattr(metric, "name", None)
1612+
if name:
1613+
name_lower = name.lower()
1614+
if name_lower not in _MANAGED_AGENT_SUPPORTED_METRICS:
1615+
unsupported.append(name_lower)
1616+
if unsupported:
1617+
raise ValueError(
1618+
f"Metrics {unsupported} are not supported for Managed Agent"
1619+
" evaluation. Supported metrics:"
1620+
f" {sorted(_MANAGED_AGENT_SUPPORTED_METRICS)}."
1621+
)
1622+
1623+
15741624
def _resolve_interactions_to_eval_cases(
15751625
api_client: BaseApiClient,
15761626
eval_cases: list[types.EvalCase],
@@ -3037,6 +3087,9 @@ def _execute_evaluation( # type: ignore[no-untyped-def]
30373087

30383088
resolved_metrics = _resolve_metrics(metrics, api_client)
30393089

3090+
# Validate metrics are supported for Managed Agent evaluation.
3091+
_validate_managed_agent_metrics(agent, resolved_metrics)
3092+
30403093
evaluation_run_config = _evals_metric_handlers.EvaluationRunConfig(
30413094
evals_module=evals.Evals(api_client_=api_client),
30423095
dataset=processed_eval_dataset,

‎agentplatform/_genai/evals.py‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3596,6 +3596,10 @@ def create_evaluation_run(
35963596

35973597
if isinstance(dataset, types.EvaluationDataset):
35983598
_evals_utils._validate_dataset_agent_data(dataset, inference_configs)
3599+
# Validate metrics are supported for Managed Agent evaluation.
3600+
# Pass metrics directly; _validate_managed_agent_metrics handles both
3601+
# EvaluationRunMetric (.metric field) and Metric (.name field).
3602+
_evals_common._validate_managed_agent_metrics(agent, metrics)
35993603
resolved_dataset = _evals_common._resolve_dataset(
36003604
self._api_client, dataset, dest, parsed_agent_info
36013605
)
@@ -6095,6 +6099,10 @@ async def create_evaluation_run(
60956099

60966100
if isinstance(dataset, types.EvaluationDataset):
60976101
_evals_utils._validate_dataset_agent_data(dataset, inference_configs)
6102+
# Validate metrics are supported for Managed Agent evaluation.
6103+
# Pass metrics directly; _validate_managed_agent_metrics handles both
6104+
# EvaluationRunMetric (.metric field) and Metric (.name field).
6105+
_evals_common._validate_managed_agent_metrics(agent, metrics)
60986106
resolved_dataset = _evals_common._resolve_dataset(
60996107
self._api_client, dataset, dest, parsed_agent_info
61006108
)

‎tests/unit/agentplatform/genai/replays/test_create_evaluation_run.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -952,7 +952,7 @@ def test_create_eval_run_with_gemini_agent(client):
952952
display_name="test_gemini_agent",
953953
dataset=types.EvaluationRunDataSource(evaluation_set=eval_set),
954954
dest=GCS_DEST,
955-
metrics=[GENERAL_QUALITY_METRIC],
955+
metrics=[FINAL_RESPONSE_QUALITY_METRIC],
956956
agent_info=types.evals.AgentInfo(name="gemini-agent"),
957957
agent=gemini_agent,
958958
user_simulator_config=types.evals.UserSimulatorConfig(max_turn=3),

‎tests/unit/agentplatform/genai/test_evals.py‎

Lines changed: 68 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10608,10 +10608,10 @@ def test_create_evaluation_run_passes_allow_cross_region_model(self):
1060810608
),
1060910609
metrics=[
1061010610
agentplatform_genai_types.EvaluationRunMetric(
10611-
metric="general_quality_v1",
10611+
metric="final_response_quality_v1",
1061210612
metric_config=agentplatform_genai_types.UnifiedMetric(
1061310613
predefined_metric_spec=genai_types.PredefinedMetricSpec(
10614-
metric_spec_name="general_quality_v1",
10614+
metric_spec_name="final_response_quality_v1",
1061510615
)
1061610616
),
1061710617
)
@@ -10650,10 +10650,10 @@ async def test_create_evaluation_run_async_passes_allow_cross_region_model(self)
1065010650
),
1065110651
metrics=[
1065210652
agentplatform_genai_types.EvaluationRunMetric(
10653-
metric="general_quality_v1",
10653+
metric="final_response_quality_v1",
1065410654
metric_config=agentplatform_genai_types.UnifiedMetric(
1065510655
predefined_metric_spec=genai_types.PredefinedMetricSpec(
10656-
metric_spec_name="general_quality_v1",
10656+
metric_spec_name="final_response_quality_v1",
1065710657
)
1065810658
),
1065910659
)
@@ -11767,6 +11767,70 @@ def test_non_sandbox_tool_before_user_input_not_merged(self):
1176711767
assert len(result.turns) == 2
1176811768

1176911769

11770+
class TestValidateManagedAgentMetrics:
11771+
"""Tests for _validate_managed_agent_metrics."""
11772+
11773+
MANAGED_AGENT = "projects/p/locations/global/agents/my-agent"
11774+
NON_MANAGED_AGENT = "projects/p/locations/global/reasoningEngines/123"
11775+
11776+
def _make_metric(self, name):
11777+
return agentplatform_genai_types.Metric(name=name)
11778+
11779+
def test_supported_metric_passes(self):
11780+
_evals_common._validate_managed_agent_metrics(
11781+
self.MANAGED_AGENT,
11782+
[self._make_metric("safety_v1")],
11783+
)
11784+
11785+
def test_multiple_supported_metrics_pass(self):
11786+
_evals_common._validate_managed_agent_metrics(
11787+
self.MANAGED_AGENT,
11788+
[
11789+
self._make_metric("safety_v1"),
11790+
self._make_metric("final_response_quality_v1"),
11791+
self._make_metric("multi_turn_task_success_v1"),
11792+
],
11793+
)
11794+
11795+
def test_unsupported_metric_raises(self):
11796+
with pytest.raises(ValueError, match="not supported for Managed Agent"):
11797+
_evals_common._validate_managed_agent_metrics(
11798+
self.MANAGED_AGENT,
11799+
[self._make_metric("hallucination_v1")],
11800+
)
11801+
11802+
def test_unsupported_metric_lists_supported(self):
11803+
with pytest.raises(ValueError, match="multi_turn_task_success_v1"):
11804+
_evals_common._validate_managed_agent_metrics(
11805+
self.MANAGED_AGENT,
11806+
[self._make_metric("multi_turn_trajectory_quality_v1")],
11807+
)
11808+
11809+
def test_non_managed_agent_allows_any_metric(self):
11810+
# Non-Managed Agent (reasoning engine) should allow any metric.
11811+
_evals_common._validate_managed_agent_metrics(
11812+
self.NON_MANAGED_AGENT,
11813+
[self._make_metric("hallucination_v1")],
11814+
)
11815+
11816+
def test_no_agent_allows_any_metric(self):
11817+
# No agent parameter should allow any metric.
11818+
_evals_common._validate_managed_agent_metrics(
11819+
None,
11820+
[self._make_metric("hallucination_v1")],
11821+
)
11822+
11823+
def test_mixed_supported_and_unsupported_raises(self):
11824+
with pytest.raises(ValueError, match="not supported"):
11825+
_evals_common._validate_managed_agent_metrics(
11826+
self.MANAGED_AGENT,
11827+
[
11828+
self._make_metric("safety_v1"),
11829+
self._make_metric("hallucination_v1"),
11830+
],
11831+
)
11832+
11833+
1177011834
class TestMergeTextPartsInAgentData:
1177111835
"""Tests for _merge_text_parts_in_agent_data."""
1177211836

0 commit comments

Comments
 (0)