AzureContentModerationMiddleware(
self,
endpoint: Optional[str] = None,
credential: Optional[Any] = None,
*,
project_endpoint: Optional[str] = None,
categories: Optional[List[Literal['Hate', 'SelfHarm', 'Sexual', 'Violence']]] = None,
severity_threshold: int = 4,
exit_behavior: Literal['error', 'continue', 'replace'] = 'error',
violation_message: Optional[str] = None,
apply_to_input: bool = True,
apply_to_output: bool = True,
blocklist_names: Optional[List[str]] = None,
name: str = 'azure_content_safety',
context_extractor: Optional[Callable[[AgentState[Any], Runtime[Any]], Optional[TextModerationInput]]] = None
)_AzureContentSafetyBaseMiddlewareAgentMiddleware that screens text messages with Azure AI Content Safety.
Pass this class (or multiple instances) in the middleware parameter of
any LangChain create_agent call:
from langchain.agents import create_agent
from langchain_azure_ai.agents.middleware import (
AzureContentModerationMiddleware
)
agent = create_agent(
model="azure_ai:gpt-4.1",
middleware=[
# Screen both input and output text for all harm categories
AzureContentModerationMiddleware(
endpoint="https://my-resource.cognitiveservices.azure.com/",
exit_behavior="error",
),
],
)
You can compose multiple instances with different configurations:
agent = create_agent(
model="azure_ai:gpt-4.1",
middleware=[
# Raise on hate/violence on input only
AzureContentModerationMiddleware(
categories=["Hate", "Violence"],
exit_behavior="error",
apply_to_input=True,
apply_to_output=False,
name="input_safety",
),
# Replace self-harm content in model output and continue
AzureContentModerationMiddleware(
categories=["SelfHarm"],
exit_behavior="continue",
apply_to_input=False,
apply_to_output=True,
name="output_safety",
),
],
)
The middleware analyses text content using the Azure AI Content Safety API and takes one of three actions when violations are detected:
"error" – raises :exc:ContentSafetyViolationError, halting the graph."replace" – replaces the offending message with a violation notice
(either a service-derived description or a custom violation_message)
and lets execution proceed."continue" – ignores the violation and lets execution proceed by
adding annotations to the message metadata with details of the violation(s).Both synchronous (before_agent / after_agent) and asynchronous
(abefore_agent / aafter_agent) hooks are implemented.
By default the middleware extracts the last HumanMessage (input) or
AIMessage (output) and submits its text to the service. You can
override this behaviour by supplying a context_extractor callable::
from langchain_azure_ai.agents.middleware import (
AzureContentModerationMiddleware,
TextModerationInput,
)
def my_extractor(state, runtime):
# Return None to skip moderation for this call
messages = state.get("messages", [])
text = " ".join(m.content for m in messages if hasattr(m, "content"))
return TextModerationInput(text=text) if text else None
middleware = AzureContentModerationMiddleware(
context_extractor=my_extractor,
)Default: None |
categories | Optional[List[Literal['Hate', 'SelfHarm', 'Sexual', 'Violence']]] | Default: None |
severity_threshold | int | Default: 4 |
exit_behavior | Literal['error', 'continue', 'replace'] | Default: 'error' |
violation_message | Optional[str] | Default: None |
apply_to_input | bool | Default: True |
apply_to_output | bool | Default: True |
blocklist_names | Optional[List[str]] | Default: None |
name | str | Default: 'azure_content_safety' |
context_extractor | Optional[Callable[[AgentState[Any], Runtime[Any]], Optional[TextModerationInput]]] | Default: None |
| Optional[List[Literal['Hate', 'SelfHarm', 'Sexual', 'Violence']]] |
| severity_threshold | int |
| exit_behavior | Literal['error', 'continue', 'replace'] |
| violation_message | Optional[str] |
| apply_to_input | bool |
| apply_to_output | bool |
| blocklist_names | Optional[List[str]] |
| name | str |
| context_extractor | Optional[Callable[[AgentState[Any], Runtime[Any]], Optional[TextModerationInput]]] |
Azure Content Safety resource endpoint URL. Falls back to
the AZURE_CONTENT_SAFETY_ENDPOINT environment variable.
Mutually exclusive with project_endpoint.
Azure credential. Accepts a
:class:~azure.core.credentials.TokenCredential,
:class:~azure.core.credentials.AzureKeyCredential, or a plain
API-key string. Defaults to
:class:~azure.identity.DefaultAzureCredential when None.
Build a NonStandardAnnotation for text content safety evaluations.
Parse an AnalyzeTextResult into typed evaluation objects.
Returns all category evaluations and any blocklist matches. Threshold filtering is NOT applied here — callers decide which evaluations constitute violations.
Screen the last HumanMessage before the agent runs.
Screen the last AIMessage after the agent runs.
Async version of :meth:before_agent.
Async version of :meth:after_agent.
Azure AI Foundry project endpoint URL (e.g.
https://<resource>.services.ai.azure.com/api/projects/<project>).
Falls back to the AZURE_AI_PROJECT_ENDPOINT environment variable.
Mutually exclusive with endpoint.
Harm categories to analyse. Valid values are "Hate",
"SelfHarm", "Sexual", and "Violence". Defaults to all
four.
Minimum severity score (0–6) that triggers the
configured exit behaviour. Defaults to 4 (medium).
What to do when a violation is detected. One of
"error" (default), "continue", or "replace".
Custom text used to replace the offending message
when exit_behavior="replace". Defaults to a message built
from the service response.
Whether to screen the agent's input (last
HumanMessage). Defaults to True.
Whether to screen the agent's output (last
AIMessage). Defaults to True.
Names of custom blocklists configured in your Azure Content Safety resource. Matches against these lists in addition to the built-in harm classifiers.
Node-name prefix used when wiring this middleware into a
LangGraph. Defaults to "azure_content_safety".
Optional callable with signature
(state, runtime) -> Optional[TextModerationInput]
that receives the current graph state and the LangGraph
:class:~langchain.agents.middleware.Runtime execution context,
and returns the text to screen, or None to skip evaluation
entirely. When None (default) the middleware uses its
built-in extraction logic.