הערה
הגישה לדף זה מחייבת הרשאה. באפשרותך לנסות להיכנס או לשנות מדריכי כתובות.
הגישה לדף זה מחייבת הרשאה. באפשרותך לנסות לשנות מדריכי כתובות.
AgentApplication הוא אבן הבניין המרכזית של סוכן שנבנה באמצעות Agents SDK.
AgentApplication היא נקודת הכניסה לכל הפעילות הנכנסת, כולל הודעות ממשתמשים, אירועי מחזור חיים של שיחה, אינטראקציות אדפטיביות עם כרטיסים, וקריאות חוזרות של OAuth.
סוכן הוא, ביסודו, AgentApplication. אתה מגדיר אותו עם מטפלים שמתארים את מה שהסוכן שלך עושה. ה-SDK מטפל בניתוב, ניהול מצבים ותשתית הנדרשת להפעלתו.
כיצד פועלת AgentApplication
לכל סוכן יש מחזור חיים שמתחיל כאשר ערוץ (Microsoft Teams, שירות בוט או לקוח מותאם אישית) מספק פעילות לנקודת הקצה של הסוכן שלך.
AgentApplication יושב במרכז מחזור החיים הזה:
Channel → Hosting layer → AgentApplication → Your handlers
שכבות העיבוד בסוכן שנבנה באמצעות Agents SDK פועלות באופן הבא:
- שכבת האירוח מקבלת את בקשת ה-HTTP ומאמתת אותה.
- ה
AgentApplicationמעבד את הפעילות הנכנסת דרך הצינור שלה. - המטפלים שלכם נקראים על סמך נתיבים תואמים.
הסוכן שלך טוען את מצב התור לפני שהמטפלים שלך רצים. לאחר מכן, הסוכן שומר את מצב התור.
מושגי ליבה
פעילויות
כל דבר ב-Agents SDK זורם כ- פְּעִילוּת. פעילות היא מסר מובנה המייצג משהו שקרה. לפעילות יש סוג, כגון הודעה, אירוע, קריאה, עדכון שיחה וכן הלאה. הוא נושא מטען הרלוונטי לסוג זה.
AgentApplication מקבל פעילויות ומנתב אותן למטפל הנכון.
מסלולים
נתיב מצמיד בורר למטפל. הבורר קובע אם מסלול תואם לפעילות הנוכחית. המטפל מפעיל את הלוגיקה שלך כאשר המסלול תואם.
רשום נתיבים בעת הגדרת הסוכן שלך. הם יכולים להתאים:
- הודעה המכילה טקסט ספציפי או תואמת לביטוי רגולרי
- כל פעילות מסוג נתון
- אירועי מחזור חיים של שיחה (הוספת חבר, הסרת חבר)
- פעולות כרטיסים אדפטיביות
- תנאים בהתאמה אישית
כאשר מגיעה פעילות, המערכת מעריכה מסלולים לפי הסדר עד שהיא מוצאת התאמה. כברירת מחדל, רק מסלול אחד פועל.
מצב פנייה
AgentApplication מנהלת את מצב _turn - אחסון מובנה המחולק לטווחים:
| סוג טווח | Description |
|---|---|
| שיחה | משותף בין כל המשתמשים בשיחה, נשמר בין תורות |
| משתמש | מוגדר למשתמש בודד בכל השיחות |
| זמני | הפנייה הנוכחית בלבד - לא נשמרת לעולם |
המערכת טוענת אוטומטית את המצב לפני שהמטפלים שלך רצים ושומרת אותו אוטומטית לאחר מכן.
הקשר פנייה
כאשר מטפל פועל, הוא מקבל הקשר פנייה. הקשר פנייה הוא תמונת מצב של הפעילות הנוכחית, חיבור המתאם וכלי שירות לשליחת תגובות. הקשר הפנייה הוא הממשק שלכם לאינטראקציה הנוכחית.
תוכנות ביניים
AgentApplication תומך ב- צינור תוכנות ביניים. תווך (Biddleware) הוא שרשרת של רכיבים שמעבדים כל תור לפני ואחרי שהמטפלים שלך רצים. תוכנת ביניים יכולה לבדוק, לשנות או לקצר את זרימת הפעילות. שימושים נפוצים כוללים רישום, בדיקות אימות ונורמליזציה של בקשות.
יצירת סוכן
תת-מחלקה AgentApplication ורשום את המטפלים שלך בבנאי. מסגרת האירוח מזריקה אוטומטית 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);
}
}
רשום את הסוכן שלך ב 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();
מטפלי פעילות רישום
טיפול בהודעות
התאמת הודעות לפי טקסט מדויק (לא תלוי אותיות גדולות/קטנות):
OnMessage("help", async (context, state, ct) =>
{
await context.SendActivityAsync("Here's what I can do...", cancellationToken: ct);
});
התאמת הודעות באמצעות ביטוי רגולרי:
OnMessage(new Regex(@"^order\s+\d+$", RegexOptions.IgnoreCase), async (context, state, ct) =>
{
await context.SendActivityAsync("Looking up your order...", cancellationToken: ct);
});
טיפול בעדכוני שיחה
רישום מטפלים עבור אירועי מחזור חיים של שיחה כגון הצטרפות או עזיבה של חברים.
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
});
להתמודד עם כל סוג פעילות
התאם כל פעילות לפי מחרוזת הסוג שלה לקבלת שליטה מלאה על הניתוב.
OnActivity(ActivityTypes.Message, async (context, state, ct) =>
{
// Handles all message activities
});
OnActivity(ActivityTypes.Event, async (context, state, ct) =>
{
// Handles event activities
});
לְהִשְׁתַמֵשׁ ActivityTypes קבועים במקום מחרוזות מקודדות קשיח.
צו הערכת נתיב בקרה
המערכת ממיינת נתיבים לסדר הערכה קבוע בעת רישוםם, ולא בזמן ריצה. המיון משתמש בשתי רמות:
סוג המסלול: המערכת מקבצת נתיבים לפי סוג, והיא תמיד מעריכה סוגים בעלי עדיפות גבוהה יותר לפני סוגים בעלי עדיפות נמוכה יותר, ללא קשר לדירוג:
עדיפות סוג נתיב 1 (הגבוה ביותר) נתיבי קריאה של סוכן 2 נתיבי קריאה (פעולות כרטיסים מסתגלים, קריאות חוזרות של OAuth וקריאות קריאה רגישות זמן אחרות) 3 נתיבי סוכן 4 (הנמוך ביותר) כל שאר המסלולים דַרגָה: בתוך כל קבוצת סוגי מסלולים, המערכת מסדרת מסלולים לפי ערך הדירוג שלהם. ערכים מספריים נמוכים יותר מוערכים תחילה.
לְהִשְׁתַמֵשׁ RouteRank קבועים לקביעת דרגה בעת רישום מטפל:
| קבוע | ערך | משמעות |
|---|---|---|
RouteRank.First |
0 |
הוערך לפני כל המסלולים האחרים בקבוצה שלו |
RouteRank.Unspecified |
32767 |
ברירת מחדל כאשר לא צוין דרגה |
RouteRank.Last |
65535 |
מוערכים לאחר כל הנתיבים האחרים בקבוצה שלהם |
כברירת מחדל, ההערכה נעצרת בנתיב התואם הראשון. לְהִשְׁתַמֵשׁ RouteRank.Last עבור פתרון כולל שמטפל בכל דבר שלא תואם על ידי נתיב ספציפי יותר.
// 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);
נקודות חיבור של מחזור חיי פנייה
לוגיקת רישום שפועלת בכל סיבוב, לפני או אחרי התאמת מסלול. נקודות חיבור אלה שימושיות לרישום ביומן, לטיפול בהיבטים רוחביים ולטיפול בשגיאות.
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, הפנייה מבוטלת ולא מופעלים נתיבים. כאשר OnAfterTurn החזרות false, מצב התור לא נשמר.
השתמש במצב סיבוב
הסוכן טוען אוטומטית את מצב התור לפני שהמטפלים שלך רצים ושומר אותו לאחר מכן. אובייקט מצב התור המועבר למטפלים שלך נותן לך גישה להיקפים השונים, כך שתוכל לקרוא ולכתוב נתונים שנשארים לאורך התורים או שהם זמניים לתור הנוכחי:
- היקף השיחה: עבור נתונים המשותפים בכל התורים בשיחה
- טווח המשתמש: עבור נתונים לפי משתמש
- טווח זמני: עבור נתונים שצריכים להתקיים רק במהלך התור הנוכחי
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);
});
הערה
לְהִשְׁתַמֵשׁ MemoryStorage לפיתוח ובדיקות מקומיות. עבור פריסות ייצור, במיוחד פריסות הפועלות על מספר מופעים, השתמש בספק אחסון קבוע כגון Azure Cosmos DB או Azure Blob Storage. לִרְאוֹת השתמשו בספקי אחסון בסוכן שלכם.