Notiz 52 · Microsoft Foundry (12/12)

Foundry Hosted Agents brauchen trotzdem eine Front Door

Hosted Agents verlagern die Laufzeit deines Agents in Foundry, nicht deine Front Door. Wann sich der Wechsel lohnt und was dein Backend behalten muss.

30. Oktober 2026 10 Min. Lesezeit

Das Wichtigste in Kürze

  • Ein Hosted Agent verlagert die Laufzeit: deinen Code, in einem Container, mit eigener Identität und eigenem Endpoint. Anmeldung, App-Rollen und die Frage, welcher Nutzer welche Session öffnen darf, verlagert er nicht.
  • Hol einen Agent nur dann aus einem Prompt Agent heraus, wenn der Agent selbst Code braucht, den ein Prompt Agent nicht ausdrücken kann. Ein schöneres Deployment ist kein Grund.
  • Die Credential, mit der dein Backend aufruft, legt den Isolationsbereich fest. Rufst du mit der eigenen Identität der App und ohne User-Header auf, landen alle Nutzer in einem Bereich.
  • Isolation pro Nutzer für deine eigenen Nutzer braucht einen User-Header und eine Custom Role, und selbst dann trennt die Plattform delegierte Nutzer nicht voneinander. Das macht deine Session-Zuordnung.
  • Guardrails können offen versagen, während alles HTTP 200 zurückgibt. Teste pro Protokoll einen Prompt, der blockiert werden muss, bevor du dich darauf verlässt.
  • Eine Version pro Endpoint, kein Traffic Splitting: Rollout und Version Pinning bleiben bei deiner Front Door.

Seit Foundry Hosted Agents allgemein verfügbar sind, liegt für jeden, der eine Agent-Web-App betreibt, die Frage auf der Hand: Können wir jetzt unser Backend weglassen? Foundry führt unseren Code aus, gibt ihm eine Identität und einen Endpoint und skaliert ihn auf null. Warum noch einen App Service davorstellen?

Ich habe noch keinen Agent auf die gehostete Laufzeit umgezogen. In den Agent-Apps, die ich baue, sind die Agents Prompt Agents hinter unserem eigenen Backend, und "hosted" existiert im Agent-Katalog als geparkter Laufzeitwert hinter einem Flag. Dieser Beitrag erklärt, warum er geparkt ist, was mich dazu bringen würde, ihn einzuschalten, und warum das Backend in jedem Fall bleibt.

Benanntes Modell: Laufzeit wandert, Front Door bleibt

  • Laufzeitebene (kann zu Foundry wandern): der Code, der den Agent ausführt, seine Sandbox, seine Skalierung, seine Agent-Identität, seine Guardrails und Egress-Regeln.
  • Front-Door-Ebene (bleibt deine): wer der Nutzer ist, was er nutzen darf, welche Sessions und Unterhaltungen ihm gehören, welche Version er bekommt und was das Produkt ihm zeigt.
  • Die Nahtstelle dazwischen: ein Aufruf pro Nutzer, mit einer Credential, die Foundry sagt, wer dieser Nutzer ist.

Zwei Ebenen nebeneinander: Die Front Door, die du behältst, verantwortet Anmeldung und App-Rollen, die Zuordnung von Nutzer zu Session, den Unterhaltungsindex und das Fortsetzen, Version Pinning und Rollout, Freigaben, Quellenangaben und Audit sowie Nutzungs- und Kostenansichten; die Laufzeit des Hosted Agent, die Foundry betreibt, verantwortet deinen Code in einem Container, Agent-Identität und Endpoint, die Sandbox pro Session, Skalierung auf null, Guardrails und Egress-Regeln sowie Protokolle; ein Pfeil dazwischen trägt einen Aufruf pro Nutzer mit einem User-Token oder einem User-Header

Abbildung 1. Hosted Agents ersetzen die rechte Seite. Auf der linken Seite wandert nichts mit.

Kontext und Rahmenbedingung

Foundry Agent Service kennt drei Agent-Typen (overview). Prompt Agents sind Konfiguration: Anweisungen, ein Modell und Tools, und Foundry führt sie aus. Hosted Agents sind dein Code, in einem beliebigen Framework, verpackt als Container, den Foundry mit verwaltetem Endpoint, Skalierung und einer eigenen Microsoft Entra Agent-Identität betreibt (hosted agents).

Mit Front Door meine ich das Backend zwischen Browser und Foundry: Es meldet den Nutzer an, prüft App-Rollen, entscheidet, welche Agents und Sessions er erreichen darf, streamt die Antwort und stellt sie dar. Beitrag 21 und Beitrag 38 erklären, warum es diese Schicht überhaupt gibt. In diesem Beitrag geht es darum, ob Hosted Agents an dieser Antwort etwas ändern. Der Produktstand unten entspricht Oktober 2026.

Design

1. Entscheide nach dem, was der Agent braucht, nicht nach Deploy-Komfort

Learn listet auf, wann du Hosted Agents statt Prompt Agents wählen solltest. Heruntergebrochen auf die Fragen, die ich zu einem Agent stelle:

  • Braucht er eine eigene Orchestrierung oder einen Framework-Graphen, den Anweisungen und Tools nicht ausdrücken können?
  • Braucht er ein Protokoll oder einen Kanal, den der Prompt Agent nicht spricht?
  • Braucht er Dateien und Arbeitsstand in einer Sandbox, die über mehrere Turns erhalten bleiben?
  • Läuft er lange oder im Hintergrund, über eine normale Anfrage hinaus?
  • Braucht er eigene Egress-Regeln für ausgehende Aufrufe?

Wenn jede Antwort Nein ist, hast du mit einem Prompt Agent weniger zu verantworten. Ein Hosted Agent bringt ein Image, das gebaut und gepatcht werden muss, eine Registry, die abgesichert werden muss, und CPU und Speicher, die dimensioniert werden müssen. Die Dimensionierung gilt pro Session, und abgerechnet werden CPU und Speicher über alle aktiven Sessions. Wie Learn es formuliert, multipliziert Überdimensionierung die Kosten mit deiner Nebenläufigkeit. Inaktive Sessions skalieren nach einem Timeout, den du festlegst, auf null, und ein Kaltstart beim Fortsetzen gehört zu deiner User Experience.

Wenn eine Antwort für einen Agent Ja ist, zieht dieser Agent um. Nicht die App.

Entscheidungspfad für einen Agent: fünf Fragen zu eigener Orchestrierung, einem eigenen Protokoll oder Kanal, Dateien und Zustand in der Sandbox, lang laufender Arbeit und Egress-Regeln pro Agent; jedes Ja verlagert diesen Agent auf eine gehostete Laufzeit, lauter Nein lassen ihn ein Prompt Agent bleiben; ein Balken darunter sagt, dass die Front Door in jedem Fall Anmeldung, Rollen, die Session-Zuordnung, Rollout und Produkt-UX behält

Abbildung 2. Die Frage stellt sich pro Agent. Die Antwort setzt ein Feld im Katalog, nicht die Architektur.

2. Die Laufzeit ist ein Feld pro Agent, kein App-weiter Schalter

Diese Designentscheidung würde ich unabhängig von der Roadmap der Plattform beibehalten. Jeder Agent in unserem Katalog trägt mit, wie er läuft. Heute steht bei jedem Eintrag Prompt Agent. Der Wert "hosted" existiert, hinter einem Flag, und nichts nutzt ihn. Wenn ein Agent ihn braucht, ändert sich ein Eintrag, und die Front Door leitet die Aufrufe dieses Agents an seinen gehosteten Endpoint. Anmeldung, Rollen, Quellenangaben, Traces und die Liste der Unterhaltungen sind so entworfen, dass es ihnen egal ist, wo der Agent läuft, also sollten sie sich nicht ändern. Tool-Freigaben würde ich erneut testen, weil eigener Code sie anders auslösen kann.

Die Alternative, von vornherein festzulegen "wir sind eine Hosted-Agents-App", koppelt das Produkt an eine Laufzeitentscheidung, die nur manche Agents brauchen. Beitrag 36 zeigt das Muster mit Flags und Overlays, das ich dafür verwende.

3. Die Credential, mit der dein Backend aufruft, ist eine Designentscheidung

Hosted Agents isolieren Sessions standardmäßig nach der Identität des Aufrufers: Jeder Aufrufer sieht und verwaltet nur seine eigenen Sessions (isolate sessions per user). Das klingt, als hätte die Plattform deine Autorisierung erledigt. Hat sie nicht. Es hängt davon ab, wen Foundry für den Aufrufer hält, und das entscheidet dein Backend:

  • Den Nutzer weiterreichen. Das Backend ruft im Namen des angemeldeten Nutzers auf, also sieht Foundry diesen Nutzer. Die Isolation gilt pro Nutzer, und Tools können über User Delegation pro Connection mit dem eigenen Zugriff des Nutzers handeln (user delegation).
  • Als App aufrufen, ohne User-Header. Foundry sieht einen einzigen Aufrufer. Die Sessions aller Nutzer liegen in einem Bereich, und es gibt keinen Nutzerkontext, an den Tools delegieren könnten.
  • Als App aufrufen, mit User-Header. Das Backend sendet eine stabile Nutzerkennung in x-ms-user-identity. Die Sessions werden auf diesen Wert begrenzt. Die aufrufende Identität braucht eine Data Action, die in keiner eingebauten Rolle enthalten ist, also legst du dafür eine Custom Role an; ohne sie gibt der Aufruf 403 zurück. Die Seite zur Delegation ergänzt, dass ein Dienst, der für viele Nutzer aufruft, diesen Wert pro Nutzer senden sollte, damit sich Nutzer keinen OAuth-Anmeldestatus für Tools teilen.

Die dritte Variante hat eine scharfe Kante. Die Warnung in Learn: Innerhalb der Delegation trennt die Plattform delegierte Nutzer nicht voneinander. Sie trennt nur delegierte von nicht delegierten Aufrufern. Leite zwei Nutzer auf dieselbe Session-ID, und sie können gegenseitig ihre Daten sehen. Die Seite zu Sessions sagt es klar: Der Isolationsschlüssel "is a partitioning value, not an authentication or authorization mechanism" (manage sessions). Learn weist außerdem darauf hin, dass eine Identität mit der Rolle Foundry User auf dem Projekt jede Session des Agents auflisten und verwalten kann. Wisse, wer sie hat.

Dieselbe Falle kenne ich von Prompt Agents. Wenn unser Backend mit seiner eigenen Managed Identity aufruft, sieht Foundry einen einzigen Aufrufer, also muss die Liste der Unterhaltungen eines Nutzers aus unserem eigenen Index pro Nutzer kommen, nicht aus Foundry. Hosted Agents machen diesen Index nicht überflüssig. Sie machen ihn wichtiger.

4. Eine Session ist keine Unterhaltung

Hosted Agents trennen zwei Dinge, die Chat-Oberflächen gern vermischen (manage sessions). Eine Session ist die Sandbox: Compute und ein persistentes Dateisystem. Eine Unterhaltung ist der Verlauf aus Nachrichten und Tool-Aufrufen. Beim Responses-Protokoll spielt die Wiederverwendung einer Session-ID den Verlauf nicht erneut ab; die Kontinuität kommt aus der vorherigen Response oder einer Conversation-ID. Beim Invocations-Protokoll speichert die Plattform überhaupt keinen Verlauf.

Die Front Door verantwortet also weiterhin den Unterhaltungsindex: welche Unterhaltungen zu welchem Nutzer gehören, ihre Titel und wie man eine fortsetzt, nachdem der Stream abgebrochen ist. Beitrag 7 erklärt, warum diese Uhr von der Oberfläche getrennt ist, und Beitrag 47, wo der Index liegt. Hosted Agents fügen eine dritte Zuordnung hinzu: welche Session zu welcher Unterhaltung gehört und zu welchem Nutzer.

Noch eine Regel von derselben Seite: Dateien, die in eine Session hochgeladen werden, landen im Home-Verzeichnis des Agents. Behandle sie als nicht vertrauenswürdig und lade von dort niemals Code, Plugins oder Konfiguration.

5. Der Rollout bleibt bei dir

Ein Endpoint eines Hosted Agent bedient jeweils eine Version, leitet den gesamten Traffic dorthin und teilt keinen Traffic zwischen Versionen auf (hosted agents). Jede Session bindet sich bei ihrer Erstellung an eine Version, und version_indicator pinnt eine Session auf eine konkrete Version, damit spätere Turns sie behalten, nachdem du eine neuere veröffentlicht hast.

Das gibt dir die Bausteine eines Rollouts, nicht den Rollout. Ein Canary, eine Pilotgruppe auf der neuen Version oder ein Rollback, der laufende Unterhaltungen in Ruhe lässt, sind Entscheidungen über Nutzer, also gehören sie in die Front Door, die die Nutzer kennt. Das Eval-Gate aus Beitrag 48 läuft, bevor eine Version veröffentlicht wird; die Front Door entscheidet, wer ihr zuerst begegnet.

6. Teste die Blockade, nicht das Deployment

Guardrails für Hosted Agents hängen an der Agent-Definition, und die Seite zu Guardrails nennt mehrere Wege, auf denen sie ohne Fehlermeldung versagen (guardrails):

  • Ein Policy-Name, den es nicht gibt: Auf vielen Subscriptions wird der Agent deployt, meldet sich als aktiv und filtert nichts.
  • Das Invocations-Protokoll ohne invocations_moderation: Die Policy ist wirkungslos, Anfragen gehen ungefiltert durch, und der Agent gibt HTTP 200 zurück.
  • Das Invocations-WebSocket-Protokoll: Content Moderation ist nicht verfügbar.
  • Eine Änderung der Policy: Laufende Sandboxes übernehmen sie nicht. Du deployst eine neue Agent-Version und startest oder setzt eine Session fort.

Streaming bringt der Front Door eine zusätzliche Aufgabe. Ein Prompt, der schon bei der Eingabe blockiert wird, wird vor jedem Event abgelehnt. Beim Invocations-Protokoll kommt eine Ausgabe, die mitten im Stream blockiert wird, aber als Error-Event innerhalb einer HTTP-200-Antwort an, und früherer Text steht vielleicht schon auf dem Bildschirm. Learn sagt es direkt: Ein Status 200 allein bedeutet nicht, dass die Antwort die Policy bestanden hat. Die Oberfläche muss dieses Event als endgültig behandeln und anzeigen, dass die Antwort abgebrochen wurde, statt eine halbe Antwort vollständig aussehen zu lassen.

Egress-Kontrollen für Hosted Agents sind in Preview und ergänzen, wie Learn es formuliert, deine eigenen Netzwerkkontrollen, statt sie zu ersetzen.

Stellen, an denen ein Hosted Agent offen versagt und trotzdem Erfolg meldet: ein Policy-Name, den es nicht gibt, das Invocations-Protokoll ohne Moderationseinstellungen, das WebSocket-Protokoll ohne Moderation, ein blockierter Stream, der nach teilweisem Text HTTP 200 mit einem Error-Event zurückgibt, eine App-Identität, die ohne User-Header aufruft, und zwei delegierte Nutzer, die auf dieselbe Session-ID geleitet werden

Abbildung 3. Jeder dieser Fälle meldet Erfolg. Der Test ist ein Prompt, der blockiert werden sollte, und ein Nutzer, der abgewiesen werden sollte.

7. Was mich dazu bringen würde, das Flag einzuschalten

An dem Tag, an dem ein Agent einen Framework-Graphen, Sandbox-Dateien über mehrere Turns oder Arbeit braucht, die eine Anfrage überdauert, wechselt sein Katalogeintrag auf hosted. Vorher drei Prüfungen: Das Backend ruft mit einer Credential auf, die den Nutzer mitträgt; ein Prompt, der blockiert werden muss, wird auf dem Protokoll blockiert, das dieser Agent nutzt; und ein zweiter Nutzer kann über unsere API nicht die Session des ersten erreichen. Keine dieser Prüfungen betrifft die gehostete Laufzeit. Alle betreffen die Front Door.

Häufige Fehler

Das Backend weglassen, weil die Laufzeit umgezogen ist. Anmeldung, Rollen und die Session-Zuordnung lagen nie in der Laufzeit.

Als App ohne User-Header aufrufen. Alle Nutzer teilen sich einen Isolationsbereich.

Eine Session-ID für mehrere Nutzer wiederverwenden. Die Plattform trennt delegierte Nutzer nicht voneinander.

Die Session-ID als Unterhaltung behandeln. Die ID spielt den Verlauf nicht erneut ab.

Einer Guardrail vertrauen, weil das Deployment geklappt hat. Teste pro Protokoll einen Prompt, der blockiert werden muss.

HTTP 200 in einem Stream als Erfolg werten. Behandle das Error-Event.

Jede Session für den schlimmsten Fall dimensionieren. Die Rechnung multipliziert sich mit der Nebenläufigkeit.

Die Laufzeit zum App-weiten Schalter machen. Mach sie zu einem Feld pro Agent.

So übernehmen oder anpassen

So übernehmen

  • Die fünf Fragen pro Agent, und nur den Agent umziehen, der mit Ja antwortet.
  • Die Laufzeit als Feld im Agent-Katalog, hinter einem Flag, bis ein Agent sie braucht.
  • Einen Index für Unterhaltungen und Sessions pro Nutzer in deinem eigenen Speicher, bei jedem Aufruf geprüft.
  • Eine Session pro Nutzer, nie zwischen delegierten Nutzern geteilt, außer du hast es genau dafür entworfen.
  • Einen Test mit einem zu blockierenden Prompt pro Protokoll als Teil jedes Releases.

Vor dem Einsatz anpassen

  • Den Nutzer weiterreichen oder einen User-Header von der App senden: Das hängt davon ab, ob sich deine Nutzer mit Entra anmelden und was deine Tools im Namen des Nutzers tun müssen.
  • Wie du Versionen für eine Pilotgruppe pinnst, da es kein Traffic Splitting gibt.
  • Idle-Timeout und Dimensionierung der Sessions, gemessen an einer repräsentativen Last statt geschätzt.
  • Ob ein abgebrochener Stream den Teiltext zurückzieht oder markiert, je nachdem, was deine Nutzer vielleicht schon kopiert haben.

Verwandte Notizen

Lass Foundry den Agent ausführen. Bestimme weiterhin selbst, wer mit ihm sprechen darf.