Skip to content

Commit 451af58

Browse files
authored
Merge pull request #3201 from aahill/agents-vnet-2
Agents vnet 2
2 parents e8a3b22 + 2a262e0 commit 451af58

File tree

2 files changed

+290
-0
lines changed

2 files changed

+290
-0
lines changed
Lines changed: 288 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,288 @@
1+
---
2+
title: 'How to use a virtual network with the Azure AI Agent Service'
3+
titleSuffix: Azure OpenAI
4+
description: Learn how to use your own virtual network with the Azure AI Agent Service.
5+
services: cognitive-services
6+
manager: nitinme
7+
ms.service: azure-ai-agent-service
8+
ms.topic: how-to
9+
ms.date: 02/24/2025
10+
author: aahill
11+
ms.author: aahi
12+
ms.reviewer: fosteramanda
13+
ms.custom: azure-ai-agents
14+
---
15+
16+
# Create a new network-secured agent with user-managed identity
17+
18+
Azure AI Agent Service offers a standard agent configuration with private networking, allowing you to bring your own (BYO) private virtual network. This setup creates an isolated network environment that lets you securely access data and perform actions while maintaining full control over your network infrastructure. This guide provides a step-by-step walkthrough of the setup process and outlines all necessary requirements.
19+
20+
> [!NOTE]
21+
> Standard setup with private networking can only be configured by deploying the Bicep template described in this article. Once deployed, agents must be created using the SDK or REST API. You can't use the Azure AI Foundry portal to create agents in a project with private networking enabled.
22+
23+
## Benefits
24+
25+
- **No public egress**: foundational infrastructure ensures the right authentication and security for your agents and tools, without you having to do trusted service bypass.
26+
27+
- **Container injection**: allows the platform network to host APIs and inject a subnet into your network, enabling local communication of your Azure resources within the same virtual network.
28+
29+
- **Private resource access**: If your resources are marked as private and nondiscoverable from the internet, the platform network can still access them, provided the necessary credentials and authorization are in place.
30+
31+
### Known limitations
32+
33+
- Azure Blob Storage: Using Azure Blob Storage files with the File Search tool isn't supported.
34+
35+
## Prerequisites
36+
37+
1. An Azure subscription - [Create one for free](https://azure.microsoft.com/free/cognitive-services).
38+
2. [Python 3.8 or later](https://www.python.org/)
39+
3. Ensure that the individual deploying the template has the [Azure AI Developer role](/azure/ai-studio/concepts/rbac-ai-studio) assigned at the resource group level where the template is being deployed.
40+
4. Additionally, to deploy the template, you need to have the preset [Role Based Access Administrator](/azure/role-based-access-control/built-in-roles/privileged#role-based-access-control-administrator) role at the subscription level.
41+
* The **Owner** role at the subscription level satisfies this requirement.
42+
* The specific admin role that is needed is `Microsoft.Authorization/roleAssignments/write`
43+
5. Install [the Azure CLI and the machine learning extension](/azure/machine-learning/how-to-configure-cli). If you have the CLI already installed, make sure it's updated to the latest version.
44+
6. Register providers. The following providers must be registered:
45+
* `Microsoft.KeyVault`
46+
* `Microsoft.CognitiveServices`
47+
* `Microsoft.Storage`
48+
* `Microsoft.MachineLearningServices`
49+
* `Microsoft.Search`
50+
* `Microsoft.Network`
51+
* To use Bing Search tool: `Microsoft.Bing`
52+
53+
```console
54+
az provider register --namespace 'Microsoft.KeyVault'
55+
az provider register --namespace 'Microsoft.CognitiveServices'
56+
az provider register --namespace 'Microsoft.Storage'
57+
az provider register --namespace 'Microsoft.MachineLearningServices'
58+
az provider register --namespace 'Microsoft.Search'
59+
# only to use Grounding with Bing Search tool
60+
az provider register --namespace 'Microsoft.Bing'
61+
```
62+
63+
## Create a new network-secured agent with user-managed identity
64+
65+
**Network secured setup**: Agents use customer-owned, single-tenant search and storage resources. With this setup, you have full control and visibility over these resources, but you incur costs based on your usage. The following bicep template provides:
66+
67+
* Resources for the hub, project, storage account, key vault, AI Services, and Azure AI Search are created for you. The AI Services, AI Search, and Azure Blob Storage account are connected to your project/hub, and a gpt-4o-mini model is deployed in the westus2 region.
68+
* Customer-owned resources are secured with a provisioned managed network and authenticated with a user-managed identity with the necessary RBAC (Role-Based Access Control) permissions. Private links and DNS (Domain Name System) zones are created on behalf of the customer to ensure network connectivity.
69+
70+
<br/>
71+
72+
<details>
73+
<summary><b> Bicep Technical Details</b>
74+
</summary>
75+
76+
**The Bicep template automates the following configurations and resource provisions:**
77+
* Creates a [User Assigned Identity](/entra/identity/managed-identities-azure-resources/how-manage-user-assigned-managed-identities?pivots=identity-mi-methods-azp#create-a-user-assigned-managed-identity).
78+
* The User Assigned Managed Identity requires the following Role-Based Access Roles:
79+
* KeyVault Secret Officer
80+
* KeyVault Contributor
81+
* Storage Blob Data Owner
82+
* Storage Queue Data Contributor
83+
* Cognitive Services Contributor
84+
* Cognitive Services OpenAI User
85+
* Search Index Data Contributor
86+
* Search Service Contributor
87+
88+
* Configures a managed virtual network with two subnet resources:
89+
* Azure resources subnet
90+
* Enables service endpoints for:
91+
* `Microsoft.KeyVault`
92+
* `Microsoft.Storage`
93+
* `Microsoft.CognitiveServices`
94+
* Agent resources subnet
95+
* Configured with subnet delegations for:
96+
* `Microsoft.app/environments`
97+
* Provisions dependent resources
98+
* Azure Key Vault, Azure Storage, Azure OpenAI/AI Services, and Azure AI Search resources are created.
99+
* All resources are configured with:
100+
* Disabled public network access
101+
* Private endpoints in the Azure Resource subnet
102+
* Private DNS integration enabled
103+
* User assigned identity for authentication
104+
* Creates a hub and project using the resources provisioned and configures them to use the Agent Resource Subnet.
105+
* Accomplished by configuring the `capabilityHost` (a subresource of hub/project) to use the Agent Resource Subnet for network isolation and secure communication.
106+
</details>
107+
108+
### Option 1: autodeploy the bicep template
109+
110+
| Template | Description | Autodeploy |
111+
| ------------------- | -----------------------------------------------| -----------------------|
112+
| `network-secured-agent.bicep` | Deploy a network secured agent setup that uses user-managed identity authentication on the Agent connections. | [![Deploy to Azure](https://aka.ms/deploytoazurebutton)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2Fazure-quickstart-templates%2Frefs%2Fheads%2Fmaster%2Fquickstarts%2Fmicrosoft.azure-ai-agent-service%2Fnetwork-secured-agent%2Fazuredeploy.json)
113+
114+
### Option 2: manually deploy the bicep template
115+
116+
1. To manually run the bicep templates, [download the template from GitHub](https://github.com/Azure/azure-quickstart-templates/tree/master/quickstarts/microsoft.azure-ai-agent-service/network-secured-agent). Download the following from the `network-secured-agent` folder:
117+
1. `main.bicep`
118+
1. `azuredeploy.parameters.json`
119+
1. `modules-network-secured folder`
120+
1. To authenticate to your Azure subscription from the Azure CLI, use the following command:
121+
122+
```console
123+
az login
124+
```
125+
126+
1. Create a resource group:
127+
128+
```console
129+
az group create --name {my_resource_group} --location eastus
130+
```
131+
132+
Make sure you have the Azure AI Developer role for the resource group you created.
133+
134+
1. Using the resource group you created in the previous step and one of the template files (either `basic-agent-keys.bicep` or `basic-agent-identity.bicep`), run one of the following commands:
135+
136+
1. To use default resource names, run:
137+
138+
```console
139+
az deployment group create --resource-group {my_resource_group} --template-file main.bicep
140+
```
141+
142+
1. To specify custom names for the hub, project, storage account, and/or Azure AI service resources run the following command. A randomly generated suffix is added to prevent accidental duplication.
143+
144+
```console
145+
az deployment group create --resource-group {my_resource_group} --template-file main.bicep --parameters aiHubName='your-hub-name' aiProjectName='your-project-name' storageName='your-storage-name' aiServicesName='your-ai-services-name'
146+
147+
```
148+
149+
1. To customize other parameters, including the OpenAI model deployment, download, and edit the `azuredeploy.parameters.json` file, then run:
150+
151+
```console
152+
az deployment group create --resource-group {my_resource_group} --template-file main.bicep --parameters @azuredeploy.parameters.json
153+
```
154+
155+
## Configure and run an agent
156+
157+
| Component | Description |
158+
| --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
159+
| Agent | Custom AI that uses AI models with tools. |
160+
| Tool | Tools help extend an agent's ability to reliably and accurately respond during conversation. Such as connecting to user-defined knowledge bases to ground the model, or enabling web search to provide current information. |
161+
| Thread | A conversation session between an agent and a user. Threads store Messages and automatically handle truncation to fit content into a model's context. |
162+
| Message | A message created by an agent or a user. Messages can include text, images, and other files. Messages are stored as a list on the Thread. |
163+
| Run | Activation of an agent to begin running based on the contents of Thread. The agent uses its configuration and Thread's Messages to perform tasks by calling models and tools. As part of a Run, the agent appends Messages to the Thread. |
164+
| Run Step | A detailed list of steps the agent took as part of a Run. An agent can call tools or create Messages during its run. Examining Run Steps allows you to understand how the agent is getting to its results. |
165+
166+
> [!TIP]
167+
> The following code shows how to create and run an agent using the Python Azure SDK. For additional languages, see the [quickstart](../quickstart.md).
168+
169+
Run the following commands to install the python packages.
170+
171+
```console
172+
pip install azure-ai-projects
173+
pip install azure-identity
174+
```
175+
Next, to authenticate your API requests and run the program, use the [az login](/cli/azure/authenticate-azure-cli-interactively) command to sign into your Azure subscription.
176+
177+
```azurecli
178+
az login
179+
```
180+
181+
Use the following code to create and run an agent. To run this code, you need to create a connection string using information from your project. This string is in the format:
182+
183+
`<HostName>;<AzureSubscriptionId>;<ResourceGroup>;<ProjectName>`
184+
185+
[!INCLUDE [connection-string-portal](../includes/connection-string-portal.md)]
186+
187+
`HostName` can be found by navigating to your `discovery_url` and removing the leading `https://` and trailing `/discovery`. To find your `discovery_url`, run this CLI command:
188+
189+
```azurecli
190+
az ml workspace show -n {project_name} --resource-group {resource_group_name} --query discovery_url
191+
```
192+
193+
For example, your connection string might look something like:
194+
195+
`eastus.api.azureml.ms;12345678-abcd-1234-9fc6-62780b3d3e05;my-resource-group;my-project-name`
196+
197+
Set this connection string as an environment variable named `PROJECT_CONNECTION_STRING`.
198+
199+
> [!NOTE]
200+
> The following code sample shows creating an agent using Python. See the [quickstart](../quickstart.md) for examples in other programming languages.
201+
202+
```python
203+
import os
204+
from azure.ai.projects import AIProjectClient
205+
from azure.ai.projects.models import CodeInterpreterTool
206+
from azure.identity import DefaultAzureCredential
207+
from typing import Any
208+
from pathlib import Path
209+
210+
# Create an Azure AI Client from a connection string, copied from your Azure AI Foundry project.
211+
# It should be in the format "<HostName>;<AzureSubscriptionId>;<ResourceGroup>;<ProjectName>"
212+
# HostName can be found by navigating to your discovery_url and removing the leading "https://" and trailing "/discovery"
213+
# To find your discovery_url, run the CLI command: az ml workspace show -n {project_name} --resource-group {resource_group_name} --query discovery_url
214+
# Project Connection example: eastus.api.azureml.ms;12345678-abcd-1234-9fc6-62780b3d3e05;my-resource-group;my-project-name
215+
# You will need to login to your Azure subscription using the Azure CLI "az login" command, and set the environment variables.
216+
217+
project_client = AIProjectClient.from_connection_string(
218+
credential=DefaultAzureCredential(), conn_str=os.environ["PROJECT_CONNECTION_STRING"]
219+
)
220+
221+
with project_client:
222+
# Create an instance of the CodeInterpreterTool
223+
code_interpreter = CodeInterpreterTool()
224+
225+
# The CodeInterpreterTool needs to be included in creation of the agent
226+
agent = project_client.agents.create_agent(
227+
model="gpt-4o-mini",
228+
name="my-agent",
229+
instructions="You are helpful agent",
230+
tools=code_interpreter.definitions,
231+
tool_resources=code_interpreter.resources,
232+
)
233+
print(f"Created agent, agent ID: {agent.id}")
234+
235+
# Create a thread
236+
thread = project_client.agents.create_thread()
237+
print(f"Created thread, thread ID: {thread.id}")
238+
239+
# Create a message
240+
message = project_client.agents.create_message(
241+
thread_id=thread.id,
242+
role="user",
243+
content="Could you please create a bar chart for the operating profit using the following data and provide the file to me? Company A: $1.2 million, Company B: $2.5 million, Company C: $3.0 million, Company D: $1.8 million",
244+
)
245+
print(f"Created message, message ID: {message.id}")
246+
247+
# Run the agent
248+
run = project_client.agents.create_and_process_run(thread_id=thread.id, assistant_id=agent.id)
249+
print(f"Run finished with status: {run.status}")
250+
251+
if run.status == "failed":
252+
# Check if you got "Rate limit is exceeded.", then you want to get more quota
253+
print(f"Run failed: {run.last_error}")
254+
255+
# Get messages from the thread
256+
messages = project_client.agents.list_messages(thread_id=thread.id)
257+
print(f"Messages: {messages}")
258+
259+
# Get the last message from the sender
260+
last_msg = messages.get_last_text_message_by_role("assistant")
261+
if last_msg:
262+
print(f"Last Message: {last_msg.text.value}")
263+
264+
# Generate an image file for the bar chart
265+
for image_content in messages.image_contents:
266+
print(f"Image File ID: {image_content.image_file.file_id}")
267+
file_name = f"{image_content.image_file.file_id}_image_file.png"
268+
project_client.agents.save_file(file_id=image_content.image_file.file_id, file_name=file_name)
269+
print(f"Saved image file to: {Path.cwd() / file_name}")
270+
271+
# Print the file path(s) from the messages
272+
for file_path_annotation in messages.file_path_annotations:
273+
print(f"File Paths:")
274+
print(f"Type: {file_path_annotation.type}")
275+
print(f"Text: {file_path_annotation.text}")
276+
print(f"File ID: {file_path_annotation.file_path.file_id}")
277+
print(f"Start Index: {file_path_annotation.start_index}")
278+
print(f"End Index: {file_path_annotation.end_index}")
279+
project_client.agents.save_file(file_id=file_path_annotation.file_path.file_id, file_name=Path(file_path_annotation.text).name)
280+
281+
# Delete the agent once done
282+
project_client.agents.delete_agent(agent.id)
283+
print("Deleted agent")
284+
```
285+
286+
## Next steps
287+
288+
Once you've provisioned your agent, you can add tools such as [Grounding with Bing Search](./tools/bing-grounding.md) to enhance their capabilities.

articles/ai-services/agents/toc.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ items:
5252
href: concepts/tracing.md
5353
- name: Content filtering
5454
href: ../openai/how-to/content-filters.md?context=/azure/ai-services/agents/context/context
55+
- name: Use virtual networks
56+
href: how-to/virtual-networks.md
5557
- name: Responsible AI
5658
items:
5759
- name: Transparency note

0 commit comments

Comments
 (0)