共用方式為


開始使用適用於 Azure AI 個人化服務工具的本機推斷 SDK

重要

從 2023 年 9 月 20 日起,您將無法建立新的個人化工具資源。 個人化工具服務將於 2026 年 10 月 1 日淘汰。

個人化工具本機推斷 SDK (預覽) 會將個人化工具模型下載至本機以消除網路呼叫,大幅降低 Rank 呼叫的延遲。 用戶端每分鐘都會在背景下載最新的模型,並用於進行推斷。

在本指南中,您將了解如何使用個人化工具本機推斷 SDK。

您必須安裝適用於 .NET 的個人化工具用戶端程式庫,才能:

  • 在 Azure 中使用個人化工具資源驗證快速入門範例用戶端。
  • 將內容和動作功能傳送至獎勵 API,這會從個人化工具模型傳回最佳動作
  • 將獎勵分數傳送至排名 API,並定型個人化工具模型。

參考文件 | 程式庫原始程式碼 | 套件 (NuGet)

必要條件

  • Azure 訂用帳戶 - 建立免費帳戶
  • 最新版 .NET Core
  • 擁有 Azure 訂閱之後,在 Azure 入口網站中建立個人化工具資源,以取得您的金鑰和端點。 在其部署後,選取 [前往資源]
    • 您需要來自所建立資源的金鑰和端點,以將應用程式連線至個人化工具 API。 您稍後會在快速入門中將金鑰和端點貼到下列程式碼中。
    • 您可以使用免費定價層 (F0) 來試用服務,之後可升級至付費層以用於實際執行環境。

設定

變更模型更新頻率

在 Azure 入口網站中,前往個人化服務工具資源的 [設定] 頁面,將 [模型更新頻率] 變更為 30 秒。 這個較短的時間將會快速定型模型,讓您可以查看建議的動作會如何針對每個反覆項目變更。

變更模型更新頻率

變更奬勵等待時間

在 Azure 入口網站中,前往個人化服務工具資源的 [設定] 頁面,將 [奬勵等待時間] 變更為 10 分鐘。 這會決定模型在傳送建議之後等候的時間長度,以接收來自該建議的獎勵意見反應。 直到獎勵等候時間過後,才會進行定型。

變更奬勵等待時間

建立新的 C# 應用程式

在您慣用的編輯器或 IDE 中,建立新的 .NET Core 應用程式。

在主控台視窗中 (例如 cmd、PowerShell 或 Bash),使用 dotnet new 命令建立名為 personalizer-quickstart 的新主控台應用程式。 此命令會建立簡單的 "Hello World" C# 專案,內含單一原始程式檔:Program.cs

dotnet new console -n personalizer-quickstart

將目錄變更為新建立的應用程式資料夾。 您可以使用下列命令來建置應用程式:

dotnet build

建置輸出應該不會有警告或錯誤。

...
Build succeeded.
 0 Warning(s)
 0 Error(s)
...

安裝用戶端程式庫

在應用程式目錄中,使用下列命令安裝適用於 .NET 的個人化工具用戶端程式庫:

dotnet add package Azure.AI.Personalizer --version 2.0.0-beta.2

提示

如果您使用 Visual Studio IDE,則可以取得可下載 NuGet 套件形式的用戶端程式庫。

從專案目錄,在慣用的編輯器或 IDE 中開啟 Program.cs 檔案。 新增下列 using 指示詞:

using Azure;
using Azure.AI.Personalizer;
using System;
using System.Collections.Generic;
using System.Linq;

物件模型

個人化工具用戶端是一種 PersonalizerClient 物件,會使用含有金鑰的 Azure.AzureKeyCredential 向 Azure 進行驗證。

若要要求向使用者顯示單一最佳項目,請建立 PersonalizerRankOptions,然後傳遞至 PersonalizerClient.Rank 方法。 Rank 方法會傳回 PersonalizerRankResult

若要將獎勵分數傳送至個人化服務工具,請將事件識別碼和獎勵分數傳遞至 PersonalizerClient.Reward 方法。

在本快速入門中,決定獎勵分數是很簡單的。 在生產系統中,判斷影響獎勵分數的因素及影響程度可能是複雜的程序,您可能會隨著時間做出變更決定。 此設計決策應該是您個人化工具架構中的其中一個主要決策。

程式碼範例

這些程式碼片段會示範如何使用適用於 .NET 的個人化工具用戶端程式庫來執行下列工作:

驗證用戶端

在本節中,您將執行兩個動作:

  • 指定您的金鑰和端點
  • 建立個人化工具用戶端

首先,將下列幾行新增至您的 Program 類別。 務必從您的個人化工具資源新增金鑰和端點。

重要

前往 Azure 入口網站。 如果您在 [必要條件] 區段中建立的個人化工具資源成功部署,請按一下 [後續步驟] 底下的 [前往資源] 按鈕。 您可以在 [資源管理] 底下的 [金鑰和端點] 頁面中找到金鑰和端點。

完成時,請記得從程式碼中移除金鑰,且不要公開張貼金鑰。 在生產環境中,請考慮使用安全的方式來儲存及存取您的認證。 例如,Azure金鑰保存庫

private const string ServiceEndpoint  = "https://REPLACE-WITH-YOUR-PERSONALIZER-RESOURCE-NAME.cognitiveservices.azure.com";
private const string ResourceKey = "<REPLACE-WITH-YOUR-PERSONALIZER-KEY>";

接下來,建構排名和獎勵 URL。 請注意,需要設定 useLocalInference: true 做為 PersonalizerClientOptions 的參數,以啟用本機推斷。

static PersonalizerClient InitializePersonalizerClient(Uri url)
{
    // Set the local inference flag to true when initializing the client.
    return new PersonalizerClient(url, new AzureKeyCredential(ResourceKey), new PersonalizerClientOptions(useLocalInference: true));
}

取得以動作表示的內容選擇

動作代表您要個人化工具從中選取最佳內容項目的內容選擇。 將下列方法新增至 Program 類別,以代表動作及其特性的組合。

static IList<PersonalizerRankableAction> GetActions()
{
    IList<PersonalizerRankableAction> actions = new List<PersonalizerRankableAction>
    {
        new PersonalizerRankableAction(
            id: "pasta",
            features: new List<object>() { new { taste = "salty", spiceLevel = "medium" }, new { nutritionLevel = 5, cuisine = "italian" } }
        ),

        new PersonalizerRankableAction(
            id: "ice cream",
            features: new List<object>() { new { taste = "sweet", spiceLevel = "none" }, new { nutritionalLevel = 2 } }
        ),

        new PersonalizerRankableAction(
            id: "juice",
            features: new List<object>() { new { taste = "sweet", spiceLevel = "none" }, new { nutritionLevel = 5 }, new { drink = true } }
        ),

        new PersonalizerRankableAction(
            id: "salad",
            features: new List<object>() { new { taste = "salty", spiceLevel = "low" }, new { nutritionLevel = 8 } }
        )
    };

    return actions;
}

取得內容的使用者喜好設定

將下列方法新增至 [程式] 類別,以從命令列取得一天時間和使用者口味喜好的使用者輸入。 這些會作為關係特性使用。

static string GetTimeOfDayForContext()
{
    string[] timeOfDayFeatures = new string[] { "morning", "afternoon", "evening", "night" };

    Console.WriteLine("\nWhat time of day is it (enter number)? 1. morning 2. afternoon 3. evening 4. night");
    if (!int.TryParse(GetKey(), out int timeIndex) || timeIndex < 1 || timeIndex > timeOfDayFeatures.Length)
    {
        Console.WriteLine("\nEntered value is invalid. Setting feature value to " + timeOfDayFeatures[0] + ".");
        timeIndex = 1;
    }

    return timeOfDayFeatures[timeIndex - 1];
}
static string GetUsersTastePreference()
{
    string[] tasteFeatures = new string[] { "salty", "sweet" };
    var random = new Random();
    var taste = random.Next(1, 2);

    Console.WriteLine("\nWhat type of food would you prefer (enter number)? 1. salty 2. sweet");
    if (!int.TryParse(GetKey(), out int tasteIndex) || tasteIndex < 1 || tasteIndex > tasteFeatures.Length)
    {
        Console.WriteLine("\nEntered value is invalid. Setting feature value to " + tasteFeatures[0] + ".");
        tasteIndex = 1;
    }

    return tasteFeatures[taste - 1];
}

這兩個方法都會使用 GetKey 方法從命令列讀取使用者的選取。

private static string GetKey()
{
    return Console.ReadKey().Key.ToString().Last().ToString().ToUpper();
}
private static IList<object> GetContext(string time, string taste)
{
    return new List<object>()
    {
        new { time = time },
        new { taste = taste }
    };
}

建立學習迴圈

個人化工具學習迴圈是排名和獎勵呼叫的循環。 在本快速入門中,用於個人化內容的每個排名呼叫後面都會接著獎勵呼叫,以告訴個人化工具該服務的成效為何。

下列程式碼會透過命令列進行詢問使用者喜好的循環迴圈,並將該資訊傳送至個人化工具以選取每個位置的最佳動作,然後向客戶顯示選取項目,讓他們從清單中選擇,接著將獎勵分數傳送至個人化工具,指出服務在其選取項目中的成效為何。

static void Main(string[] args)
{
    Console.WriteLine($"Welcome to this Personalizer Quickstart!\n" +
    $"This code will help you understand how to use the Personalizer APIs (rank and reward).\n" +
    $"Each iteration represents a user interaction and will demonstrate how context, actions, and rewards work.\n" +
    $"Note: Personalizer AI models learn from a large number of user interactions:\n" +
    $"You won't be able to tell the difference in what Personalizer returns by simulating a few events by hand.\n" +
    $"If you want a sample that focuses on seeing how Personalizer learns, see the Python Notebook sample.");

    int iteration = 1;
    bool runLoop = true;

    IList<PersonalizerRankableAction> actions = GetActions();
    PersonalizerClient client = InitializePersonalizerClient(new Uri(ServiceEndpoint));

    do
    {
        Console.WriteLine("\nIteration: " + iteration++);

        string timeOfDayFeature = GetTimeOfDayForContext();
        string deviceFeature = GetUsersTastePreference();

        IList<object> currentContext = GetContext(timeOfDayFeature, deviceFeature);

        string eventId = Guid.NewGuid().ToString();

        var rankOptions = new PersonalizerRankOptions(actions: actions, contextFeatures: currentContext, eventId: eventId);
        PersonalizerRankResult rankResult = client.Rank(rankOptions);

        Console.WriteLine("\nPersonalizer service thinks you would like to have: " + rankResult.RewardActionId + ". Is this correct? (y/n)");

        float reward = 0.0f;
        string answer = GetKey();

        if (answer == "Y")
        {
            reward = 1.0f;
            Console.WriteLine("\nGreat! Enjoy your food.");
        }
        else if (answer == "N")
        {
            reward = 0.0f;
            Console.WriteLine("\nYou didn't like the recommended food choice.");
        }
        else
        {
            Console.WriteLine("\nEntered choice is invalid. Service assumes that you didn't like the recommended food choice.");
        }

        client.Reward(rankResult.EventId, reward);

        Console.WriteLine("\nPress q to break, any other key to continue:");
        runLoop = !(GetKey() == "Q");

    } while (runLoop);
}

執行程式

從應用程式目錄使用 dotnet run 命令來執行應用程式。

dotnet run

快速入門程式會詢問幾個問題以收集使用者偏好 (稱為特性),然後提供最佳的動作。