Autenticar e autorizar o Serviço de Aplicativo em um banco de dados vetorial
Este artigo demonstra como gerenciar a conexão entre o aplicativo .NET do Serviço de Aplicativo e uma solução de banco de dados vetorial. Ele aborda o uso de identidades gerenciadas do Microsoft Entra para serviços com suporte e o armazenamento seguro de cadeias de conexão para outras pessoas.
Ao adicionar um banco de dados vetorial ao seu aplicativo, você pode habilitar [memórias semânticas ou repositórios de vetores] (repositórios de vetores) à sua IA. O SDK de Kernel Semântico para .NET permite que você implemente facilmente o armazenamento de memória e o recall usando sua solução de banco de dados vetorial preferencial.
Pré-requisitos
- Uma conta do Azure com uma assinatura ativa. Crie uma conta gratuitamente.
- SDK .NET
Microsoft.SemanticKernel
Pacote NuGet- Pacote NuGet
Microsoft.SemanticKernel.Plugins.Memory
- Criar e implantar um aplicativo .NET no Serviço de Aplicativo
- Criar e implantar uma solução de banco de dados vetorial
Usar identidade gerenciada do Microsoft Entra para autenticação
Se um serviço de banco de dados vetorial der suporte à autenticação do Microsoft Entra, você poderá usar uma identidade gerenciada com o Serviço de Aplicativo para acessar com segurança seu banco de dados vetorial sem precisar provisionar ou girar manualmente os segredos. Para obter uma lista dos serviços do Azure que dão suporte à autenticação do Microsoft Entra, consulte Serviços do Azure que dão suporte à autenticação do Microsoft Entra.
Adicionar uma identidade gerenciada ao Serviço de Aplicativo
Seu aplicativo pode receber dois tipos de identidades:
- Uma identidade atribuída pelo sistema é vinculada ao seu aplicativo e é excluída se o seu aplicativo for excluído. Um aplicativo pode ter apenas uma identidade atribuída pelo sistema.
- Uma identidade atribuída pelo usuário é um recurso independente do Azure que pode ser atribuído ao seu aplicativo. Um aplicativo pode ter várias identidades atribuídas pelo usuário.
Adicionar uma identidade atribuída pelo sistema
- Navegue até a página do aplicativo no portal do Azure e role para baixo até o grupo Configurações.
- Selecionar Identidade.
- Na guia Atribuído pelo Sistema, alterne Status para Ativado e selecione Salvar.
Execute o comando az webapp identity assign
para criar uma identidade atribuída pelo 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.
Crie um recurso de identidade gerenciada atribuída pelo usuário seguindo estas instruções.
No painel de navegação esquerdo da página do aplicativo, role para baixo até o grupo Configurações.
Selecionar Identidade.
Selecione Usuário atribuído>Adicionar.
Localize a identidade que você criou anteriormente, selecione-a e clique em Adicionar.
Importante
Depois de selecionar Adicionar, o aplicativo será reiniciado.
Crie uma identidade atribuída pelo usuário:
az identity create --resource-group <groupName> --name <identityName>
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
- 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.
- No painel de navegação à esquerda, selecione Controle de acesso (IAM).
- Selecione Adicionar e Adicionar atribuição de função.
- Na guia Função, selecione a função apropriada que concede acesso de leitura ao banco de dados vetorial.
- Na guia Membros, selecione a identidade gerenciada.
- Na guia Examinar + atribuir, selecione Examinar + atribuir para atribuir a função.
Escopo do recurso
az role assignment create --assignee "<managedIdentityObjectID>" \
--role "<myVectorDbReaderRole>" \
--scope "/subscriptions/<subscriptionId>/resourcegroups/<resourceGroupName>/providers/<providerName>/<resourceType>/<resourceSubType>/<resourceName>"
Escopo do grupo de recursos
az role assignment create --assignee "<managedIdentityObjectID>" \
--role "<myVectorDbReaderRole>" \
--scope "/subscriptions/<subscriptionId>/resourcegroups/<resourceGroupName>"
Escopo da assinatura
az role assignment create --assignee "<managedIdentityObjectID>" \
--role "<myVectorDbReaderRole>" \
--scope "/subscriptions/<subscriptionId>"
Escopo do grupo de gerenciamento
az role assignment create --assignee "<managedIdentityObjectID>" \
--role "<myVectorDbReaderRole>" \
--scope "/providers/Microsoft.Management/managementGroups/<managementGroupName>"
Implementar a autenticação baseada em token com o banco de dados vetorial
Os exemplos de código a seguir exigem estas bibliotecas adicionais:
Inicialize um objeto
DefaultAzureCredential
para obter a identidade gerenciada do 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". } );
Inicialize um objeto
IMemoryStore
para o banco de dados vetorial e, em seguida, use-o para criar umISemanticTextMemory
:// 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();
Crie um objeto
Kernel
e depois importe o objetoISemanticTextMemory
usando oTextMemoryPlugin
:// 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));
Use o objeto
Kernel
para invocar um prompt que inclua o recall 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 Key Vault para armazenar segredos de conexão
Se um banco de dados vetorial não der suporte à autenticação do Microsoft Entra, você poderá usar um Key Vault para armazenar seus segredos de conexão e recuperá-los com seu aplicativo do Serviço de Aplicativo. Ao usar um Key Vault 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 estas etapas, recupere uma cadeia de conexão para o 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 Key Vault
Importante
Antes de seguir estas etapas, verifique se você criou um Key Vault usando o portal do Azure.
- Navegue até seu cofre de chaves no portal do Azure.
- Na navegação à esquerda do Key Vault, selecione Objetos e selecione Segredos.
- Selecione + Gerar/importar.
- Na tela Criar um segredo, escolha os seguintes valores:
- Opções de upload:
Manual
. - Nome: Digite um nome para o segredo. O nome do segredo precisa ser exclusivo dentro de um Key Vault.
- Valor: a cadeia de conexão do banco de dados vetorial.
- Deixe os outros valores com seus padrões. Selecione Criar.
- Opções de upload:
- Quando você recebe a mensagem de que o segredo foi criado com sucesso, ele está pronto para ser usado em seu aplicativo.
Importante
Antes de seguir estas etapas, verifique se você criou um Key Vault usando a CLI do Azure.
Conceda permissões da sua conta de usuário ao cofre de chaves por meio do RBAC (Controle de Acesso Baseado em Função), atribua uma função usando o comando
az role assignment create
da CLI do Azure:az role assignment create \ --role "Key Vault Secrets User" \ --assignee "<yourEmailAddress>" \ --scope "/subscriptions/<subscriptionId>/resourceGroups/<resourceGroupName>/providers/Microsoft.KeyVault/vaults/<keyVaultName>"
Adicione a cadeia de conexão ao Key Vault usando o comando
az keyvault secret set
da CLI do Azure:az keyvault secret set \ --vault-name "<keyVaultName>" \ --name "<secretName>" \ --value "<connectionString>"
Conceder ao Serviço de Aplicativo acesso ao Key Vault
- Atribuir uma identidade gerenciada ao seu Serviço de Aplicativo.
- Adicione as funções
Key Vault Secrets User
eKey Vault Reader
à sua identidade gerenciada.
Implementar a recuperação de cadeia de conexão do Key Vault
Para usar os exemplos de código a seguir, você precisa destas bibliotecas adicionais:
- Pacote NuGet
Azure.Identity
Azure.Extensions.AspNetCore.Configuration.Secrets
Pacote NuGet- Pacote NuGet
Microsoft.Extensions.Configuration
Esses exemplos de código usam um banco de dados Redis, mas você pode aplicá-los a qualquer banco de dados vetorial que dê suporte a cadeias de conexão.
Inicialize um objeto
DefaultAzureCredential
para obter a identidade gerenciada do 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". } );
Adicione o Key Vault ao compilar sua configuração, isso mapeará seus segredos do Key Vault para o objeto
IConfigurationRoot
:// 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"]!;
Use a cadeia de conexão de banco de dados vetorial do Key Vault para inicializar um objeto
IMemoryStore
e, em seguida, use-a para criar umISemanticTextMemory
:// 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();
Crie um objeto
Kernel
e depois importe o objetoISemanticTextMemory
usando oTextMemoryPlugin
:// 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));
Use o objeto
Kernel
para invocar um prompt que inclua o recall 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 configurações de aplicativo para armazenar segredos de conexão
Se um banco de dados vetorial não der suporte à autenticação do Microsoft Entra, você pode usar as configurações do aplicativo do Serviço de Aplicativo para armazenar seus segredos de conexão. Ao usar configurações de aplicativo, você pode armazenar seus segredos de conexão sem provisionar recursos adicionais do Azure.
Antes de seguir estas etapas, recupere uma cadeia de conexão para o 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
- Navegue até a página do seu aplicativo no portal do Azure.
- No menu à esquerda do aplicativo, selecione Configurações>Configurações do aplicativo.
- Por padrão, os valores das configurações do aplicativo ficam ocultos no portal para segurança.
- Para ver um valor oculto de uma configuração de aplicativo, selecione o campo Valor.
- Selecione Nova configuração de conexão.
- 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 precisa ser exclusivo.
- Valor: a cadeia de conexão do banco de dados vetorial.
- Tipo: o tipo de conexão,
Custom
se nenhum outro se aplicar. - Deixe os outros valores com seus padrões. Selecione OK.
- Selecione Salvar de volta na página de Configuração.
Adicionar ou editar uma configuração de aplicativo com o comando az webapp config connection-string set
da CLI do Azure:
az webapp config connection-string set \
--name "<appName>" \
--resource-group "<groupName>" \
--connection-string-type "<connectionType>" \
--settings <connectionName>='<connectionString>'
Implementar a recuperação de cadeia de conexão das configurações do aplicativo
Para usar os exemplos de código a seguir, você precisa destas bibliotecas adicionais:
- Pacote NuGet
Microsoft.Extensions.Configuration
- Pacote NuGet
Microsoft.Extensions.Configuration.EnvironmentVariables
Esses exemplos de código usam um banco de dados Redis, mas você pode aplicá-los a qualquer banco de dados vetorial que dê suporte a cadeias de conexão.
Adicione variáveis de ambiente ao criar sua configuração, isso mapeará suas cadeias de conexão para o objeto
IConfigurationRoot
:// 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")!;
Use a cadeia de conexão de banco de dados vetorial da configurações do aplicativo para inicializar um objeto
IMemoryStore
e, em seguida, use-a para criar umISemanticTextMemory
:// 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();
Crie um objeto
Kernel
e depois importe o objetoISemanticTextMemory
usando oTextMemoryPlugin
:// 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));
Use o objeto
Kernel
para invocar um prompt que inclua o recall 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}");
Conteúdo relacionado
- [Use o Redis para armazenamento de memória com o SDK de Kernel Semântico]
- Como usar identidades gerenciadas para o Serviço de Aplicativo e o Azure Functions
- Etapas para atribuir funções no Azure