Contratto di runtime dell'agente ospitato

Importante

Gli elementi contrassegnati (anteprima) in questo articolo sono attualmente in anteprima pubblica. Questa anteprima viene fornita senza un contratto di servizio e non è consigliabile per i carichi di lavoro di produzione. Alcune funzionalità potrebbero non essere supportate o potrebbero avere funzionalità limitate. Per ulteriori informazioni, vedere Condizioni supplementari per l'uso delle versioni di anteprima di Microsoft Azure.

Un agente ospitato è un contenitore che soddisfa un contratto di runtime specifico con la piattaforma Microsoft Foundry. Questo riferimento descrive le aspettative della piattaforma dal contenitore e il modo in cui i pacchetti dell'adattatore SDK consentono di soddisfare tali requisiti.

I pacchetti dell'adattatore SDK implementano l'intero contratto. Se si usa azure-ai-agentserver-responses o azure-ai-agentserver-invocations, si implementa solo la logica del gestore.

Requisiti del contratto

Il contenitore deve:

Requisito Dettagli
Ascolto sulla porta 8088 HTTP/1.1, HTTP normale. La piattaforma termina TLS.
Gestire un probe di integrità Restituire 200 OK da GET /readiness.
Implementare un endpoint di protocollo Servire almeno uno di POST /responses o POST /invocations.
Usare le variabili di ambiente della piattaforma Leggere le variabili che la piattaforma inserisce all'avvio.
Arrestare normalmente Scaricare le scritture e chiudere le connessioni in SIGTERM.

Endpoint del protocollo

Un protocollo definisce il contratto HTTP tra Foundry e il contenitore dell'agente. Il contenitore implementa almeno un endpoint di protocollo.

Protocollo di risposte

Il protocollo di risposte implementa l'API Risposte OpenAI. La piattaforma invia richieste a POST /responses e prevede una risposta JSON o un flusso SSE (Server-Sent Events).

Aspect Dettagli
Punto finale POST /responses
Inserimento Richiesta API Risposte OpenAI (input, model, streame così via)
Risultato Oggetto risposta JSON o flusso SSE di eventi di risposta
Cronologia della conversazione Idratato automaticamente dall'adattatore SDK quando conversation.id è presente
Streaming Crittografia del servizio di archiviazione con il text/event-stream tipo di contenuto

Usare il protocollo delle risposte come scelta standard. È compatibile con l'ecosistema di API OpenAI.

Protocollo di Invocazioni

Il protocollo di chiamata è un protocollo pass-through minimo. Si definisce la struttura del payload e la piattaforma lo passa attraverso senza interpretazione.

Aspect Dettagli
Punto finale POST /invocations
Inserimento Qualsiasi payload JSON previsto dal gestore
Risultato Qualsiasi risposta JSON o flusso SSE
Cronologia della conversazione Non gestito. Se necessario, il codice gestisce lo stato.
Streaming Facoltativo, tramite SSE

Usare il protocollo di chiamata quando è necessario il controllo completo sui payload di richiesta e risposta.

Pacchetti di adattatori SDK

I pacchetti di adattatori sono specifici del protocollo e indipendenti dal framework. Funzionano con qualsiasi framework agente, tra cui Microsoft Agent Framework, LangGraph e codice personalizzato.

Protocol Pacchetto Python pacchetto .NET
Responses azure-ai-agentserver-responses Azure.AI.AgentServer.Responses
Invocazioni azure-ai-agentserver-invocations Azure.AI.AgentServer.Invocations

L'adattatore gestisce automaticamente le parti seguenti del contratto:

  • Configurazione del server HTTP sulla porta 8088.
  • Endpoint del probe di integrità (GET /readiness).
  • Analisi delle richieste e formattazione delle risposte specifiche del protocollo.
  • Idratazione della cronologia delle conversazioni (protocollo di risposte).
  • Infrastruttura di streaming SSE.
  • Strumentazione OpenTelemetry.
  • Arresto normale in SIGTERM.
  • Consumo di variabili di ambiente della piattaforma.

Si implementa una funzione del gestore che riceve richieste analizzate e restituisce risposte.

Esempi di gestore

Gli esempi bring-your-own completi per entrambi i protocolli e entrambi i linguaggi si trovano nel repository foundry-samples .

Esempio di protocollo di risposte

Questo gestore minimo inoltra l'input dell'utente a un modello dal catalogo dei modelli Foundry tramite l'API Risposte. L'adattatore SDK idrata automaticamente la cronologia delle conversazioni tramite context.get_history() (Python) o context.GetHistoryAsync() (C#), in modo che l'agente mantenga il contesto tra turni.

Da bring-your-own/responses/hello-world/main.py:

import asyncio
import os

from azure.ai.agentserver.responses import (
    CreateResponse,
    ResponseContext,
    ResponsesAgentServerHost,
    ResponsesServerOptions,
    TextResponse,
)
from azure.ai.projects import AIProjectClient
from azure.identity import DefaultAzureCredential

# FOUNDRY_PROJECT_ENDPOINT is auto-injected in hosted Foundry containers and
# set by 'azd ai agent run' for local development.
_endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"]
_model = os.environ["FOUNDRY_MODEL_NAME"]

_project_client = AIProjectClient(
    endpoint=_endpoint, credential=DefaultAzureCredential()
)
_responses_client = _project_client.get_openai_client().responses

app = ResponsesAgentServerHost(
    options=ResponsesServerOptions(default_fetch_history_count=20),
)


@app.response_handler
async def handler(
    request: CreateResponse,
    context: ResponseContext,
    _cancellation_signal: asyncio.Event,
):
    user_input = await context.get_input_text() or "Hello!"
    history = await context.get_history()

    # Build the model input from prior conversation turns + the current message.
    input_items = []
    for item in history:
        # Map history items to {"role": ..., "content": ...} dicts; see the
        # full sample for the unpacking helper.
        ...
    input_items.append({"role": "user", "content": user_input})

    response = await asyncio.get_running_loop().run_in_executor(
        None,
        lambda: _responses_client.create(
            model=_model,
            instructions="You are a helpful AI assistant.",
            input=input_items,
            store=False,  # platform manages history; don't store at model level
        ),
    )

    return TextResponse(context, request, text=response.output_text)


app.run()

Riferimento: ResponsesAgentServerHost, AIProjectClient, DefaultAzureCredential

Esempio di protocollo chiamate

Con il protocollo di chiamata, il gestore riceve qualsiasi json inviato dal chiamante e restituisce qualsiasi CODICE JSON scelto dal codice. Non esiste una cronologia di conversazione predefinita.

Modello da bring-your-own/invocations/hello-world:

from starlette.requests import Request
from starlette.responses import JSONResponse, Response
from azure.ai.agentserver.invocations import InvocationAgentServerHost

app = InvocationAgentServerHost()


@app.invoke_handler
async def handle_invoke(request: Request) -> Response:
    data = await request.json()
    message = data.get("message", "Hello!")
    return JSONResponse({"echo": message})


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

Gli esempi completi includono anche l'idratazione della cronologia delle conversazioni, la gestione degli errori, la telemetria, l'integrazione della casella degli strumenti e dockerfile e azure.yaml la configurazione.

Sonda di diagnostica

La piattaforma invia GET /readiness per determinare se il contenitore è pronto per gestire il traffico. Restituisce 200 OK quando il contenitore è pronto o uno stato diverso da 200 per segnalare che la piattaforma deve riavviare l'istanza. Gli adattatori SDK registrano automaticamente questo endpoint.

Rete e trasporto

Proprietà Value
Protocol HTTP/1.1
Porta predefinita 8088 (override con la PORT variabile di ambiente)
Indirizzo di associazione 0.0.0.0 (tutte le interfacce)
TLS Terminata dalla piattaforma. Il contenitore serve http normale.

Arresto normale

Quando la piattaforma invia SIGTERM, il contenitore smette di accettare nuove richieste, termina le richieste in anteprima, scarica le scritture $HOME in sospeso (il file system di sessione) e viene chiuso correttamente. Gli adattatori SDK gestiscono automaticamente questa sequenza.

Variabili di ambiente della piattaforma

La piattaforma inserisce le variabili di ambiente nel contenitore all'avvio. Il codice può leggere le variabili chiave seguenti:

Variable Purpose
FOUNDRY_PROJECT_ENDPOINT Endpoint del progetto Foundry per le chiamate API
FOUNDRY_AGENT_ID Identificatore stabile dell'agente (GUID). Usarlo per il routing, la telemetria o il partizionamento dell'archiviazione per agente.
FOUNDRY_AGENT_NAME Nome dell'agente
FOUNDRY_AGENT_VERSION Versione dell'agente
FOUNDRY_AGENT_SESSION_ID ID sessione corrente

Intestazioni della richiesta della piattaforma (protocollo contenitore 2.0.0)

Queste intestazioni si applicano solo agli agenti ospitati nel protocollo contenitore versione 2.0.0. Nel protocollo 2.0.0 la piattaforma li inserisce in ogni richiesta agli endpoint del protocollo, sia per i protocolli Responses che Invocations. Non vengono inviati agli endpoint dell'infrastruttura, ad esempio il probe di integrità. Considerare i valori come opachi e leggere, ma non eseguirne l'override.

Intestazione Purpose
x-agent-user-id Identificatore globale per utente per il chiamante corrente. Usarlo come chiave di partizione primaria per i dati per utente archiviati dai contenitori; è per il proprio uso del contenitore e non viene inoltrato in uscita. Lo stesso utente restituisce lo stesso valore tra gli agenti.
x-agent-foundry-call-id Identificatore per richiesta. Inoltrarlo senza modifiche alle chiamate in uscita ai servizi Foundry (Archiviazione, Casella degli strumenti e altri agenti); la piattaforma risolve l'identità del chiamante da essa. Gli adattatori SDK ufficiali lo inoltrano automaticamente quando si chiamano tali servizi tramite i client.

Entrambe le intestazioni sono attendibili: la piattaforma li genera dall'identità verificata e nessuno dei due è garantito quando si esegue localmente, quindi gestire correttamente i valori mancanti.

AgentServer SDK espone questi elementi come costanti su PlatformHeaders e li legge per l'utenteFoundryAgentRequestContext.Current, in .NET o get_request_context() in Python. Per l'elenco completo delle intestazioni della piattaforma, incluse le intestazioni di risposta aggiunte dal runtime, x-agent-session-idad esempio , x-platform-servere x-platform-error-source, vedere le informazioni di riferimento sulla libreria Azure ai Agent Server Core.

Per informazioni su come il protocollo 2.0.0 modifica la propagazione delle identità, vedere Eseguire la migrazione degli agenti ospitati.

Esempio: partizionare i dati archiviati per sessione

Quando il contenitore mantiene i dati di proprietà dell'utente, la chiave viene eseguita dalla sessione (e, per le sessioni condivise, l'utente) in modo che un chiamante non possa leggere i dati di un altro. L'esempio dell'agente che accetta note esegue questa operazione derivando un percorso di file per sessione in $HOME, dove i file sono raggiungibili anche tramite l'API File di sessione:

# note_store.py - one JSONL file per session, stored under $HOME.
def _get_file_path(session_id: str) -> str:
    safe_id = "".join(c if c.isalnum() or c in "-_" else "_" for c in session_id)
    base_dir = os.environ.get("HOME", os.getcwd())
    return os.path.join(base_dir, f"notes_{safe_id}.jsonl")

Quando più utenti possono condividere una sessione, aggiungere x-agent-user-id alla chiave. Vedere Multiplex multiple users in una sessione dell'agente ospitato.

Inoltrare intestazioni di richiesta personalizzate al contenitore

La sezione precedente illustra le intestazioni degli inserimenti della piattaforma . Separatamente, il gateway inoltra solo un set fisso di intestazioni di richiesta fornite dal chiamante al contenitore. Qualsiasi intestazione del chiamante all'esterno del set viene eliminata nel gateway prima che la richiesta raggiunga il contenitore, che mantiene le credenziali e le intestazioni interne fuori dal contenitore per impostazione predefinita.

Per passare i propri dati contestuali al contenitore, usare il prefisso dell'intestazione client pass-through, x-client-. La piattaforma inoltra ogni intestazione che inizia senza x-client- modifiche, quindi è possibile inviare valori come un ID tenant o un flag di funzionalità senza modificare il corpo della richiesta, quindi leggerli nel gestore come qualsiasi altra intestazione della richiesta. AgentServer SDK definisce questo prefisso come PlatformHeaders.ClientHeaderPrefix. Per l'elenco completo delle intestazioni della piattaforma, vedere le informazioni di riferimento sulla libreria Azure AI Agent Server Core.

Il gateway inoltra queste intestazioni del chiamante agli endpoint del protocollo Risposte e chiamate:

Intestazione o prefisso Purpose
x-client-* Qualsiasi intestazione personalizzata preceduta da x-client-. Usare questo prefisso per passare i propri valori contestuali, ad esempio tenant, flag di funzionalità o token di correlazione, al contenitore.
accept, accept-encoding, accept-language, content-type, content-lengthcontent-encoding Intestazioni standard di negoziazione del contenuto e corpo necessarie per analizzare la richiesta.
traceparent, tracestate, baggage, x-ms-client-request-id, x-request-idrequest-id, correlation-context, , request-contextms-cv ID di traccia distribuita e correlazione, quindi i log del contenitore si collegano alla richiesta di origine.
user-agent Identifica l'SDK chiamante o il client per la diagnostica.

Il gateway non inoltra mai le intestazioni delle credenziali, ad Authorizationesempio , o HostCookie, e x-forwarded-*. Qualsiasi intestazione che non corrisponde all'elenco consenti viene eliminata, quindi non fare affidamento su intestazioni personalizzate all'esterno del x-client-* prefisso che raggiunge il contenitore.