Laufzeitvertrag für gehostete Agent

Important

Die in diesem Artikel markierten Elemente (Vorschau) sind aktuell als öffentliche Vorschau verfügbar. Diese Vorschauversion wird ohne Vereinbarung zum Servicelevel bereitgestellt und sollte nicht für Produktionsworkloads verwendet werden. Manche Features werden möglicherweise nicht unterstützt oder sind nur eingeschränkt verwendbar. Weitere Informationen finden Sie unter Supplementale Nutzungsbedingungen für Microsoft Azure Previews.

Ein gehosteter Agent ist ein Container, der einen bestimmten Laufzeitvertrag mit der Microsoft Foundry-Plattform erfüllt. In dieser Referenz wird beschrieben, was die Plattform von Ihrem Container erwartet und wie die SDK-Adapterpakete Ihnen dabei helfen, diese Anforderungen zu erfüllen.

Die SDK-Adapterpakete implementieren den gesamten Vertrag für Sie. Wenn Sie die Handlerlogik verwenden azure-ai-agentserver-responses oder azure-ai-agentserver-invocationsimplementieren.

Vertragsanforderungen

Ihr Container muss:

Anforderung Einzelheit
Überwachen von Port 8088 HTTP/1.1, einfaches HTTP. Die Plattform beendet TLS.
Bereitstellen einer Integritätssonde Rückgabe 200 OK von GET /readiness.
Implementieren eines Protokollendpunkts Dient mindestens einem von POST /responses oder POST /invocations.
Nutzen von Plattformumgebungsvariablen Lesen Sie die Variablen, die die Plattform beim Start einjiziert.
Ordnungsgemäß herunterfahren Leeren von Schreibvorgängen und Schließen von Verbindungen auf SIGTERM.

Protokollendpunkte

Ein Protokoll definiert den HTTP-Vertrag zwischen Foundry und Ihrem Agent-Container. Ihr Container implementiert mindestens einen Protokollendpunkt.

Antwortprotokoll

Das Antwortprotokoll implementiert die OpenAI-Antwort-API. Die Plattform sendet Anforderungen an POST /responses und erwartet entweder eine JSON-Antwort oder einen Server-Sent Events (SSE)-Datenstrom.

Aspect Einzelheit
Endpunkt POST /responses
Eingabe OpenAI-Antwort-API-Anforderung (input, model, streamusw.)
Output JSON-Antwortobjekt oder SSE-Stream von Antwortereignissen
Konversationsverlauf Automatisch vom SDK-Adapter hydratisiert, wenn conversation.id vorhanden
Streaming SSE mit dem text/event-stream Inhaltstyp

Verwenden Sie das Antwortprotokoll als Standardauswahl. Es ist kompatibel mit dem OpenAI API-Ökosystem.

Aufrufeprotokoll

Das Aufrufprotokoll ist ein minimales Pass-Through-Protokoll. Sie definieren die Nutzlaststruktur, und die Plattform übergibt sie ohne Interpretation.

Aspect Einzelheit
Endpunkt POST /invocations
Eingabe Jede JSON-Nutzlast, die ihr Handler erwartet
Output Json-Antwort oder SSE-Stream
Konversationsverlauf Nicht verwaltet. Ihr Code behandelt den Zustand bei Bedarf.
Streaming Optional, bis SSE

Verwenden Sie das Aufrufprotokoll, wenn Sie volle Kontrolle über die Anforderungs- und Antwortnutzlasten benötigen.

SDK-Adapterpakete

Die Adapterpakete sind protokollspezifisch und frameworkagnostisch. Sie arbeiten mit jedem Agent-Framework, einschließlich Microsoft Agent Framework, LangGraph und benutzerdefiniertem Code.

Protocol Python-Paket .NET-Paket
Antworten azure-ai-agentserver-responses Azure.AI.AgentServer.Responses
Aufrufe azure-ai-agentserver-invocations Azure.AI.AgentServer.Invocations

Der Adapter verarbeitet die folgenden Vertragsteile für Sie:

  • HTTP-Serversetup auf Port 8088.
  • Der Integritätstestendpunkt (GET /readiness).
  • Protokollspezifische Anforderungsanalyse und Antwortformatierung.
  • Hydratation des Unterhaltungsverlaufs (Antwortprotokoll).
  • SSE Streaming-Infrastruktur.
  • OpenTelemetry-Instrumentierung.
  • Ordnungsgemäß heruntergefahren am SIGTERM.
  • Variable Nutzung der Plattformumgebung.

Sie implementieren eine Handlerfunktion, die analysierte Anforderungen empfängt und Antworten zurückgibt.

Beispiele für Handler

Die vollständigen Bring-your-own-Samples für beide Protokolle und beide Sprachen befinden sich im Repository für Gießereibeispiele .

Beispiel für das Antwortprotokoll

Dieser minimale Handler leitet Benutzereingaben über die Antwort-API an ein Modell aus dem Foundry-Modellkatalog weiter. Der SDK-Adapter hydratisiert den Unterhaltungsverlauf automatisch über context.get_history() (Python) oder context.GetHistoryAsync() (C#), sodass der Agent kontextübergreifend verwaltet.

Von 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()

Referenz: ResponsesAgentServerHost, AIProjectClient, DefaultAzureCredential

Beispiel für Aufrufe des Protokolls

Mit dem Aufrufprotokoll empfängt Ihr Handler den JSON-Code, den der Aufrufer veröffentlicht, und gibt den von Ihrem Code ausgewählten JSON-Code zurück. Es gibt keinen integrierten Unterhaltungsverlauf.

Muster von 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()

Die vollständigen Beispiele umfassen auch die Hydratation von Unterhaltungen, Fehlerbehandlung, Telemetrie, Toolboxintegration und Dockerfile und azure.yaml Setup.

Gesundheitsuntersuchung

Die Plattform sendet, GET /readiness um zu bestimmen, ob Ihr Container für den Datenverkehr bereit ist. Kehren Sie zurück 200 OK , wenn der Container bereit ist, oder einen Status ohne 200, um zu signalisieren, dass die Plattform die Instanz neu starten soll. Die SDK-Adapter registrieren diesen Endpunkt automatisch.

Netzwerk und Transport

Eigentum Wert
Protocol HTTP/1.1
Standard-Port 8088 (Außerkraftsetzung mit der PORT Umgebungsvariable)
Bindungsadresse 0.0.0.0 (alle Schnittstellen)
TLS Beendet von der Plattform. Ihr Container dient nur HTTP.

Ordnungsgemäßes Herunterfahren

Wenn die Plattform sendet SIGTERM, nimmt Ihr Container nicht mehr neue Anforderungen an, beendet In-Flight-Anforderungen, löscht ausstehende Schreibvorgänge $HOME (das Sitzungsdateisystem) und beendet sauber. Die SDK-Adapter behandeln diese Sequenz automatisch.

Plattformumgebungsvariablen

Die Plattform fügt Umgebungsvariablen beim Start in Ihren Container ein. Ihr Code kann die folgenden Schlüsselvariablen lesen:

Variable Purpose
FOUNDRY_PROJECT_ENDPOINT Foundry-Projektendpunkt für API-Aufrufe
FOUNDRY_AGENT_ID Der stabile Bezeichner des Agents (GUID). Verwenden Sie sie für das Routing pro Agent, Telemetrie oder Speicherpartitionierung.
FOUNDRY_AGENT_NAME Der Name des Agents
FOUNDRY_AGENT_VERSION Die Version des Agents
FOUNDRY_AGENT_SESSION_ID Die aktuelle Sitzungs-ID

Plattformanforderungsheader (Containerprotokoll 2.0.0)

Diese Header gelten nur für gehostete Agents im Containerprotokoll, Version 2.0.0. Auf Protokoll 2.0.0 fügt die Plattform sie für die Protokolle "Antworten" und "Aufrufe" in jede Anforderung an Ihre Protokollendpunkte ein. Sie werden nicht an Infrastrukturendpunkte wie den Integritätstest gesendet. Behandeln Sie ihre Werte als undurchsichtig, und lesen Sie sie, aber überschreiben Sie sie nicht.

Kopfzeile Purpose
x-agent-user-id Globaler Bezeichner pro Benutzer für den aktuellen Aufrufer. Verwenden Sie ihn als Primärpartitionsschlüssel für Benutzerdaten, die Ihr Container speichert; es ist für die eigene Verwendung Ihres Containers vorgesehen und wird nicht ausgehend weitergeleitet. Derselbe Benutzer liefert den gleichen Wert für alle Agents.
x-agent-foundry-call-id Id pro Anforderung. Leiten Sie sie bei ausgehenden Anrufen an Foundry-Dienste (Speicher, Toolbox und andere Agents) unverändert weiter. die Plattform löst die Identität des Anrufers daraus auf. Die offiziellen SDK-Adapter leiten sie automatisch weiter, wenn Sie diese Dienste über ihre Clients aufrufen.

Beide Header sind vertrauenswürdig - die Plattform generiert sie aus überprüfter Identität - und keines ist garantiert, wenn Sie lokal ausgeführt werden, sodass fehlende Werte ordnungsgemäß behandelt werden.

Das AgentServer SDK macht diese als Konstanten verfügbar PlatformHeaders und liest sie für Sie – über FoundryAgentRequestContext.Current .NET oder get_request_context() in Python. Die vollständige Plattformheaderliste, einschließlich Antwortheadern, die die Laufzeit hinzufügt, zx-agent-session-id. B. , x-platform-serverund x-platform-error-sourcefinden Sie in der referenz zur Azure AI Agent Server Core-Bibliothek.

Informationen dazu, wie das Protokoll 2.0.0 die Identitätsverteilung ändert, finden Sie unter Migrieren gehosteter Agents.

Beispiel: Gespeicherte Partitionsdaten pro Sitzung

Wenn Ihr Container benutzereigene Daten speichert, legen Sie ihn für die Sitzung (und für freigegebene Sitzungen den Benutzer) fest, damit ein Anrufer die Daten einer anderen Person nicht lesen kann. Das Beispiel für einen Notiz-Agent führt dies durch Ableiten eines Dateipfads pro Sitzung unter $HOME, unter dem Dateien auch über die Api für Sitzungsdateien erreichbar sind:

# 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")

Wenn mehrere Benutzer eine Sitzung freigeben können, fügen Sie dem Schlüssel hinzu x-agent-user-id . Anzeigen mehrerer Multiplex-Benutzer in einer gehosteten Agentsitzung.

Weiterleiten von benutzerdefinierten Anforderungsheadern an Ihren Container

Im vorherigen Abschnitt werden Überschriften behandelt, die die Plattform einfügt. Separat leitet das Gateway nur einen festen Satz von vom Anrufer bereitgestellten Anforderungsheadern an Ihren Container weiter. Jeder Anruferheader außerhalb dieses Satzes wird am Gateway abgelegt, bevor die Anforderung Ihren Container erreicht, wodurch Anmeldeinformationen und interne Header standardmäßig aus Dem Container entfernt werden.

Verwenden Sie das Präfix "Pass-Through-Clientheader", x-client-um Ihre eigenen Kontextdaten an Ihren Container zu übergeben. Die Plattform leitet jeden Header weiter, der mit x-client- unverändert beginnt, sodass Sie Werte wie eine Mandanten-ID oder ein Featureflagge senden können, ohne den Anforderungstext zu ändern, und lesen Sie sie dann in Ihrem Handler wie jeder andere Anforderungsheader. Das AgentServer SDK definiert dieses Präfix als PlatformHeaders.ClientHeaderPrefix; für die vollständige Plattformheaderliste finden Sie in der Referenz zur Azure AI Agent Server Core-Bibliothek.

Das Gateway leitet diese Aufruferheader an die Endpunkte "Antworten" und "Aufrufe"-Protokolle weiter:

Kopfzeile oder Präfix Purpose
x-client-* Jede benutzerdefinierte Kopfzeile, die Sie präfixen.x-client- Verwenden Sie dieses Präfix, um Ihre eigenen Kontextwerte ( z. B. Mandant, Featurekennzeichnungen oder Korrelationstoken ) an Ihren Container zu übergeben.
accept, accept-encoding, accept-language, content-type, , content-length, content-encoding Standardinhaltsaushandlung und Textkopfzeilen, die zum Analysieren der Anforderung erforderlich sind.
traceparent, tracestate, baggagex-ms-client-request-id, x-request-id, request-id, correlation-context, request-contextms-cv Verteilte Ablaufverfolgung und Korrelations-IDs, sodass die Protokolle Ihres Containers mit der ursprünglichen Anforderung verknüpft sind.
user-agent Identifiziert das aufrufende SDK oder den Client für die Diagnose.

Das Gateway leitet niemals Anmeldeinformationsheader wie Authorization, oder Host, Cookieund x-forwarded-*. Jede Kopfzeile, die nicht der Zulassungsliste entspricht, wird gelöscht. Verlassen Sie sich daher nicht auf benutzerdefinierte Kopfzeilen außerhalb des Präfixes, die x-client-* ihren Container erreichen.