Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Standaard krijgt elke beller een eigen gehoste agentsessie, zoals beschreven in Gehoste agentsessies isoleren per gebruiker. Toepassingen die veel gebruikers bedienen: een Teams-bot, een ISV-gateway of een klantondersteuningsplatform, hebben niet één sessie per gebruiker nodig. In plaats daarvan wijst een service in de middelste laag veel gebruikers toe aan een gebonden groep gedeelde sessies en identificeert elke gebruiker in elke oproep.
In dit artikel leest u hoe u sessies groepeert tussen gebruikers vanuit de middelste laag, terwijl de gegevens van elke gebruiker geïsoleerd blijven binnen een gedeelde sessie.
Het platform isoleert de gespreksstatus voor u, zelfs wanneer gebruikers een sessie delen: een reactieketen die door een gebruiker wordt gemaakt, kan niet worden voortgezet door een andere gebruiker via previous_response_iden context.get_history() retourneert alleen de geschiedenis die de gebruiker van de huidige aanvraag mag zien. U hebt twee dingen: de gebruikers-naar-sessie-toewijzing in de middelste laag en de partitionering van gegevens die uw container zelf opslaat (bestanden, rijen of cache) buiten die door platform beheerde gespreksstatus.
Een volledig uitvoerbaar voorbeeld van sessiemultiplexing laat beide kanten zien: de sessiepool in de tussenlaag en de containerverwerker, en dit artikel verwijst gaandeweg naar de bijbehorende bestanden.
Prerequisites
- Een gehoste agent die gebruikmaakt van containerprotocolversie 2.0.0. Zie Gehoste agents migreren om een upgrade uit te voeren.
- De
Microsoft.CognitiveServices/accounts/AIServices/agents/endpoints/UserIdentityImpersonation/actionmachtiging die is toegewezen aan de identiteit van uw middellaagservice. Deze machtiging is niet opgenomen in ingebouwde rollen; deze verlenen via een aangepaste rol. Zie De identiteit van de eindgebruiker delegeren. Zonder deze wordt dex-ms-user-identitykoptekst geweigerd met een403. - De Azure AI Projects-clientbibliotheek voor de middelste laag en de Azure AI AgentServer SDK voor de container (
azure-ai-agentserver-core2.0.0b7+ voor Python ofAzure.AI.AgentServer.Core1.0.0-beta.26+ voor .NET). - Een uitgerolde agent om tegen te testen. Isolatie wordt niet toegepast bij lokale uitvoeringen.
Twee gebruikers isoleren in een gedeelde sessie
Begin met de basiswerking: twee gebruikers — noem ze Alice en Bob, de gebruikers namens wie wordt gehandeld in het voorbeeld — kunnen één agent_session_id delen, en het platform houdt de gesprekken van elke gebruiker nog steeds privé. Uw middellaag identificeert bij elke oproep de gebruiker namens wie wordt gehandeld met de x-ms-user-identity-header (delegatie). Als u het eigen gesprek van een gebruiker wilt voortzetten, wordt het vorige antwoord van die gebruiker doorgegeven als previous_response_id.
De minimale invoke_previous_response_isolation.py aanroeper in het voorbeeld verzendt precies dat met behulp van de client voor agentgebonden antwoorden van de SDK:
# Agent-bound Responses client from the Foundry SDK.
responses_client = project_client.get_openai_client(agent_name=agent_name).responses
# Target the shared session with agent_session_id, and identify the acted-for
# user with x-ms-user-identity (delegation). Pass previous_response_id to
# continue this user's own chain. Don't send x-agent-user-id; Foundry sets the
# container-side request context after it resolves the user.
kwargs = {
"input": user_message,
"stream": False,
"store": True,
"extra_body": {"agent_session_id": session_id},
"extra_headers": {"x-ms-user-identity": user_id},
}
if previous_response_id:
kwargs["previous_response_id"] = previous_response_id
response = responses_client.create(**kwargs)
Het platform koppelt elke responsketen aan de gebruiker die het heeft gemaakt. Als Bob Alices previous_response_id verstuurt terwijl hij zich in dezelfde sessie bevindt, mislukt de oproep - Bob kan Alices gesprek niet voortzetten. Deze garantie geldt zonder extra isolatiecode in uw container.
Schaal op naar grote aantallen gebruikers met een sessiepool
Het isoleren van twee gebruikers in één sessie is de bouwsteen. Als u veel gebruikers wilt bedienen, kunt u ze groeperen in een gekoppelde set sessies in plaats van één sessie per gebruiker te openen.
Elke sessie telt mee op basis van de regionale limieten voor gelijktijdige sessies terwijl deze actief een beurt verwerkt, zodat één sessie per gebruiker niet wordt geschaald. Omdat gebruikers tussen beurten lezen, denken en typen, zijn uw piekaantal gelijktijdige aanvragen meestal een klein deel van het totale aantal gebruikers. Pas de grootte van een pool aan die piek toe en wijs elke gebruiker vervolgens toe aan een sessie erin en geef de identiteit van die gebruiker door aan elke oproep, precies zoals in de vorige sectie.
Bepaal hoe u gebruikers toewijst aan sessies. Veelvoorkomende strategieën zijn:
- Plakkerig, minst geladen. Een terugkerende gebruiker hergebruikt zijn sessie; nieuwe gebruikers gaan naar de minst geladen sessie. Deze strategie verspreidt de belasting gelijkmatig en houdt de beurten van een gebruiker bij elkaar. Vergroot de pool wanneer sessies een limiet per gebruiker bereiken.
- Op basis van hash. Wijs een sessie toe met
hash(user_id) % pool_size. Deze strategie is eenvoudig en staatloos, maar de belasting kan ongelijk verdeeld zijn en het aanpassen van de poolgrootte herverdeelt gebruikers. - Round-robin. Distribueer aanvragen gelijkmatig over de pool. Deze strategie is eenvoudig, maar de interacties van een gebruiker kunnen in verschillende sessies terechtkomen.
- Op groepsbasis. Route per tenant, team of regio, zodat gerelateerde gebruikers sessies delen. Deze strategie is nuttig wanneer gebruikers in een groep een context delen.
De invoke_session_pool.py-aanroeper in het voorbeeld implementeert een aan de aanroeper toegewezen toewijzing met twee strategieën, sticky-fill en round-robin. Een terugkerende gebruiker houdt altijd zijn sessie bij; een nieuwe gebruiker wordt geplaatst door de geselecteerde strategie. Het sticky-fill-pad vult de minst belaste sessie en opent alleen een nieuwe sessie wanneer elke sessie vol is:
def get_session_for_user(self, user_id: str) -> str:
if user_id in self.user_to_session:
return self.user_to_session[user_id] # returning user is sticky
session_id = self._next_fill_session() # new user: place by strategy
self.user_to_session[user_id] = session_id
self.session_user_counts[session_id] += 1
return session_id
def _next_fill_session(self) -> str:
# Reuse a session with capacity; open a new one only when all are full.
session_id = next(
(s for s, count in self.session_user_counts.items()
if count < self.max_users_per_session),
None,
)
if session_id is None:
session_id = self._session_name(len(self.session_user_counts))
self.session_user_counts[session_id] = 0
return session_id
Voer de geretourneerde sessie-id in dezelfde gedelegeerde aanroep in die eerder wordt weergegeven: deze wordt agent_session_id in extra_bodyen x-ms-user-identity blijft de id per gebruiker.
Het verzoek in uw container afhandelen
In protocol 2.0.0 bepaalt het platform de gebruiker namens wie wordt gehandeld en stelt deze beschikbaar aan uw handler via get_request_context(). Valideer die context (niet gesloten wanneer deze ontbreekt, zoals bij lokale uitvoeringen), laat het platform vervolgens de geschiedenis per gebruiker retourneren met context.get_history(). De main.py handler in het voorbeeld behoudt geen eigen gespreksstatus:
from azure.ai.agentserver.core import get_request_context
@app.response_handler
async def handler(request, context, _cancellation_signal):
ctx = get_request_context()
if not (ctx.user_id and ctx.call_id):
# Hosted protocol 2.0.0 populates this context; off-platform it's absent.
raise ValueError("A user context is required on protocol 2.0.0.")
user_input = await context.get_input_text() or "Hello!"
history = await context.get_history() # platform-authorized for this user
input_items = _build_input(user_input, history)
response = _responses_client.create(model=_model, input=input_items, store=False)
return TextResponse(context, request, text=response.output_text)
Omdat het platform per aanvraag autoriseert context.get_history() , ontvangt een gebruiker in een gedeelde sessie nooit de gespreksgeschiedenis van een andere gebruiker.
Gegevens per gebruiker partitioneren in uw containeropslag
Het platform isoleert de gespreksgeschiedenis voor u. Als uw container ook eigen gegevens ( bestanden, databaserijen of een cache) opslaat, worden die gegevens niet automatisch gepartitioneerd. Sleutel deze door zowel de sessie-id als de gebruikers-id, zodat twee gebruikers in dezelfde sessie elkaars gegevens niet kunnen zien:
partition = (agent_session_id, user_id)
Warning
Wanneer gebruikers een sessie delen, partitionert het platform niet de gegevens die uw container zelf opslaat. Als uw container die gegevens uitsluitend op basis van de sessie-ID indeelt, ziet elke gebruiker in de pool dezelfde gegevens. Neem altijd de gebruikers-id op in de partitiesleutel.
Lees de gebruikers-id uit de platformcontext van het verzoek:
from azure.ai.agentserver.core import get_request_context
def partition_key() -> tuple[str, str]:
ctx = get_request_context()
if not ctx or not ctx.user_id:
raise PermissionError("A user context is required on protocol 2.0.0.")
return (ctx.session_id, ctx.user_id) # key all user-owned data by this
Het platform injecteert de gebruiker ook als aanvraagheader x-agent-user-id . Als uw runtime de SDK-context niet gebruikt, leest u deze header rechtstreeks.
Het platform vult get_request_context().user_id in met protocol 2.0.0. Gebruik nooit alleen de sessie-id voor gegevens die eigendom zijn van de gebruiker wanneer meer dan één gebruiker de sessie kan invoeren.
Zie het voorbeeld van de notitie-agent voor een uitgewerkt voorbeeld van opslag per sessie om op voort te bouwen. Het maakt per sessie één sleutel voor één bestand aan onder $HOME. Voor een gedeelde sessie kunt u die sleutel uitbreiden met de gebruikers-id vanuit de aanvraagcontext, zodat elke gebruiker een eigen partitie krijgt.
Isolatie controleren
Bevestig de garantie met de A-A-B-test van het voorbeeld. invoke_previous_response_isolation.py Voer deze uit op uw geïmplementeerde agent met twee afzonderlijke gebruikers (het voorbeeld wordt standaard ingesteld op Alice en Bob):
- Maak als Alice in een gedeelde sessie een antwoord en leg het
idvast. - Maak als Alice een tweede reactie in dezelfde sessie, waarbij
previous_response_idwordt ingesteld op deidvan de eerste reactie, en leg deidervan vast. - Stuur als Bob in dezelfde sessie een verzoek waarbij
previous_response_idis ingesteld op Alice's tweede reactie. De oproep mislukt - Bob kan Alices keten niet voortzetten.
Gebruik twee verschillende Entra-gebruikers of object-id's. Twee labels die worden omgezet in dezelfde identiteit, zijn geen geldige test voor meerdere gebruikers.
Het verzenden van een verouderde isolatieheader op een protocol 2.0.0-pad retourneert een fout, omdat dat model wordt vervangen door de gebruikerscontext van het platform.
Verwante inhoud
- Isolatie van gehoste agentsessies per gebruiker voor het standaardisolatiemodel per aanroeper.
- Voorbeeld van sessie-multiplexing voor de volledige sessiegroep in de middelste laag, containerhandler en isolatietest.
- Voorbeeld van een notitieagent voor een container die gegevens in eigendom van de gebruiker per sessie (Python en C#) persistent maakt.
- Quota en limieten voor Foundry Agent Service voor regionale limieten voor gelijktijdige sessies.
- Migreer gehoste agents om een container over te zetten op protocol 2.0.0.
- Gehoste agentruntimecontract voor de platformheaders en omgevingsvariabelen die een container ontvangt.