AgentApplication i SDK for Microsoft 365-agenter

AgentApplication er den sentrale byggeblokken i en agent bygget med Agents SDK. AgentApplication er inngangspunktet for all innkommende aktivitet, inkludert meldinger fra brukere, hendelser i samtalens livssyklus, dynamisk kort-interaksjoner og OAuth-callbacks.

En agent er, i sin kjerne, en AgentApplication. Du konfigurerer det med håndterere som beskriver hva agenten din gjør. SDK-en tar seg av ruting, tilstandsstyring og infrastrukturen som kreves for å kjøre den.

Slik fungerer AgentApplication

Hver agent har en livssyklus som starter når en kanal (Microsoft Teams, en robot-tjeneste eller en tilpasset klient) leverer en aktivitet til agentens endepunkt. AgentApplication ligger i sentrum av den livssyklusen:

Channel → Hosting layer → AgentApplication → Your handlers

Behandlingslagene i en agent bygget med Agents SDK fungerer som følger:

  1. Vertslaget mottar HTTP-forespørselen og autentiserer den.
  2. AgentApplication behandler den innkommende aktiviteten gjennom sin pipeline.
  3. Behandlingsprogrammene kalles opp basert på samsvarende ruter.

Agenten laster inn omgangsstatusen før behandlingsprogrammene kjøres. Etterpå lagrer agenten tur-tilstanden.

Kjernekonsepter

Aktiviteter

Alt i Agents SDK flyter som en aktivitet. En aktivitet er en strukturert melding som representerer noe som har skjedd. En aktivitet har en type, for eksempel melding, hendelse, invoke, oppdatering av samtale, og så videre. Den bærer en nyttelast som er relevant for den typen. AgentApplication mottar aktiviteter og ruter dem til riktig handler

Ruter

En rute parer en selector med en handler. Selectoren bestemmer om en rute matcher den gjeldende aktiviteten. Handleren kjører logikken din når ruten matcher.

Registrer ruter når du konfigurerer agenten din. De kan matche:

  • En melding som inneholder spesifikk tekst eller matcher et regulært uttrykk
  • Enhver aktivitet av en gitt type
  • Hendelser i samtalens livssyklus (medlem lagt til, medlem fjernet)
  • Dynamiske korthandlinger
  • Egendefinerte vilkår

Når en aktivitet mottas, evaluerer systemet ruter i rekkefølge til den finner et treff. Som standard går bare én rute.

Turn-tilstand

AgentApplication håndterer turn-tilstand—strukturert lagring delt inn i områder:

Områdetype Description
Samtale Delt mellom alle brukere i en samtale, lagres mellom omgangene
Bruker Omfatter én enkelt bruker på tvers av alle samtaler
Temp Bare nåværende omgang – aldri oppretthold

Systemet laster automatisk tilstanden før handlerne dine kjører og lagrer den automatisk etterpå.

Omgangskontekst

Når en handler kjører, får den en turn context. Turn context er et øyeblikksbilde av den nåværende aktiviteten, adaptertilkoblingen og verktøy for å sende svar. Turn context er grensesnittet ditt til den nåværende interaksjonen.

Mellomvare

AgentApplication støtter en mellomvare-pipeline. Middleware er en kjede av komponenter som behandler hver tur før og etter at handlerne dine kjøres. Mellomvare kan inspisere, transformere eller kortslutte aktivitetsflyten. Vanlige bruksområder inkluderer logging, autentiseringssjekker og normalisering av forespørsler.

Opprett en agent

Arv fra AgentApplication og registrer håndterere i konstruktøren. Hosting-rammeverket injiserer automatisk AgentApplicationOptions.

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);
    }
}

Registrer agenten din i 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();

Registrer aktivitetshåndterere

Håndter meldinger

Sammenlign meldinger etter eksakt tekst (uten hensyn til store og små bokstaver):

OnMessage("help", async (context, state, ct) =>
{
    await context.SendActivityAsync("Here's what I can do...", cancellationToken: ct);
});

Match meldinger ved hjelp av et regulært uttrykk:

OnMessage(new Regex(@"^order\s+\d+$", RegexOptions.IgnoreCase), async (context, state, ct) =>
{
    await context.SendActivityAsync("Looking up your order...", cancellationToken: ct);
});

Håndter samtaleoppdateringer

Registrer håndterere for hendelser i samtalens livssyklus, slik som når medlemmer blir med eller forlater.

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
});

Håndter enhver aktivitetstype

Samsvar enhver aktivitet etter typestrengen for fullstendig kontroll over ruting.

OnActivity(ActivityTypes.Message, async (context, state, ct) =>
{
    // Handles all message activities
});

OnActivity(ActivityTypes.Event, async (context, state, ct) =>
{
    // Handles event activities
});

Bruk ActivityTypes konstanter i stedet for hardkodede strenger.

Evalueringsordre for kontrollrute

Systemet sorterer ruter i en fast evalueringsrekkefølge når du registrerer dem, ikke under kjøretid. Sorteringen bruker to nivåer:

  1. Rutetype: Systemet grupperer ruter etter type, og evaluerer alltid først de med høyere prioritet før de med lavere prioritet, uavhengig av rang:

    Prioritet Rutetype
    1 (høyeste) Agentbaserte invoke-ruter
    2 Kalle ruter (dynamiske korthandlinger, OAuth-callbacks og andre tidssensitive kall)
    3 Agentbaserte ruter
    4 (laveste) Alle andre ruter
  2. Rang: Innenfor hver rutetype sorterer systemet rutene etter deres rangverdi. Lavere numeriske verdier evalueres først.

Bruk RouteRank konstanter for å sette rang når du registrerer en handler:

Konstant Verdi Betydning
RouteRank.First 0 Evaluert før alle andre ruter i gruppen
RouteRank.Unspecified 32767 Standard når ingen rang er spesifisert
RouteRank.Last 65535 Evaluert etter alle andre ruter i gruppen

Som standard stopper evalueringen ved første matchende rute. Bruk RouteRank.Last for en catch-all fallback som håndterer alt som ikke matches av en mer spesifikk rute.

// 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);

Omgangslivssykluskroker

Registrer logikk som kjøres på hver tur, før eller etter rutematching. Disse krokene er nyttige for logging, aspekter på tvers av systemet og feilhåndtering.

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);
});

Når OnBeforeTurn returnerer false, avbrytes turen og ingen ruter kjøres. Når OnAfterTurn returnerer false, lagres ikke turtilstanden.

Bruk turtilstand

Agenten laster automatisk tur-tilstanden før handlerne dine kjører og lagrer den etterpå. Turn state-objektet som sendes til håndtererne dine gir deg tilgang til de ulike scopene, slik at du kan lese og skrive data som vedvarer over turer eller er flyktig for den nåværende turen:

  • Samtaleomfang: For data delt på tvers av alle turer i en samtale
  • Brukeromfang: For data per bruker
  • Temp scope: For data som kun trenger å eksistere i løpet av den nåværende runden
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);
});

Notat

Bruk MemoryStorage for lokal utvikling og testing. I produksjonsmiljøer, spesielt når applikasjonen kjører på flere instanser, bør du bruke en persistent lagringsleverandør som Azure Cosmos DB eller Azure Blob Storage. Se Bruk lagringsleverandører i agenten.

Neste trinn