Microsoft 365 Aracıları SDK'sında AgentApplication

AgentApplication Agents SDK ile oluşturulan bir aracının merkezi yapı taşıdır. AgentApplication; kullanıcı mesajları, konuşma yaşam döngüsü olayları, uyarlamalı kart etkileşimleri ve OAuth geri çağrıları dahil olmak üzere tüm gelen aktivitelerin giriş noktasıdır.

Bir aracı özünde AgentApplication'dır. Aracınızın ne yaptığını açıklayan işleyicilerle yapılandırabilirsiniz. SDK, yönlendirme, durum yönetimi ve onu çalıştırmak için gereken altyapıyı sağlar.

AgentApplication Nasıl Çalışır

Her aracı, bir kanal (Microsoft Teams, bir Bot Hizmeti veya özel bir istemci) bir etkinliği aracınızın uç noktasına ilettiğinde başlayan bir yaşam döngüsüne sahiptir. AgentApplication Bu yaşam döngüsünün merkezinde yer alır:

Channel → Hosting layer → AgentApplication → Your handlers

Agents SDK ile oluşturulmuş bir aracı üzerindeki işlem katmanları aşağıdaki gibi işler:

  1. Barındırma katmanı HTTP isteğini alır ve onu doğrular.
  2. AgentApplication gelen etkinliği kendi işlem hattında işler.
  3. İşleyicileriniz yolların eşleşmesine bağlı olarak çağrılır.

İşleyicileriniz çalışmadan önce aracınız işlem durumunu yükler. Daha sonra aracı tur durumunu kaydeder.

Temel kavramlar

Aktiviteler

Agents SDK'daki her şey bir etkinlik olarak akıyor. Bir etkinlik, gerçekleşen bir olayı temsil eden yapılandırılmış bir mesajdır. Bir etkinlik, mesaj, olay, invoke, konuşma güncellemesi gibi bir türde olabilir. Bu tipe ait bir yük taşır. AgentApplication etkinlikleri alır ve onları doğru işleyiciye yönlendirir.

Rotalar

Bir rota, bir seçiciyi bir işleyici ile eşleştirir. Seçici, bir rotanın mevcut etkinlikle eşleşip eşleşmediğini belirler. Handler, rota eşleştiğinde mantığınızı çalıştırır.

Aracınızı yapılandırırken rotaları kaydedin. Bunlar eşleşebilir:

  • Belirli metin içeren veya düzenli ifadeyle eşleşen bir mesaj
  • Belirli bir türdeki herhangi bir faaliyet
  • Konuşma yaşam döngüsü etkinlikleri (üye eklendi, üye çıkarıldı)
  • Uyarlamalı kart eylemleri
  • Özel koşullar

Bir etkinlik geldiğinde, sistem rotaları sırayla kontrol eder ve bir eşleşme bulana kadar aramaya devam eder. Varsayılan olarak sadece bir rota çalışır.

Dönüş durumu

AgentApplication _turn durumunu yönetir—kapsamlara ayrılmış yapılandırılmış depolama:

Kapsam türü Açıklama
Konuşma Konuşmadaki tüm kullanıcılar arasında paylaşılır ve diyalog adımları arasında kalıcılığını sürdürür
User Her kullanıcıya özel, tüm konuşmalarda geçerli
Şablon Yalnızca geçerli tur - hiçbir zaman kalıcı değil

Sistem, işleyicileriniz çalışmadan önce otomatik olarak durumu yükler ve sonrasında otomatik olarak kaydeder.

Tur bağlamı

Bir işleyici çalıştırıldığında, bir dönüş bağlamı alır. Tur bağlamı, geçerli etkinlik, bağdaştırıcı bağlantısı ve yanıt gönderme araçlarının anlık görüntüsüdür. Tur bağlamı, geçerli etkileşime olan arabiriminizdir.

Ara yazılım

AgentApplication, ara yazılım ardışık düzen destekliyor. Ara yazılım, her turda işleyiciniz çalışmadan önce ve sonra işleyen bir bileşen zinciridir. Ara yazılım, etkinlik akışını inceleyebilir, dönüştürebilir veya akışı erken sonlandırabilir. Yaygın kullanım alanları arasında kayıt, kimlik doğrulama kontrolleri ve istek normalizasyonu yer alır.

Aracı oluşturma

AgentApplication sınıfını türetin ve işleyicilerinizi yapıcıda kaydedin. Barındırma çerçevesi AgentApplicationOptions öğesini otomatik olarak enjekte eder.

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

Aracınızı Program.cs adresinde kaydedin:

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

Etkinlik işleyicilerini kaydedin

Mesajları Ele Al

Mesajları tam metinle eşleştirin (büyük/küçük harf duyarlılığı olmadan):

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

Mesajları düzenli ifadeyle eşleştirin:

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

Konuşma güncellemelerini işleyin

Üyelerin katılması veya ayrılması gibi konuşma yaşam döngüsü etkinlikleri için işleyicileri kaydedin.

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

Herhangi bir faaliyet türünü yönetin

Herhangi bir etkinliği tür dizisiyle eşleştirerek yönlendirme üzerinde tam kontrol sağlanır.

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

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

ActivityTypes sabitlerini sabit kodlanmış dizeler yerine kullanın.

Kontrol rotası değerlendirme emri

Sistem, rotaları kayıt sırasında sabit bir değerlendirme sırasına göre sıralar; bu işlem çalışma zamanında gerçekleşmez. Sıralama iki düzeyde yapılır:

  1. Rota türü: Sistem, rotaları türlerine göre gruplar ve her zaman, rütbesine bakılmaksızın, daha yüksek öncelikli türleri daha düşük öncelikli türlerden önce değerlendirir:

    Öncelik Rota türü
    1 (En yüksek) Aracısal çağırma rotaları
    2 Rotaları çağırma (uyarlamalı kart eylemleri, OAuth geri çağırmaları ve zamana duyarlı diğer çağrılar)
    3 Aracı tabanlı rotalar
    4 (en düşük) Diğer tüm rotalar
  2. Rank: Her bir rota türü grubunda, sistem rotaları rank değerine göre sıralar. Daha düşük sayısal değerler önce değerlendirilir.

Bir işleyici kaydı sırasında RouteRank sabitlerini kullanarak rank değerini ayarlayın:

Sabit Değer Anlamı
RouteRank.First 0 Grubundaki diğer tüm rotalardan önce değerlendirilir
RouteRank.Unspecified 32767 Herhangi bir sıra belirtilmediğinde varsayılan olarak değerlendirilir
RouteRank.Last 65535 Grubundaki diğer tüm rotalardan sonra değerlendirilir

Varsayılan olarak, değerlendirme ilk eşleşen rotada durur. Daha belirli bir rotayla eşleşmeyen her şeyi işleyen genel bir geri dönüş için RouteRank.Last kullanın.

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

Tur yaşam döngüsü kancaları

Her turda, rota eşleşmesinden önce veya sonra çalışacak mantığı kaydedin. Bu bağlantılar günlük kaydı, çapraz ilgilendiren sorunlar ve hata işleme için kullanışlıdır.

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

OnBeforeTurn, false döndürdüğünde, tur iptal edilir ve hiçbir rota çalıştırılmaz. OnAfterTurn false dönerse, tur durumu kaydedilmez.

Tur durumunu kullanın

Aracı, işleyicileriniz çalışmadan önce tur durumunu otomatik olarak yükler ve daha sonra kaydeder. İşleyicilerinize geçirilen tur durumu nesnesi, farklı kapsamlara erişmenizi sağlar; böylece sırayla kalıcı olan veya geçerli tur için kısa ömürlü olan verileri okuyup yazabilirsiniz:

  • Konuşma kapsamı: Bir konuşmadaki tüm turlarda paylaşılan veriler için
  • Kullanıcı kapsamı: Kullanıcıya özel veri için
  • Geçici kapsam: Yalnızca mevcut turda var olması gereken veriler için
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);
});

Not

Yerel geliştirme ve test için MemoryStorage kullanın. Özellikle birden fazla instance üzerinde çalışan üretim dağıtımlarında, Azure Cosmos DB veya Azure Blob Depolama gibi kalıcı bir depolama sağlayıcısı kullanın. Bkz. Aracınızda depolama sağlayıcıları kullanma.

Sonraki adımlar