Skip to content

Commit bfa8054

Browse files
committed
First attempt with infra
1 parent 7859d25 commit bfa8054

File tree

8 files changed

+500
-51
lines changed

8 files changed

+500
-51
lines changed

.vscode/launch.json

Lines changed: 55 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,57 @@
11
{
2-
// Use IntelliSense to learn about possible attributes.
3-
// Hover to view descriptions of existing attributes.
4-
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5-
"version": "0.2.0",
6-
"configurations": [
7-
{
8-
"name": "Backend (Python)",
9-
"type": "debugpy",
10-
"request": "launch",
11-
"module": "quart",
12-
"cwd": "${workspaceFolder}/app/backend",
13-
"python": "${workspaceFolder}/.venv/bin/python",
14-
"env": {
15-
"QUART_APP": "main:app",
16-
"QUART_ENV": "development",
17-
"QUART_DEBUG": "0",
18-
// Set this to "no-override" if you want env vars here to override AZD env vars
19-
"LOADING_MODE_FOR_AZD_ENV_VARS": "override"
20-
},
21-
"args": [
22-
"run",
23-
"--no-reload",
24-
"-p 50505"
25-
],
26-
"console": "integratedTerminal",
27-
"justMyCode": false
28-
},
29-
{
30-
"name": "Frontend",
31-
"type": "node-terminal",
32-
"request": "launch",
33-
"command": "npm run dev",
34-
"cwd": "${workspaceFolder}/app/frontend",
35-
},
36-
{
37-
"name": "Tests (Python)",
38-
"type": "debugpy",
39-
"request": "launch",
40-
"program": "${file}",
41-
"purpose": ["debug-test"],
42-
"console": "integratedTerminal",
43-
"justMyCode": false
44-
}
45-
],
46-
"compounds": [
47-
{
48-
"name": "Frontend & Backend",
49-
"configurations": ["Backend (Python)", "Frontend"],
50-
"stopAll": true
51-
}
52-
]
2+
// Use IntelliSense to learn about possible attributes.
3+
// Hover to view descriptions of existing attributes.
4+
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5+
"version": "0.2.0",
6+
"configurations": [
7+
{
8+
"name": "Python Debugger: Current File",
9+
"type": "debugpy",
10+
"request": "launch",
11+
"program": "${file}",
12+
"console": "integratedTerminal",
13+
"justMyCode": false
14+
},
15+
{
16+
"name": "Backend (Python)",
17+
"type": "debugpy",
18+
"request": "launch",
19+
"module": "quart",
20+
"cwd": "${workspaceFolder}/app/backend",
21+
"python": "${workspaceFolder}/.venv/bin/python",
22+
"env": {
23+
"QUART_APP": "main:app",
24+
"QUART_ENV": "development",
25+
"QUART_DEBUG": "0",
26+
// Set this to "no-override" if you want env vars here to override AZD env vars
27+
"LOADING_MODE_FOR_AZD_ENV_VARS": "override"
28+
},
29+
"args": ["run", "--no-reload", "-p 50505"],
30+
"console": "integratedTerminal",
31+
"justMyCode": false
32+
},
33+
{
34+
"name": "Frontend",
35+
"type": "node-terminal",
36+
"request": "launch",
37+
"command": "npm run dev",
38+
"cwd": "${workspaceFolder}/app/frontend"
39+
},
40+
{
41+
"name": "Tests (Python)",
42+
"type": "debugpy",
43+
"request": "launch",
44+
"program": "${file}",
45+
"purpose": ["debug-test"],
46+
"console": "integratedTerminal",
47+
"justMyCode": false
48+
}
49+
],
50+
"compounds": [
51+
{
52+
"name": "Frontend & Backend",
53+
"configurations": ["Backend (Python)", "Frontend"],
54+
"stopAll": true
55+
}
56+
]
5357
}

evals/simulate_adversarial.py

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
import asyncio
2+
import logging
3+
import os
4+
import pathlib
5+
from typing import Any, Dict, List, Optional
6+
7+
import requests
8+
from azure.ai.evaluation.simulator import AdversarialScenario, AdversarialSimulator
9+
from azure.identity import AzureDeveloperCliCredential
10+
from dotenv_azd import load_azd_env
11+
from rich.logging import RichHandler
12+
13+
logger = logging.getLogger("ragapp")
14+
15+
root_dir = pathlib.Path(__file__).parent
16+
17+
18+
def get_azure_credential():
19+
AZURE_TENANT_ID = os.getenv("AZURE_TENANT_ID")
20+
if AZURE_TENANT_ID:
21+
logger.info("Setting up Azure credential using AzureDeveloperCliCredential with tenant_id %s", AZURE_TENANT_ID)
22+
azure_credential = AzureDeveloperCliCredential(tenant_id=AZURE_TENANT_ID, process_timeout=60)
23+
else:
24+
logger.info("Setting up Azure credential using AzureDeveloperCliCredential for home tenant")
25+
azure_credential = AzureDeveloperCliCredential(process_timeout=60)
26+
return azure_credential
27+
28+
29+
async def callback(
30+
messages: List[Dict],
31+
stream: bool = False,
32+
session_state: Any = None,
33+
context: Optional[Dict[str, Any]] = None,
34+
):
35+
messages_list = messages["messages"]
36+
latest_message = messages_list[-1]
37+
query = latest_message["content"]
38+
headers = {"Content-Type": "application/json"}
39+
body = {
40+
"messages": [{"content": query, "role": "user"}],
41+
"stream": stream,
42+
"context": {
43+
"overrides": {
44+
"top": 3,
45+
"temperature": 0.3,
46+
"minimum_reranker_score": 0,
47+
"minimum_search_score": 0,
48+
"retrieval_mode": "hybrid",
49+
"semantic_ranker": True,
50+
"semantic_captions": False,
51+
"suggest_followup_questions": False,
52+
"use_oid_security_filter": False,
53+
"use_groups_security_filter": False,
54+
"vector_fields": ["embedding"],
55+
"use_gpt4v": False,
56+
"gpt4v_input": "textAndImages",
57+
"seed": 1,
58+
}
59+
},
60+
}
61+
url = "http://localhost:50505/chat"
62+
r = requests.post(url, headers=headers, json=body)
63+
response = r.json()
64+
response["messages"] = messages_list + [response["message"]]
65+
return response
66+
67+
68+
async def run_simulator():
69+
azure_ai_project = {
70+
"subscription_id": os.getenv("AZURE_SUBSCRIPTION_ID"),
71+
"resource_group_name": os.getenv("AZURE_RESOURCE_GROUP"),
72+
"project_name": os.getenv("AZURE_AI_PROJECT"),
73+
}
74+
75+
scenario = AdversarialScenario.ADVERSARIAL_QA
76+
adversarial_simulator = AdversarialSimulator(azure_ai_project=azure_ai_project, credential=get_azure_credential())
77+
78+
outputs = await adversarial_simulator(
79+
scenario=scenario, # required adversarial scenario to simulate
80+
target=callback, # callback function to simulate against
81+
max_conversation_turns=1, # optional, applicable only to conversation scenario
82+
max_simulation_results=3, # optional
83+
)
84+
85+
# By default simulator outputs json, use the following helper function to convert to QA pairs in jsonl format
86+
print(outputs.to_eval_qr_json_lines())
87+
88+
89+
if __name__ == "__main__":
90+
logging.basicConfig(
91+
level=logging.WARNING, format="%(message)s", datefmt="[%X]", handlers=[RichHandler(rich_tracebacks=True)]
92+
)
93+
logger.setLevel(logging.INFO)
94+
load_azd_env()
95+
96+
asyncio.run(run_simulator())

infra/core/ai/ai-environment.bicep

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
@minLength(1)
2+
@description('Primary location for all resources')
3+
param location string
4+
5+
@description('The AI Hub resource name.')
6+
param hubName string
7+
@description('The AI Project resource name.')
8+
param projectName string
9+
@description('The Key Vault resource name.')
10+
param keyVaultId string
11+
@description('The Key Vault resource name.')
12+
param keyVaultName string
13+
@description('The Storage Account resource ID.')
14+
param storageAccountId string
15+
@description('The Application Insights resource ID.')
16+
param applicationInsightsId string = ''
17+
@description('The Azure Search resource name.')
18+
param searchServiceName string = ''
19+
@description('The Azure Search connection name.')
20+
param searchConnectionName string = ''
21+
param tags object = {}
22+
23+
module hub './hub.bicep' = {
24+
name: 'hub'
25+
params: {
26+
location: location
27+
tags: tags
28+
name: hubName
29+
displayName: hubName
30+
keyVaultId: keyVaultId
31+
storageAccountId: storageAccountId
32+
containerRegistryId: null
33+
applicationInsightsId: applicationInsightsId
34+
aiSearchName: searchServiceName
35+
aiSearchConnectionName: searchConnectionName
36+
}
37+
}
38+
39+
module project './project.bicep' = {
40+
name: 'project'
41+
params: {
42+
location: location
43+
tags: tags
44+
name: projectName
45+
displayName: projectName
46+
hubName: hub.outputs.name
47+
keyVaultName: keyVaultName
48+
}
49+
}
50+
51+
// Outputs
52+
// Resource Group
53+
output resourceGroupName string = resourceGroup().name
54+
55+
// Hub
56+
output hubName string = hub.outputs.name
57+
output hubPrincipalId string = hub.outputs.principalId
58+
59+
// Project
60+
output projectName string = project.outputs.name
61+
output projectPrincipalId string = project.outputs.principalId
62+
63+
//Discoveryurl
64+
output discoveryUrl string = project.outputs.discoveryUrl
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
metadata description = 'Creates an Azure Cognitive Services instance.'
2+
param name string
3+
param location string = resourceGroup().location
4+
param tags object = {}
5+
@description('The custom subdomain name used to access the API. Defaults to the value of the name parameter.')
6+
param customSubDomainName string = name
7+
param disableLocalAuth bool = false
8+
param deployments array = []
9+
param kind string = 'OpenAI'
10+
//param kind string = 'AIServices'
11+
12+
@allowed([ 'Enabled', 'Disabled' ])
13+
param publicNetworkAccess string = 'Enabled'
14+
param sku object = {
15+
name: 'S0'
16+
}
17+
18+
param allowedIpRules array = []
19+
param networkAcls object = empty(allowedIpRules) ? {
20+
defaultAction: 'Allow'
21+
} : {
22+
ipRules: allowedIpRules
23+
defaultAction: 'Deny'
24+
}
25+
26+
resource account 'Microsoft.CognitiveServices/accounts@2023-05-01' = {
27+
name: name
28+
location: location
29+
tags: tags
30+
kind: kind
31+
properties: {
32+
customSubDomainName: customSubDomainName
33+
publicNetworkAccess: publicNetworkAccess
34+
networkAcls: networkAcls
35+
disableLocalAuth: disableLocalAuth
36+
}
37+
sku: sku
38+
}
39+
40+
@batchSize(1)
41+
resource deployment 'Microsoft.CognitiveServices/accounts/deployments@2023-05-01' = [for deployment in deployments: {
42+
parent: account
43+
name: deployment.name
44+
properties: {
45+
model: deployment.model
46+
raiPolicyName: contains(deployment, 'raiPolicyName') ? deployment.raiPolicyName : null
47+
}
48+
sku: contains(deployment, 'sku') ? deployment.sku : {
49+
name: 'Standard'
50+
capacity: 20
51+
}
52+
}]
53+
54+
output endpoint string = account.properties.endpoint
55+
output endpoints object = account.properties.endpoints
56+
output id string = account.id
57+
output name string = account.name

0 commit comments

Comments
 (0)