Skip to content

Commit 793c3fc

Browse files
needuvw-javed
authored andcommitted
Make Credentials Required for Content Safety and Protected Materials Evaluators (Azure#37707)
* Make Credentials Required for Content Safety Evaluators * fix a typo * lint, fix content safety evaluator * revert test change * remove credential from rai_service
1 parent db68d9d commit 793c3fc

File tree

17 files changed

+58
-71
lines changed

17 files changed

+58
-71
lines changed

sdk/evaluation/azure-ai-evaluation/CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
### Breaking Changes
88

99
- Removed `numpy` dependency. All NaN values returned by the SDK have been changed to from `numpy.nan` to `math.nan`.
10+
- `credential` is now required to be passed in for all content safety evaluators and `ProtectedMaterialsEvaluator`. `DefaultAzureCredential` will no longer be chosen if a credential is not passed.
1011

1112
### Bugs Fixed
1213

sdk/evaluation/azure-ai-evaluation/azure/ai/evaluation/_common/rai_service.py

-5
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
from azure.ai.evaluation._http_utils import get_async_http_client
2121
from azure.ai.evaluation._model_configurations import AzureAIProject
2222
from azure.core.credentials import TokenCredential
23-
from azure.identity import DefaultAzureCredential
2423

2524
from .constants import (
2625
CommonConstants,
@@ -438,10 +437,6 @@ async def evaluate_with_rai_service(
438437
:return: The parsed annotation result.
439438
:rtype: List[List[Dict]]
440439
"""
441-
# Use DefaultAzureCredential if no credential is provided
442-
# This is for the for batch run scenario as the credential cannot be serialized by promoptflow
443-
if credential is None or credential == {}:
444-
credential = DefaultAzureCredential()
445440

446441
# Get RAI service URL from discovery service and check service availability
447442
token = await fetch_or_reuse_token(credential)

sdk/evaluation/azure-ai-evaluation/azure/ai/evaluation/_evaluators/_common/_base_rai_svc_eval.py

+8-12
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from typing import Dict, Optional
66
from typing_extensions import override
77

8-
from azure.identity import DefaultAzureCredential
8+
from azure.core.credentials import TokenCredential
99
from azure.ai.evaluation._common.constants import EvaluationMetrics
1010
from azure.ai.evaluation._common.rai_service import evaluate_with_rai_service
1111
from azure.ai.evaluation._exceptions import EvaluationException
@@ -17,32 +17,28 @@ class RaiServiceEvaluatorBase(EvaluatorBase):
1717
This includes content safety evaluators, protected material evaluators, and others. These evaluators
1818
are all assumed to be of the "query and response or conversation" input variety.
1919
20-
param eval_metric: The evaluation metric to be used for evaluation. This is used by the API call logic
21-
to specify which evaluation to perform.
22-
type eval_metric: ~azure.ai.evaluation._common.constants.EvaluationMetrics
23-
param eval_last_turn: If True, only the last turn of the conversation will be evaluated, and no
20+
:param eval_metric: The evaluation metric to be used for evaluation. This is used by the API call logic
21+
to specify which evaluation to perform.
22+
:type eval_metric: ~azure.ai.evaluation._common.constants.EvaluationMetrics
23+
:param eval_last_turn: If True, only the last turn of the conversation will be evaluated, and no
2424
aggregation will be performed. If False, all turns will be evaluated and the numeric results will be,
2525
aggregated. Per-turn results are still be available in the output via the "evaluation_per_turn" key
2626
when this occurs. Default is False, resulting full conversation evaluation and aggregation.
27-
type eval_last_turn: bool
27+
:type eval_last_turn: bool
2828
"""
2929

3030
@override
3131
def __init__(
3232
self,
3333
eval_metric: EvaluationMetrics,
3434
azure_ai_project: dict,
35-
credential: Optional[dict] = None,
35+
credential: TokenCredential,
3636
eval_last_turn: bool = False,
3737
):
3838
super().__init__(eval_last_turn=eval_last_turn)
3939
self._eval_metric = eval_metric
4040
self._azure_ai_project = azure_ai_project
41-
if credential is None:
42-
# Use DefaultCredential if no credential is provided
43-
self._credential = DefaultAzureCredential()
44-
else:
45-
self._credential = credential
41+
self._credential = credential
4642

4743
@override
4844
def __call__(

sdk/evaluation/azure-ai-evaluation/azure/ai/evaluation/_evaluators/_content_safety/_content_safety.py

+7-7
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,13 @@ class ContentSafetyEvaluator:
2121
"""
2222
Initialize a content safety evaluator configured to evaluate content safetry metrics for QA scenario.
2323
24+
:param credential: The credential for connecting to Azure AI project. Required
25+
:type credential: ~azure.core.credentials.TokenCredential
2426
:param azure_ai_project: The scope of the Azure AI project.
2527
It contains subscription id, resource group, and project name.
2628
:type azure_ai_project: ~azure.ai.evaluation.AzureAIProject
2729
:param parallel: If True, use parallel execution for evaluators. Else, use sequential execution.
2830
Default is True.
29-
:param credential: The credential for connecting to Azure AI project.
30-
:type credential: ~azure.core.credentials.TokenCredential
3131
:return: A function that evaluates content-safety metrics for "question-answering" scenario.
3232
:rtype: Callable
3333
@@ -66,13 +66,13 @@ class ContentSafetyEvaluator:
6666
}
6767
"""
6868

69-
def __init__(self, azure_ai_project: dict, parallel: bool = True, credential=None):
69+
def __init__(self, credential, azure_ai_project: dict, parallel: bool = True):
7070
self._parallel = parallel
7171
self._evaluators = [
72-
ViolenceEvaluator(azure_ai_project, credential),
73-
SexualEvaluator(azure_ai_project, credential),
74-
SelfHarmEvaluator(azure_ai_project, credential),
75-
HateUnfairnessEvaluator(azure_ai_project, credential),
72+
ViolenceEvaluator(credential, azure_ai_project),
73+
SexualEvaluator(credential, azure_ai_project),
74+
SelfHarmEvaluator(credential, azure_ai_project),
75+
HateUnfairnessEvaluator(credential, azure_ai_project),
7676
]
7777

7878
def __call__(self, *, query: str, response: str, **kwargs):

sdk/evaluation/azure-ai-evaluation/azure/ai/evaluation/_evaluators/_content_safety/_content_safety_chat.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ class ContentSafetyChatEvaluator:
2929
"""
3030
Initialize a content safety chat evaluator configured to evaluate content safetry metrics for chat scenario.
3131
32+
:param credential: The credential for connecting to Azure AI project. Required
33+
:type credential: ~azure.core.credentials.TokenCredential
3234
:param azure_ai_project: The scope of the Azure AI project.
3335
It contains subscription id, resource group, and project name.
3436
:type azure_ai_project: ~azure.ai.evaluation.AzureAIProject
@@ -38,8 +40,6 @@ class ContentSafetyChatEvaluator:
3840
:param parallel: If True, use parallel execution for evaluators. Else, use sequential execution.
3941
Default is True.
4042
:type parallel: bool
41-
:param credential: The credential for connecting to Azure AI project.
42-
:type credential: ~azure.core.credentials.TokenCredential
4343
:return: A function that evaluates and generates metrics for "chat" scenario.
4444
:rtype: Callable
4545
@@ -88,7 +88,7 @@ class ContentSafetyChatEvaluator:
8888
}
8989
"""
9090

91-
def __init__(self, azure_ai_project: dict, eval_last_turn: bool = False, parallel: bool = True, credential=None):
91+
def __init__(self, credential, azure_ai_project: dict, eval_last_turn: bool = False, parallel: bool = True):
9292
self._eval_last_turn = eval_last_turn
9393
self._parallel = parallel
9494
self._evaluators = [

sdk/evaluation/azure-ai-evaluation/azure/ai/evaluation/_evaluators/_content_safety/_hate_unfairness.py

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
# ---------------------------------------------------------
22
# Copyright (c) Microsoft Corporation. All rights reserved.
33
# ---------------------------------------------------------
4-
from typing import Optional
54
from typing_extensions import override
65
from azure.ai.evaluation._common.constants import EvaluationMetrics
76
from azure.ai.evaluation._evaluators._common import RaiServiceEvaluatorBase
@@ -11,11 +10,11 @@ class HateUnfairnessEvaluator(RaiServiceEvaluatorBase):
1110
"""
1211
Initialize a hate-unfairness evaluator for hate unfairness score.
1312
13+
:param credential: The credential for connecting to Azure AI project. Required
14+
:type credential: ~azure.core.credentials.TokenCredential
1415
:param azure_ai_project: The scope of the Azure AI project.
1516
It contains subscription id, resource group, and project name.
1617
:type azure_ai_project: ~azure.ai.evaluation.AzureAIProject
17-
:param credential: The credential for connecting to Azure AI project.
18-
:type credential: Optional[~azure.core.credentials.TokenCredential]
1918
2019
**Usage**
2120
@@ -43,8 +42,8 @@ class HateUnfairnessEvaluator(RaiServiceEvaluatorBase):
4342
@override
4443
def __init__(
4544
self,
45+
credential,
4646
azure_ai_project: dict,
47-
credential: Optional[dict] = None,
4847
eval_last_turn: bool = False,
4948
):
5049
super().__init__(

sdk/evaluation/azure-ai-evaluation/azure/ai/evaluation/_evaluators/_content_safety/_self_harm.py

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
# ---------------------------------------------------------
22
# Copyright (c) Microsoft Corporation. All rights reserved.
33
# ---------------------------------------------------------
4-
from typing import Optional
54
from typing_extensions import override
65
from azure.ai.evaluation._common.constants import EvaluationMetrics
76
from azure.ai.evaluation._evaluators._common import RaiServiceEvaluatorBase
@@ -11,11 +10,11 @@ class SelfHarmEvaluator(RaiServiceEvaluatorBase):
1110
"""
1211
Initialize a self harm evaluator for self harm score.
1312
13+
:param credential: The credential for connecting to Azure AI project. Required
14+
:type credential: ~azure.core.credentials.TokenCredential
1415
:param azure_ai_project: The scope of the Azure AI project.
1516
It contains subscription id, resource group, and project name.
1617
:type azure_ai_project: ~azure.ai.evaluation.AzureAIProject
17-
:param credential: The credential for connecting to Azure AI project.
18-
:type credential: Optional[~azure.core.credentials.TokenCredential]
1918
2019
**Usage**
2120
@@ -43,8 +42,8 @@ class SelfHarmEvaluator(RaiServiceEvaluatorBase):
4342
@override
4443
def __init__(
4544
self,
45+
credential,
4646
azure_ai_project: dict,
47-
credential: Optional[dict] = None,
4847
eval_last_turn: bool = False,
4948
):
5049
super().__init__(

sdk/evaluation/azure-ai-evaluation/azure/ai/evaluation/_evaluators/_content_safety/_sexual.py

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
# ---------------------------------------------------------
22
# Copyright (c) Microsoft Corporation. All rights reserved.
33
# ---------------------------------------------------------
4-
from typing import Optional
54
from typing_extensions import override
65
from azure.ai.evaluation._common.constants import EvaluationMetrics
76
from azure.ai.evaluation._evaluators._common import RaiServiceEvaluatorBase
@@ -11,11 +10,11 @@ class SexualEvaluator(RaiServiceEvaluatorBase):
1110
"""
1211
Initialize a sexual evaluator for sexual score.
1312
13+
:param credential: The credential for connecting to Azure AI project. Required
14+
:type credential: ~azure.core.credentials.TokenCredential
1415
:param azure_ai_project: The scope of the Azure AI project.
1516
It contains subscription id, resource group, and project name.
1617
:type azure_ai_project: ~azure.ai.evaluation.AzureAIProject
17-
:param credential: The credential for connecting to Azure AI project.
18-
:type credential: Optional[~azure.core.credentials.TokenCredential]
1918
2019
**Usage**
2120
@@ -43,8 +42,8 @@ class SexualEvaluator(RaiServiceEvaluatorBase):
4342
@override
4443
def __init__(
4544
self,
45+
credential,
4646
azure_ai_project: dict,
47-
credential: Optional[dict] = None,
4847
eval_last_turn: bool = False,
4948
):
5049
super().__init__(

sdk/evaluation/azure-ai-evaluation/azure/ai/evaluation/_evaluators/_content_safety/_violence.py

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
# ---------------------------------------------------------
22
# Copyright (c) Microsoft Corporation. All rights reserved.
33
# ---------------------------------------------------------
4-
from typing import Optional
54
from typing_extensions import override
65
from azure.ai.evaluation._common.constants import EvaluationMetrics
76
from azure.ai.evaluation._evaluators._common import RaiServiceEvaluatorBase
@@ -11,11 +10,11 @@ class ViolenceEvaluator(RaiServiceEvaluatorBase):
1110
"""
1211
Initialize a violence evaluator for violence score.
1312
13+
:param credential: The credential for connecting to Azure AI project. Required
14+
:type credential: ~azure.core.credentials.TokenCredential
1415
:param azure_ai_project: The scope of the Azure AI project.
1516
It contains subscription id, resource group, and project name.
1617
:type azure_ai_project: ~azure.ai.evaluation.AzureAIProject
17-
:param credential: The credential for connecting to Azure AI project.
18-
:type credential: Optional[~azure.core.credentials.TokenCredential]
1918
2019
**Usage**
2120
@@ -43,8 +42,8 @@ class ViolenceEvaluator(RaiServiceEvaluatorBase):
4342
@override
4443
def __init__(
4544
self,
45+
credential,
4646
azure_ai_project: dict,
47-
credential: Optional[dict] = None,
4847
eval_last_turn: bool = False,
4948
):
5049
super().__init__(

sdk/evaluation/azure-ai-evaluation/azure/ai/evaluation/_evaluators/_eci/_eci.py

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
# ---------------------------------------------------------
22
# Copyright (c) Microsoft Corporation. All rights reserved.
33
# ---------------------------------------------------------
4-
from typing import Optional
54
from typing_extensions import override
65
from azure.ai.evaluation._common.constants import _InternalEvaluationMetrics
76
from azure.ai.evaluation._evaluators._common import RaiServiceEvaluatorBase
@@ -17,11 +16,11 @@ class ECIEvaluator(RaiServiceEvaluatorBase):
1716
"AI-generated content may be incorrect. If you are seeking ECI-related information, please go to Bing Search."
1817
Outputs True or False with AI-generated reasoning.
1918
19+
:param credential: The credential for connecting to Azure AI project. Required
20+
:type credential: ~azure.core.credentials.TokenCredential
2021
:param azure_ai_project: The scope of the Azure AI project.
2122
It contains subscription id, resource group, and project name.
2223
:type azure_ai_project: ~azure.ai.evaluation.AzureAIProject
23-
:param credential: The credential for connecting to Azure AI project.
24-
:type credential: Optional[~azure.core.credentials.TokenCredential]
2524
:return: Whether or not ECI was found in the response without a disclaimer, with AI-generated reasoning
2625
:rtype: Dict[str, str]
2726
@@ -50,8 +49,8 @@ class ECIEvaluator(RaiServiceEvaluatorBase):
5049
@override
5150
def __init__(
5251
self,
52+
credential,
5353
azure_ai_project: dict,
54-
credential: Optional[dict] = None,
5554
eval_last_turn: bool = False,
5655
):
5756
super().__init__(

sdk/evaluation/azure-ai-evaluation/azure/ai/evaluation/_evaluators/_protected_material/_protected_material.py

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
# ---------------------------------------------------------
22
# Copyright (c) Microsoft Corporation. All rights reserved.
33
# ---------------------------------------------------------
4-
from typing import Optional
54
from typing_extensions import override
65
from azure.ai.evaluation._common.constants import EvaluationMetrics
76
from azure.ai.evaluation._evaluators._common import RaiServiceEvaluatorBase
@@ -12,11 +11,11 @@ class ProtectedMaterialEvaluator(RaiServiceEvaluatorBase):
1211
Initialize a protected material evaluator to detect whether protected material
1312
is present in your AI system's response. Outputs True or False with AI-generated reasoning.
1413
14+
:param credential: The credential for connecting to Azure AI project. Required
15+
:type credential: ~azure.core.credentials.TokenCredential
1516
:param azure_ai_project: The scope of the Azure AI project.
1617
It contains subscription id, resource group, and project name.
1718
:type azure_ai_project: ~azure.ai.evaluation.AzureAIProject
18-
:param credential: The credential for connecting to Azure AI project.
19-
:type credential: Optional[~azure.core.credentials.TokenCredential]
2019
:return: Whether or not protected material was found in the response, with AI-generated reasoning.
2120
:rtype: Dict[str, str]
2221
@@ -45,8 +44,8 @@ class ProtectedMaterialEvaluator(RaiServiceEvaluatorBase):
4544
@override
4645
def __init__(
4746
self,
47+
credential,
4848
azure_ai_project: dict,
49-
credential: Optional[dict] = None,
5049
eval_last_turn: bool = False,
5150
):
5251
super().__init__(

sdk/evaluation/azure-ai-evaluation/azure/ai/evaluation/_evaluators/_protected_materials/_protected_materials.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,11 @@ class ProtectedMaterialsEvaluator:
5454
Initialize a protected materials evaluator to detect whether protected material
5555
is present in your AI system's response. Outputs True or False with AI-generated reasoning.
5656
57+
:param credential: The credential for connecting to Azure AI project. Required
58+
:type credential: ~azure.core.credentials.TokenCredential
5759
:param azure_ai_project: The scope of the Azure AI project.
5860
It contains subscription id, resource group, and project name.
5961
:type azure_ai_project: ~azure.ai.evaluation.AzureAIProject
60-
:param credential: The credential for connecting to Azure AI project.
61-
:type credential: ~azure.core.credentials.TokenCredential
6262
:return: Whether or not protected material was found in the response, with AI-generated reasoning.
6363
:rtype: Dict[str, str]
6464
@@ -84,7 +84,7 @@ class ProtectedMaterialsEvaluator:
8484
}
8585
"""
8686

87-
def __init__(self, azure_ai_project: dict, credential=None):
87+
def __init__(self, credential, azure_ai_project: dict):
8888
self._async_evaluator = _AsyncProtectedMaterialsEvaluator(azure_ai_project, credential)
8989

9090
def __call__(self, *, query: str, response: str, **kwargs):

sdk/evaluation/azure-ai-evaluation/azure/ai/evaluation/_evaluators/_xpia/xpia.py

+3-4
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
# ---------------------------------------------------------
44
import logging
55

6-
from typing import Optional
76
from typing_extensions import override
87
from azure.ai.evaluation._common.constants import EvaluationMetrics
98
from azure.ai.evaluation._evaluators._common import RaiServiceEvaluatorBase
@@ -17,14 +16,14 @@ class IndirectAttackEvaluator(RaiServiceEvaluatorBase):
1716
1817
Detect whether cross domain injected attacks are present in your AI system's response.
1918
19+
:param credential: The credential for connecting to Azure AI project. Required
20+
:type credential: ~azure.core.credentials.TokenCredential
2021
:param azure_ai_project: The scope of the Azure AI project. It contains subscription id, resource group, and project
2122
name.
2223
:type azure_ai_project: ~azure.ai.evaluation.AzureAIProject
2324
:param eval_last_turn: Set to True to evaluate only the most recent exchange in the dialogue,
2425
focusing on the latest user inquiry and the assistant's corresponding response. Defaults to False
2526
:type eval_last_turn: bool
26-
:param credential: The credential for connecting to Azure AI project.
27-
:type credential: Optional[~azure.core.credentials.TokenCredential]
2827
:return: A function that evaluates and generates metrics for XPIA chat scenario. Metrics include the overall
2928
evaluation label and reason for the Q/A Pair, as well as sub-labels for manipulated content, intrusion, and
3029
information.
@@ -53,8 +52,8 @@ class IndirectAttackEvaluator(RaiServiceEvaluatorBase):
5352
@override
5453
def __init__(
5554
self,
55+
credential,
5656
azure_ai_project: dict,
57-
credential: Optional[dict] = None,
5857
eval_last_turn: bool = False,
5958
):
6059
super().__init__(

sdk/evaluation/azure-ai-evaluation/setup.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,8 @@
6868
"promptflow-devkit>=1.15.0",
6969
"promptflow-core>=1.15.0",
7070
"pyjwt>=2.8.0",
71-
"azure-identity>=1.12.0",
71+
# pickle support for credentials was added to this release
72+
"azure-identity>=1.16.0",
7273
"azure-core>=1.30.2",
7374
"nltk>=3.9.1",
7475
"rouge-score>=0.1.2",

0 commit comments

Comments
 (0)