Notatka
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
AgentApplication jest centralnym modułem konstrukcyjnym agenta zbudowanego przy użyciu Agents SDK.
AgentApplication to punkt wejścia dla wszystkich działań przychodzących, w tym wiadomości od użytkowników, zdarzeń cyklu życia konwersacji, interakcji z kartami adaptacyjnymi i wywołań zwrotnych protokołu OAuth.
Agent jest w swojej istocie elementem typu AgentApplication. Konfigurujesz go za pomocą programów obsługujących, które opisują, co robi agent. SDK zajmuje się routingiem, zarządzaniem stanem oraz infrastrukturą niezbędną do uruchomienia agenta.
Jak działa AgentApplication
Każdy agent ma cykl życia, który rozpoczyna się, gdy kanał (Microsoft Teams, Bot Service lub niestandardowy klient) dostarcza aktywność do punktu końcowego agenta.
AgentApplication znajduje się w centrum tego cyklu życia:
Channel → Hosting layer → AgentApplication → Your handlers
Warstwy przetwarzania w agencie zbudowanym za pomocą Agents SDK działają następująco:
- Warstwa hostingowa odbiera żądanie HTTP i uwierzytelnia je.
- Element
AgentApplicationprzetwarza przychodzące działanie za pośrednictwem swojego potoku. - Procedury obsługi są wywoływane na podstawie pasujących tras.
Agent ładuje stan tury przed uruchomieniem procedur obsługi. Następnie agent zapisuje stan tury.
Podstawowe pojęcia
Działania
Wszystkie elementy w zestawach SDK agentów przepływają jako działanie. Aktywność to uporządkowana wiadomość reprezentująca coś, co się wydarzyło. Aktywność ma typ, taki jak wiadomość, zdarzenie, wywołanie, conversationUpdate itd. Zawiera ładunek odpowiedni dla tego typu.
AgentApplication odbiera aktywności i kieruje je do właściwej procedury obsługi.
Trasy
Trasa łączy selektor z procedurą obsługi. Selektor określa, czy trasa pasuje do aktualnej aktywności. Procedura obsługi uruchamia logikę, gdy trasa jest zgodna.
Rejestruj trasy podczas konfiguracji agenta. Mogą one być zgodne:
- Wiadomość zawierająca konkretny tekst lub pasująca do wyrażenia regularnego
- Dowolna aktywność danego typu
- Zdarzenia cyklu życia rozmowy (dodanie członka, usunięcie członka)
- Działania związane z kartami adaptacyjnymi
- Warunki niestandardowe
Po nadejściu działania system ocenia trasy w kolejności do momentu znalezienia dopasowania. Domyślnie uruchomiona jest tylko jedna trasa.
Stan tury
AgentApplication zarządza stanem elementu _turn — magazyn strukturalny podzielony na partycje na podstawie zakresów:
| Typ zakresu | Podpis |
|---|---|
| Konwersacja | Współdzielone przez wszystkich użytkowników rozmowy, przechowywane między turami |
| Użytkownika | Przypisane do zakresu obejmującego pojedynczego użytkownika we wszystkich konwersacjach |
| Tymczasowe | Tylko bieżąca kolejka — nigdy nieutrwalana |
System automatycznie ładuje stan przed uruchomieniem procedur obsługi i zapisuje go automatycznie później.
Kontekst tury
Po uruchomieniu procedury obsługi otrzymuje kontekst sesji. Kontekst tury jest migawką bieżącego działania, połączenia z adapterem oraz narzędzi do wysyłania odpowiedzi. Kontekst tury to twój interfejs do bieżącej interakcji.
Oprogramowanie pośredniczące
AgentApplication obsługuje potok oprogramowania pośredniczącego. Oprogramowanie pośredniczące to łańcuch składników, które przetwarzają każdą turę przed i po uruchomieniu procedur obsługi. Oprogramowanie pośredniczące może analizować, transformować lub przerywać przepływ aktywności. Do typowych zastosowań należą logowanie, kontrola uwierzytelniania oraz normalizacja żądań.
Utwórz agenta
Rozszerz klasę AgentApplication i zarejestruj programy obsługujące w konstruktorze. Struktura hostingowa automatycznie wstrzykuje 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);
}
}
Zarejestruj agenta w 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();
Rejestrowanie procedur obsługi działań
Obsługa wiadomości
Dopasuj wiadomości po dokładnym tekście (niezależnie od wielkości liter):
OnMessage("help", async (context, state, ct) =>
{
await context.SendActivityAsync("Here's what I can do...", cancellationToken: ct);
});
Dopasuj wiadomości za pomocą wyrażenia regularnego:
OnMessage(new Regex(@"^order\s+\d+$", RegexOptions.IgnoreCase), async (context, state, ct) =>
{
await context.SendActivityAsync("Looking up your order...", cancellationToken: ct);
});
Obsługa aktualizacji rozmów
Zarejestruj procedury obsługi dla zdarzeń cyklu życia konwersacji, takich jak dołączanie członków lub opuszczanie przez członków.
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
});
Obsługa dowolnego typu aktywności
Dopasowywanie dowolnej aktywności według jej ciągu znaków typu dla pełnej kontroli nad routingiem.
OnActivity(ActivityTypes.Message, async (context, state, ct) =>
{
// Handles all message activities
});
OnActivity(ActivityTypes.Event, async (context, state, ct) =>
{
// Handles event activities
});
Używaj ActivityTypes stałych zamiast zakodowanych na stałe ciągów znaków.
Kontroluj kolejność oceny tras
System ustala ustaloną kolejność oceny tras podczas ich rejestracji, a nie w czasie działania programu. Sortowanie wykorzystuje dwa poziomy:
Typ trasy: System grupuje trasy według typu i zawsze rozpatruje typy o wyższym priorytecie przed typami o niższym priorytecie, niezależnie od rangi:
Priorytet Typ trasy 1 (najwyższy) Trasy wywołania agentów 2 Trasy wywoływania (akcje kart adaptacyjnych, wywołania zwrotne protokołu OAuth i inne wywołania zależne od czasu) 3 Trasy agentów 4 (najniższy) Wszystkie inne trasy Rank: W każdej grupie typu trasy system porządkuje trasy według wartości ich rangi. Najpierw oceniane są niższe wartości liczbowe.
Użyj RouteRank stałych do ustawiania rangi przy rejestracji procedury obsługi:
| Stała | Value | Znaczenie |
|---|---|---|
RouteRank.First |
0 |
Oceniane przed wszystkimi innymi trasami w swojej grupie |
RouteRank.Unspecified |
32767 |
Domyślnie, gdy ranga nie jest określona |
RouteRank.Last |
65535 |
Oceniane po wszystkich innych trasach w swojej grupie |
Domyślnie przetwarzanie zatrzymuje się na pierwszej pasującej trasie. Użyj RouteRank.Last jako ogólnego mechanizmu rezerwowego, który obsługuje wszystko, co nie pasuje do bardziej szczegółowej trasy.
// 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);
Elementy zaczepienia cyklu życia tury
Zarejestruj logikę, która działa przy każdej turze, przed lub po dopasowaniu tras. Te elementy zaczepienia są przydatne w przypadku rejestrowania, zagadnień przekrojowych i obsługi błędów.
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);
});
Gdy OnBeforeTurn zwraca wartość false, tura jest przerywana i nie są uruchamiane żadne trasy. Gdy OnAfterTurn zwraca false, stan tury nie jest zapisywany.
Korzystanie ze stanu tury
Agent automatycznie ładuje stan tury przed uruchomieniem procedur obsługi i zapisuje go później. Obiekt stanu tury przekazany do procedur obsługi zapewnia dostęp do różnych zakresów, dzięki czemu można odczytywać i zapisywać dane, które są utrwalane między turami lub są tymczasowe dla bieżącej tury.
- Zakres rozmowy: Dla danych współdzielonych na wszystkich turach rozmowy
- Zakres użytkownika: Dla danych indywidualnych użytkownika
- Zakres tymczasowy: dla danych, które muszą istnieć tylko podczas bieżącej tury
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);
});
Notatka
Użyj MemoryStorage do lokalnego tworzenia i testowania. W przypadku wdrożeń produkcyjnych, zwłaszcza wdrożeń działających na wielu wystąpieniach, należy użyć dostawcy trwałej pamięci masowej, takiego jak Azure Cosmos DB lub Azure Blob Storage. Zobacz Używanie dostawców magazynu w agencie.