Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions samples/python/hosted-agents/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ The platform manages conversation history, streaming lifecycle, and background e
9. **[Declarative Workflows](./agent-framework/responses/09-declarative-customer-support/)** — A multi-turn customer-support triage workflow defined entirely in YAML and hosted as an agent, demonstrating declarative workflow authoring with `InvokeAzureAgent` calls to specialist Foundry-hosted agents and conversation-aware routing.
10. **[Downstream Azure services](./agent-framework/responses/09-downstream-azure/)** — Call Azure Blob Storage and Service Bus from the agent using its per-agent Microsoft Entra identity (no connection strings).
11. **[A2A Delegation](./agent-framework/a2a/01-delegation/)** — Two-agent walkthrough: a hosted Responses **caller** delegates to a hosted Responses **executor** that is exposed as an A2A endpoint via Foundry's incoming A2A feature, wired together through a Foundry Toolbox `a2a_preview` tool over a `RemoteA2A` connection.
12. **[Content safety guardrail](./agent-framework/responses/16-content-safety-guardrail/)** — Attach a Responsible AI content safety guardrail to a hosted agent so the platform screens prompts and responses against your safety policy.

### Invocations protocol

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
agent.manifest.yaml
agent.yaml
.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.venv
__pycache__
*.pyc
*.pyo
*.pyd
.Python
.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
FOUNDRY_PROJECT_ENDPOINT="..."
AZURE_AI_MODEL_DEPLOYMENT_NAME="..."
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
FROM python:3.12-slim

WORKDIR /app

COPY . user_agent/
WORKDIR /app/user_agent

RUN if [ -f requirements.txt ]; then \
pip install -r requirements.txt; \
else \
echo "No requirements.txt found"; \
fi

EXPOSE 8088

CMD ["python", "main.py"]
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
# Content safety guardrail (Responses protocol)

An [Agent Framework](https://github.com/microsoft/agent-framework) agent hosted on Microsoft Foundry using the **Responses protocol**, with a Responsible AI (RAI) **content safety guardrail** attached. The guardrail screens the prompts the agent receives and the responses it returns against an RAI policy, so harmful content is filtered according to your safety configuration.

## How it works

The agent itself is the basic `FoundryChatClient` agent served via `ResponsesHostServer` — see [main.py](main.py). The guardrail is **not** code; it's a definition-level setting. The agent declares a `policies` list with a `rai_policy` entry that points to an RAI policy by its full Azure Resource Manager (ARM) resource ID:

```yaml
policies:
- type: rai_policy
rai_policy_name: /subscriptions/<subscription-id>/resourceGroups/<resource-group>/providers/Microsoft.CognitiveServices/accounts/<account>/raiPolicies/<policy-name>
```

The platform applies that policy to the agent at runtime. When you omit the `policies` block, the platform applies the default policy, `Microsoft.DefaultV2`. For a conceptual overview, see [Add a content safety guardrail to a hosted agent](https://learn.microsoft.com/en-us/azure/foundry/agents/how-to/add-hosted-agent-guardrails).

## Prerequisites

1. An RAI policy created on your Foundry resource, and its full ARM resource ID. To create one, see [Configure guardrails and controls](https://learn.microsoft.com/en-us/azure/foundry/guardrails/how-to-create-guardrails). The ARM resource ID has this form:

```text
/subscriptions/<subscription-id>/resourceGroups/<resource-group>/providers/Microsoft.CognitiveServices/accounts/<account>/raiPolicies/<policy-name>
```

1. **Azure Developer CLI (`azd`)** — [Install azd](https://learn.microsoft.com/en-us/azure/developer/azure-developer-cli/install-azd), then install the AI agent extension and authenticate:

```bash
azd ext install azure.ai.agents
azd auth login
```

## Configure the guardrail

Set `rai_policy_name` to your RAI policy's full ARM resource ID in both [agent.yaml](agent.yaml) and [agent.manifest.yaml](agent.manifest.yaml). Use the full ARM resource ID, not the bare policy name.

## Option 1: Azure Developer CLI (`azd`)

### Initialize the agent project

No cloning required. Create a new folder and initialize from the manifest:

```bash
mkdir my-guardrail-agent && cd my-guardrail-agent

azd ai agent init -m https://github.com/microsoft-foundry/foundry-samples/blob/main/samples/python/hosted-agents/agent-framework/responses/16-content-safety-guardrail/agent.manifest.yaml
```

Follow the prompts to configure your Foundry project and model deployment. If you don't have an existing Foundry project, `azd ai agent init` guides you through creating one.

> [!NOTE]
> After init, confirm that `rai_policy_name` in the generated `agent.yaml` holds your policy's full ARM resource ID.

### Provision Azure resources (if needed)

If you don't already have a Foundry project and model deployment:

```bash
azd provision
```

> [!IMPORTANT]
> If you provisioned a new Foundry project, it doesn't have your RAI policy yet. Before you deploy, [create an RAI policy](https://learn.microsoft.com/en-us/azure/foundry/guardrails/how-to-create-guardrails) on the provisioned account, then set `rai_policy_name` in the generated `agent.yaml` to that policy's full ARM resource ID. Deploying with a placeholder or nonexistent policy ID fails.

### Deploy to Foundry

```bash
azd deploy
```

The platform applies the guardrail when it creates the agent version. For the full deployment guide, see [Deploy a hosted agent](https://learn.microsoft.com/en-us/azure/foundry/agents/how-to/deploy-hosted-agent).

### Invoke the deployed agent

```bash
azd ai agent invoke "Write a short friendly hello message."
```

## Option 2: VS Code (Foundry Toolkit)

1. Install the **[Foundry Toolkit](https://marketplace.visualstudio.com/items?itemName=ms-azuretools.azure-ai-foundry)** extension and sign in to Azure.
1. Open the Command Palette (`Ctrl+Shift+P`) and run **Foundry Toolkit: Create Hosted Agent**, then select this sample from the gallery. The extension scaffolds the project and generates `agent.yaml`.
1. Set `rai_policy_name` in the generated `agent.yaml` to your policy's full ARM resource ID.
1. Run **Foundry Toolkit: Deploy Hosted Agent** and follow the wizard to deploy.

## Verify the guardrail

After deployment, confirm the guardrail filters content by sending a benign prompt and a prompt that violates your policy to the agent's Responses endpoint. The platform screens prompts at the input stage and rejects a violating prompt before the agent runs.

A prompt that passes the policy returns `HTTP 200` with the agent's response. A blocked prompt returns `HTTP 400` with a `content_filter` error:

```json
{
"error": {
"code": "content_filter",
"message": "The request was blocked due to content safety policy violation at input stage.",
"type": "content_safety_error"
}
}
```

If a violating prompt isn't blocked, confirm that the policy referenced by `rai_policy_name` is configured to filter the relevant content category and severity.

## Next steps

- [Add a content safety guardrail to a hosted agent](https://learn.microsoft.com/en-us/azure/foundry/agents/how-to/add-hosted-agent-guardrails) — set a guardrail with `azd`, the Python SDK, or REST
- [Guardrails and controls overview](https://learn.microsoft.com/en-us/azure/foundry/guardrails/guardrails-overview) — what guardrails are and the risks they detect
- [Basic hosted agent](../01-basic/) — the agent this sample builds on
- [Manage hosted agents](https://learn.microsoft.com/en-us/azure/foundry/agents/how-to/manage-hosted-agent) — monitor and manage deployed agents
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: agent-framework-content-safety-guardrail
displayName: "Content safety guardrail (Agent Framework, Responses)"
description: >
An Agent Framework agent hosted by Foundry with a Responsible AI content
safety guardrail. The guardrail screens prompts and responses against an RAI
policy, so harmful content is filtered according to your safety configuration.
metadata:
tags:
- Agent Framework
- AI Agent Hosting
- Azure AI AgentServer
- Responses Protocol
- Content Safety
- Guardrails
template:
name: agent-framework-content-safety-guardrail
kind: hosted
protocols:
- protocol: responses
version: 1.0.0
# Content safety guardrail. Replace rai_policy_name with the full ARM resource
# ID of an RAI policy on your Foundry resource. See README.md for how to create
# one. Omit the policies block to use the default policy (Microsoft.DefaultV2).
policies:
- type: rai_policy
rai_policy_name: /subscriptions/<subscription-id>/resourceGroups/<resource-group>/providers/Microsoft.CognitiveServices/accounts/<account>/raiPolicies/<policy-name>
environment_variables:
- name: AZURE_AI_MODEL_DEPLOYMENT_NAME
value: "{{AZURE_AI_MODEL_DEPLOYMENT_NAME}}"
resources:
- kind: model
id: gpt-4.1-mini
name: AZURE_AI_MODEL_DEPLOYMENT_NAME
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# yaml-language-server: $schema=https://raw.githubusercontent.com/microsoft/AgentSchema/refs/heads/main/schemas/v1.0/ContainerAgent.yaml
kind: hosted
name: agent-framework-content-safety-guardrail
protocols:
- protocol: responses
version: 1.0.0
# Content safety guardrail. Replace rai_policy_name with the full ARM resource
# ID of an RAI policy on your Foundry resource. See README.md for how to create
# one. Omit the policies block to use the default policy (Microsoft.DefaultV2).
policies:
- type: rai_policy
rai_policy_name: /subscriptions/<subscription-id>/resourceGroups/<resource-group>/providers/Microsoft.CognitiveServices/accounts/<account>/raiPolicies/<policy-name>
resources:
cpu: '0.25'
memory: '0.5Gi'
environment_variables:
- name: AZURE_AI_MODEL_DEPLOYMENT_NAME
value: ${AZURE_AI_MODEL_DEPLOYMENT_NAME}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Copyright (c) Microsoft. All rights reserved.

import os

from agent_framework import Agent
from agent_framework.foundry import FoundryChatClient
from agent_framework_foundry_hosting import ResponsesHostServer
from azure.identity import DefaultAzureCredential
from dotenv import load_dotenv

# Load environment variables from .env file
load_dotenv()


def main():
client = FoundryChatClient(
project_endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"],
model=os.environ["AZURE_AI_MODEL_DEPLOYMENT_NAME"],
credential=DefaultAzureCredential(),
)

agent = Agent(
client=client,
instructions="You are a friendly assistant. Keep your answers brief.",
# History will be managed by the hosting infrastructure, thus there
# is no need to store history by the service. Learn more at:
# https://developers.openai.com/api/reference/resources/responses/methods/create
default_options={"store": False},
)

server = ResponsesHostServer(agent)
server.run()


if __name__ == "__main__":
main()
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
agent-framework>=1.2.2
agent-framework-foundry-hosting
Loading