Partilhar via


Tutorial: Adicionar o Personalizador a um aplicativo Web .NET

Importante

A partir de 20 de setembro de 2023, você não poderá criar novos recursos do Personalizador. O serviço de Personalizador será aposentado no dia 1º de outubro de 2026.

Personalize um aplicativo Web C# .NET com um loop do Personalizador para fornecer o conteúdo correto a um usuário com base em ações (com recursos) e recursos de contexto.

Neste tutorial, vai aprender a:

  • Configurar a chave e o ponto de extremidade do Personalizer
  • Colete recursos
  • APIs de classificação de chamadas e recompensas
  • Exibir a ação principal, designada como rewardActionId

Selecione o melhor conteúdo para um aplicativo Web

Um aplicativo Web deve usar o Personalizador quando há uma lista de ações (algum tipo de conteúdo) na página da Web que precisa ser personalizada para um único item superior (rewardActionId) para exibição. Exemplos de listas de ações incluem artigos de notícias, locais de posicionamento de botões e opções de palavras para nomes de produtos.

Você envia a lista de ações, juntamente com os recursos de contexto, para o loop do Personalizador. O Personalizador seleciona a melhor ação e, em seguida, seu aplicativo Web exibe essa ação.

Neste tutorial, as ações são tipos de alimentos:

  • massas alimentícias
  • Gelado
  • sumo
  • salada
  • pipoca
  • café
  • sopa

Para ajudar o Personalizador a saber mais sobre suas ações, envie ambas as ações com recursos e recursos de contexto com cada solicitação da API de classificação.

Um recurso do modelo são informações sobre a ação ou o contexto que podem ser agregados (agrupados) entre os membros da base de usuários do seu aplicativo Web. Um recurso não é específico individualmente (como um ID de usuário) ou altamente específico (como uma hora exata do dia).

Ações com recursos

Cada ação (item de conteúdo) tem recursos para ajudar a distinguir o item alimentar.

Os recursos não são configurados como parte da configuração de loop no portal do Azure. Em vez disso, eles são enviados como um objeto JSON com cada chamada de API de classificação. Isso permite flexibilidade para que as ações e seus recursos cresçam, mudem e diminuam ao longo do tempo, o que permite que o Personalizer siga as tendências.

 /// <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;
  }

Recursos de contexto

Os recursos de contexto ajudam o Personalizer a entender o contexto das ações. O contexto para este aplicativo de exemplo inclui:

  • Hora do dia - manhã, tarde, noite, noite
  • preferência do utilizador pelo sabor - salgado, doce, amargo, azedo ou salgado
  • contexto do navegador - agente do usuário, localização geográfica, referenciador
/// <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];
}

Como é que a aplicação Web utiliza o Personalizador?

A aplicação Web utiliza o Personalizador para selecionar a melhor ação a partir da lista de opções alimentares. Ele faz isso enviando as seguintes informações com cada chamada de API de classificação:

  • ações com as suas características, tais como taste e spiceLevel
  • recursos de contexto , como time de dia, preferência do taste usuário e informações do agente do usuário do navegador e recursos de contexto
  • ações a excluir , tais como sumo
  • eventId, que é diferente para cada chamada para Rank API.

Recursos de modelo do personalizador em um aplicativo Web

O personalizador precisa de recursos para as ações (conteúdo) e o contexto atual (usuário e ambiente). Os recursos são usados para alinhar as ações ao contexto atual no modelo. O modelo é uma representação do conhecimento passado do Personalizer sobre ações, contexto e suas características que lhe permite tomar decisões informadas.

O modelo, incluindo recursos, é atualizado em um cronograma com base na configuração de frequência de atualização do modelo no portal do Azure.

Atenção

As funcionalidades desta aplicação destinam-se a ilustrar funcionalidades e valores de funcionalidades, mas não necessariamente às melhores funcionalidades a utilizar numa aplicação Web.

Planejar recursos e seus valores

Os recursos devem ser selecionados com o mesmo planejamento e design que você aplicaria a qualquer esquema ou modelo em sua arquitetura técnica. Os valores dos recursos podem ser definidos com lógica de negócios ou sistemas de terceiros. Os valores de recursos não devem ser tão específicos que não se apliquem a um grupo ou classe de recursos.

Generalizar valores de recurso

Generalizar em categorias

Este aplicativo usa time como um recurso, mas agrupa o tempo em categorias como morning, afternoon, eveninge night. Este é um exemplo de utilização da informação do tempo, mas não de uma forma muito específica, como 10:05:01 UTC+2a .

Generalizar em partes

Este aplicativo usa os recursos de solicitação HTTP do navegador. Isso começa com uma cadeia de caracteres muito específica com todos os dados, por exemplo:

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

A biblioteca de classes HttpRequestFeatures generaliza essa cadeia de caracteres em um objeto userAgentInfo com valores individuais. Todos os valores que são muito específicos são definidos como uma cadeia de caracteres vazia. Quando os recursos de contexto para a solicitação são enviados, ele tem o seguinte formato JSON:

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

Usando o aplicativo Web de exemplo

O aplicativo Web baseado em navegador de exemplo (todo o código é fornecido) precisa dos seguintes aplicativos instalados para executar o aplicativo.

Instale o seguinte software:

  • .NET Core 2.1 - o servidor back-end de exemplo usa o .NET core
  • Node.js - o cliente/front-end depende desta aplicação
  • Visual Studio 2019 ou CLI do .NET Core - use o ambiente de desenvolvedor do Visual Studio 2019 ou a CLI do .NET Core para criar e executar o aplicativo

Configurar o exemplo

  1. Clone o repositório de Amostras do Personalizador de IA do Azure.

    git clone https://github.com/Azure-Samples/cognitive-services-personalizer-samples.git
    
  2. Navegue até samples/HttpRequestFeatures para abrir a solução, HttpRequestFeaturesExample.sln.

    Se solicitado, permita que o Visual Studio atualize o pacote .NET para o Personalizer.

Configurar o Serviço de Personalização de IA do Azure

  1. Crie um recurso do Personalizador no portal do Azure.

  2. No portal do Azure, localize o Endpoint e ou (qualquer um Key1 Key2 funcionará) na guia Chaves e Pontos de Extremidade . Estes são os seus e os PersonalizerServiceEndpoint seus PersonalizerApiKey.

  3. Preencha o PersonalizerServiceEndpoint appsettings.json.

  4. Configure o PersonalizerApiKey como segredos de aplicativo de uma das seguintes maneiras:

    • Se você estiver usando a CLI do .NET Core, poderá usar o dotnet user-secrets set "PersonalizerApiKey" "<API Key>" comando.
    • Se você estiver usando o Visual Studio, poderá clicar com o botão direito do mouse no projeto e selecionar a opção de menu Gerenciar segredos do usuário para configurar as chaves do personalizador. Ao fazer isso, o Visual Studio abrirá um secrets.json arquivo onde você pode adicionar as chaves da seguinte maneira:
    {
      "PersonalizerApiKey": "<your personalizer key here>",
    }
    

Executar o exemplo

Crie e execute HttpRequestFeaturesExample com um dos seguintes métodos:

  • Visual Studio 2019: Pressione F5
  • CLI do .NET Core: dotnet build então dotnet run

Através de um navegador da web, você pode enviar uma solicitação de classificação e uma solicitação de recompensa e ver suas respostas, bem como os recursos de solicitação http extraídos do seu ambiente.

A captura de tela mostra um exemplo do recurso de solicitação http em um navegador da Web.

Demonstrar o loop do Personalizador

  1. Selecione o botão Gerar nova solicitação de classificação para criar um novo objeto JSON para a chamada da API de classificação. Isso cria as ações (com recursos) e os recursos de contexto e exibe os valores para que você possa ver a aparência do JSON.

    Para sua própria aplicação futura, a geração de ações e recursos pode acontecer no cliente, no servidor, uma mistura dos dois, ou com chamadas para outros serviços.

  2. Selecione Enviar solicitação de classificação para enviar o objeto JSON para o servidor. O servidor chama a API de classificação do personalizador. O servidor recebe a resposta e retorna a ação mais bem classificada para o cliente exibir.

  3. Defina o valor da recompensa e, em seguida, selecione o botão Enviar Pedido de Recompensa . Se você não alterar o valor da recompensa, o aplicativo cliente sempre enviará o valor de 1 para o Personalizador.

    A captura de tela mostra a seção Solicitação de recompensa.

    Para sua própria aplicação futura, a geração da pontuação de recompensa pode acontecer após a coleta de informações do comportamento do usuário no cliente, juntamente com a lógica de negócios no servidor.

Compreender a aplicação Web de exemplo

O aplicativo Web de exemplo tem um servidor C# .NET , que gerencia a coleção de recursos e o envio e recebimento de chamadas HTTP para seu ponto de extremidade do Personalizer.

O aplicativo Web de exemplo usa um aplicativo cliente front-end knockout para capturar recursos e processar ações da interface do usuário, como clicar em botões e enviar dados para o servidor .NET.

As seções a seguir explicam as partes do servidor e do cliente que um desenvolvedor precisa entender para usar o Personalizador.

Rank API: O aplicativo cliente envia contexto para o servidor

O aplicativo cliente coleta o agente de usuário do navegador do usuário.

Crie e execute o projeto HTTPRequestFeaturesExample. Uma janela do navegador é aberta para exibir o aplicativo de página única.

Rank API: O aplicativo de servidor chama o Personalizer

Este é um aplicativo Web .NET típico com um aplicativo cliente, grande parte do código da placa de caldeira é fornecido para você. Qualquer código não específico do Personalizer é removido dos seguintes trechos de código para que você possa se concentrar no código específico do Personalizador.

Criar cliente Personalizer

No Startup.cs do servidor, o ponto de extremidade e a chave do Personalizer são usados para criar o cliente do Personalizer. O aplicativo cliente não precisa se comunicar com o Personalizer neste aplicativo, em vez disso, depende do servidor para fazer essas chamadas SDK.

O código de inicialização do .NET do servidor Web é:

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
    }
}

Selecione a melhor ação

No PersonalizerController.cs do servidor, a API do servidor GenerateRank resume a preparação para chamar a API Rank

  • Criar novo eventId para a chamada de Rank
  • Obter a lista de ações
  • Obter a lista de recursos do usuário e criar recursos de contexto
  • Opcionalmente, defina todas as ações excluídas
  • API de classificação de chamadas, retornar resultados para o cliente
/// <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);
}

O JSON enviado para o Personalizer, contendo ações (com recursos) e os recursos de contexto atual, tem a seguinte aparência:

{
    "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
}

Devolver Personalizer rewardActionId ao cliente

A API Rank retorna a melhor ação selecionada rewardActionId para o servidor.

Exiba a ação retornada em 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"
}

O cliente exibe a ação rewardActionId

Neste tutorial, o rewardActionId valor é exibido.

Em seu próprio aplicativo futuro, isso pode ser algum texto exato, um botão ou uma seção da página da Web destacada. A lista é retornada para qualquer pós-análise de pontuações, não para uma ordenação do conteúdo. Apenas o rewardActionId conteúdo deve ser exibido.

API de recompensa: coletar informações para recompensa

A pontuação de recompensa deve ser cuidadosamente planejada, assim como os recursos são planejados. A pontuação de recompensa normalmente deve ser um valor de 0 a 1. O valor pode ser calculado parcialmente no aplicativo cliente, com base nos comportamentos do usuário, e parcialmente no servidor, com base na lógica de negócios e metas.

Se o servidor não chamar a API de Recompensa dentro do tempo de espera de Recompensa configurado no portal do Azure para seu recurso de Personalizador, a recompensa Padrão (também configurada no portal do Azure) será usada para esse evento.

Neste aplicativo de exemplo, você pode selecionar um valor para ver como a recompensa afeta as seleções.

Outras formas de aprender com este exemplo

O exemplo usa vários eventos baseados no tempo configurados no portal do Azure para seu recurso do Personalizador. Jogue com esses valores e retorne a este aplicativo Web de exemplo para ver como as alterações afetam as chamadas de Classificação e Recompensa:

  • Tempo de espera de recompensa
  • Frequência de atualização do modelo

As configurações adicionais para jogar incluem:

  • Recompensa padrão
  • Percentagem de exploração

Clean up resources (Limpar recursos)

Quando terminar este tutorial, limpe os seguintes recursos:

  • Exclua o diretório de projeto de exemplo.
  • Exclua seu recurso do Personalizador - pense em um recurso do Personalizador como dedicado às ações e ao contexto - só reutilize o recurso se ainda estiver usando os alimentos como domínio do assunto das ações.

Próximos passos