開始使用適用于 Azure AI 個人化工具的本機推斷 SDK
重要
從 2023 年 9 月 20 日起,您將無法建立新的個人化工具資源。 個人化工具服務將于 2026 年 10 月 1 日淘汰。
個人化工具本機推斷 SDK (預覽) 會在本機下載個人化工具模型,藉由消除網路呼叫來大幅減少排名呼叫的延遲。 每分鐘,用戶端都會下載背景中最新的模型,並將其用於推斷。
在本指南中,您將瞭解如何使用個人化工具本機推斷 SDK。
您必須安裝適用于 .NET 的個人化工具用戶端程式庫,才能:
- 使用 Azure 中的個人化工具資源驗證快速入門範例用戶端。
- 將內容和動作功能傳送至 Reward 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;
物件模型
個人化工具用戶端是 個人化工具Client 物件,可使用包含金鑰的 Azure.AzureKeyCredential 向 Azure 進行驗證。
若要要求顯示使用者的單一最佳專案,請建立 PersonalizerRankOptions ,然後將它傳遞至 PersonalizerClient.Rank 方法。 Rank 方法會 傳回 PersonalizerRankResult 。
若要將獎勵分數傳送給個人化工具,請將事件識別碼和獎勵分數傳遞至 個人化工具Client.Reward 方法。
判斷獎勵分數,在本快速入門中是微不足道的。 在生產系統中,決定哪些專案會影響獎勵分數 ,以及複雜程式可能有多少 ,而您可能會決定隨著時間而變更。 此設計決策應該是個人化工具架構中的主要決策之一。
程式碼範例
這些程式碼片段示範如何使用適用于 .NET 的個人化工具用戶端程式庫來執行下列工作:
- 建立個人化工具用戶端
- 多位置排名 API
- 多位置獎勵 API
驗證用戶端
在本節中,您將執行兩件事:
- 指定您的金鑰和端點
- 建立個人化工具用戶端
首先,將下列幾行新增至您的 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;
}
取得內容的使用者喜好設定
將下列方法新增至 Program 類別,以從命令列取得使用者的輸入,以取得一天中的時間和使用者口味喜好設定。 這些會作為內容功能使用。
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