Agenti ospitati di Foundry

Agenti ospitati nel servizio Microsoft Foundry Agent consentono di distribuire agenti del framework Agent come applicazioni containerizzate nell'infrastruttura gestita da Microsoft. La piattaforma gestisce la scalabilità, la persistenza dello stato della sessione, la sicurezza e la gestione del ciclo di vita, in modo da poter concentrarsi sulla logica dell'agente. Microsoft Foundry Hosted Agents è ora disponibile a livello generale.

Con l'integrazione di hosting di Agent Framework, è possibile esporre un Agent, incluso un flusso di lavoro racchiuso con Workflow.as_agent(), tramite il protocollo Foundry Responses o Invocations con una quantità minima di codice.

Quando usare gli agenti ospitati

Scegliere agenti ospitati da Foundry quando si vuole:

  • Infrastruttura gestita : non è necessario configurare manualmente contenitori, server Web o regole di ridimensionamento.
  • Gestione delle sessioni predefinita : la piattaforma mantiene e carica i $HOME file tra turni e periodi di inattività.
  • Identità dell'agente dedicato : ogni agente distribuito ottiene la propria identità Entra per proteggere l'accesso a modelli, strumenti e servizi downstream.
  • Endpoint compatibili con OpenAI : i client possono interagire con l'agente usando qualsiasi SDK compatibile con OpenAI tramite il protocollo Responses.

Annotazioni

L'integrazione di Python agent-framework-foundry-hosting è in versione preliminare. Microsoft Foundry Hosted Agents, il servizio gestito di hosting, è generalmente disponibile.

Prerequisites

  • Una sottoscrizione di Azure
  • Azure Developer CLI (azd) con l'estensione dell'agente di intelligenza artificiale: azd ext install azure.ai.agents

Per i test locali, è necessario anche:

Installare il pacchetto NuGet di hosting:

dotnet add package Microsoft.Agents.AI.Foundry.Hosting --prerelease
dotnet add package Azure.AI.Projects --prerelease
  • Python 3.10 o versione successiva

Installare il pacchetto di hosting prerelease, il client Foundry e il pacchetto di autenticazione di Azure:

pip install --pre agent-framework-foundry agent-framework-foundry-hosting azure-identity

In Foundry, la piattaforma fornisce il contesto utente del chiamante e il contesto di chiamata; l'infrastruttura di hosting li usa per isolare lo stato per utente e inoltrare il contesto di richiesta ai servizi Foundry. Le esecuzioni locali non ricevono il contesto della piattaforma, quindi le applicazioni devono fornire i propri controlli di identità e stato quando necessario.

Protocollo di risposte

Il protocollo Risposte è il punto di partenza consigliato per la maggior parte degli agenti. Espone un endpoint compatibile con /responses OpenAI e la piattaforma gestisce automaticamente la cronologia delle conversazioni, lo streaming e il ciclo di vita della sessione.

using Azure.AI.AgentServer.Core;
using Azure.AI.Projects;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Agents.AI.Foundry.Hosting;

var projectEndpoint = new Uri(Environment.GetEnvironmentVariable("FOUNDRY_PROJECT_ENDPOINT")
    ?? throw new InvalidOperationException("FOUNDRY_PROJECT_ENDPOINT is not set."));
var deployment = Environment.GetEnvironmentVariable("AZURE_AI_MODEL_DEPLOYMENT_NAME") ?? "gpt-4o";

AIAgent agent = new AIProjectClient(projectEndpoint, new DefaultAzureCredential())
    .AsAIAgent(
        model: deployment,
        instructions: "You are a helpful AI assistant.",
        name: "my-agent");

var builder = AgentHost.CreateBuilder(args);
builder.Services.AddFoundryResponses(agent);
builder.RegisterProtocol("responses", endpoints => endpoints.MapFoundryResponses());

var app = builder.Build();
app.Run();

AgentHost.CreateBuilder Crea un host dell'applicazione preconfigurato per l'ambiente host Foundry. AddFoundryResponses registra l'agente con il gestore del protocollo Responses ed MapFoundryResponses esegue il mapping dell'endpoint /responses HTTP.

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

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 helpful AI assistant.",
)

server = ResponsesHostServer(agent)
server.run()

L'elemento ResponsesHostServer esegue il wrapping dell'agente e lo espone tramite il protocollo Foundry Responses. Per un agente non basato su flusso di lavoro, l'impostazione predefinita history_source="agent_server" usa il provider di risposte configurato di Agent Server come origine della cronologia del modello. L'host impedisce al servizio modello downstream di conservare una seconda copia quando il client archivia la cronologia per impostazione predefinita.

Non combinare l'origine della cronologia predefinita con un HistoryProvider oggetto con load_messages=True. Inoltre, non impostare le opzioni di continuazione del servizio a valle conversation_id, previous_response_id o conversation. L'host rifiuta queste configurazioni per evitare duplicati nella cronologia.

Usare ResponsesHostServer(agent, history_source="agent") quando il provider di cronologia dell'agente o il servizio modello downstream deve gestire la cronologia delle conversazioni. Questa modalità passa solo l'input della richiesta corrente dal server Agent e mantiene la cronologia dell'agente e il comportamento di archiviazione del servizio. Le implementazioni personalizzate SupportsAgentRun devono usare questa modalità. Il store parametro rimane separato: seleziona il provider di risposta che rende persistenti gli input e gli output dell'API Risposte in entrambe le modalità.

L'host è proprietario dell'agente fornito e potrebbe aggiungere provider di contesto specifici dell'hosting. Non riutilizzare l'agente con un altro host né invocarlo direttamente dopo la creazione dell'host.

Mantenere lo stato e gestire conversazioni di lunga durata

ResponsesHostServer configura per impostazione predefinita gli store basati su Foundry. Per gli agenti non relativi al flusso di lavoro, AgentSessionStoreProvider fornisce un FoundryAgentSessionStore. Per gli agenti del flusso di lavoro, CheckpointStoreProvider fornisce un oggetto FoundryCheckpointStore. FunctionApprovalStoreProvider fornisce un elemento FoundryFunctionApprovalStore per le approvazioni in attesa. Questi archivi usano Foundry State Store quando sono ospitati e lo stato locale di Agent Server quando vengono eseguiti in locale.

Con history_source="agent", l'archivio sessioni configurato mantiene lo stato del provider trasportato da AgentSession, inclusi i messaggi da InMemoryHistoryProvider.

Per personalizzare l'archiviazione, passare StoreProvider a agent_session_store_provider o function_approval_store_provider. Passa un ContextScopedStoreProvider a checkpoint_store_provider. Ad esempio, implementa SessionStore e StoreProvider[SessionStore] per utilizzare il tuo archivio delle sessioni dell'agente non basato su workflow.

Importare ResponsesServerOptions da azure.ai.agentserver.responsese passarlo al ResponsesHostServeroptions parametro . Le opzioni di conversazione a esecuzione prolungata disponibili dipendono dal tipo di agente:

Funzionalità Tipo di agente Requisiti e comportamento
Risposte in background resilienti Solo flusso di lavoro Imposta ResponsesServerOptions(resilient_background=True). Inviare la richiesta Risposte con store=true e background=true. Dopo un riavvio, l'host riprende il checkpoint del flusso di lavoro durevole più recente o riproduce l'input originale se non esiste alcun checkpoint. Non configurare l'archiviazione dei checkpoint nel workflow perché è gestita dall'host. Rendere idempotenti gli effetti collaterali esterni perché l'elaborazione successiva all'ultimo checkpoint persistente potrebbe ripetersi.
Conversazioni guidate Solo non-workflow Impostare ResponsesServerOptions(steerable_conversations=True) e inviare richieste di risposte con store=true. Mantieni i turni su un’unica catena lineare riutilizzando lo stesso valore conversation. In alternativa, invia il previous_response_id immediatamente precedente e preserva il agent_session_id risolto. L'host rifiuta i predecessori obsoleti che potrebbero causare un fork.

ResponsesHostServer solleva RuntimeError se vengono abilitate risposte in background resilienti per un agente non di workflow o conversazioni pilotabili per un agente di workflow. Per le implementazioni complete, vedere l'archivio personalizzato, il flusso di lavoro resiliente a esecuzione prolungata e gli esempi di agenti a esecuzione prolungata gestibili .

Quando uno strumento MCP ospitato in Foundry richiede il consenso dell'utente, ResponsesHostServer restituisce una risposta incompleta con un oauth_consent_request elemento di output. Presentare consent_link all'utente, quindi continuare usando l'ID della risposta incompleta come previous_response_id dopo che l'utente ha fornito il consenso. L'host mantiene la sessione dell'agente per questo nuovo tentativo ed espone solo collegamenti di consenso HTTPS assoluti.

Protocollo di Invocazioni

Il protocollo Chiamate offre il controllo completo sulla richiesta e sulla risposta HTTP. Usarlo quando sono necessari payload personalizzati, elaborazione non di conversazione o protocolli di streaming non compatibili con OpenAI.

Con il protocollo Invocations in C#, si implementa un InvocationHandler personalizzato per elaborare le richieste in ingresso.

using Azure.AI.AgentServer.Core;
using Azure.AI.AgentServer.Invocations;
using Microsoft.Agents.AI;

var builder = AgentHost.CreateBuilder(args);

builder.Services.AddSingleton<AIAgent, MyAgent>();
builder.Services.AddInvocationsServer();
builder.Services.AddScoped<InvocationHandler, MyInvocationHandler>();

builder.RegisterProtocol("invocations", endpoints => endpoints.MapInvocationsServer());

var app = builder.Build();
app.Run();

Il AddInvocationsServer metodo registra i servizi del protocollo Invocations. Si implementa InvocationHandler per definire il modo in cui l'agente elabora ogni richiesta.

Per un'installazione leggera, usare InvocationsHostServer dal agent_framework_foundry_hosting pacchetto. Esegue il wrapping dell'agente in modo analogo a ResponsesHostServer e gestisce automaticamente la gestione delle sessioni:

import os

from agent_framework import Agent
from agent_framework.foundry import FoundryChatClient
from agent_framework_foundry_hosting import InvocationsHostServer
from azure.identity import DefaultAzureCredential

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.",
    default_options={"store": False},
)

server = InvocationsHostServer(agent)
server.run()

Per il controllo completo sulla gestione delle richieste, usare InvocationAgentServerHost direttamente dal azure.ai.agentserver.invocations pacchetto e implementare il proprio gestore invoke:

import os
from collections.abc import AsyncGenerator

from agent_framework import Agent, AgentSession
from agent_framework.foundry import FoundryChatClient
from azure.ai.agentserver.invocations import InvocationAgentServerHost
from azure.identity import DefaultAzureCredential
from starlette.requests import Request
from starlette.responses import JSONResponse, Response, StreamingResponse

_sessions: dict[str, AgentSession] = {}

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.",
    default_options={"store": False},
)

app = InvocationAgentServerHost()


@app.invoke_handler
async def handle_invoke(request: Request):
    """Handle streaming multi-turn chat."""
    data = await request.json()
    session_id = request.state.session_id
    stream = data.get("stream", False)
    user_message = data.get("message", None)

    if user_message is None:
        return Response(content="Missing 'message' in request", status_code=400)

    session = _sessions.setdefault(session_id, AgentSession(session_id=session_id))

    if stream:

        async def stream_response() -> AsyncGenerator[str]:
            async for update in agent.run(user_message, session=session, stream=True):
                yield update.text

        return StreamingResponse(
            stream_response(),
            media_type="text/event-stream",
            headers={"Cache-Control": "no-cache", "Connection": "keep-alive"},
        )

    response = await agent.run([user_message], session=session, stream=stream)
    return JSONResponse({"response": response.text})


if __name__ == "__main__":
    app.run()

Avvertimento

L'archivio di sessioni in memoria nell'esempio del gestore personalizzato viene perso al riavvio. Usare l'archiviazione durevole ,ad esempio Cosmos DB, nell'ambiente di produzione.

Per una distribuzione completa di Invocations, consulta l'esempio Telegram ospitato su Foundry. Colloca API Management davanti al webhook dell'agente ospitato e usa identità gestite, Key Vault e Cosmos DB per una cronologia delle conversazioni persistente.

Annotazioni

Il supporto di Go per gli agenti ospitati di Foundry sarà presto disponibile. Vedere il repository di Agent Framework Go per lo stato più aggiornato.

Tip

Fare riferimento agli esempi Python o C# per esempi di un progetto agente ospitato. In alternativa, usare il comando azd ai agent init per creare da zero la struttura di un nuovo progetto di agente ospitato. Per istruzioni dettagliate, vedere questa guida introduttiva .

Esecuzione in locale

L'interfaccia della riga di comando Azure Developer (azd) offre il modo più semplice per eseguire e testare l'agente ospitato in locale.

Inizializzare un progetto

Creare una nuova cartella e inizializzare da un manifesto di esempio:

mkdir my-hosted-agent && cd my-hosted-agent
azd ai agent init -m <path-to-agent.manifest.yaml>

Tip

Il manifesto può essere un percorso di un file YAML locale o un URL di un manifesto remoto.

Impostare le variabili di ambiente

export FOUNDRY_PROJECT_ENDPOINT="https://<account>.services.ai.azure.com/api/projects/<project>"
export AZURE_AI_MODEL_DEPLOYMENT_NAME="<your-model-deployment>"

Eseguire l'host dell'agente

azd ai agent run

L'host dell'agente viene avviato in http://localhost:8088.

Invocare l'agente

azd ai agent invoke --local "Hello!"

In alternativa, usare curl:

curl -X POST http://localhost:8088/responses \
  -H "Content-Type: application/json" \
  -d '{"input": "Hello!"}'

Oppure in PowerShell:

(Invoke-WebRequest -Uri http://localhost:8088/responses -Method POST -ContentType "application/json" -Body '{"input": "Hello!"}').Content

Distribuzione in Foundry

Dopo aver verificato l'agente in locale, distribuirlo in Microsoft Foundry:

  1. Effettuare il provisioning delle risorse (se non si ha già un progetto Foundry):

    azd provision
    

    Crea un gruppo di risorse con un'istanza di Foundry, un progetto, una distribuzione del modello, Application Insights e un registro contenitori.

  2. Distribuire l'agente:

    azd deploy
    

    Questo crea un pacchetto dell'agente come immagine del contenitore, lo inserisce in Registro Azure Container e lo distribuisce nel servizio Foundry Agent.

L'infrastruttura di hosting Foundry inserisce automaticamente le variabili di ambiente seguenti nel contenitore dell'agente in fase di esecuzione:

Variabile Descrizione
FOUNDRY_PROJECT_ENDPOINT URL dell'endpoint per il progetto Foundry.
AZURE_AI_MODEL_DEPLOYMENT_NAME Nome della distribuzione del modello (configurato durante azd ai agent init).
APPLICATIONINSIGHTS_CONNECTION_STRING La stringa di connessione di Application Insights per la telemetria.

Dopo la distribuzione, l'agente è accessibile tramite l'endpoint Foundry dedicato e può anche essere testato dal portale foundry.

Passaggi successivi