Partilhar via


Autenticar e autorizar o Serviço de Aplicativo em um banco de dados vetorial

Este artigo demonstra como gerenciar a conexão entre seu aplicativo .NET do Serviço de Aplicativo e uma solução de banco de dados vetorial. Ele abrange o uso de identidades gerenciadas do Microsoft Entra para serviços suportados e o armazenamento seguro de cadeias de conexão para outros.

Ao adicionar um banco de dados vetorial ao seu aplicativo, você pode habilitar [memórias semânticas ou repositórios vetoriais] (repositórios vetoriais) para sua IA. O SDK do Kernel Semântico para .NET permite que você implemente facilmente o armazenamento e a recuperação de memória usando sua solução de banco de dados vetorial preferida.

Pré-requisitos

Usar a identidade gerenciada do Microsoft Entra para autenticação

Se um serviço de banco de dados vetorial oferecer suporte à autenticação do Microsoft Entra, você poderá usar uma identidade gerenciada com seu Serviço de Aplicativo para acessar com segurança seu banco de dados vetorial sem precisar provisionar ou girar manualmente quaisquer segredos. Para obter uma lista dos serviços do Azure que suportam a autenticação do Microsoft Entra, consulte Serviços do Azure que suportam a autenticação do Microsoft Entra.

Adicionar uma identidade gerenciada ao Serviço de Aplicativo

Pode conceder dois tipos de identidades à aplicação:

  • Uma identidade atribuída pelo sistema está associada à aplicação e será eliminada se a aplicação for eliminada. Um aplicativo pode ter apenas uma identidade atribuída ao sistema.
  • Uma identidade atribuída pelo utilizador é um recurso autónomo do Azure que pode ser atribuído à aplicação. Uma aplicação pode ter várias identidades atribuídas pelo utilizador.

Adicionar uma identidade atribuída ao sistema

  1. Navegue até a página do seu aplicativo no portal do Azure e role para baixo até o grupo Configurações.
  2. Selecione a Identidade.
  3. Na guia Sistema atribuído, alterne Status para Ativado e selecione Salvar.

Execute o comando para criar uma identidade atribuída ao az webapp identity assign sistema:

az webapp identity assign --name <appName> --resource-group <groupName>

Adicionar uma identidade atribuída pelo usuário

Para adicionar uma identidade atribuída pelo usuário ao seu aplicativo, crie a identidade e adicione seu identificador de recurso à configuração do aplicativo.

  1. Crie um recurso de identidade gerenciado atribuído pelo usuário seguindo estas instruções.

  2. No painel de navegação esquerdo da página da sua aplicação, desloque-se para baixo até ao grupo Definições .

  3. Selecione a Identidade.

  4. Selecione Adicionar atribuído ao> usuário.

  5. Localize a identidade que criou anteriormente, selecione-a e, em seguida, selecione Adicionar.

    Importante

    Depois de selecionar Adicionar, o aplicativo é reiniciado.

  1. Crie uma identidade atribuída pelo usuário:

    az identity create --resource-group <groupName> --name <identityName>
    
  2. Atribua a identidade ao seu aplicativo:

    az webapp identity assign --resource-group <groupName> --name <appName> --identities <identityId>
    

Adicionar uma função do Azure à sua identidade gerenciada

  1. No Portal do Azure, navegue até o escopo ao qual você deseja conceder acesso ao banco de dados vetorial. O escopo pode ser um grupo de Gerenciamento, Assinatura, Grupo de Recursos ou um recurso específico do Azure.
  2. No painel de navegação esquerdo, selecione Controle de acesso (IAM).
  3. Selecione Adicionar e, em seguida, selecione Adicionar atribuição de função.
  4. Na guia Função, selecione a função apropriada que concede acesso de leitura ao seu banco de dados vetorial.
  5. Na guia Membros, selecione a identidade gerenciada.
  6. No separador Rever + atribuir, selecione Rever + atribuir para atribuir a função.

Âmbito do recurso

az role assignment create --assignee "<managedIdentityObjectID>" \
--role "<myVectorDbReaderRole>" \
--scope "/subscriptions/<subscriptionId>/resourcegroups/<resourceGroupName>/providers/<providerName>/<resourceType>/<resourceSubType>/<resourceName>"

Âmbito do grupo de recursos

az role assignment create --assignee "<managedIdentityObjectID>" \
--role "<myVectorDbReaderRole>" \
--scope "/subscriptions/<subscriptionId>/resourcegroups/<resourceGroupName>"

Âmbito da subscrição

az role assignment create --assignee "<managedIdentityObjectID>" \
--role "<myVectorDbReaderRole>" \
--scope "/subscriptions/<subscriptionId>"

Âmbito do grupo de gestão

az role assignment create --assignee "<managedIdentityObjectID>" \
--role "<myVectorDbReaderRole>" \
--scope "/providers/Microsoft.Management/managementGroups/<managementGroupName>"

Implementar autenticação baseada em token com o banco de dados vetorial

Os exemplos de código a seguir exigem essas bibliotecas adicionais:

  1. Inicialize um DefaultAzureCredential objeto para pegar a identidade gerenciada do seu aplicativo:

    // Initialize a DefaultAzureCredential.
    // This credential type will try several authentication flows in order until one is available.
    // Will pickup Visual Studio or Azure CLI credentials in local environments.
    // Will pickup managed identity credentials in production deployments.
    TokenCredential credentials = new DefaultAzureCredential(
        new DefaultAzureCredentialOptions
        {
            // If using a user-assigned identity specify either:
            // ManagedIdentityClientId or ManagedIdentityResourceId.
            // e.g.: ManagedIdentityClientId = "myIdentityClientId".
        }
    );
    
  2. Inicialize um IMemoryStore objeto para seu banco de dados vetorial e use-o para criar um ISemanticTextMemory:

    // Retrieve the endpoint obtained from the Azure AI Search deployment.
    // Retrieve the endpoint and deployments obtained from the Azure OpenAI deployment.
    // Must use the deployment name not the underlying model name.
    IConfigurationRoot config = new ConfigurationBuilder().AddUserSecrets<Program>().Build();
    string searchEndpoint = config["AZURE_AISEARCH_ENDPOINT"]!;
    string openAiEndpoint = config["AZURE_OPENAI_ENDPOINT"]!;
    string embeddingModel = config["AZURE_OPENAI_EMBEDDING_NAME"]!;
    
    // The Semantic Kernel SDK provides a connector extension for Azure AI Search.
    // Initialize an AzureAISearchMemoryStore using your managed identity credentials.
    IMemoryStore memoryStore = new AzureAISearchMemoryStore(searchEndpoint, credentials);
    
    // Build a SemanticMemoryStore with Azure AI Search as the store.
    // Must also include a text embedding generation service.
    ISemanticTextMemory memory = new MemoryBuilder()
        .WithOpenAITextEmbeddingGeneration(embeddingModel, openAiEndpoint)
        .WithMemoryStore(memoryStore)
        .Build();
    
  3. Crie um Kernel objeto e, em seguida, importe-o ISemanticTextMemory usando o TextMemoryPlugin:

    // Build a Kernel, include a chat completion service.
    string chatModel = config["AZURE_OPENAI_GPT_NAME"]!;
    Kernel kernel = Kernel
        .CreateBuilder()
        .AddAzureOpenAIChatCompletion(chatModel, openAiEndpoint, credentials)
        .Build();
    
    // Import the semantic memory store as a TextMemoryPlugin.
    // The TextMemoryPlugin enable recall via prompt expressions.
    kernel.ImportPluginFromObject(new TextMemoryPlugin(memory));
    
  4. Use o objeto para invocar um prompt que inclua a Kernel recuperação de memória:

    // Must configure the memory collection, number of memories to recall, and relevance score.
    // The {{...}} syntax represents an expression to Semantic Kernel.
    // For more information on this syntax see:
    // https://learn.microsoft.com/semantic-kernel/prompts/prompt-template-syntax
    string memoryCollection = config["AZURE_OPENAI_MEMORY_NAME"]!;
    string? result = await kernel.InvokePromptAsync<string>(
        "{{recall 'where did I grow up?'}}",
        new()
        {
            [TextMemoryPlugin.CollectionParam] = memoryCollection,
            [TextMemoryPlugin.LimitParam] = "2",
            [TextMemoryPlugin.RelevanceParam] = "0.79",
        }
    );
    Console.WriteLine($"Output: {result}");
    

Usar o Cofre da Chave para armazenar segredos de conexão

Se um banco de dados vetorial não oferecer suporte à autenticação do Microsoft Entra, você poderá usar um Cofre da Chave para armazenar seus segredos de conexão e recuperá-los com seu aplicativo do Serviço de Aplicativo. Usando um Cofre de Chaves para armazenar seus segredos de conexão, você pode compartilhá-los com vários aplicativos e controlar o acesso a segredos individuais por aplicativo.

Antes de seguir essas etapas, recupere uma cadeia de conexão para seu banco de dados vetorial. Por exemplo, consulte Usar o Cache do Azure para Redis com um aplicativo Web ASP.NET Core.

Adicionar uma cadeia de conexão ao Cofre da Chave

Importante

Antes de seguir estas etapas, verifique se você criou um Cofre da Chave usando o Portal do Azure.

  1. Navegue até o cofre da chave no Portal do Azure.
  2. Na navegação à esquerda do Cofre da Chave, selecione Objetos e, em seguida, selecione Segredos.
  3. Selecione + Gerar/Importar.
  4. Na tela Criar um segredo, escolha os seguintes valores:
    • Opções de upload: Manual.
    • Nome: escreva um nome para o segredo. O nome do segredo tem de ser exclusivo dentro de um Key Vault.
    • Valor: A cadeia de conexão para seu banco de dados vetorial.
    • Deixe as outras opções com os valores predefinidos. Selecione Criar.
  5. Quando você receber a mensagem de que o segredo foi criado com êxito, ele estará pronto para ser usado em seu aplicativo.

Importante

Antes de seguir estas etapas, verifique se você criou um Cofre da Chave usando a CLI do Azure.

  1. Conceda permissões à sua conta de utilizador para o seu cofre de chaves através do Controlo de Acesso Baseado em Funções (RBAC), atribua uma função utilizando o comando az role assignment createda CLI do Azure :

    az role assignment create \
    --role "Key Vault Secrets User" \
    --assignee "<yourEmailAddress>" \
    --scope "/subscriptions/<subscriptionId>/resourceGroups/<resourceGroupName>/providers/Microsoft.KeyVault/vaults/<keyVaultName>"
    
  2. Adicione a cadeia de conexão ao Cofre da Chave usando o comando az keyvault secret setda CLI do Azure :

    az keyvault secret set \
    --vault-name "<keyVaultName>" \
    --name "<secretName>" \
    --value "<connectionString>"
    

Conceda ao seu Serviço de Aplicativo acesso ao Cofre da Chave

  1. Atribua uma identidade gerenciada ao seu Serviço de Aplicativo.
  2. Adicione as Key Vault Secrets User funções e Key Vault Reader à sua identidade gerenciada.

Implementar a recuperação da cadeia de conexão do Cofre da Chave

Para usar os seguintes exemplos de código, você precisa destas bibliotecas adicionais:

Esses exemplos de código usam um banco de dados Redis, mas você pode aplicá-los a qualquer banco de dados vetorial que ofereça suporte a cadeias de conexão.

  1. Inicialize um DefaultAzureCredential objeto para pegar a identidade gerenciada do seu aplicativo:

    // Initialize a DefaultAzureCredential.
    // This credential type will try several authentication flows in order until one is available.
    // Will pickup Visual Studio or Azure CLI credentials in local environments.
    // Will pickup managed identity credentials in production deployments.
    TokenCredential credentials = new DefaultAzureCredential(
        new DefaultAzureCredentialOptions
        {
            // If using a user-assigned identity specify either:
            // ManagedIdentityClientId or ManagedIdentityResourceId.
            // e.g.: ManagedIdentityClientId = "myIdentityClientId".
        }
    );
    
  2. Adicione o Cofre da Chave ao criar sua configuração, isso mapeará seus segredos do Cofre da Chave para o IConfigurationRoot objeto:

    // User secrets let you provide connection strings when testing locally
    // For more info see: https://learn.microsoft.com/aspnet/core/security/app-secrets
    IConfigurationRoot config = new ConfigurationBuilder()
        .AddUserSecrets<Program>()
        .AddAzureKeyVault(new Uri("{vaultURI}"), credentials)
        .Build();
    
    // Retrieve the Redis connection string obtained from the Key Vault.
    string redisConnectionString = config["AZURE_REDIS_CONNECT_STRING"]!;
    
  3. Use sua cadeia de conexão de banco de dados vetorial do Cofre da Chave para inicializar um IMemoryStore objeto e, em seguida, use-a para criar um ISemanticTextMemory:

    // Use the connection string to connect to the database
    IDatabase database = (
        await ConnectionMultiplexer.ConnectAsync(redisConnectionString)
    ).GetDatabase();
    
    // The Semantic Kernel SDK provides a connector extension for Redis.
    // Initialize an RedisMemoryStore using your managed identity credentials.
    IMemoryStore memoryStore = new RedisMemoryStore(database);
    
    // Retrieve the endpoint and deployments obtained from the Azure OpenAI deployment.
    // Must use the deployment name not the underlying model name.
    string openAiEndpoint = config["AZURE_OPENAI_ENDPOINT"]!;
    string embeddingModel = config["AZURE_OPENAI_EMBEDDING_NAME"]!;
    
    // Build a SemanticMemoryStore with Azure AI Search as the store.
    // Must also include a text embedding generation service.
    ISemanticTextMemory memory = new MemoryBuilder()
        .WithOpenAITextEmbeddingGeneration(embeddingModel, openAiEndpoint)
        .WithMemoryStore(memoryStore)
        .Build();
    
  4. Crie um Kernel objeto e, em seguida, importe-o ISemanticTextMemory usando o TextMemoryPlugin:

    // Build a Kernel, include a chat completion service.
    string chatModel = config["AZURE_OPENAI_GPT_NAME"]!;
    Kernel kernel = Kernel
        .CreateBuilder()
        .AddAzureOpenAIChatCompletion(chatModel, openAiEndpoint, credentials)
        .Build();
    
    // Import the semantic memory store as a TextMemoryPlugin.
    // The TextMemoryPlugin enable recall via prompt expressions.
    kernel.ImportPluginFromObject(new TextMemoryPlugin(memory));
    
  5. Use o objeto para invocar um prompt que inclua a Kernel recuperação de memória:

    // Must configure the memory collection, number of memories to recall, and relevance score.
    // The {{...}} syntax represents an expression to Semantic Kernel.
    // For more information on this syntax see:
    // https://learn.microsoft.com/semantic-kernel/prompts/prompt-template-syntax
    string memoryCollection = config["AZURE_OPENAI_MEMORY_NAME"]!;
    string? result = await kernel.InvokePromptAsync<string>(
        "{{recall 'where did I grow up?'}}",
        new()
        {
            [TextMemoryPlugin.CollectionParam] = memoryCollection,
            [TextMemoryPlugin.LimitParam] = "2",
            [TextMemoryPlugin.RelevanceParam] = "0.79",
        }
    );
    Console.WriteLine($"Output: {result}");
    

Usar as configurações do aplicativo para armazenar segredos de conexão

Se um banco de dados vetorial não oferecer suporte à autenticação do Microsoft Entra, você poderá usar as configurações do aplicativo do Serviço de Aplicativo para armazenar seus segredos de conexão. Usando as configurações do aplicativo, você pode armazenar seus segredos de conexão sem provisionar recursos adicionais do Azure.

Antes de seguir essas etapas, recupere uma cadeia de conexão para seu banco de dados vetorial. Por exemplo, consulte Usar o Cache do Azure para Redis no .NET Framework.

Adicionar uma cadeia de conexão às configurações do aplicativo

  1. Navegue até a página do seu aplicativo no Portal do Azure.
  2. No menu esquerdo do aplicativo, selecione Configurações>do aplicativo.
    • Por padrão, os valores para as configurações do aplicativo ficam ocultos no portal para segurança.
    • Para ver um valor oculto de uma configuração de aplicativo, selecione seu campo Valor.
  3. Selecione Nova configuração de conexão.
  4. Na tela Adicionar/Editar cadeia de conexão, escolha os seguintes valores:
    • Nome: digite um nome para a configuração. O nome da configuração deve ser exclusivo.
    • Valor: A cadeia de conexão para seu banco de dados vetorial.
    • Tipo: O tipo de conexão, Custom se nenhuma outra se aplicar.
    • Deixe as outras opções com os valores predefinidos. Selecione OK.
  5. Selecione Salvar novamente na página Configuração.

Adicione ou edite uma configuração de aplicativo com o comando az webapp config connection-string setCLI do Azure :

az webapp config connection-string set \
--name "<appName>" \
--resource-group "<groupName>" \
--connection-string-type "<connectionType>" \
--settings <connectionName>='<connectionString>'

Implementar a recuperação da cadeia de conexão a partir das configurações do aplicativo

Para usar os seguintes exemplos de código, você precisa destas bibliotecas adicionais:

Esses exemplos de código usam um banco de dados Redis, mas você pode aplicá-los a qualquer banco de dados vetorial que ofereça suporte a cadeias de conexão.

  1. Adicione variáveis de ambiente ao criar sua configuração, isso mapeará suas cadeias de conexão para o IConfigurationRoot objeto:

    // User secrets let you provide connection strings when testing locally
    // For more info see: https://learn.microsoft.com/en-us/aspnet/core/security/app-secrets
    IConfigurationRoot config = new ConfigurationBuilder()
        .AddUserSecrets<Program>()
        .AddEnvironmentVariables()
        .Build();
    
    // Retrieve the Redis connection string obtained from the app settings.
    // The connection string name should match the entry in application settings
    string redisConnectionString = config.GetConnectionString("AZURE_REDIS")!;
    
  2. Use sua cadeia de conexão de banco de dados vetorial das configurações do aplicativo para inicializar um IMemoryStore objeto e, em seguida, use-a para criar um ISemanticTextMemory:

    // Use the connection string to connect to the database
    IDatabase database = (
        await ConnectionMultiplexer.ConnectAsync(redisConnectionString)
    ).GetDatabase();
    
    // The Semantic Kernel SDK provides a connector extension for Redis.
    // Initialize an RedisMemoryStore using your managed identity credentials.
    IMemoryStore memoryStore = new RedisMemoryStore(database);
    
    // Retrieve the endpoint and deployments obtained from the Azure OpenAI deployment.
    // Must use the deployment name not the underlying model name.
    string openAiEndpoint = config["AZURE_OPENAI_ENDPOINT"]!;
    string embeddingModel = config["AZURE_OPENAI_EMBEDDING_NAME"]!;
    
    // Build a SemanticMemoryStore with Azure AI Search as the store.
    // Must also include a text embedding generation service.
    ISemanticTextMemory memory = new MemoryBuilder()
        .WithOpenAITextEmbeddingGeneration(embeddingModel, openAiEndpoint)
        .WithMemoryStore(memoryStore)
        .Build();
    
  3. Crie um Kernel objeto e, em seguida, importe-o ISemanticTextMemory usando o TextMemoryPlugin:

    // Build a Kernel, include a chat completion service.
    string chatModel = config["AZURE_OPENAI_GPT_NAME"]!;
    Kernel kernel = Kernel
        .CreateBuilder()
        .AddAzureOpenAIChatCompletion(chatModel, openAiEndpoint, credentials)
        .Build();
    
    // Import the semantic memory store as a TextMemoryPlugin.
    // The TextMemoryPlugin enable recall via prompt expressions.
    kernel.ImportPluginFromObject(new TextMemoryPlugin(memory));
    
  4. Use o objeto para invocar um prompt que inclua a Kernel recuperação de memória:

    // Must configure the memory collection, number of memories to recall, and relevance score.
    // The {{...}} syntax represents an expression to Semantic Kernel.
    // For more information on this syntax see:
    // https://learn.microsoft.com/semantic-kernel/prompts/prompt-template-syntax
    string memoryCollection = config["AZURE_OPENAI_MEMORY_NAME"]!;
    string? result = await kernel.InvokePromptAsync<string>(
        "{{recall 'where did I grow up?'}}",
        new()
        {
            [TextMemoryPlugin.CollectionParam] = memoryCollection,
            [TextMemoryPlugin.LimitParam] = "2",
            [TextMemoryPlugin.RelevanceParam] = "0.79",
        }
    );
    Console.WriteLine($"Output: {result}");