Distribuire un agente ospitato

Questo articolo illustra come distribuire un agente in contenitori nel servizio Agente Foundry usando l'SDK di Python o l'API REST. Usare questi approcci quando si vogliono gestire le distribuzioni degli agenti direttamente dalle applicazioni o dai servizi personali.

Se si esegue la distribuzione per la prima volta o si vuole il percorso più veloce, usare invece la guida introduttiva: Creare e distribuire un agente ospitato . L'avvio rapido usa Azure Developer CLI (azd) o l'estensione VS Code, che gestisce la creazione, il push, il controllo della versione e la configurazione del controllo degli accessi in base al ruolo in modo automatico.

Ciclo di vita dell'implementazione

Ogni distribuzione dell'agente ospitato segue questa sequenza:

  1. Crea e invia: crea un pacchetto del codice dell'agente in un'immagine del contenitore e invialo a Registro Azure Container.
  2. Creare una versione dell'agente: registrare l'immagine con il Servizio agenti Foundry. La piattaforma fornisce l'infrastruttura e crea un'identità dedicata dell'agente Entra.
  3. Eseguire il polling dello stato: attendere lo stato della versione per raggiungere active.
  4. Invoke : inviare richieste all'endpoint dedicato dell'agente.

Prerequisiti

Autorizzazioni necessarie

È necessario disporre di Foundry Project Manager a livello di progetto per creare e distribuire agenti ospitati. Questo ruolo include sia le autorizzazioni del piano dati per creare agenti sia la possibilità di assegnare il ruolo Foundry User all'identità dell'agente creata dalla piattaforma. L'identità dell'agente richiede l'utente Foundry nel progetto per accedere ai modelli e agli artefatti in fase di esecuzione.

Importante

I ruoli RBAC di Foundry sono stati recentemente rinominati. Foundry User, Foundry Owner, Foundry Account Owner e Foundry Project Manager erano precedentemente denominati Azure AI User, Azure AI Owner, Azure AI Account Owner e Azure AI Project Manager. È possibile che i nomi precedenti vengano visualizzati in alcune posizioni durante l'esecuzione della ridenominazione. Gli ID ruolo e le autorizzazioni di base sono invariati dalla ridenominazione.

Se si usa azd o l'estensione di VS Code, lo strumento gestisce automaticamente la maggior parte delle assegnazioni RBAC, tra cui:

  • Lettore repository Registro Container per l'identità gestita del progetto (pull delle immagini)
  • Utente Foundry per l'identità dell'agente creata dalla piattaforma (modello di esecuzione e accesso agli strumenti)

Nota

  • La piattaforma crea un'identità dell'agente Entra dedicata per ogni agente ospitato in fase di distribuzione. Questa identità è un'entità servizio usata dal contenitore in esecuzione per chiamare modelli e strumenti. Non è necessario configurare manualmente le identità gestite. Tuttavia, l'utente che crea l'agente deve disporre dell'autorizzazione per assegnare Azure AI User a tale identità, motivo per cui si consiglia Azure AI Project Manager anziché il solo Azure AI User.
  • Mentre azd e le estensioni di VS Code gestiscono automaticamente le assegnazioni RBAC di base, gli scenari complessi possono richiedere un'ulteriore configurazione manuale. Per informazioni dettagliate su tutte le autorizzazioni e le assegnazioni di ruolo coinvolte, consultare il Riferimento sulle autorizzazioni per agenti ospitati.

Per altre informazioni, vedere Autenticazione e autorizzazione.

Importante

Il Registro Azure Container che contiene l'immagine del contenitore dell'agente ospitato deve essere attualmente raggiungibile tramite l'endpoint pubblico. Posizionare il registro dietro una rete privata (endpoint privato con l'accesso alla rete pubblica disabilitato) non è attualmente supportato per gli agenti ospitati: la piattaforma non può prelevare l'immagine. Per l'elenco completo dei vincoli di rete, vedere Limitazioni.

Requisiti dei contenitori

L'immagine del container deve soddisfare i requisiti seguenti per essere eseguita sulla piattaforma Hosted agent.

Importante

La piattaforma di hosting richiede immagini del contenitore x86_64 (linux/amd64). Se si usa Apple Silicon o altri computer basati su ARM, usare docker build --platform linux/amd64 . per evitare di produrre un'immagine ARM incompatibile.

Librerie di protocolli

Gli agenti ospitati comunicano con il gateway Foundry tramite librerie di protocolli. Scegliere il protocollo che corrisponde al modello di interazione dell'agente:

Protocollo libreria Python libreria .NET Endpoint Migliore per
Risposte azure-ai-agentserver-responses Azure.AI.AgentServer.Responses /responses Chatbot conversazionali, streaming, più turni con cronologia gestita dalla piattaforma
Invocazioni azure-ai-agentserver-invocations Azure.AI.AgentServer.Invocations /invocations Ricevitori webhook, elaborazione non conversazionale, flussi di lavoro asincroni personalizzati

Un singolo contenitore può esporre entrambi i protocolli contemporaneamente dichiarando sia quando si crea l'agente, nel file, nella agent.yaml chiamata SDK o nella richiesta api REST, sia importando entrambe le librerie. Usare le librerie di protocolli all'interno del framework esistente, sia che si tratti di Microsoft Framework agente, LangChain o codice personalizzato.

Libreria di protocolli di risposta

Le librerie Python e .NET per il protocollo Risposte implementano l'API risposte di intelligenza artificiale Azure. Importare il pacchetto e implementare l'interfaccia IResponseHandler . La libreria gestisce il routing, lo streaming con eventi inviati dal server ( SSE), l'esecuzione in background, l'annullamento, la memorizzazione nella cache e la gestione del ciclo di vita delle risposte.

IResponseHandler

IResponseHandler è l'astrazione di base implementata. La libreria chiama CreateAsync per ogni richiesta in ingresso e consegna il IAsyncEnumerable<ResponseStreamEvent> restituito ai client attraverso la crittografia del servizio di archiviazione.

public class EchoHandler : ResponseHandler
{
    public override IAsyncEnumerable<ResponseStreamEvent> CreateAsync(
        CreateResponse request,
        ResponseContext context,
        CancellationToken cancellationToken)
    {
        return new TextResponse(context, request,
            createText: async ct =>
            {
                var input = await context.GetInputTextAsync(cancellationToken: ct);
                return $"Echo: {input}";
            });
    }
}

ResponseEventStream

ResponseEventStream gestisce automaticamente sequenceNumber, outputIndex, contentIndex, itemId e il ciclo di vita completo Response. Ogni yield return esegue il mapping uno-a-uno a un evento di crittografia del servizio di archiviazione, quindi non è necessario tenere traccia di questo stato manualmente.

Modalità di streaming e in background

  • Modalità di streaming (impostazione predefinita): gli eventi SSE vengono recapitati in tempo reale al client connesso.
  • Modalità in background: il gestore viene eseguito completamente anche senza un client di crittografia del servizio di archiviazione connesso. Gli eventi vengono memorizzati nel buffer e disponibili per la riproduzione tramite GET /responses/{id}.

Ciclo di vita della risposta

La libreria orchestra il ciclo di vita completo della risposta: createdin_progresscompleted (o failed o cancelled). La libreria gestisce automaticamente l'annullamento, la gestione degli errori e garantisce gli eventi terminali.

Sicurezza dei thread

Tutte le istanze del servizio registrate tramite AddResponsesServer() sono thread-safe. Le istanze del gestore hanno ambito per richiesta.

Per indicazioni dettagliate sull'implementazione del gestore, vedere la guida all'implementazione handler. Per esempi eseguibili, vedere gli esempi di protocollo Responses.

Endpoint di integrità

Le librerie di protocolli espongono automaticamente un /readiness endpoint per i controlli di integrità della piattaforma. Non è necessario implementare questa operazione manualmente.

Porta

I container servono traffico sulla porta 8088 localmente. Nell'ambiente di produzione, il gateway Foundry gestisce il routing e il contenitore non deve esporre una porta pubblica.

Variabili di ambiente inserite dalla piattaforma

La piattaforma dell'agente ospitato inserisce automaticamente le variabili di ambiente nel contenitore in fase di esecuzione. Il codice può leggerli senza dichiararli in agent.yaml o environment_variables. Il FOUNDRY_* prefisso è riservato per l'uso della piattaforma.

Variabile Scopo
FOUNDRY_PROJECT_ENDPOINT URL dell'endpoint del progetto Foundry
FOUNDRY_PROJECT_ARM_ID ID risorsa ARM del progetto Foundry
FOUNDRY_AGENT_NAME Nome dell'agente in esecuzione
FOUNDRY_AGENT_VERSION Versione dell'agente in esecuzione
FOUNDRY_AGENT_SESSION_ID ID sessione per la richiesta corrente (solo contenitori ospitati)
APPLICATIONINSIGHTS_CONNECTION_STRING Stringa di connessione di Application Insights per i dati di telemetria

Non ridefinire le variabili iniettate dalla piattaforma in agent.yaml: sono impostate automaticamente.

Le variabili che dichiari tu stesso, come MODEL_DEPLOYMENT_NAME o gli endpoint MCP della toolbox, vanno nella sezione environment_variables di agent.yaml o nella chiamata SDK create_version.

Riferimenti alle connessioni di progetto nelle variabili di ambiente

Anziché codificare direttamente i segreti (chiavi API, token, endpoint) in agent.yaml o nella tua immagine, recuperali da una connessione di progetto Foundry all'avvio della sandbox. Qualsiasi valore in environment_variables può essere un'espressione segnaposto risolta dalla piattaforma prima dell'avvio del contenitore.

Sintassi del segnaposto

Un segnaposto ha la forma ${{connections.<name>.<path>}}, dove <name> è il nome della risorsa della connessione (visibile nel portale in Dettagli progetto>Risorse connesse) e <path> è uno dei seguenti:

Percorso Risolve in modo che
credentials.<field> Campo segreto sulla connessione
target La proprietà della connessione target (ad esempio, un URL di un endpoint)
metadata.<field> Un campo sotto quello della connessione metadata

Il nome del campo da usare dipende dalla categoria di connessione:

Categoria di connessione Nome del campo nel placeholder
ApiKey, AppInsights Sempre key, ad esempio credentials.key
CustomKeys Nome della chiave specificato durante la creazione della connessione, ad esempio credentials.github_token

Esempio

Per prima cosa, crea una connessione CustomKeys nel progetto che contiene il segreto. Vedere Aggiungi una nuova connessione in Microsoft Foundry. Quindi fare riferimento a esso da agent.yaml:

environment_variables:
  - name: MODEL_DEPLOYMENT_NAME
    value: gpt-5-mini
  - name: GITHUB_TOKEN
    value: ${{connections.agent-secrets.credentials.github_token}}

All'avvio della sandbox Foundry risolve il segnaposto e inserisce il valore risolto come variabile di ambiente normale. Il codice lo legge come qualsiasi altro var di env:

import os
token = os.environ["GITHUB_TOKEN"]

Una funzione GET sulla versione dell'agente restituisce il ${{...}} testo letterale, ovvero il segreto risolto non viene mai restituito tramite l'API di gestione.

Considerations

  • Creare la connessione prima di distribuire la versione. Se la connessione o il campo a cui si fa riferimento non è presente all'avvio della sandbox, il segnaposto non viene risolto e la variabile è vuota.
  • I segreti sono di sola scrittura. GET su una connessione restituisce credentials: null. Verificare la risoluzione leggendo la variabile d'ambiente dall'interno del container in esecuzione, non ispezionando la connessione.
  • Annota tu stesso i nomi dei campi CustomKeys. L'API di gestione non le restituisce mai dopo la creazione. Tienili accanto alla sorgente dell'agente (ad esempio, nei modelli IaC o accanto a agent.yaml) in modo da poter creare dei segnaposto successivamente senza dover tirare a indovinare.
  • Foundry gestisce il nome del segreto di backup. Quando si crea la connessione, Foundry archivia il valore in Key Vault sotto un nome scelto. Non è possibile fare riferimento a un segreto Key Vault preesistente in base al nome. Per collegare il proprio Key Vault come archivio di supporto, vedi Configurare una connessione a Key Vault.

Creare un pacchetto e testare l'agente in locale

Prima di eseguire la distribuzione in Foundry, verificare che l'agente funzioni in locale usando la libreria di protocolli. Il contenitore gestisce gli stessi endpoint in locale come avviene nell'ambiente di produzione.

Testare il protocollo Risposte

POST http://localhost:8088/responses
Content-Type: application/json

{
    "input": "Where is Seattle?",
    "stream": false
}

Testare il protocollo Invocations

POST http://localhost:8088/invocations
Content-Type: application/json

{
    "message": "Hello!"
}

Eseguire la distribuzione usando l'interfaccia della riga di comando per sviluppatori Azure o VS Code

L'estensione Azure Developer CLI (azd) e VS Code automatizzano il ciclo di vita completo della distribuzione. Per una procedura dettagliata, vedere Avvio rapido: Creare e distribuire un agente ospitato.

Eseguire la distribuzione con Python SDK

Usare l'SDK per gestire le distribuzioni degli agenti direttamente dal codice Python.

Prerequisiti aggiuntivi

Creare l'immagine del contenitore ed eseguirne il push

  1. Costruisci la tua immagine Docker:

    docker build --platform linux/amd64 -t myagent:v1 .
    

    Vedere i Dockerfile di esempio per Python e C#.

  2. Inviare al Registro Azure Container:

    az acr login --name myregistry
    docker tag myagent:v1 myregistry.azurecr.io/myagent:v1
    docker push myregistry.azurecr.io/myagent:v1
    

Suggerimento

Usare tag di immagine univoci anziché :latest per le distribuzioni riproducibili.

Configurare le autorizzazioni del registro contenitori

Concedi l'accesso all'identità gestita del progetto per il pull delle immagini.

  1. Nel portale Azure passare alla risorsa del progetto Foundry.

  2. Selezionare Identità e copiare l'ID oggetto (entità) sotto Assegnato dal sistema.

  3. Assegnare il ruolo Lettore repository Registro Container a questa identità nel Registro Container. Vedere Ruoli e autorizzazioni di Registro Azure Container.

Creare una versione dell'agent ospitato

Creare una versione fa sì che la piattaforma provveda automaticamente al provisioning dell'agente. Non esiste un passaggio di avvio separato: la piattaforma compila uno snapshot del contenitore e rende l'agente pronto per la gestione delle richieste.

from azure.ai.projects import AIProjectClient
from azure.ai.projects.models import HostedAgentDefinition, ProtocolVersionRecord, AgentProtocol
from azure.identity import DefaultAzureCredential

# Format: "https://resource_name.services.ai.azure.com/api/projects/project_name"
PROJECT_ENDPOINT = "your_project_endpoint"

# Create project client
credential = DefaultAzureCredential()
project = AIProjectClient(
    endpoint=PROJECT_ENDPOINT,
    credential=credential,
    allow_preview=True,
)

# Create a hosted agent version
agent = project.agents.create_version(
    agent_name="my-agent",
    definition=HostedAgentDefinition(
        container_protocol_versions=[
            ProtocolVersionRecord(protocol=AgentProtocol.RESPONSES, version="1.0.0")
        ],
        cpu="1",
        memory="2Gi",
        image="your-registry.azurecr.io/your-image:tag",
        environment_variables={
            "MODEL_DEPLOYMENT_NAME": "gpt-5-mini"
        }
    )
)

print(f"Agent created: {agent.name}, version: {agent.version}")

Per esporre entrambi i protocolli, passare entrambi in container_protocol_versions:

container_protocol_versions=[
    ProtocolVersionRecord(protocol=AgentProtocol.RESPONSES, version="1.0.0"),
    ProtocolVersionRecord(protocol=AgentProtocol.INVOCATIONS, version="1.0.0")
],

Parametri chiave:

Parametro Descrizione
agent_name Nome univoco (alfanumerico con trattini, massimo 63 caratteri)
image URL completo dell'immagine di Registro Azure Container con tag
cpu Allocazione cpu (ad esempio, "1")
memory Allocazione di memoria (ad esempio, "2Gi")
container_protocol_versions Protocolli esposti dal contenitore (responses, invocationso entrambi)

Verificare lo stato della versione

Dopo aver creato una versione, eseguire il polling finché lo stato non è active, quindi richiamare l'agente. Il provisioning richiede in genere meno di un minuto in base alle dimensioni dell'immagine.

import time

# Poll until the agent version is active
while True:
    version_info = project.agents.get_version(
        agent_name="my-agent",
        agent_version=agent.version
    )
    status = version_info["status"]
    print(f"Status: {status}")

    if status == "active":
        print("Agent is ready!")
        break
    elif status == "failed":
        print(f"Provisioning failed: {version_info['error']}")
        break

    time.sleep(5)

Valori dello stato della versione:

Stato Descrizione
creating Provisioning dell'infrastruttura in corso
active Agent è pronto per gestire le richieste
failed Provisioning non riuscito: controllare il campo error per informazioni dettagliate
deleting La versione è in fase di pulizia
deleted La versione è stata rimossa completamente

Richiamare l'agente

Dopo che la versione raggiunge active lo stato, usare get_openai_client per creare un client OpenAI associato all'endpoint dell'agente.

Per il protocollo Risposte :

# Create an OpenAI client bound to the agent endpoint
openai_client = project.get_openai_client(agent_name="my-agent")

response = openai_client.responses.create(
    input="Hello! What can you do?",
)

print(response.output_text)

Per il protocollo Invocazioni, chiamare direttamente l'endpoint delle invocazioni:

import requests

token = credential.get_token("https://ai.azure.com/.default").token
url = f"{PROJECT_ENDPOINT}/agents/my-agent/endpoint/protocols/invocations"

response = requests.post(url, headers={
    "Authorization": f"Bearer {token}",
    "Content-Type": "application/json",
    "Foundry-Features": "HostedAgents=V1Preview"
}, params={"api-version": "v1"}, json={
    "message": "Process this task"
})

print(response.json())

Per esempi più completi, consulta gli esempi di agenti ospitati.

Distribuire usando l'API REST

Usare l'API REST per distribuzioni dirette basate su HTTP o durante l'integrazione con strumenti personalizzati.

Prima di iniziare, compilare ed eseguire il push dell'immagine del contenitore e configurare le autorizzazioni del registro contenitori.

Configurare le variabili

BASE_URL="https://{account}.services.ai.azure.com/api/projects/{project}"
API_VERSION="v1"
TOKEN=$(az account get-access-token --resource https://ai.azure.com --query accessToken -o tsv)

Creare un agente

curl -X POST "$BASE_URL/agents?api-version=$API_VERSION" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "my-agent",
    "definition": {
      "kind": "hosted",
      "image": "myacr.azurecr.io/my-agent:v1",
      "cpu": "1",
      "memory": "2Gi",
      "container_protocol_versions": [
        {"protocol": "responses", "version": "1.0.0"}
      ],
      "environment_variables": {
        "MODEL_DEPLOYMENT_NAME": "gpt-5-mini"
      }
    }
  }'

La creazione di un agente crea anche la versione 1 e attiva il provisioning.

Verificare lo stato della versione

Eseguire il polling dell'endpoint versione finché status non diventa active:

while true; do
  STATUS=$(curl -s -X GET "$BASE_URL/agents/my-agent/versions/1?api-version=$API_VERSION" \
    -H "Authorization: Bearer $TOKEN" | jq -r '.status')
  echo "Status: $STATUS"
  [ "$STATUS" = "active" ] && echo "Ready!" && break
  [ "$STATUS" = "failed" ] && echo "Provisioning failed." && exit 1
  sleep 5
done

Richiamare l'agente

Usare l'endpoint dedicato dell'agente per inviare richieste. Impostare "stream": true per ricevere eventi inviati dal server.

Protocollo di risposte:

curl -X POST "$BASE_URL/agents/my-agent/endpoint/protocols/openai/responses?api-version=$API_VERSION" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "input": "Hello! What can you do?",
    "store": true
  }'

Protocollo invocazioni:

curl -X POST "$BASE_URL/agents/my-agent/endpoint/protocols/invocations?api-version=$API_VERSION" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -H "Foundry-Features: HostedAgents=V1Preview" \
  -d '{
    "message": "Process this task"
  }'

Creare una nuova versione

Distribuire il codice o la configurazione aggiornati creando una nuova versione:

curl -X POST "$BASE_URL/agents/my-agent/versions?api-version=$API_VERSION" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "definition": {
      "kind": "hosted",
      "image": "myacr.azurecr.io/my-agent:v2",
      "cpu": "1",
      "memory": "2Gi",
      "container_protocol_versions": [
        {"protocol": "responses", "version": "1.0.0"}
      ],
      "environment_variables": {
        "MODEL_DEPLOYMENT_NAME": "gpt-5-mini"
      }
    }
  }'

Pulire le risorse

Per evitare addebiti, pulire le risorse al termine. Il provisioning della risorsa di calcolo dell'agente viene annullato dopo 15 minuti di inattività, pertanto non ci sono costi quando l'agente non gestisce le richieste.

pulizia della Azure Developer CLI

azd down

Pulizia dell'SDK

Eliminare una singola versione:

project.agents.delete_version(agent_name="my-agent", agent_version=agent.version)

In alternativa, eliminare l'intero agente e tutte le relative versioni:

project.agents.delete(agent_name="my-agent")

Pulizia dell'API REST

Eliminare una singola versione:

curl -X DELETE "$BASE_URL/agents/my-agent/versions/1?api-version=$API_VERSION" \
  -H "Authorization: Bearer $TOKEN"

In alternativa, eliminare l'intero agente:

curl -X DELETE "$BASE_URL/agents/my-agent?api-version=$API_VERSION" \
  -H "Authorization: Bearer $TOKEN"

Avviso

L'eliminazione di un agente rimuove tutte le relative versioni e termina le sessioni attive. Questa azione non può essere annullata.

Risoluzione dei problemi

Gli errori di provisioning si manifestano nei campi error.code e error.message dell'oggetto versione. Controllare lo stato della versione dopo la creazione per identificare i problemi.

Codice di errore Codice HTTP Soluzione
image_pull_failed 400 Verificare che l'URI dell'immagine sia corretto e che l'identità gestita del progetto disponga del ruolo Lettore repository Registro Container nel Registro Azure Container
SubscriptionIsNotRegistered 400 Registrare il provider di sottoscrizioni
InvalidAcrPullCredentials 401 Correggere l'identità gestita o il controllo degli accessi in base al ruolo del registro
UnauthorizedAcrPull 403 Specificare le credenziali o l'identità corrette
AcrImageNotFound 404 Correggere il nome/il tag dell'immagine o pubblicare l'immagine
RegistryNotFound 400/404 Correggere il DNS del Registro di sistema o la raggiungibilità della rete

Per gli errori 5xx, contattare Microsoft supporto tecnico.

Per requisiti dettagliati di controllo degli accessi basati su ruolo e risoluzione dei problemi di autorizzazione, vedere il riferimento sulle autorizzazioni dell'agente ospitato.

Passaggi successivi