AgentApplication i SDK för Microsoft 365-agenter

AgentApplication är den centrala byggblocket i en agent byggd med Agents SDK. AgentApplication är startpunkten för all inkommande aktivitet, inklusive meddelanden från användare, livscykelhändelser i konversationer, interaktioner med adaptiva kort, OAuth-callbacks.

En agent är i sin kärna en AgentApplication. Du konfigurerar det med hanterare som beskriver vad din agent gör. SDK:n hanterar routing, tillståndshantering och den infrastruktur som krävs för att driva agenten.

Hur AgentApplication fungerar

Varje agent har en livscykel som börjar när en kanal (Microsoft Teams, en bot service eller en anpassad klient) levererar en aktivitet till agentens slutpunkt. AgentApplication utgör kärnan i den livscykeln:

Channel → Hosting layer → AgentApplication → Your handlers

Bearbetningslagren i en agent som byggs med Agents SDK fungerar enligt följande:

  1. Hostinglagret tar emot HTTP-förfrågan och autentiserar den.
  2. AgentApplication bearbetar den inkommande aktiviteten genom sin pipeline.
  3. Dina hanterare anropas baserat på matchande rutter.

Din agent läser in omgångstillstånd innan dina hanterare körs. Därefter sparar agenten omgångstillstånd.

Huvudkoncept

Aktiviteter

Allt i Agents SDK flyter som en aktivitet. En aktivitet är ett strukturerat meddelande som representerar en händelse. En aktivitet har en typ, till exempel meddelande, händelse, anrop, conversationUpdate och så vidare. Den bär en nyttolast som är relevant för den typen. AgentApplication tar emot aktiviteter och vidarebefordrar dem till rätt hanterare.

Flöden

En rutt parar ihop en selector med en handler. Väljare avgör om en route matchar den aktuella aktiviteten. Väljaren kör din logik när rutten stämmer.

Registrera rutter när du konfigurerar din agent. De kan matcha:

  • Ett meddelande som innehåller specifik text eller matchar ett reguljärt uttryck
  • Vilken aktivitet som helst av en viss typ
  • Konversationslivscykelhändelser (medlem tillagd, medlem borttagen)
  • Åtgärder för adaptivt kort
  • Anpassade villkor

När en aktivitet anländer utvärderar systemet routes i ordning tills det hittar en match. Som standard körs endast en route.

Omgångstillstånd

AgentApplication hanterar _turn state—strukturerad lagring uppdelad i omfattningar:

Typer av omfattning beskrivning
Konversation Delas mellan alla användare i en konversation, sparas över turer
Användare Associerat med en enskild användare över alla konversationer
Tillfällig Endast aktuell omgång – sparas inte

Systemet läser automatiskt in tillstånd innan dina hanterare körs och sparar det automatiskt efteråt.

Omgångskontext

När en hanterare körs får den en omgångskontext. Omgångskontext är en ögonblicksbild över den pågående aktiviteten, adapteranslutningen och verktyg för att skicka svar. Omgångskontexten är ditt gränssnitt till den aktuella interaktionen.

Mellanprogram

AgentApplication stöder en pipeline för mellanprogram. Mellanprogram är en kedja av komponenter som bearbetar varje omgång före och efter att dina hanterare har körts. Mellanprogram kan inspektera, transformera eller kortsluta aktivitetsflödet. Vanliga användningsområden inkluderar loggning, autentiseringskontroller och normalisering av förfrågningar.

Skapa en agent

Skapa en underklass av AgentApplication och registrera dina hanterare i konstruktor. Värdramverket injicerar AgentApplicationOptions automatiskt.

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

Registrera agenten 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();

Registrera aktivitetshanterare

Hantera meddelanden

Matcha meddelanden med exakt text (skiftlägesokänslig):

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

Matcha meddelanden med ett reguljärt uttryck:

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

Hantera konversationsuppdateringar

Registrera hanterare för livscykelhändelser i konversationer, såsom när medlemmar går med eller lämnar.

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

Hantera alla typer av aktiviteter

Matcha vilken aktivitet som helst efter dess typsträng för fullständig kontroll över routing.

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

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

Använd ActivityTypes konstanter i stället för hårdkodade strängar.

Hantera utvärderingsordning för rutter

Systemet sorterar rutter i en fast utvärderingsordning när du registrerar dem, inte vid körning. Sorteringen använder två nivåer:

  1. Cirkuleringstyp: Systemet grupperar rutter efter typ och utvärderar alltid typer med högre prioritet före typer med lägre prioritet, oavsett rang:

    Prioritet Cirkuleringstyp
    1 (högsta) Agentiska anropsvägar
    2 Anropa rutter (adaptiva kortåtgärder, OAuth-motringningar och andra tidskänsliga anrop)
    3 Agentrutter
    4 (lägst) Alla andra rutter
  2. Rang: Inom varje rutt-typgrupp ordnar systemet rutter efter deras rangvärde. Lägre numeriska värden utvärderas först.

Använd RouteRank konstanter för att ange rang när du registrerar en handler:

Konstant Value Betydelse
RouteRank.First 0 Utvärderas före alla andra rutter i sin grupp
RouteRank.Unspecified 32767 Förvalt när ingen rang anges
RouteRank.Last 65535 Utvärderas efter alla andra rutter i sin grupp

Som standardläge avbryts utvärderingen vid den första matchande rutten. Använd RouteRank.Last för en catch-all fallback som hanterar allt som inte matchas av en mer specifik rutt.

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

Omgångens livscykelkrokar

Registerlogik som körs på varje omgång, före eller efter ruttmatchning. Dessa krokar är användbara för loggning, övergripande problem och felhantering.

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 returnerar false, avbryts omgången och inga rutter körs. När OnAfterTurn återvänder falsesparas inte omgångstillståndet.

Använd omgångstillstånd

Agenten läser automatiskt in omgångstillstånd innan dina hanterare körs och sparar det efteråt. Omgångstillståndsobjektet som skickas till dina hanterare ger dig tillgång till de olika omfången så att du kan läsa och skriva data som består över omgångar eller är tillfällig för den aktuella omgången:

  • Konversationsomfång: För data som delas över alla turer i en konversation
  • Användaromfång: För data per användare
  • Tillfälligt omfång: För data som bara behöver finnas under den aktuella omgången
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);
});

Kommentar

Använd MemoryStorage för lokal utveckling och testning. För produktionsinstallationer, särskilt sådana som körs på flera instanser, använd en persistent lagringsleverantör som Azure Cosmos DB eller Azure Blob Storage. Se Använda lagringsleverantörer i din agent.

Nästa steg