البرنامج التعليمي: إضافة Personalizer إلى تطبيق ويب ‎.NET

هام

اعتبارا من 20 سبتمبر 2023، لن تتمكن من إنشاء موارد Personalizer جديدة. يتم إيقاف خدمة Personalizer في 1 أكتوبر 2026.

تخصيص تطبيق ويب C# .NET مع حلقة Personalizer لتوفير المحتوى الصحيح للمستخدم استنادًا إلى الإجراءات (مع الميزات) والميزات السياقية.

في هذا البرنامج التعليمي، ستتعلم كيفية:

  • إعداد مفتاح Personalizer ونقطة النهاية
  • جمع الميزات
  • استدعاء واجهات برمجة التطبيقات للرتب والمكافآت
  • عرض الإجراء العلوي، المعين ك rewardActionId

تحديد أفضل محتوى لتطبيق ويب

يجب أن يستخدم تطبيق الويب Personalizer عندما تكون هناك قائمة بالإجراءات (نوع من المحتوى) على صفحة الويب التي تحتاج إلى تخصيص عنصر علوي واحد (rewardActionId) لعرضها. تتضمن أمثلة قوائم الإجراءات مقالات إخبارية، ومواقع موضع الزر، واختيارات الكلمات لأسماء المنتجات.

ترسل قائمة الإجراءات، جنبًا إلى جنب مع الميزات السياقية، إلى حلقة Personalizer. يحدد Personalizer أفضل إجراء بعينه، ثم يعرض تطبيق الويب هذا الإجراء.

في هذا البرنامج التعليمي، تُمثل الإجراءات بأنواع من المواد الغذائية:

  • معكرونة
  • أيس كريم
  • عصير
  • سلطة
  • فشار
  • قهوة
  • حساء

لمساعدة Personalizer على التعرف على إجراءاتك، أرسل كلا من الإجراءات مع الميزات وميزات السياق مع كل طلب Rank API.

ميزة النموذج هي معلومات حول الإجراء أو السياق الذي يمكن تجميعه (تجميعه) عبر أعضاء قاعدة مستخدمي تطبيق الويب. الميزة ليست محددة بشكل فردي (مثل معرف المستخدم) أو محددة بدرجة كبيرة (مثل الوقت المحدد من اليوم).

الإجراءات ذات الميزات

لكل إجراء (عنصر محتوى) ميزات للمساعدة في تمييز العنصر الغذائي.

لم يتم تكوين الميزات كجزء من تكوين الحلقة في مدخل Azure. بدلاً من ذلك، يتم إرسالها ككائن JSON مع كل استدعاء لواجهة برمجة تطبيقات الرتبة. وهذا يسمح بالمرونة للإجراءات ولمميزاتها بالنمو والتغيير والتقلص بمرور الوقت، مما يسمح لـ Personalizer بمتابعة الاتجاهات.

 /// <summary>
  /// Creates personalizer actions feature list.
  /// </summary>
  /// <returns>List of actions for personalizer.</returns>
  private IList<RankableAction> GetActions()
  {
      IList<RankableAction> actions = new List<RankableAction>
      {
          new RankableAction
          {
              Id = "pasta",
              Features =
              new List<object>() { new { taste = "savory", spiceLevel = "medium" }, new { nutritionLevel = 5, cuisine = "italian" } }
          },

          new RankableAction
          {
              Id = "ice cream",
              Features =
              new List<object>() { new { taste = "sweet", spiceLevel = "none" }, new { nutritionalLevel = 2 } }
          },

          new RankableAction
          {
              Id = "juice",
              Features =
              new List<object>() { new { taste = "sweet", spiceLevel = "none" }, new { nutritionLevel = 5 }, new { drink = true } }
          },

          new RankableAction
          {
              Id = "salad",
              Features =
              new List<object>() { new { taste = "sour", spiceLevel = "low" }, new { nutritionLevel = 8 } }
          },

          new RankableAction
          {
              Id = "popcorn",
              Features =
              new List<object>() { new { taste = "salty", spiceLevel = "none" }, new { nutritionLevel = 3 } }
          },

          new RankableAction
          {
              Id = "coffee",
              Features =
              new List<object>() { new { taste = "bitter", spiceLevel = "none" }, new { nutritionLevel = 3 }, new { drink = true } }
          },

          new RankableAction
          {
              Id = "soup",
              Features =
              new List<object>() { new { taste = "sour", spiceLevel = "high" }, new { nutritionLevel =  7} }
          }
      };

      return actions;
  }

الميزات الخاصة بالسياق

تساعد الميزات السياقية Personalizer على فهم سياق الإجراءات. يتضمن سياق نموذج التطبيق هذا ما يلي:

  • الوقت من اليوم - الصباح، بعد الظهر، المساء، الليل
  • تفضيل المستخدم للذوق - مالح، حلو، مرير، حامض، أو لذيذ
  • سياق المستعرض - عميل المستخدم، والموقع الجغرافي، وجهة الإحالة
/// <summary>
/// Get users time of the day context.
/// </summary>
/// <returns>Time of day feature selected by the user.</returns>
private string GetUsersTimeOfDay()
{
    Random rnd = new Random();
    string[] timeOfDayFeatures = new string[] { "morning", "noon", "afternoon", "evening", "night", "midnight" };
    int timeIndex = rnd.Next(timeOfDayFeatures.Length);
    return timeOfDayFeatures[timeIndex];
}

/// <summary>
/// Gets user food preference.
/// </summary>
/// <returns>Food taste feature selected by the user.</returns>
private string GetUsersTastePreference()
{
    Random rnd = new Random();
    string[] tasteFeatures = new string[] { "salty", "bitter", "sour", "savory", "sweet" };
    int tasteIndex = rnd.Next(tasteFeatures.Length);
    return tasteFeatures[tasteIndex];
}

كيف يستخدم تطبيق الويب Personalizer؟

يستخدم تطبيق الويب Personalizer لتحديد أفضل إجراء من قائمة خيارات الطعام. وهو ينفذ ذلك عن طريق إرسال المعلومات التالية مع كل استدعاء لواجهة برمجة تطبيقات الرتبة:

  • الإجراءات مع ميزاتها مثل taste و spiceLevel
  • ميزات السياق مثل time اليوم وتفضيلات المستخدم taste ومعلومات وكيل مستخدم المستعرض وميزات السياق
  • إجراءات لاستبعاد مثل عصير
  • معرف الحدث، الذي يختلف لكل استدعاء إلى Rank API.

ميزات نموذج Personalizer في تطبيق ويب

يحتاج Personalizer إلى ميزات للإجراءات (المحتوى) والسياق الحالي (المستخدم والبيئة). يتم استخدام الميزات لمحاذاة الإجراءات إلى السياق الحالي في النموذج. يُعد النموذج تمثيلاً لمعرفة Personalizer الماضية حول الإجراءات، والسياق، وميزاتها التي تسمح لها باتخاذ قرارات مستنيرة.

يتم تحديث النموذج، بما في ذلك الميزات، على جدول استناداً إلى إعداد Model update frequency في مدخل Microsoft Azure.

تنبيه

تهدف الميزات في هذا التطبيق إلى توضيح الميزات، وقيم الميزات؛ ولكن ليس بالضرورة إلى أفضل الميزات لاستخدامها في تطبيق ويب.

التخطيط للميزات وقيمها

يجب تحديد الميزات بنفس التخطيط والتصميم الذي تطبقه على أي مخطط أو نموذج في البنية التقنية لديك. يمكن تعيين قيم الميزة باستخدام منطق العمل أو أنظمة الجهات الخارجية. يجب ألا تكون قيم الميزات محددة بشكل كبير بحيث لا تنطبق عبر مجموعة أو فئة من الميزات.

تعميم قيم الميزات

التعميم إلى فئات

يستخدم time هذا التطبيق كميزة ولكنه يجمع الوقت في فئات مثل morningو afternooneveningو وnight. هذا مثال على استخدام معلومات الوقت ولكن ليس بطريقة محددة للغاية، مثل 10:05:01 UTC+2.

التعميم إلى أجزاء

يستخدم هذا التطبيق ميزات طلب HTTP من المستعرض. يبدأ هذا بسلسلة محددة جدًا تحمل جميع البيانات، على سبيل المثال:

Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/530.99 (KHTML, like Gecko) Chrome/80.0.3900.140 Safari/537.36

تعمم مكتبة فئات HttpRequestFeatures هذه السلسلة في كائن userAgentInfo بقيم فردية. يتم تعيين أي قيم محددة أكثر من اللازم إلى سلسلة فارغة. عند إرسال الميزات السياقية للطلب، يكون تنسيق JSON التالي:

{
  "httpRequestFeatures": {
    "_synthetic": false,
    "OUserAgent": {
      "_ua": "",
      "_DeviceBrand": "",
      "_DeviceFamily": "Other",
      "_DeviceIsSpider": false,
      "_DeviceModel": "",
      "_OSFamily": "Windows",
      "_OSMajor": "10",
      "DeviceType": "Desktop"
    }
  }
}

استخدام نموذج تطبيق ويب

يحتاج تطبيق الويب المستند إلى المستعرض (يتم توفير جميع التعليمات البرمجية) إلى التطبيقات التالية المثبتة لتشغيل التطبيق.

قم بتثبيت البرمجية التالية:

  • .NET Core 2.1 - يستخدم نموذج الخادم الخلفي .NET core
  • Node.js - يعتمد العميل/الواجهة الأمامية على هذا التطبيق
  • Visual Studio 2019 أو .NET Core CLI - استخدم إما بيئة المطور ل Visual Studio 2019 أو .NET Core CLI لإنشاء التطبيق وتشغيله

إعداد النموذج

  1. استنساخ مستودع نماذج Azure الذكاء الاصطناعي Personalizer.

    git clone https://github.com/Azure-Samples/cognitive-services-personalizer-samples.git
    
  2. انتقل إلى samples/HttpRequestFeatures لفتح الحل، HttpRequestFeaturesExample.sln.

    إذا طُلب منك ذلك، فاسمح لـ Visual Studio بتحديث حزمة ‎.NET لـ Personalizer.

إعداد خدمة Azure الذكاء الاصطناعي Personalizer

  1. إنشاء مورد Personalizer في مدخل Microsoft Azure.

  2. في مدخل Microsoft Azure، ابحث عن Endpoint و أو Key1 Key2 (إما ستعمل) في علامة التبويب Keys and Endpoints. هذه هي الخاص بك PersonalizerServiceEndpoint و.PersonalizerApiKey

  3. PersonalizerServiceEndpoint املأ في appsettings.json.

  4. تكوين PersonalizerApiKey كبيانات سرية للتطبيق بإحدى الطرق التالية:

    • إذا كنت تستخدم .NET Core CLI، يمكنك استخدام dotnet user-secrets set "PersonalizerApiKey" "<API Key>" الأمر .
    • إذا كنت تستخدم Visual Studio، يمكنك النقر بزر الماوس الأيمن فوق المشروع وتحديد خيار القائمة إدارة أسرار المستخدم لتكوين مفاتيح Personalizer. من خلال القيام بذلك، سيفتح Visual Studio ملفا secrets.json حيث يمكنك إضافة المفاتيح كما يلي:
    {
      "PersonalizerApiKey": "<your personalizer key here>",
    }
    

تشغيل تطبيق العرض التوضيحي

يمكنك إنشاء HttpRequestFeaturesExample وتشغيله بإحدى الطرق التالية:

  • Visual Studio 2019: اضغط على F5
  • .NET Core CLI: dotnet build ثم dotnet run

من خلال مستعرض ويب، يمكنك إرسال طلب رتبة وطلب مكافأة ورؤية استجاباتهما، بالإضافة إلى ميزات طلب http المستخرجة من بيئتك.

Screenshot shows an example of the Http Request Feature in a web browser.

شرح حلقة Personalizer

  1. حدد الزر Generate new Rank Request لإنشاء كائن JSON جديد لاستدعاء Rank API. يؤدي ذلك إلى إنشاء الإجراءات (ذات الميزات) والميزات السياقية، ويعرض القيم حتى تتمكن من رؤية مظهر JSON.

    لتطبيقك المستقبلي، قد يحدث إنشاء الإجراءات والميزات على العميل، أو على الخادم، أو مزيج من الاثنين، أو مع الاستدعاءات إلى خدمات أخرى.

  2. حدد Send Rank Request لإرسال كائن JSON إلى الخادم. يستدعي الخادم واجهة برمجة تطبيقات الرتبة لـ Personalizer. يتلقى الخادم الاستجابة، ويُرجع الإجراء ذا الرتبة الأعلى إلى العميل للعرض.

  3. قم بتعيين قيمة المكافأة، ثم حدد الزر إرسال طلب مكافأة. إذا لم تقم بتغيير قيمة المكافأة، يرسل تطبيق العميل دائما قيمة 1 إلى Personalizer.

    Screenshot shows the Reward Request section.

    لتطبيقك المستقبلي، قد يحدث إنشاء نقاط المكافآت بعد جمع المعلومات من سلوك المستخدم على العميل، جنبًا إلى جنب مع منطق العمل على الخادم.

فهم نموذج تطبيق الويب

يحتوي نموذج تطبيق الويب على خادم C# .NET ، والذي يدير مجموعة الميزات وإرسال واستقبال مكالمات HTTP إلى نقطة نهاية Personalizer.

يستخدم نموذج تطبيق الويب تطبيق عميل الواجهة الأمامية لالتقاط الميزات ومعالجة إجراءات واجهة المستخدم مثل النقر على الأزرار وإرسال البيانات إلى خادم .NET.

تشرح المقاطع التالية أجزاء الخادم والعميل التي يحتاج المطور إلى فهمها لاستخدام Personalizer.

واجهة برمجة تطبيقات الرتبة: يرسل تطبيق العميل السياق إلى الخادم

يجمع تطبيق العميل عامل مستخدم المتصفح الخاص بالمستخدم.

Build and run the HTTPRequestFeaturesExample project. A browser window opens to display the single page application.

واجهة برمجة تطبيقات الرتبة: يستدعي تطبيق الخادم Personalizer

يُعد تطبيق ‎.NET نموذجيًا على شبكة الإنترنت مع تطبيق عميل، ويتوفر الكثير من تعليمات النموذج المتداول البرمجية لك. تتم إزالة أي رمز غير خاص بـ Personalizer من أجزاء التعليمات البرمجية التالية؛ لتتمكن من التركيز على التعليمات البرمجية الخاصة بـ Personalizer.

إنشاء عميل Personalizer

في Startup.cs للخادم، يتم استخدام نقطة نهاية Personalizer والمفتاح لإنشاء عميل Personalizer. لا يحتاج تطبيق العميل إلى التواصل مع Personalizer في هذا التطبيق، بدلاً من الاعتماد على الخادم لإجراء استدعاءات SDK هذه.

رمز بدء تشغيل خادم الويب ‎.NET هو:

using Microsoft.Azure.CognitiveServices.Personalizer;
// ... other using statements removed for brevity

namespace HttpRequestFeaturesExample
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            string personalizerApiKey = Configuration.GetSection("PersonalizerApiKey").Value;
            string personalizerEndpoint = Configuration.GetSection("PersonalizerConfiguration:ServiceEndpoint").Value;
            if (string.IsNullOrEmpty(personalizerEndpoint) || string.IsNullOrEmpty(personalizerApiKey))
            {
                throw new ArgumentException("Missing Azure AI Personalizer endpoint and/or api key.");
            }
            services.AddSingleton(client =>
            {
                return new PersonalizerClient(new ApiKeyServiceClientCredentials(personalizerApiKey))
                {
                    Endpoint = personalizerEndpoint
                };
            });

            services.AddMvc();
        }

        // ... code removed for brevity
    }
}

تحديد أفضل إجراء

في PersonalizerController.cs للخادم، تلخص واجهة برمجة تطبيقات خادم GenerateRank الإعداد لاستدعاء واجهة برمجة تطبيقات Rank

  • إنشاء جديد eventId لاستدعاء Rank
  • الحصول على قائمة الإجراءات
  • الحصول على قائمة الميزات من المستخدم وإنشاء الميزات السياقية
  • اختياريًا، قم بتعيين أي إجراءات مستبعدة
  • استدعاء واجهة برمجة تطبيقات الرتبة، وإرجاع النتائج إلى العميل
/// <summary>
/// Creates a RankRequest with user time of day, HTTP request features,
/// and taste as the context and several different foods as the actions
/// </summary>
/// <returns>RankRequest with user info</returns>
[HttpGet("GenerateRank")]
public RankRequest GenerateRank()
{
    string eventId = Guid.NewGuid().ToString();

    // Get the actions list to choose from personalizer with their features.
    IList<RankableAction> actions = GetActions();

    // Get context information from the user.
    HttpRequestFeatures httpRequestFeatures = GetHttpRequestFeaturesFromRequest(Request);
    string timeOfDayFeature = GetUsersTimeOfDay();
    string tasteFeature = GetUsersTastePreference();

    // Create current context from user specified data.
    IList<object> currentContext = new List<object>() {
            new { time = timeOfDayFeature },
            new { taste = tasteFeature },
            new { httpRequestFeatures }
    };

    // Exclude an action for personalizer ranking. This action will be held at its current position.
    IList<string> excludeActions = new List<string> { "juice" };

    // Rank the actions
    return new RankRequest(actions, currentContext, excludeActions, eventId);
}

يبدو JSON المرسل إلى Personalizer، الذي يحتوي على كل من الإجراءات (ذات ميزات) والميزات السياقية الحالية، كما يلي:

{
    "contextFeatures": [
        {
            "time": "morning"
        },
        {
            "taste": "savory"
        },
        {
            "httpRequestFeatures": {
                "_synthetic": false,
                "MRefer": {
                    "referer": "http://localhost:51840/"
                },
                "OUserAgent": {
                    "_ua": "",
                    "_DeviceBrand": "",
                    "_DeviceFamily": "Other",
                    "_DeviceIsSpider": false,
                    "_DeviceModel": "",
                    "_OSFamily": "Windows",
                    "_OSMajor": "10",
                    "DeviceType": "Desktop"
                }
            }
        }
    ],
    "actions": [
        {
            "id": "pasta",
            "features": [
                {
                    "taste": "savory",
                    "spiceLevel": "medium"
                },
                {
                    "nutritionLevel": 5,
                    "cuisine": "italian"
                }
            ]
        },
        {
            "id": "ice cream",
            "features": [
                {
                    "taste": "sweet",
                    "spiceLevel": "none"
                },
                {
                    "nutritionalLevel": 2
                }
            ]
        },
        {
            "id": "juice",
            "features": [
                {
                    "taste": "sweet",
                    "spiceLevel": "none"
                },
                {
                    "nutritionLevel": 5
                },
                {
                    "drink": true
                }
            ]
        },
        {
            "id": "salad",
            "features": [
                {
                    "taste": "sour",
                    "spiceLevel": "low"
                },
                {
                    "nutritionLevel": 8
                }
            ]
        },
        {
            "id": "popcorn",
            "features": [
                {
                    "taste": "salty",
                    "spiceLevel": "none"
                },
                {
                    "nutritionLevel": 3
                }
            ]
        },
        {
            "id": "coffee",
            "features": [
                {
                    "taste": "bitter",
                    "spiceLevel": "none"
                },
                {
                    "nutritionLevel": 3
                },
                {
                    "drink": true
                }
            ]
        },
        {
            "id": "soup",
            "features": [
                {
                    "taste": "sour",
                    "spiceLevel": "high"
                },
                {
                    "nutritionLevel": 7
                }
            ]
        }
    ],
    "excludedActions": [
        "juice"
    ],
    "eventId": "82ac52da-4077-4c7d-b14e-190530578e75",
    "deferActivation": null
}

إرجاع «rewardActionId» لـ Personalizer إلى العميل

ترجع واجهة برمجة تطبيقات Rank أفضل إجراء محدد rewardActionId إلى الخادم.

عرض الإجراء الذي تم إرجاعه في rewardActionId.

{
    "ranking": [
        {
            "id": "popcorn",
            "probability": 0.833333254
        },
        {
            "id": "salad",
            "probability": 0.03333333
        },
        {
            "id": "juice",
            "probability": 0
        },
        {
            "id": "soup",
            "probability": 0.03333333
        },
        {
            "id": "coffee",
            "probability": 0.03333333
        },
        {
            "id": "pasta",
            "probability": 0.03333333
        },
        {
            "id": "ice cream",
            "probability": 0.03333333
        }
    ],
    "eventId": "82ac52da-4077-4c7d-b14e-190530578e75",
    "rewardActionId": "popcorn"
}

يعرض العميل إجراء «rewardActionId»

في هذا البرنامج التعليمي، rewardActionId يتم عرض القيمة.

في تطبيقك المستقبلي الخاص، قد يكون ذلك بعض النص الدقيق، أو زرًا، أو قسمًا من صفحة الويب المميزة. يتم إرجاع القائمة لأي تحليل إضافي للدرجات، وليس لطلب المحتوى. rewardActionId يجب عرض المحتوى فقط.

واجهة برمجة تطبيقات المكافأة: جمع المعلومات للمكافأة

يجب التخطيط بعناية لدرجة المكافأة، تماما كما هو مخطط للميزات. يجب أن تكون نقاط المكافأة عادةً قيمة تبدأ من 0 إلى 1. يمكن حساب القيمة جزئيا في تطبيق العميل، استنادا إلى سلوكيات المستخدم، وجزئيا على الخادم، استنادا إلى منطق العمل والأهداف.

إذا لم يستدعي الخادم واجهة برمجة تطبيقات المكافأة ضمن وقت انتظار المكافأة الذي تم تكوينه في مدخل Microsoft Azure لمورد Personalizer الخاص بك، فسيتم استخدام المكافأة الافتراضية (التي تم تكوينها أيضا في مدخل Microsoft Azure) لهذا الحدث.

في نموذج التطبيق هذا، يمكنك تحديد قيمة لمعرفة كيفية تأثير المكافأة على التحديدات.

طرق إضافية للتعلم من هذا النموذج

يستخدم النموذج عدة أحداث تستند إلى الوقت، تم تكوينها في مدخل Azure لمورد Personalizer. عدّل هذه القيم ثم ارجع إلى نموذج تطبيق الويب هذا؛ لمعرفة كيفية تأثير التغييرات على استدعاءات الرتبة والمكافأة:

  • وقت انتظار المكافأة
  • تكرار تحديث النموذج

تتضمن الإعدادات الإضافية اللازم تعديلها ما يلي:

  • المكافأة الافتراضية
  • نسبة الاستكشاف

تنظيف الموارد

عند الانتهاء من هذا البرنامج التعليمي، قم بتنظيف الموارد التالية:

  • احذف نموذج دليل المشروع.
  • حذف مورد Personalizer - فكر في مورد Personalizer كأنه مخصص للإجراءات والسياق - لا تُعيد استخدام المورد إلا إذا كنت لا تزال تستخدم الأطعمة كمجال لموضوع الإجراءات.

الخطوات التالية