-
Notifications
You must be signed in to change notification settings - Fork 3.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Python: Supports better exceptions when Azure OpenAI content filterin…
…g is triggered (#4428) ### Motivation and Context When an Azure OpenAI content filter error is triggered the current `AIException` hides the details of that specific error. This makes it hard for the consumer to see a more detailed description of the error in their prompt or input. Solves #4197 ### Description Detects when a content filter error is raised, then parses the meaningful information about it and raises a new `ContentFilterAIException` with that information ready for the consumer to use. ### Contribution Checklist - [X] The code builds clean without any errors or warnings - [X] The PR follows the [SK Contribution Guidelines](https://github.com/microsoft/semantic-kernel/blob/main/CONTRIBUTING.md) and the [pre-submission formatting script](https://github.com/microsoft/semantic-kernel/blob/main/CONTRIBUTING.md#development-scripts) raises no violations - [X] All unit tests pass, and I have added new tests where possible - [X] I didn't break anyone 😄 --------- Co-authored-by: Evan Mattson <35585003+moonbox3@users.noreply.github.com>
- Loading branch information
1 parent
fa3e32b
commit 7f68a88
Showing
5 changed files
with
202 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
1 change: 1 addition & 0 deletions
1
python/semantic_kernel/connectors/ai/open_ai/exceptions/__init__.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
# Copyright (c) Microsoft. All rights reserved. |
112 changes: 112 additions & 0 deletions
112
python/semantic_kernel/connectors/ai/open_ai/exceptions/content_filter_ai_exception.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
# Copyright (c) Microsoft. All rights reserved. | ||
|
||
from dataclasses import dataclass | ||
from enum import Enum | ||
from typing import Any, Dict | ||
|
||
from openai import BadRequestError | ||
|
||
from semantic_kernel.connectors.ai.ai_exception import AIException | ||
|
||
|
||
class ContentFilterResultSeverity(Enum): | ||
HIGH = "high" | ||
MEDIUM = "medium" | ||
SAFE = "safe" | ||
|
||
|
||
@dataclass | ||
class ContentFilterResult: | ||
filtered: bool = False | ||
detected: bool = False | ||
severity: ContentFilterResultSeverity = ContentFilterResultSeverity.SAFE | ||
|
||
@classmethod | ||
def from_inner_error_result(cls, inner_error_results: Dict[str, Any]) -> "ContentFilterResult": | ||
"""Creates a ContentFilterResult from the inner error results. | ||
Arguments: | ||
key {str} -- The key to get the inner error result from. | ||
inner_error_results {Dict[str, Any]} -- The inner error results. | ||
Returns: | ||
ContentFilterResult -- The ContentFilterResult. | ||
""" | ||
return cls( | ||
filtered=inner_error_results.get("filtered", False), | ||
detected=inner_error_results.get("detected", False), | ||
severity=ContentFilterResultSeverity( | ||
inner_error_results.get("severity", ContentFilterResultSeverity.SAFE.value) | ||
), | ||
) | ||
|
||
|
||
class ContentFilterCodes(Enum): | ||
RESPONSIBLE_AI_POLICY_VIOLATION = "ResponsibleAIPolicyViolation" | ||
|
||
|
||
class ContentFilterAIException(AIException): | ||
"""AI exception for an error from Azure OpenAI's content filter""" | ||
|
||
# The parameter that caused the error. | ||
_param: str | ||
|
||
# The error code specific to the content filter. | ||
_content_filter_code: ContentFilterCodes | ||
|
||
# The results of the different content filter checks. | ||
_content_filter_result: Dict[str, ContentFilterResult] | ||
|
||
def __init__( | ||
self, | ||
error_code: AIException.ErrorCodes, | ||
message: str, | ||
inner_exception: BadRequestError, | ||
) -> None: | ||
"""Initializes a new instance of the ContentFilterAIException class. | ||
Arguments: | ||
error_code {ErrorCodes} -- The error code. | ||
message {str} -- The error message. | ||
inner_exception {Exception} -- The inner exception. | ||
""" | ||
super().__init__(error_code, message, inner_exception) | ||
|
||
self._param = inner_exception.param | ||
|
||
inner_error = inner_exception.body.get("innererror", {}) | ||
self._content_filter_code = ContentFilterCodes(inner_error.get("code", "")) | ||
self._content_filter_result = dict( | ||
[ | ||
key, | ||
ContentFilterResult.from_inner_error_result(values), | ||
] | ||
for key, values in inner_error.get("content_filter_result", {}).items() | ||
) | ||
|
||
@property | ||
def param(self) -> str: | ||
"""Gets the parameter that caused the error. | ||
Returns: | ||
str -- The parameter that caused the error. | ||
""" | ||
return self._param | ||
|
||
@property | ||
def content_filter_code(self) -> ContentFilterCodes: | ||
"""Gets the error code specific to the content filter. | ||
Returns: | ||
ContentFilterCode -- The error code specific to the content filter. | ||
""" | ||
return self._content_filter_code | ||
|
||
@property | ||
def content_filter_result(self) -> Dict[str, ContentFilterResult]: | ||
"""Gets the result of the content filter checks. | ||
Returns: | ||
Dict[str, ContentFilterResult] -- The result of the content filter checks. | ||
""" | ||
return self._content_filter_result |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters