APIM przed połączeniami agentic Foundry wykorzystuje model RBAC z najniższymi uprawnieniami.
Wywołania modelu frontowego przy użyciu API Management, zarządzanej tożsamości, dostosowanych ról w warstwie danych oraz backendów Function App.
To, co tworzymy
AI Foundry może hostować wiele rodzin modeli. Tworzenie agentów na ich podstawie staje się ciekawe – ale też skomplikowane – gdy każdy model ma inne metody autoryzacji oraz gdy obowiązują zasady dotyczące PII/PCI. Azure API Management (APIM) w połączeniu z tożsamościami o minimalnych uprawnieniach zapewnia jedno wejście do systemu.
Część 1 — Podstawa
Zainstaluj zasoby Foundry/OpenAI, aplikację Function App, która będzie wywoływać modele, oraz APIM, który będzie zarządzać tą funkcją. Z góry określ regiony oraz strukturę sieci prywatnej.
Część 2 — Wdrożenie modeli
Wdroż modele do rozmów, które faktycznie potrzebujesz. Zapisz nazwy wdrożeń oddzielnie od nazw podstawowych modeli.
CZĘŚĆ 2: Spersonalizowany RBAC o minimalnych uprawnieniach
OpenAI — tylko uzupełnianie treści w rozmowach
Spersonalizowane role, które pozwalają wykonywać tylko te operacje na danych, których potrzebuje Twoja funkcja, są lepsze od ogólnych przydziałów uprawnień w Cognitive Services.
Anthropic — role wbudowane do działań z danymi mogą coś przeoczyć
Część tras modeli third-party wymaga dodatkowych działań z danymi; sprawdź treść błędu nieudanej próby połączenia, a następnie popraw role — a nie odwrotnie.
RG="rg-foundry-func-demo"
LOCATION="eastus2"
UMI_NAME="umi-foundry-func"
FOUNDRY_NAME="foundry-func-demo"
STORAGE_NAME="stfoundryfuncdemo"
FUNC_NAME="func-foundry-py-$RANDOM"
SUBSCRIPTION_ID=$(az account show --query id -o tsv)
az group create --name $RG --location $LOCATION
az identity create --name $UMI_NAME --resource-group $RG
UMI_CLIENT_ID=$(az identity show --name $UMI_NAME --resource-group $RG --query clientId -o tsv)
UMI_PRINCIPAL_ID=$(az identity show --name $UMI_NAME --resource-group $RG --query principalId -o tsv)
UMI_RESOURCE_ID=$(az identity show --name $UMI_NAME --resource-group $RG --query id -o tsv)
az cognitiveservices account create \
--name $FOUNDRY_NAME \
--resource-group $RG \
--location $LOCATION \
--kind AIServices \
--sku S0 \
--custom-domain $FOUNDRY_NAME \
--yes
FOUNDRY_ENDPOINT=$(az cognitiveservices account show \
--name $FOUNDRY_NAME --resource-group $RG \
--query properties.endpoint -o tsv)
FOUNDRY_ID=$(az cognitiveservices account show \
--name $FOUNDRY_NAME --resource-group $RG --query id -o tsv)
az cognitiveservices account deployment create \
--name $FOUNDRY_NAME \
--resource-group $RG \
--deployment-name gpt-5-mini \
--model-name gpt-5-mini \
--model-version "2025-08-07" \
--model-format OpenAI \
--sku-name GlobalStandard \
--sku-capacity 10
{
"etag": "\"c39e7d0e-7c32-48a2-ba62-8a897265efbb\"",
"id": "/subscriptions/a509ec7e-2297-419d-8587-ca08543e3cbe/resourceGroups/rg-foundry-func-demo/providers/Microsoft.CognitiveServices/accounts/foundry-func-demo-01/deployments/gpt-5-mini",
"name": "gpt-5-mini",
"properties": {
"callRateLimit": null,
"capabilities": {
"agentsV2": "true",
"area": "US",
"assistants": "true",
"chatCompletion": "true",
"responses": "true"
},
"capacitySettings": null,
"currentCapacity": 10,
"deploymentState": "Running",
"dynamicThrottlingEnabled": null,
"model": {
"callRateLimit": null,
"format": "OpenAI",
"name": "gpt-5-mini",
"publisher": null,
"source": null,
"sourceAccount": null,
"version": "2025-08-07"
},
"parentDeploymentName": null,
"provisioningState": "Succeeded",
"raiPolicyName": "Microsoft.DefaultV2",
"rateLimits": [
{
"count": 10.0,
"dynamicThrottlingEnabled": null,
"key": "request",
"matchPatterns": null,
"minCount": null,
"renewalPeriod": 60.0
},
{
"count": 10000.0,
"dynamicThrottlingEnabled": null,
"key": "token",
"matchPatterns": null,
"minCount": null,
"renewalPeriod": 60.0
}
],
"routing": null,
"scaleSettings": null,
"serviceTier": null,
"spilloverDeploymentName": null,
"versionUpgradeOption": "OnceNewDefaultVersionAvailable"
},
"resourceGroup": "rg-foundry-func-demo",
"sku": {
"capacity": 10,
"family": null,
"name": "GlobalStandard",
"size": null,
"tier": null
},
"systemData": {
"createdAt": "2026-07-05T18:03:12.346795+00:00",
"createdBy": "krishnan.sriram@hotmail.com",
"createdByType": "User",
"lastModifiedAt": "2026-07-05T18:03:12.346795+00:00",
"lastModifiedBy": "krishnan.sriram@hotmail.com",
"lastModifiedByType": "User"
},
"tags": null,
"type": "Microsoft.CognitiveServices/accounts/deployments"
}
FOUNDRY_ID=$(az cognitiveservices account show \
--name $FOUNDRY_NAME --resource-group $RG --query id -o tsv)
az resource create \
--id "$FOUNDRY_ID/deployments/claude-opus-4-6" \
--api-version 2025-10-01-preview \
--is-full-object \
--properties '{
"location": "eastus2",
"properties": {
"model": {
"format": "Anthropic",
"name": "claude-opus-4-6",
"version": "1"
},
"modelProviderData": {
"organizationName": "SRK Tech",
"countryCode": "US",
"industry": "technology"
}
},
"sku": {
"name": "GlobalStandard",
"capacity": 10
}
}'
# execution Results
{
"etag": "\"a5b65a53-a65a-494b-9059-b16dc700b743\"",
"extendedLocation": null,
"id": "/subscriptions/a509ec7e-2297-419d-8587-ca08543e3cbe/resourceGroups/rg-foundry-func-demo/providers/Microsoft.CognitiveServices/accounts/foundry-func-demo-01/deployments/claude-opus-4-6",
"identity": null,
"kind": null,
"location": null,
"managedBy": null,
"name": "claude-opus-4-6",
"plan": null,
"properties": {
"capabilities": {
"agentsV2": "true",
"chatCompletion": "true"
},
"currentCapacity": 10,
"deploymentState": "Running",
"model": {
"format": "Anthropic",
"name": "claude-opus-4-6",
"version": "1"
},
"modelProviderData": {
"countryCode": "US",
"industry": "technology",
"organizationName": "SRK Tech"
},
"provisioningState": "Succeeded",
"raiPolicyName": "Microsoft.DefaultV2",
"rateLimits": [
{
"count": 10,
"key": "request",
"renewalPeriod": 60
},
{
"count": 10000,
"key": "token",
"renewalPeriod": 60
}
],
"versionUpgradeOption": "OnceNewDefaultVersionAvailable"
},
"resourceGroup": "rg-foundry-func-demo",
"sku": {
"capacity": 10,
"family": null,
"model": null,
"name": "GlobalStandard",
"size": null,
"tier": null
},
"systemData": {
"createdAt": "2026-07-05T18:06:43.6897129Z",
"createdBy": "krishnan.sriram@hotmail.com",
"createdByType": "User",
"lastModifiedAt": "2026-07-05T18:06:43.6897129Z",
"lastModifiedBy": "krishnan.sriram@hotmail.com",
"lastModifiedByType": "User"
},
"tags": null,
"type": "Microsoft.CognitiveServices/accounts/deployments"
}
az cognitiveservices account deployment list \
--name $FOUNDRY_NAME --resource-group $RG -o table
Name ResourceGroup
--------------- --------------------
gpt-5-mini rg-foundry-func-demo
claude-opus-4-6 rg-foundry-func-demo
cat > /tmp/foundry-openai-role.json << EOF
{
"Name": "Foundry OpenAI Chat Inference User",
"IsCustom": true,
"Description": "Minimal data-plane access to call chat completions on a Microsoft Foundry OpenAI deployment.",
"Actions": [],
"DataActions": [
"Microsoft.CognitiveServices/accounts/OpenAI/deployments/chat/completions/action"
],
"AssignableScopes": ["/subscriptions/$SUBSCRIPTION_ID"]
}
EOF
az role definition create --role-definition /tmp/foundry-openai-role.json
# Execution results
{
"assignableScopes": [
"/subscriptions/a509ec7e-2297-419d-8587-ca08543e3cbe"
],
"createdBy": null,
"createdOn": "2026-07-05T18:22:39.111105+00:00",
"description": "Minimal data-plane access to call chat completions on a Microsoft Foundry OpenAI deployment.",
"id": "/subscriptions/a509ec7e-2297-419d-8587-ca08543e3cbe/providers/Microsoft.Authorization/roleDefinitions/c7035712-c66d-482d-9fd5-0fc116a2d9f4",
"name": "c7035712-c66d-482d-9fd5-0fc116a2d9f4",
"permissions": [
{
"actions": [],
"condition": null,
"conditionVersion": null,
"dataActions": [
"Microsoft.CognitiveServices/accounts/OpenAI/deployments/chat/completions/action"
],
"notActions": [],
"notDataActions": []
}
],
"roleName": "Foundry OpenAI Chat Inference User",
"roleType": "CustomRole",
"type": "Microsoft.Authorization/roleDefinitions",
"updatedBy": "28567f42-a049-464e-9211-8f1b270cdf6a",
"updatedOn": "2026-07-05T18:22:39.111105+00:00"
}
az role assignment create \
--assignee-object-id $UMI_PRINCIPAL_ID \
--assignee-principal-type ServicePrincipal \
--role "Foundry OpenAI Chat Inference User" \
--scope $FOUNDRY_ID
# Execution results
{
"condition": null,
"conditionVersion": null,
"createdBy": null,
"createdOn": "2026-07-05T18:23:42.642379+00:00",
"delegatedManagedIdentityResourceId": null,
"description": null,
"id": "/subscriptions/a509ec7e-2297-419d-8587-ca08543e3cbe/resourceGroups/rg-foundry-func-demo/providers/Microsoft.CognitiveServices/accounts/foundry-func-demo-01/providers/Microsoft.Authorization/roleAssignments/580a3b61-aaad-456e-9b3e-6ced977dd378",
"name": "580a3b61-aaad-456e-9b3e-6ced977dd378",
"principalId": "a114ced5-b53e-4c42-8949-bddd053610cc",
"principalType": "ServicePrincipal",
"resourceGroup": "rg-foundry-func-demo",
"roleDefinitionId": "/subscriptions/a509ec7e-2297-419d-8587-ca08543e3cbe/providers/Microsoft.Authorization/roleDefinitions/c7035712-c66d-482d-9fd5-0fc116a2d9f4",
"scope": "/subscriptions/a509ec7e-2297-419d-8587-ca08543e3cbe/resourceGroups/rg-foundry-func-demo/providers/Microsoft.CognitiveServices/accounts/foundry-func-demo-01",
"type": "Microsoft.Authorization/roleAssignments",
"updatedBy": "28567f42-a049-464e-9211-8f1b270cdf6a",
"updatedOn": "2026-07-05T18:23:42.913375+00:00"
}
cat > /tmp/foundry-anthropic-role.json << EOF
{
"Name": "Foundry Anthropic Inference User",
"IsCustom": true,
"Description": "Minimal data-plane access to invoke Claude models on a Microsoft Foundry AIServices resource.",
"Actions": [],
"DataActions": [
"Microsoft.CognitiveServices/accounts/AIServices/providers/action",
"Microsoft.CognitiveServices/accounts/OpenAI/*/read"
],
"AssignableScopes": ["/subscriptions/$SUBSCRIPTION_ID"]
}
EOF
az role definition create --role-definition /tmp/foundry-anthropic-role.json
# Execution results
{
"assignableScopes": [
"/subscriptions/a509ec7e-2297-419d-8587-ca08543e3cbe"
],
"createdBy": null,
"createdOn": "2026-07-05T18:26:14.247654+00:00",
"description": "Minimal data-plane access to invoke Claude models on a Microsoft Foundry AIServices resource.",
"id": "/subscriptions/a509ec7e-2297-419d-8587-ca08543e3cbe/providers/Microsoft.Authorization/roleDefinitions/323e0475-0098-4161-b03d-69bce7452c9c",
"name": "323e0475-0098-4161-b03d-69bce7452c9c",
"permissions": [
{
"actions": [],
"condition": null,
"conditionVersion": null,
"dataActions": [
"Microsoft.CognitiveServices/accounts/AIServices/providers/action",
"Microsoft.CognitiveServices/accounts/OpenAI/*/read"
],
"notActions": [],
"notDataActions": []
}
],
"roleName": "Foundry Anthropic Inference User",
"roleType": "CustomRole",
"type": "Microsoft.Authorization/roleDefinitions",
"updatedBy": "28567f42-a049-464e-9211-8f1b270cdf6a",
"updatedOn": "2026-07-05T18:26:14.247654+00:00"
}
az role assignment create \
--assignee-object-id $UMI_PRINCIPAL_ID \
--assignee-principal-type ServicePrincipal \
--role "Foundry Anthropic Inference User" \
--scope $FOUNDRY_ID
# Execution Results
{
"condition": null,
"conditionVersion": null,
"createdBy": null,
"createdOn": "2026-07-05T18:28:12.789555+00:00",
"delegatedManagedIdentityResourceId": null,
"description": null,
"id": "/subscriptions/a509ec7e-2297-419d-8587-ca08543e3cbe/resourceGroups/rg-foundry-func-demo/providers/Microsoft.CognitiveServices/accounts/foundry-func-demo-01/providers/Microsoft.Authorization/roleAssignments/18e509dc-b539-49d8-a2e6-65a12415e206",
"name": "18e509dc-b539-49d8-a2e6-65a12415e206",
"principalId": "a114ced5-b53e-4c42-8949-bddd053610cc",
"principalType": "ServicePrincipal",
"resourceGroup": "rg-foundry-func-demo",
"roleDefinitionId": "/subscriptions/a509ec7e-2297-419d-8587-ca08543e3cbe/providers/Microsoft.Authorization/roleDefinitions/323e0475-0098-4161-b03d-69bce7452c9c",
"scope": "/subscriptions/a509ec7e-2297-419d-8587-ca08543e3cbe/resourceGroups/rg-foundry-func-demo/providers/Microsoft.CognitiveServices/accounts/foundry-func-demo-01",
"type": "Microsoft.Authorization/roleAssignments",
"updatedBy": "28567f42-a049-464e-9211-8f1b270cdf6a",
"updatedOn": "2026-07-05T18:28:13.050559+00:00"
}
az storage account create \
--name $STORAGE_NAME \
--resource-group $RG \
--location $LOCATION \
--sku Standard_LRS
az functionapp create \
--name $FUNC_NAME \
--resource-group $RG \
--storage-account $STORAGE_NAME \
--consumption-plan-location $LOCATION \
--runtime python \
--runtime-version 3.12 \
--functions-version 4 \
--os-type Linux
az functionapp identity assign \
--name $FUNC_NAME \
--resource-group $RG \
--identities $UMI_RESOURCE_ID
# Execution results
{
"principalId": null,
"tenantId": null,
"type": "UserAssigned",
"userAssignedIdentities": {
"/subscriptions/a509ec7e-2297-419d-8587-ca08543e3cbe/resourcegroups/rg-foundry-func-demo/providers/Microsoft.ManagedIdentity/userAssignedIdentities/umi-foundry-func": {
"clientId": "e7c8a6b7-bd4e-43c7-b49b-d9d6a9e01821",
"principalId": "a114ced5-b53e-4c42-8949-bddd053610cc"
}
}
}
az functionapp config appsettings set \
--name $FUNC_NAME \
--resource-group $RG \
--settings \
FOUNDRY_ENDPOINT="$FOUNDRY_ENDPOINT" \
FOUNDRY_DEPLOYMENT="gpt-5-mini" \
FOUNDRY_API_VERSION="2024-12-01-preview" \
CLAUDE_BASE_URL="https://${FOUNDRY_NAME}.services.ai.azure.com/anthropic" \
CLAUDE_OPUS_DEPLOYMENT="claude-opus-4-6" \
LANGUAGE_ENDPOINT="$FOUNDRY_ENDPOINT" \
LANGUAGE_API_VERSION="2024-11-01" \
UMI_CLIENT_ID="$UMI_CLIENT_ID"
az functionapp config appsettings list \
--name $FUNC_NAME --resource-group $RG \
--query "[].name" -o tsv
# Execution results
FUNCTIONS_WORKER_RUNTIME
FUNCTIONS_EXTENSION_VERSION
AzureWebJobsStorage
WEBSITE_CONTENTAZUREFILECONNECTIONSTRING
WEBSITE_CONTENTSHARE
AzureWebJobsDashboard
FOUNDRY_ENDPOINT
FOUNDRY_DEPLOYMENT
FOUNDRY_API_VERSION
CLAUDE_BASE_URL
CLAUDE_OPUS_DEPLOYMENT
LANGUAGE_ENDPOINT
LANGUAGE_API_VERSION
UMI_CLIENT_ID
mkdir foundry-llm-function-py && cd foundry-llm-function-py
func new --name AskLLM --template "HTTP trigger" --authlevel function
azure-functions
azure-identity
openai
anthropic
requests
import azure.functions as func
import json
import logging
import os
from azure.identity import ManagedIdentityCredential, get_bearer_token_provider
from openai import AzureOpenAI
from anthropic import AnthropicFoundry
app = func.FunctionApp()
# --- Shared config ---
FOUNDRY_ENDPOINT = os.environ.get("FOUNDRY_ENDPOINT")
FOUNDRY_API_VERSION = os.environ.get("FOUNDRY_API_VERSION", "2024-12-01-preview")
CLAUDE_BASE_URL = os.environ.get("CLAUDE_BASE_URL")
UMI_CLIENT_ID = os.environ.get("UMI_CLIENT_ID")
# --- Per-model deployment names ---
GPT_DEPLOYMENT = os.environ.get("FOUNDRY_DEPLOYMENT") # e.g. "gpt-5-mini"
CLAUDE_OPUS_DEPLOYMENT = os.environ.get("CLAUDE_OPUS_DEPLOYMENT") # e.g. "claude-opus-4-6"
DEFAULT_MODEL = "gpt"
# --- Single UMI credential, shared by both clients ---
_credential = ManagedIdentityCredential(client_id=UMI_CLIENT_ID)
_openai_token_provider = get_bearer_token_provider(
_credential, "https://cognitiveservices.azure.com/.default"
)
_claude_token_provider = get_bearer_token_provider(
_credential, "https://cognitiveservices.azure.com/.default"
)
_openai_client = AzureOpenAI(
azure_endpoint=FOUNDRY_ENDPOINT,
api_version=FOUNDRY_API_VERSION,
azure_ad_token_provider=_openai_token_provider,
)
_claude_client = AnthropicFoundry(
azure_ad_token_provider=_claude_token_provider,
base_url=CLAUDE_BASE_URL,
)
# --- Model registry: alias -> (provider, deployment name) ---
MODEL_REGISTRY = {
"gpt": ("openai", GPT_DEPLOYMENT),
"opus": ("anthropic", CLAUDE_OPUS_DEPLOYMENT),
}
def _call_openai(deployment: str, query: str, user_context: str | None) -> str:
messages = []
if user_context:
messages.append({"role": "system", "content": str(user_context)})
messages.append({"role": "user", "content": query})
result = _openai_client.chat.completions.create(
model=deployment,
messages=messages,
)
return result.choices[0].message.content or ""
def _call_claude(deployment: str, query: str, user_context: str | None) -> str:
kwargs = {
"model": deployment,
"max_tokens": 1024,
"messages": [{"role": "user", "content": query}],
}
if user_context:
kwargs["system"] = [{"type": "text", "text": str(user_context)}]
result = _claude_client.messages.create(**kwargs)
return "".join(block.text for block in result.content if block.type == "text")
@app.route(route="ask", methods=["POST"], auth_level=func.AuthLevel.FUNCTION)
def AskLLM(req: func.HttpRequest) -> func.HttpResponse:
try:
body = req.get_json()
except ValueError:
return func.HttpResponse(
json.dumps({"error": "Request body must be valid JSON"}),
status_code=400,
mimetype="application/json",
)
query = body.get("query")
user_context = body.get("context")
model_alias = (body.get("model") or DEFAULT_MODEL).strip().lower()
if not query or not isinstance(query, str):
return func.HttpResponse(
json.dumps({"error": '"query" (string) is required in the request body'}),
status_code=400,
mimetype="application/json",
)
if model_alias not in MODEL_REGISTRY:
return func.HttpResponse(
json.dumps({
"error": f'"model" must be one of: {", ".join(MODEL_REGISTRY.keys())}',
}),
status_code=400,
mimetype="application/json",
)
provider, deployment = MODEL_REGISTRY[model_alias]
if not deployment:
return func.HttpResponse(
json.dumps({"error": f'No deployment configured for model "{model_alias}"'}),
status_code=500,
mimetype="application/json",
)
try:
if provider == "openai":
answer = _call_openai(deployment, query, user_context)
else:
answer = _call_claude(deployment, query, user_context)
return func.HttpResponse(
json.dumps({"answer": answer, "model": model_alias}),
status_code=200,
mimetype="application/json",
)
except Exception as e:
logging.exception(f"Foundry call failed for model={model_alias}")
return func.HttpResponse(
json.dumps({"error": "Failed to get a response from the LLM", "detail": str(e)}),
status_code=500,
mimetype="application/json",
)
func azure functionapp publish $FUNC_NAME
Getting site publishing info...
[2026-07-05T23:43:36.764Z] Starting the function app deployment...
Removing WEBSITE_CONTENTAZUREFILECONNECTIONSTRING app setting.
Removing WEBSITE_CONTENTSHARE app setting.
Creating archive for current directory...
Performing remote build for functions project.
Creating placeholder blob for linux consumption function app...
.....................
.....................
.....................
SCM_RUN_FROM_PACKAGE placeholder blob scm-latest-func-foundry-py-19514.zip located
Uploading built content /home/site/artifacts/functionappartifact.squashfs for linux consumption function app...
Resetting all workers for func-foundry-py-19514.azurewebsites.net
Deployment successful. deployer = Push-Deployer deploymentPath = Functions App ZipDeploy. Extract zip. Remote build.
Remote build succeeded!
[2026-07-05T23:44:23.731Z] Syncing triggers...
Functions in func-foundry-py-19514:
AskLLM - [httpTrigger]
Invoke url: https://func-foundry-py-19514.azurewebsites.net/api/ask
FUNC_KEY=$(az functionapp keys list \
--name $FUNC_NAME --resource-group $RG \
--query "functionKeys.default" -o tsv)
curl -X POST "https://$FUNC_NAME.azurewebsites.net/api/ask?code=$FUNC_KEY" \
-H "Content-Type: application/json" \
-d '{"query": "What is the capital of France?"}'
# Execution results
{"answer": "The capital of France is Paris.", "model": "gpt"}
curl -X POST "https://$FUNC_NAME.azurewebsites.net/api/ask?code=$FUNC_KEY" \
-H "Content-Type: application/json" \
-d '{"query": "What is the capital of France?", "model": "opus"}'
# Execution results
{"answer": "The capital of France is **Paris**.", "model": "opus"}
az group delete --name $RG --yes --no-wait
az role definition delete --name "Foundry OpenAI Chat Inference User"
az role definition delete --name "Foundry Anthropic Inference User"
CZĘŚĆ 3 — Azure Function
1–2. Storage + Python Function App
3. Dołączenie zarządzanej tożsamości przypisanej przez użytkownika
4. Ustawienia aplikacji
Adresy URL punktów końcowych, nazwy implementacji, klucze APIM lub ustawienia odbiorców — nigdy nie przechowuj tajemnic w repozytorium.
5–7. Szkielet aplikacji, requirements.txt, function_app.py, implementacja
8. Testowanie przez APIM
Należy wywołać trasę APIM, a nie URL funkcji, aby polityki (ograniczenie szybkości, JWT, filtr IP) rzeczywiście miały zastosowanie.
Podręcznik rozwiązywania problemów
Błędy 401/403 zazwyczaj oznaczają problem z RBAC lub błędny nazwa implementacji. Błąd 404 często wynika z niezgodności regionu/modelu. Problemy z czasem oczekiwania często są spowodowane chłodnym uruchamianiem funkcji przy zbyt niskim limicie czasowym backendu APIM.
Lekcje wyciągnięte
Centralizuj dostęp do modeli za pośrednictwem APIM; używaj zarządzanych tożsamości do dostępu do modeli; utrzymuj ścisłe zasady RBAC; testuj działania związane z danymi w każdej nowej rodzinie modeli; rejestruj identyfikatory korelacji od APIM, przez funkcję, aż po wywołanie modelu.
Rozwój oparty na agentach bez bramy API powoduje ponowne rozprzestrzenianie się kluczowych elementów systemu. APIM umożliwia efektywne zarządzanie ruchem agentów.
Wskazówka dotycząca polityki: umieść budżety tokenów oraz limity przepustowości na poziomie poszczególnych użytkowników w APIM, aby błędnie działający cykl agenta nie mógł obejść ograniczeń na poziomie aplikacji poprzez bezpośrednie wywołanie funkcji — zablokuj bezpośredni dostęp do funkcji w sieciach produkcyjnych.
Wskazówka dotycząca polityki: umieść budżety tokenów oraz limity przepustowości na poziomie poszczególnych użytkowników w APIM, aby błędnie działający cykl agenta nie mógł obejść ograniczeń na poziomie aplikacji poprzez bezpośrednie wywołanie funkcji — zablokuj bezpośredni dostęp do funkcji w sieciach produkcyjnych.
Wskazówka dotycząca polityki: umieść budżety tokenów oraz limity przepustowości na poziomie poszczególnych użytkowników w APIM, aby błędnie działający cykl agenta nie mógł obejść ograniczeń na poziomie aplikacji poprzez bezpośrednie wywołanie funkcji — zablokuj bezpośredni dostęp do funkcji w sieciach produkcyjnych.
Wskazówka dotycząca polityki: umieść budżety tokenów oraz limity przepustowości na poziomie poszczególnych użytkowników w APIM, aby błędnie działający cykl agenta nie mógł obejść ograniczeń na poziomie aplikacji poprzez bezpośrednie wywołanie funkcji — zablokuj bezpośredni dostęp do funkcji w sieciach produkcyjnych.
Wskazówka dotycząca polityki: umieść budżety tokenów oraz limity przepustowości na poziomie poszczególnych użytkowników w APIM, aby błędnie działający cykl agenta nie mógł obejść ograniczeń na poziomie aplikacji poprzez bezpośrednie wywołanie funkcji — zablokuj bezpośredni dostęp do funkcji w sieciach produkcyjnych.
Wskazówka dotycząca polityki: umieść budżety tokenów oraz limity przepustowości na poziomie poszczególnych użytkowników w APIM, aby błędnie działający cykl agenta nie mógł obejść ograniczeń na poziomie aplikacji poprzez bezpośrednie wywołanie funkcji — zablokuj bezpośredni dostęp do funkcji w sieciach produkcyjnych.
Wskazówka dotycząca polityki: umieść budżety tokenów oraz limity przepustowości na poziomie poszczególnych użytkowników w APIM, aby błędnie działający cykl agenta nie mógł obejść ograniczeń na poziomie aplikacji poprzez bezpośrednie wywołanie funkcji — zablokuj bezpośredni dostęp do funkcji w sieciach produkcyjnych.
Wskazówka dotycząca polityki: umieść budżety tokenów oraz limity przepustowości na poziomie poszczególnych użytkowników w APIM, aby błędnie działający cykl agenta nie mógł obejść ograniczeń na poziomie aplikacji poprzez bezpośrednie wywołanie funkcji — zablokuj bezpośredni dostęp do funkcji w sieciach produkcyjnych.
Wskazówka dotycząca polityki: umieść budżety tokenów oraz limity przepustowości na poziomie poszczególnych użytkowników w APIM, aby błędnie działający cykl agenta nie mógł obejść ograniczeń na poziomie aplikacji poprzez bezpośrednie wywołanie funkcji — zablokuj bezpośredni dostęp do funkcji w sieciach produkcyjnych.
Wskazówka dotycząca polityki: umieść budżety tokenów oraz limity przepustowości na poziomie poszczególnych użytkowników w APIM, aby błędnie działający cykl agenta nie mógł obejść ograniczeń na poziomie aplikacji poprzez bezpośrednie wywołanie funkcji — zablokuj bezpośredni dostęp do funkcji w sieciach produkcyjnych.
Wskazówka dotycząca polityki: umieść budżety tokenów oraz limity przepustowości na poziomie poszczególnych użytkowników w APIM, aby błędnie działający cykl agenta nie mógł obejść ograniczeń na poziomie aplikacji poprzez bezpośrednie wywołanie funkcji — zablokuj bezpośredni dostęp do funkcji w sieciach produkcyjnych.
Wskazówka dotycząca polityki: umieść budżety tokenów oraz limity przepustowości na poziomie poszczególnych użytkowników w APIM, aby błędnie działający cykl agenta nie mógł obejść ograniczeń na poziomie aplikacji poprzez bezpośrednie wywołanie funkcji — zablokuj bezpośredni dostęp do funkcji w sieciach produkcyjnych.
Wskazówka dotycząca polityki: umieść budżety tokenów oraz limity przepustowości na poziomie poszczególnych użytkowników w APIM, aby błędnie działający cykl agenta nie mógł obejść ograniczeń na poziomie aplikacji poprzez bezpośrednie wywołanie funkcji — zablokuj bezpośredni dostęp do funkcji w sieciach produkcyjnych.
Wskazówka dotycząca polityki: umieść budżety tokenów oraz limity przepustowości na poziomie poszczególnych użytkowników w APIM, aby błędnie działający cykl agenta nie mógł obejść ograniczeń na poziomie aplikacji poprzez bezpośrednie wywołanie funkcji — zablokuj bezpośredni dostęp do funkcji w sieciach produkcyjnych.
Wskazówka dotycząca polityki: umieść budżety tokenów oraz limity przepustowości na poziomie poszczególnych użytkowników w APIM, aby błędnie działający cykl agenta nie mógł obejść ograniczeń na poziomie aplikacji poprzez bezpośrednie wywołanie funkcji — zablokuj bezpośredni dostęp do funkcji w sieciach produkcyjnych.
Wskazówka dotycząca polityki: umieść budżety tokenów oraz limity przepustowości na poziomie poszczególnych użytkowników w APIM, aby błędnie działający cykl agenta nie mógł obejść ograniczeń na poziomie aplikacji poprzez bezpośrednie wywołanie funkcji — zablokuj bezpośredni dostęp do funkcji w sieciach produkcyjnych.
Wskazówka dotycząca polityki: umieść budżety tokenów oraz limity przepustowości na poziomie poszczególnych użytkowników w APIM, aby błędnie działający cykl agenta nie mógł obejść ograniczeń na poziomie aplikacji poprzez bezpośrednie wywołanie funkcji — zablokuj bezpośredni dostęp do funkcji w sieciach produkcyjnych.
Wskazówka dotycząca polityki: umieść budżety tokenów oraz limity przepustowości na poziomie poszczególnych użytkowników w APIM, aby błędnie działający cykl agenta nie mógł obejść ograniczeń na poziomie aplikacji poprzez bezpośrednie wywołanie funkcji — zablokuj bezpośredni dostęp do funkcji w sieciach produkcyjnych.
Wskazówka dotycząca polityki: umieść budżety tokenów oraz limity szybkości na poziomie poszczególnych użytkowników w APIM, aby błędnie działający cykl agenta nie mógł obejść ograniczeń na poziomie aplikacji poprzez bezpośrednie wywoływanie funkcji — zablokuj bezpośrednie wejście do funkcji w sieciach produkcyjnych.
Wskazówka dotycząca polityki: umieść budżety tokenów oraz limity szybkości na poziomie poszczególnych użytkowników w APIM, aby błędnie działający cykl agenta nie mógł obejść ograniczeń na poziomie aplikacji poprzez bezpośrednie wywoływanie funkcji — zablokuj bezpośrednie wejście do funkcji w sieciach produkcyjnych.
Różne środowiska wymagają oddzielnych produktów i tożsamości APIM. Dzielenie się jedną implementacją Foundry pomiędzy środowisko rozwojowe a produkcyjne w celu „oszczędzenia pieniędzy” zazwyczaj powoduje wyciek informacji i narusza izolację poszczególnych obszarów.
Zapisz, którzy użytkownicy mogą tworzyć implementacje modeli, a którzy mogą je jedynie wywoływać. Zwykle zdrowym rozwiązaniem jest oddzielenie uprawnień do wywoływania od uprawnień do implementacji.
Gdy dodaje się nową rodzinę modeli, należy w tym samym PR zaktualizować dostosowaną rolę, backend APIM, ustawienia funkcji oraz przeprowadzić test sprawdzający. Częściowe wdrażanie jest sposobem, dzięki któremu błędy 403 pojawiają się wyłącznie w piątki.
Należy preferować nagłówki korelacji od APIM, przez funkcję, aż do logowania w SDK modelu, aby pojedynczy ticket obsługi klienta mógł odtworzyć pełną ścieżkę.
Różne środowiska wymagają oddzielnych produktów i tożsamości APIM. Dzielenie się jednym wdrożeniem Foundry pomiędzy środowisko rozwojowe a produkcyjne w celu „oszczędzenia pieniędzy” zazwyczaj powoduje wyciek informacji i narusza izolację poszczególnych obszarów.
Należy udokumentować, które osoby mogą tworzyć wdrożenia modeli, a które mogą je jedynie wywoływać. Prawo do wywoływania bez prawa do wdrażania stanowi zwykle zdrowy podział uprawnień.
Gdy dodaje się nową rodzinę modeli, należy w tym samym PR zaktualizować dostosowaną rolę, backend APIM, ustawienia funkcji oraz przeprowadzić test sprawdzający. Częściowe wdrażanie jest sposobem, dzięki któremu błędy 403 pojawiają się wyłącznie w piątki.
Należy preferować nagłówki korelacji z APIM, przechodzące przez funkcję do logowania w modelu SDK, aby pojedynczy ticket obsługi klienta mógł odtworzyć pełną ścieżkę.
Różne środowiska wymagają oddzielnych produktów i tożsamości APIM. Dzielenie się jedną implementacją Foundry pomiędzy środowiskiem rozwojowym a produkcyjnym w celu „oszczędzenia pieniędzy” zazwyczaj powoduje wyciek informacji i narusza izolację poszczególnych obszarów.
Należy udokumentować, które konta mogą tworzyć implementacje modeli, a które mogą je jedynie wywoływać. Zwykle zdrowym rozwiązaniem jest posiadanie uprawnień do wywoływania bez uprawnień do tworzenia implementacji.
Przy dodawaniu nowej rodziny modeli należy zaktualizować dostosowaną rolę, backend APIM, ustawienia funkcji oraz przeprowadzić test w tym samym PR. Częściowe wdrażania są przyczyną pojawiania się błędów 403 wyłącznie w piątki.
Należy preferować nagłówki korelacji z APIM, przechodzące przez funkcję do logowania w modelu SDK, aby pojedynczy ticket obsługi klienta mógł odtworzyć pełną ścieżkę.
Różne środowiska wymagają oddzielnych produktów APIM oraz tożsamości. Dzielenie się jedną implementacją Foundry pomiędzy środowiskiem rozwojowym a produkcyjnym w celu „oszczędzenia pieniędzy” zazwyczaj powoduje wyciek informacji i narusza izolację poszczególnych obszarów.