AgentApplication v sadě SDK pro agenty Microsoft 365

AgentApplication je centrální stavební blok agenta sestaveného pomocí sady Agents SDK. AgentApplication je vstupním bodem pro všechny příchozí aktivity, včetně zpráv od uživatelů, událostí životního cyklu konverzace, interakcí adaptivních karet a callbacků OAuth.

Agent je ve svém jádru AgentApplication. Nakonfigurujete ho pomocí obslužných rutin, které popisují, co váš agent dělá. Sada SDK se stará o směrování, správu stavu a infrastrukturu potřebnou ke spuštění.

Jak funguje AgentApplication

Každý agent má životní cyklus, který se spustí, když kanál (Microsoft Teams, služba robota nebo vlastní klient) doručí aktivitu do koncového bodu vašeho agenta. AgentApplication se nachází uprostřed tohoto životního cyklu:

Channel → Hosting layer → AgentApplication → Your handlers

Vrstvy zpracování v agentu vytvořeném pomocí sady Agents SDK fungují takto:

  1. Vrstva hostování obdrží požadavek HTTP a ověří ho.
  2. AgentApplication zpracovává příchozí aktivitu prostřednictvím svého kanálu.
  3. Vaše obslužné rutiny se volají na základě odpovídajících tras.

Agent načte stav tahu před spuštěním obslužných rutin. Potom agent uloží stav tahu.

Klíčové koncepty

Aktivity

Všechno v Sadě SDK pro agenty funguje jako aktivita. Aktivita je strukturovaná zpráva představující něco, co se stalo. Aktivita má typ, například zprávu, událost, vyvolání, conversationUpdate atd. Nese užitečné zatížení, které je pro daný typ relevantní. AgentApplication přijímá aktivity a směruje je do správné obslužné rutiny.

Postupy

Směrovač spáruje selektor s handlerem. Selektor určuje, jestli trasa odpovídá aktuální aktivitě. Obslužná rutina spustí logiku, když se trasa shoduje.

Při konfiguraci agenta zaregistrujte trasy. Můžou se shodovat:

  • Zpráva obsahující konkrétní text nebo odpovídající regulárnímu výrazu
  • Jakákoli aktivita daného typu
  • Události životního cyklu konverzace (přidání člena, odebrání člena)
  • Akce adaptivní karty
  • Vlastní podmínky

Když aktivita dorazí, systém vyhodnocuje trasy v pořadí, dokud nenajde shodu. Ve výchozím nastavení běží pouze jedna trasa.

Změnit stav

AgentApplication spravuje stav tahu – strukturované úložiště rozdělené do oborů:

Typ oboru Description
Konverzace Sdílené mezi všemi uživateli v konverzaci, uchované mezi jednotlivými kroky dialogu.
Uživatel Vymezený na jednotlivého uživatele ve všech konverzacích
Dočasné Pouze aktuální tah – nikdy se neuchovávalo

Systém automaticky načte stav před spuštěním obslužných rutin a automaticky ho uloží.

Otočení kontextu

Když se obslužná rutina spustí, obdrží kontext tahu. Kontext tahu je snímek aktuální aktivity, připojení adaptéru a nástrojů pro odesílání odpovědí. Kontext tahu je vaše rozhraní pro aktuální interakci.

Middleware

AgentApplication podporuje kanál middlewaru. Middleware je řetězec komponent, které zpracovávají každou akci před a po spuštění obslužných rutin. Middleware může zkontrolovat, transformovat nebo zkratovat tok aktivity. Mezi běžné použití patří protokolování, kontroly ověřování a normalizace požadavků.

Vytvořit agenta

Vytvořte podtřídu AgentApplication a zaregistrujte obslužné rutiny v konstruktoru. Hostitelská architektura automaticky vloží 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);
    }
}

Zaregistrujte svého agenta v 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();

Registrujte obslužné rutiny aktivit

Vyřizování zpráv

Porovná zprávy přesným textem (nerozlišuje velká a malá písmena):

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

Porovná zprávy pomocí regulárního výrazu:

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

Zpracování aktualizací konverzací

Zaregistrujte obslužné rutiny pro události životního cyklu konverzace, jako jsou například členové, kteří se připojují nebo odcházejí.

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

Zvládnutí jakéhokoliv typu aktivity

Porovná jakoukoli aktivitu podle řetězce typu pro úplnou kontrolu nad směrováním.

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

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

Místo pevně zakódovaných řetězců používejte ActivityTypes konstanty.

Ovládání pořadí vyhodnocení trasy

Systém seřadí trasy do pevného pořadí vyhodnocení, když je zaregistrujete, ne za běhu. Řazení používá dvě úrovně:

  1. Typ trasy: Systém seskupuje trasy podle typu a vždy vyhodnocuje typy s vyšší prioritou před typy s nižší prioritou bez ohledu na pořadí:

    Priorita Typ trasy
    1 (nejvyšší) Trasy volání agentů
    2 Volání tras (akce adaptivní karty, zpětné volání OAuth a jiná volání citlivá na čas)
    3 Agentní trasy
    4 (nejnižší) Všechny ostatní trasy
  2. Pořadí: V rámci každé skupiny typů tras systém objednává trasy podle jejich hodnoty pořadí. Nižší číselné hodnoty se vyhodnocují jako první.

Při registraci obslužné rutiny použijte RouteRank konstanty k nastavení pořadí:

Konstanta Value Význam
RouteRank.First 0 Vyhodnoceno před všemi ostatními trasami ve skupině
RouteRank.Unspecified 32767 Výchozí hodnota, pokud není zadáno žádné pořadí
RouteRank.Last 65535 Vyhodnoceno po všech ostatních trasách ve skupině

Ve výchozím nastavení se vyhodnocení zastaví na první odpovídající trase. Použijte RouteRank.Last pro univerzální záložní řešení, které zpracuje cokoli, co neodpovídá specifičtější trase.

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

Háčky životního cyklu tahu

Zaregistrujte logiku, která se spouští při každém průběhu, před nebo po porovnávání tras. Tyto háčky jsou užitečné pro protokolování, průřezové zájmy a zpracování chyb.

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

Když OnBeforeTurn vrátí false, tah se přeruší a nespustí se žádné trasy. Pokud OnAfterTurn vrátí false, stav tahu se neuloží.

Použij stav otočení

Agent automaticky načte stav tahu před spuštěním vašich obslužných rutin a po jejich ukončení jej uloží. Objekt stavu obratu předaný vašim handlerům poskytuje přístup k různým oborům, abyste mohli číst a zapisovat data, která se zachovají napříč obraty nebo jsou dočasná pro aktuální obrat:

  • Rozsah konverzace: Pro data sdílená napříč všemi částmi konverzace.
  • Obor uživatele: Pro uživatelská data
  • Dočasný rozsah: Pro data, která musí existovat pouze během aktuálního turnu
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);
});

Poznámka:

Používá se MemoryStorage pro místní vývoj a testování. Pro produkční nasazení, zejména nasazení spuštěná na více instancích, použijte trvalého poskytovatele úložiště, jako je Azure Cosmos DB nebo Azure Blob Storage. Viz Použití poskytovatelů úložiště ve vašem agentu.

Další kroky