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.
AgentApplication is de centrale bouwsteen van een agent die is gebouwd met de Agents SDK.
AgentApplication is het toegangspunt voor alle binnenkomende activiteiten, waaronder berichten van gebruikers, gebeurtenissen in de levenscyclus van gesprekken, adaptieve kaartinteracties, OAuth-callbacks.
Een agent is, in zijn kern, een AgentApplication. U configureert deze met handlers die beschrijven wat uw agent doet. De SDK zorgt voor routering, statusbeheer en de infrastructuur die nodig is om deze uit te voeren.
Hoe AgentApplication werkt
Elke agent heeft een levenscyclus die begint wanneer een kanaal (Microsoft Teams, een botservice of een aangepaste client) een activiteit levert aan het eindpunt van uw agent.
AgentApplication bevindt zich in het midden van die levenscyclus:
Channel → Hosting layer → AgentApplication → Your handlers
De verwerkingslagen in een agent die is gebouwd met de Agents SDK werken als volgt:
- De hostinglaag ontvangt de HTTP-aanvraag en verifieert deze.
-
AgentApplicationverwerkt de binnenkomende activiteit via de pijplijn. - Uw handlers worden aangeroepen op basis van overeenkomende routes.
Uw agent laadt de status Turn voordat uw handlers worden uitgevoerd. Daarna slaat de agent de draaistatus op.
Basisconcepten
Activiteiten
Alles in de Agents SDK loopt als activiteit. Een activiteit is een gestructureerd bericht dat iets vertegenwoordigt dat is gebeurd. Een activiteit heeft een type, zoals bericht, gebeurtenis, aanroepen, conversationUpdate, enzovoort. Het draagt een payload die relevant is voor dit type.
AgentApplication ontvangt activiteiten en stuurt ze door naar de juiste handler.
Routes
Een route pareert een selector met een handler. De selector bepaalt of een route overeenkomt met de huidige activiteit. De handler voert uw logica uit wanneer de route overeenkomt.
Registreer routes wanneer u uw agent configureert. Ze kunnen overeenstemmen met:
- Een bericht dat specifieke tekst bevat of overeenkomt met een reguliere expressie
- Elke activiteit van een bepaald type
- Gebeurtenissen in de levenscyclus van gesprekken (lid toegevoegd, lid verwijderd)
- Adaptieve kaartacties
- Aangepaste voorwaarden
Wanneer een activiteit binnenkomt, evalueert het systeem routes op volgorde totdat er een overeenkomst wordt gevonden. Standaard wordt slechts één route uitgevoerd.
Status wijzigen
AgentApplication beheert _turn toestand—gestructureerde opslag, opgedeeld in scopes:
| Bereiktype | Beschrijving |
|---|---|
| Gesprek | Gedeeld met alle gebruikers in een gesprek, opgeslagen tussen uitwisselingen. |
| Gebruiker | Toegewezen aan een individuele gebruiker voor alle gesprekken |
| Temp | Alleen voor de huidige sessie - niet blijvend |
Het systeem laadt de status automatisch voordat uw handlers worden uitgevoerd en slaat deze daarna automatisch op.
Context omkeren
Wanneer een handler wordt uitgevoerd, ontvangt deze een beurtcontext. Turncontext is een momentopname van de huidige activiteit, de adapterverbinding en hulpprogramma's voor het verzenden van antwoorden. De beurtcontext is uw interface voor de huidige interactie.
Middleware
AgentApplication ondersteunt een middleware-pijplijn. Middleware is een keten van onderdelen die elke draai vóór en nadat uw handlers worden uitgevoerd. Middleware kan de activiteitsstroom inspecteren, transformeren of kortsluiten. Veelvoorkomende toepassingen zijn logboekregistratie, verificatiecontroles en normalisatie van aanvragen.
Een agent maken
Maak een subklasse van AgentApplication en registreer uw handlers in de constructor. Het hostingframework injecteert AgentApplicationOptionsautomatisch .
public class MyAgent : AgentApplication
{
public MyAgent(AgentApplicationOptions options) : base(options)
{
OnConversationUpdate(ConversationUpdateEvents.MembersAdded, WelcomeAsync);
OnActivity(ActivityTypes.Message, OnMessageAsync, rank: RouteRank.Last);
}
private async Task WelcomeAsync(ITurnContext context, ITurnState state, CancellationToken ct)
{
foreach (var member in context.Activity.MembersAdded)
{
if (member.Id != context.Activity.Recipient.Id)
{
await context.SendActivityAsync("Hello! How can I help you?", cancellationToken: ct);
}
}
}
private async Task OnMessageAsync(ITurnContext context, ITurnState state, CancellationToken ct)
{
await context.SendActivityAsync($"You said: {context.Activity.Text}", cancellationToken: ct);
}
}
Registreer uw agent in Program.cs:
WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
builder.Services.AddHttpClient();
builder.Services.AddSingleton<IStorage, MemoryStorage>();
builder.Services.AddAgent<MyAgent>();
builder.Services.AddAgentAspNetAuthentication(builder.Configuration);
WebApplication app = builder.Build();
app.UseAuthentication();
app.UseAuthorization();
app.MapAgentApplicationEndpoints(requireAuth: !app.Environment.IsDevelopment());
app.Run();
Activiteitenhandlers registreren
Berichten verwerken
Berichten matchen met exacte tekst (hoofdletterongevoelig):
OnMessage("help", async (context, state, ct) =>
{
await context.SendActivityAsync("Here's what I can do...", cancellationToken: ct);
});
Berichten vergelijken met een reguliere expressie:
OnMessage(new Regex(@"^order\s+\d+$", RegexOptions.IgnoreCase), async (context, state, ct) =>
{
await context.SendActivityAsync("Looking up your order...", cancellationToken: ct);
});
Gespreksupdates verwerken
Registreer handlers voor gebeurtenissen in de levenscyclus van gesprekken, zoals leden die deelnemen aan of vertrekken.
OnConversationUpdate(ConversationUpdateEvents.MembersAdded, async (context, state, ct) =>
{
foreach (var member in context.Activity.MembersAdded)
{
if (member.Id != context.Activity.Recipient.Id)
{
await context.SendActivityAsync("Welcome!", cancellationToken: ct);
}
}
});
OnConversationUpdate(ConversationUpdateEvents.MembersRemoved, async (context, state, ct) =>
{
// Called when participants leave the conversation
});
Elk activiteitstype verwerken
Koppel een activiteit aan de hand van de typetekenreeks voor volledige controle over routering.
OnActivity(ActivityTypes.Message, async (context, state, ct) =>
{
// Handles all message activities
});
OnActivity(ActivityTypes.Event, async (context, state, ct) =>
{
// Handles event activities
});
Gebruik ActivityTypes constanten in plaats van vastgelegde tekenreeksen.
Volgorde van route-evaluatie beheren
Het systeem sorteert routes in een vaste evaluatievolgorde wanneer u ze registreert, niet tijdens runtime. De sortering maakt gebruik van twee niveaus:
Routetype: Het systeem groepeert routes per type en evalueert altijd typen met een hogere prioriteit vóór typen met lagere prioriteit, ongeacht rang:
Prioriteit Routetype 1 (hoogste) Agentgebaseerde aanroeproutes 2 Routes aanroepen (adaptieve kaartacties, OAuth-callbacks en andere tijdgevoelige aanroepen) 3 Agentische routes 4 (laagste) Alle andere routes Rangschikking: Binnen elke routetypegroep worden routes geordeerd op basis van hun rangwaarde. Lagere numerieke waarden worden eerst geëvalueerd.
Gebruik RouteRank constanten om rang in te stellen bij het registreren van een handler:
| Constante | Waarde | Betekenis |
|---|---|---|
RouteRank.First |
0 |
Geëvalueerd vóór alle andere routes in de groep |
RouteRank.Unspecified |
32767 |
Standaard wanneer er geen rang is opgegeven |
RouteRank.Last |
65535 |
Geëvalueerd na alle andere routes in de groep |
Evaluatie stopt standaard bij de eerste overeenkomende route. Gebruik RouteRank.Last als een catch-all-terugvaloptie die alles afhandelt wat niet overeenkomt met een specifiekere route.
// Specific handlers use the default rank
OnMessage("status", HandleStatusAsync);
OnMessage("help", HandleHelpAsync);
// Catch-all — handles anything not matched above
OnActivity(ActivityTypes.Message, HandleUnknownMessageAsync, rank: RouteRank.Last);
Levenscyclushook draaien
Registreer logica die wordt uitgevoerd op elke beurt, vóór of na het vergelijken van routes. Deze hooks zijn handig voor logboekregistratie, kruislingse problemen en foutafhandeling.
OnBeforeTurn(async (context, state, ct) =>
{
logger.LogInformation("Turn started: {Type}", context.Activity.Type);
return true; // Return false to abort the turn
});
OnAfterTurn(async (context, state, ct) =>
{
logger.LogInformation("Turn completed");
return true; // Return false to skip state saving
});
OnTurnError(async (context, state, exception, ct) =>
{
logger.LogError(exception, "Turn error");
await context.SendActivityAsync("Something went wrong. Please try again.", cancellationToken: ct);
});
Wanneer OnAfterTurnfalse retourneert, wordt de status van de schakelaar niet opgeslagen.
Turnstatus gebruiken
De agent laadt automatisch de beurtstatus voordat uw handlers worden uitgevoerd en slaat deze daarna op. Het turn state object dat aan uw handlers wordt doorgegeven, geeft u toegang tot de verschillende scopes, zodat u gegevens kunt lezen en schrijven die persistent zijn over meerdere beurten of tijdelijk zijn voor de huidige beurt.
- Gespreksbereik: Voor gegevens die over alle beurten in een gesprek worden gedeeld
- Gebruikersbereik: Voor gegevens per gebruiker
- Tijdelijk bereik: Voor gegevens die alleen tijdens de huidige sessie moeten bestaan
OnActivity(ActivityTypes.Message, async (context, state, ct) =>
{
// Conversation scope — persisted per conversation
var count = state.Conversation.GetValue<int>("messageCount", () => 0);
state.Conversation.SetValue("messageCount", count + 1);
// User scope — persisted per user
var name = state.User.GetValue<string>("displayName");
// Temp scope — current turn only
state.Temp.SetValue("parsedInput", context.Activity.Text?.Trim());
await context.SendActivityAsync($"Message #{count + 1}: {context.Activity.Text}", cancellationToken: ct);
});
Opmerking
Gebruiken MemoryStorage voor lokale ontwikkeling en testen. Gebruik voor productie-implementaties, met name implementaties die worden uitgevoerd op meerdere exemplaren, een permanente opslagprovider, zoals Azure Cosmos DB of Azure Blob Storage. Zie Opslagproviders gebruiken in uw agent.