नोट
इस पेज तक पहुँच के लिए प्रमाणन की आवश्यकता होती है. आप साइन इन करने या निर्देशिकाओं को बदलने का प्रयास कर सकते हैं.
इस पेज तक पहुँच के लिए प्रमाणन की आवश्यकता होती है. आप निर्देशिकाओं को बदलने का प्रयास कर सकते हैं.
AgentApplication Agents SDK से बनाए गए एजेंट का मुख्य बिल्डिंग ब्लॉक है।
AgentApplication सभी आने वाली गतिविधियों के लिए एंट्री पॉइंट है, जिसमें यूज़र्स के मैसेज, बातचीत के लाइफ़साइकल इवेंट, एडेप्टिव कार्ड इंटरैक्शन और OAuth कॉलबैक शामिल हैं।
एक एजेंट, इसके मूल में, एक AgentApplication। आप इसे ऐसे हैंडलर्स के साथ कॉन्फ़िगर करते हैं जो बताते हैं कि आपका एजेंट क्या करता है। SDK रूटिंग, स्टेट मैनेजमेंट और इसे चलाने के लिए ज़रूरी इंफ्रास्ट्रक्चर का ध्यान रखता है।
AgentApplication कैसे काम करता है
हर एजेंट का एक लाइफ़साइकल होता है जो तब शुरू होता है जब कोई चैनल (Microsoft Teams, बॉट सर्विस, या कस्टम क्लाइंट) आपके एजेंट के एंडपॉइंट पर कोई एक्टिविटी भेजता है।
AgentApplication उस लाइफ़साइकल के केंद्र में है:
Channel → Hosting layer → AgentApplication → Your handlers
Agents SDK से बनाए गए एजेंट में प्रोसेसिंग की लेयर्स इस तरह काम करती हैं:
- होस्टिंग लेयर HTTP रिक्वेस्ट को रिसीव करती है और उसे ऑथेंटिकेट करती है।
-
AgentApplicationअपनी पाइपलाइन के ज़रिए आने वाली गतिविधि को प्रोसेस करता है। - आपके हैंडलर्स को मैचिंग रूट्स के आधार पर बुलाया जाता है।
आपके हैंडलर के चलने से पहले आपका एजेंट लोड स्थिति बदल जाता है। इसके बाद, एजेंट टर्न की स्थिति को सेव करता है।
मुख्य अवधारणाएँ
गतिविधियाँ
एजेंट्स SDK में सब कुछ एक गतिविधि के तौर पर चलता है। एक्टिविटी एक व्यवस्थित संदेश है जो किसी हुई घटना को दर्शाता है। किसी एक्टिविटी का एक प्रकार होता है, जैसे कि मैसेज, इवेंट, इनवोक, conversationUpdate, वगैरह। इसमें उस प्रकार के अनुरूप पेलोड होता है।
AgentApplication गतिविधियाँ प्राप्त करता है और उन्हें सही हैंडलर तक पहुँचाता है।
रूट
एक रूट, एक चयनकर्ता को एक हैंडलर के साथ जोड़ता है। सिलेक्टर यह तय करता है कि कोई रूट मौजूदा गतिविधि से मेल खाता है या नहीं। जब रूट मैच करता है, तो हैंडलर आपके लॉजिक को चलाता है।
अपने एजेंट को कॉन्फ़िगर करते समय रूट्स रजिस्टर करें। वे मेल खा सकते हैं:
- एक ऐसा मैसेज जिसमें खास टेक्स्ट हो या जो रेगुलर एक्सप्रेशन से मेल खाता हो
- किसी खास तरह की कोई भी गतिविधि
- बातचीत के लाइफ़साइकल इवेंट (सदस्य जोड़ा गया, सदस्य हटाया गया)
- एडेप्टिव कार्ड के एक्शन
- कस्टम शर्तें
जब कोई गतिविधि आती है, तो सिस्टम तब तक क्रम से रूट का मूल्यांकन करता है जब तक कि उसे कोई मेल न मिल जाए। डिफ़ॉल्ट रूप से, केवल एक ही रूट चलता है।
टर्न स्टेट
AgentApplication _टर्न स्टेट को मैनेज करता है—यह एक स्ट्रक्चर्ड स्टोरेज है जिसे अलग-अलग स्कोप में बांटा गया है:
| स्कोप का प्रकार | विवरण |
|---|---|
| वार्तालाप | वार्तालाप में सभी उपयोगकर्ताओं के बीच साझा किया गया, इंटरैक्शन के बीच में भी स्थायी बना रहा |
| User | सभी बातचीत में किसी एक यूज़र तक सीमित |
| टेम्प | केवल वर्तमान मोड़ - कभी नहीं बना |
यह सिस्टम आपके हैंडलर्स के चलने से पहले अपने-आप स्टेट लोड करता है और बाद में उसे अपने-आप सेव कर लेता है।
संदर्भ बदलें
जब कोई हैंडलर चलता है, तो उसे एक टर्न कॉन्टेक्स्ट मिलता है। टर्न कॉन्टेक्स्ट मौजूदा गतिविधि, एडॉप्टर कनेक्शन और रिस्पॉन्स भेजने के लिए यूटिलिटीज़ का एक स्नैपशॉट है। टर्न कॉन्टेक्स्ट, मौजूदा बातचीत के साथ आपका इंटरफ़ेस है।
मिडलवेयर
AgentApplication एक मिडलवेयर पाइपलाइन को सपोर्ट करता है। मिडलवेयर ऐसे कंपोनेंट्स की एक चेन है जो आपके हैंडलर्स के चलने से पहले और बाद में हर बार प्रोसेस करते हैं। मिडलवेयर एक्टिविटी फ़्लो की जाँच कर सकता है, उसे बदल सकता है या उसे बीच में ही रोक सकता है। इसके आम इस्तेमाल में लॉगिंग, ऑथेंटिकेशन की जाँच और रिक्वेस्ट नॉर्मलाइज़ेशन शामिल हैं।
एक एजेंट बनाएँ
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);
});
जब OnBeforeTurnfalse लौटता है, तो चरण निरस्त हो जाता है और कोई मार्ग नहीं चलता है। जब OnAfterTurnfalse रिटर्न करता है, तो टर्न की स्थिति सेव नहीं होती है।
टर्न स्टेट का इस्तेमाल करें
एजेंट आपके हैंडलर्स के चलने से पहले अपने-आप 'टर्न स्टेट' लोड करता है और बाद में उसे सेव कर लेता है। आपके हैंडलर्स को भेजा गया 'टर्न स्टेट ऑब्जेक्ट' आपको अलग-अलग स्कोप्स का एक्सेस देता है, ताकि आप ऐसा डेटा पढ़ और लिख सकें जो टर्न्स के बीच बना रहता है या जो सिर्फ़ मौजूदा टर्न के लिए ही होता है:
- बातचीत का दायरा: बातचीत के सभी चरणों में शेयर किए गए डेटा के लिए
- यूज़र स्कोप: हर यूज़र के डेटा के लिए
- Temp स्कोप: ऐसे डेटा के लिए जो सिर्फ़ मौजूदा टर्न के दौरान ही मौजूद रहना चाहिए
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 जैसे परसिस्टेंट स्टोरेज प्रोवाइडर का इस्तेमाल करें। देखें अपने एजेंट में स्टोरेज प्रोवाइडर का इस्तेमाल करें।