Segurança de Conteúdo de IA do Azure biblioteca de clientes para Python – versão 1.0.0

Segurança de Conteúdo de IA do Azure detecta conteúdo prejudicial gerado pelo usuário e gerado por IA em aplicativos e serviços. A Segurança de Conteúdo inclui APIs de texto e imagem que permitem detectar material prejudicial:

  • API de Análise de Texto: examina o texto quanto a conteúdo sexual, violência, ódio e automutilação com níveis de várias gravidades.
  • API de Análise de Imagem: examina imagens de conteúdo sexual, violência, ódio e automutilação com níveis de múltipla gravidade.
  • APIs de Gerenciamento de Lista de Bloqueados de Texto: os classificadores de IA padrão são suficientes para a maioria das necessidades de segurança de conteúdo; no entanto, talvez seja necessário examinar os termos específicos para seu caso de uso. Você pode criar listas de bloqueio de termos a serem usados com a API de Texto.

Documentação

Várias documentações estão disponíveis para ajudá-lo a começar

Introdução

Pré-requisitos

Instalar o pacote

pip install azure-ai-contentsafety

Autenticar o cliente

Obter o ponto de extremidade

Você pode encontrar o ponto de extremidade do recurso de serviço Segurança de Conteúdo de IA do Azure usando o Portal do Azure ou a CLI do Azure:

# Get the endpoint for the Azure AI Content Safety service resource
az cognitiveservices account show --name "resource-name" --resource-group "resource-group-name" --query "properties.endpoint"

Criar um ContentSafetyClient/BlocklistClient com a chave de API

Para usar uma chave de API como o credential parâmetro .

  • Etapa 1: Obter a chave de API. A chave de API pode ser encontrada no Portal do Azure ou executando o seguinte comando da CLI do Azure :

    az cognitiveservices account keys list --name "<resource-name>" --resource-group "<resource-group-name>"
    
  • Etapa 2: passe a chave como uma cadeia de caracteres para uma instância do AzureKeyCredential.

    from azure.core.credentials import AzureKeyCredential
    from azure.ai.contentsafety import ContentSafetyClient, BlocklistClient
    
    endpoint = "https://<my-custom-subdomain>.cognitiveservices.azure.com/"
    credential = AzureKeyCredential("<api_key>")
    content_safety_client = ContentSafetyClient(endpoint, credential)
    blocklist_client = BlocklistClient(endpoint, credential)
    

Criar um ContentSafetyClient/BlocklistClient com Microsoft Entra credencial de token de ID

  • Etapa 1: habilitar Microsoft Entra ID para o recurso. Consulte este documento Autenticar com Microsoft Entra ID para ver as etapas para habilitar Microsoft Entra ID para o recurso.

    As main etapas são:

    • Crie um recurso com um subdomínio personalizado.
    • Crie uma Entidade de Serviço e atribua a função de Usuário dos Serviços Cognitivos a ela.
  • Etapa 2: defina os valores da ID do cliente, da ID do locatário e do segredo do cliente do aplicativo Microsoft Entra como variáveis de ambiente: AZURE_CLIENT_ID, AZURE_TENANT_ID, AZURE_CLIENT_SECRET.

    DefaultAzureCredential usará os valores dessas variáveis de ambiente.

    from azure.identity import DefaultAzureCredential
    from azure.ai.contentsafety import ContentSafetyClient, BlocklistClient
    
    endpoint = "https://<my-custom-subdomain>.cognitiveservices.azure.com/"
    credential = DefaultAzureCredential()
    content_safety_client = ContentSafetyClient(endpoint, credential)
    blocklist_client = BlocklistClient(endpoint, credential)
    

Principais conceitos

Recursos disponíveis

Há diferentes tipos de análise disponíveis nesse serviço. A tabela a seguir descreve as funções atuais.

Recurso Descrição
API de Análise de Texto Examina o texto quanto a conteúdo sexual, violência, ódio e automutilação com níveis de várias gravidades.
API de Análise de Imagem Examina imagens de conteúdo sexual, violência, ódio e automutilação com níveis de múltipla gravidade.
APIs de gerenciamento de lista de bloqueio de texto Os classificadores de IA padrão são suficientes para a maioria das necessidades de segurança de conteúdo. No entanto, talvez seja necessário examinar os termos específicos para seu caso de uso. Você pode criar listas de bloqueio de termos a serem usados com a API de Texto.

Categorias de danos

O Content Safety reconhece quatro categorias distintas de conteúdo questionável.

Categoria Descrição
Ódio Os danos relacionados ao ódio e à imparcialidade referem-se a qualquer conteúdo que ataque ou use linguagem pejorativa ou discriminatória com referência a uma pessoa ou grupo de identidade com base em certos atributos diferenciais desses grupos, incluindo, mas não se limitando a raça, etnia, nacionalidade, identidade e expressão de gênero, orientação sexual, religião, status de imigração, capacidade status, aparência pessoal e tamanho do corpo.
Sexual Sexual descreve linguagem relacionada a órgãos anatômicos e genitais, relacionamentos românticos, atos retratados em termos eróticos ou afetuosos, gravidez, atos sexuais físicos, incluindo aqueles retratados como uma agressão ou um ato violento sexual forçado contra a vontade, prostituição, pornografia e abuso.
Violência Violência descreve a linguagem relacionada a ações físicas destinadas a ferir, ferir, danificar ou matar alguém ou algo assim; descreve armas, armas e entidades relacionadas, como fabricantes, associações, legislação e assim por diante.
Automutilação Auto-mutilação descreve a linguagem relacionada a ações físicas destinadas a ferir, ferir, danificar o corpo ou se matar propositalmente.

A classificação pode ter vários rótulos. Por exemplo, quando uma amostra de texto passa pelo modelo de moderação de texto, ela pode ser classificada como Conteúdo sexual e Violência.

Níveis de severidade

Cada categoria de dano que o serviço aplica também vem com uma classificação de nível de severidade. O nível de severidade deve indicar a gravidade das consequências de mostrar o conteúdo sinalizado.

Texto: a versão atual do modelo de texto dá suporte à escala de severidade completa de 0 a 7. Por padrão, a resposta produzirá quatro valores: 0, 2, 4 e 6. Cada dois níveis adjacentes são mapeados para um único nível. Os usuários podem usar "outputType" na solicitação e defini-lo como "EightSeverityLevels" para obter 8 valores na saída: 0,1,2,3,4,5,6,7. Você pode consultar definições de níveis de severidade de conteúdo de texto para obter detalhes.

  • [0,1] -> 0
  • [2,3] -> 2
  • [4,5] -> 4
  • [6,7] -> 6

Imagem: a versão atual do modelo de imagem dá suporte à versão cortada da escala de severidade completa de 0 a 7. O classificador retorna apenas as severidades 0, 2, 4 e 6; cada dois níveis adjacentes são mapeados para um único nível. Você pode consultar definições de níveis de severidade de conteúdo de imagem para obter detalhes.

  • [0,1] -> 0
  • [2,3] -> 2
  • [4,5] -> 4
  • [6,7] -> 6

Gerenciamento de lista de bloqueios de texto

Há suporte para as seguintes operações para gerenciar sua lista de bloqueados de texto:

  • Criar ou modificar uma lista de bloqueados
  • Listar todas as listas de bloqueados
  • Obter uma lista de bloqueios por blocklistName
  • Adicionar blocklistItems a uma lista de bloqueios
  • Remover blocklistItems de uma lista de bloqueios
  • Listar todos os blocklistItems em uma lista de bloqueios por blocklistName
  • Obter um blocklistItem em uma lista de bloqueios por blocklistItemId e blocklistName
  • Excluir uma lista de bloqueios e todos os seus blocklistItems

Você pode definir as listas de bloqueio que deseja usar ao analisar texto e, em seguida, obter o resultado da correspondência da lista de bloqueios da resposta retornada.

Exemplos

A seção a seguir fornece vários snippets de código que abrangem algumas das tarefas mais comuns do serviço de Segurança de Conteúdo, incluindo:

Consulte os dados de exemplo para os dados usados aqui. Para obter mais exemplos, consulte exemplos.

Analisar o texto

Analisar texto sem listas de bloqueio


    import os
    from azure.ai.contentsafety import ContentSafetyClient
    from azure.ai.contentsafety.models import TextCategory
    from azure.core.credentials import AzureKeyCredential
    from azure.core.exceptions import HttpResponseError
    from azure.ai.contentsafety.models import AnalyzeTextOptions

    key = os.environ["CONTENT_SAFETY_KEY"]
    endpoint = os.environ["CONTENT_SAFETY_ENDPOINT"]

    # Create a Content Safety client
    client = ContentSafetyClient(endpoint, AzureKeyCredential(key))

    # Construct a request
    request = AnalyzeTextOptions(text="You are an idiot")

    # Analyze text
    try:
        response = client.analyze_text(request)
    except HttpResponseError as e:
        print("Analyze text failed.")
        if e.error:
            print(f"Error code: {e.error.code}")
            print(f"Error message: {e.error.message}")
            raise
        print(e)
        raise

    hate_result = next(item for item in response.categories_analysis if item.category == TextCategory.HATE)
    self_harm_result = next(item for item in response.categories_analysis if item.category == TextCategory.SELF_HARM)
    sexual_result = next(item for item in response.categories_analysis if item.category == TextCategory.SEXUAL)
    violence_result = next(item for item in response.categories_analysis if item.category == TextCategory.VIOLENCE)

    if hate_result:
        print(f"Hate severity: {hate_result.severity}")
    if self_harm_result:
        print(f"SelfHarm severity: {self_harm_result.severity}")
    if sexual_result:
        print(f"Sexual severity: {sexual_result.severity}")
    if violence_result:
        print(f"Violence severity: {violence_result.severity}")

Analisar texto com listas de bloqueios


    import os
    from azure.ai.contentsafety import ContentSafetyClient
    from azure.core.credentials import AzureKeyCredential
    from azure.ai.contentsafety.models import AnalyzeTextOptions
    from azure.core.exceptions import HttpResponseError

    key = os.environ["CONTENT_SAFETY_KEY"]
    endpoint = os.environ["CONTENT_SAFETY_ENDPOINT"]

    # Create a Content Safety client
    client = ContentSafetyClient(endpoint, AzureKeyCredential(key))

    blocklist_name = "TestBlocklist"
    input_text = "I h*te you and I want to k*ll you."

    try:
        # After you edit your blocklist, it usually takes effect in 5 minutes, please wait some time before analyzing with blocklist after editing.
        analysis_result = client.analyze_text(
            AnalyzeTextOptions(text=input_text, blocklist_names=[blocklist_name], halt_on_blocklist_hit=False)
        )
        if analysis_result and analysis_result.blocklists_match:
            print("\nBlocklist match results: ")
            for match_result in analysis_result.blocklists_match:
                print(
                    f"BlocklistName: {match_result.blocklist_name}, BlockItemId: {match_result.blocklist_item_id}, "
                    f"BlockItemText: {match_result.blocklist_item_text}"
                )
    except HttpResponseError as e:
        print("\nAnalyze text failed: ")
        if e.error:
            print(f"Error code: {e.error.code}")
            print(f"Error message: {e.error.message}")
            raise
        print(e)
        raise

Analisar a imagem


    import os
    from azure.ai.contentsafety import ContentSafetyClient
    from azure.ai.contentsafety.models import ImageCategory
    from azure.core.credentials import AzureKeyCredential
    from azure.core.exceptions import HttpResponseError
    from azure.ai.contentsafety.models import AnalyzeImageOptions, ImageData

    key = os.environ["CONTENT_SAFETY_KEY"]
    endpoint = os.environ["CONTENT_SAFETY_ENDPOINT"]
    image_path = os.path.abspath(os.path.join(os.path.abspath(__file__), "..", "./sample_data/image.jpg"))

    # Create a Content Safety client
    client = ContentSafetyClient(endpoint, AzureKeyCredential(key))

    # Build request
    with open(image_path, "rb") as file:
        request = AnalyzeImageOptions(image=ImageData(content=file.read()))

    # Analyze image
    try:
        response = client.analyze_image(request)
    except HttpResponseError as e:
        print("Analyze image failed.")
        if e.error:
            print(f"Error code: {e.error.code}")
            print(f"Error message: {e.error.message}")
            raise
        print(e)
        raise

    hate_result = next(item for item in response.categories_analysis if item.category == ImageCategory.HATE)
    self_harm_result = next(item for item in response.categories_analysis if item.category == ImageCategory.SELF_HARM)
    sexual_result = next(item for item in response.categories_analysis if item.category == ImageCategory.SEXUAL)
    violence_result = next(item for item in response.categories_analysis if item.category == ImageCategory.VIOLENCE)

    if hate_result:
        print(f"Hate severity: {hate_result.severity}")
    if self_harm_result:
        print(f"SelfHarm severity: {self_harm_result.severity}")
    if sexual_result:
        print(f"Sexual severity: {sexual_result.severity}")
    if violence_result:
        print(f"Violence severity: {violence_result.severity}")

Gerenciar lista de bloqueios de texto

Criar ou atualizar a lista de bloqueios de texto


    import os
    from azure.ai.contentsafety import BlocklistClient
    from azure.ai.contentsafety.models import TextBlocklist
    from azure.core.credentials import AzureKeyCredential
    from azure.core.exceptions import HttpResponseError

    key = os.environ["CONTENT_SAFETY_KEY"]
    endpoint = os.environ["CONTENT_SAFETY_ENDPOINT"]

    # Create a Blocklist client
    client = BlocklistClient(endpoint, AzureKeyCredential(key))

    blocklist_name = "TestBlocklist"
    blocklist_description = "Test blocklist management."

    try:
        blocklist = client.create_or_update_text_blocklist(
            blocklist_name=blocklist_name,
            options=TextBlocklist(blocklist_name=blocklist_name, description=blocklist_description),
        )
        if blocklist:
            print("\nBlocklist created or updated: ")
            print(f"Name: {blocklist.blocklist_name}, Description: {blocklist.description}")
    except HttpResponseError as e:
        print("\nCreate or update text blocklist failed: ")
        if e.error:
            print(f"Error code: {e.error.code}")
            print(f"Error message: {e.error.message}")
            raise
        print(e)
        raise

Listar listas de bloqueados de texto


    import os
    from azure.ai.contentsafety import BlocklistClient
    from azure.core.credentials import AzureKeyCredential
    from azure.core.exceptions import HttpResponseError

    key = os.environ["CONTENT_SAFETY_KEY"]
    endpoint = os.environ["CONTENT_SAFETY_ENDPOINT"]

    # Create a Blocklist client
    client = BlocklistClient(endpoint, AzureKeyCredential(key))

    try:
        blocklists = client.list_text_blocklists()
        if blocklists:
            print("\nList blocklists: ")
            for blocklist in blocklists:
                print(f"Name: {blocklist.blocklist_name}, Description: {blocklist.description}")
    except HttpResponseError as e:
        print("\nList text blocklists failed: ")
        if e.error:
            print(f"Error code: {e.error.code}")
            print(f"Error message: {e.error.message}")
            raise
        print(e)
        raise

Obter lista de bloqueio de texto


    import os
    from azure.ai.contentsafety import BlocklistClient
    from azure.core.credentials import AzureKeyCredential
    from azure.core.exceptions import HttpResponseError

    key = os.environ["CONTENT_SAFETY_KEY"]
    endpoint = os.environ["CONTENT_SAFETY_ENDPOINT"]

    # Create a Blocklist client
    client = BlocklistClient(endpoint, AzureKeyCredential(key))

    blocklist_name = "TestBlocklist"

    try:
        blocklist = client.get_text_blocklist(blocklist_name=blocklist_name)
        if blocklist:
            print("\nGet blocklist: ")
            print(f"Name: {blocklist.blocklist_name}, Description: {blocklist.description}")
    except HttpResponseError as e:
        print("\nGet text blocklist failed: ")
        if e.error:
            print(f"Error code: {e.error.code}")
            print(f"Error message: {e.error.message}")
            raise
        print(e)
        raise

Excluir lista de bloqueios de texto


    import os
    from azure.ai.contentsafety import BlocklistClient
    from azure.core.credentials import AzureKeyCredential
    from azure.core.exceptions import HttpResponseError

    key = os.environ["CONTENT_SAFETY_KEY"]
    endpoint = os.environ["CONTENT_SAFETY_ENDPOINT"]

    # Create a Blocklist client
    client = BlocklistClient(endpoint, AzureKeyCredential(key))

    blocklist_name = "TestBlocklist"

    try:
        client.delete_text_blocklist(blocklist_name=blocklist_name)
        print(f"\nDeleted blocklist: {blocklist_name}")
    except HttpResponseError as e:
        print("\nDelete blocklist failed:")
        if e.error:
            print(f"Error code: {e.error.code}")
            print(f"Error message: {e.error.message}")
            raise
        print(e)
        raise

Adicionar blockItems


    import os
    from azure.ai.contentsafety import BlocklistClient
    from azure.ai.contentsafety.models import AddOrUpdateTextBlocklistItemsOptions, TextBlocklistItem
    from azure.core.credentials import AzureKeyCredential
    from azure.core.exceptions import HttpResponseError

    key = os.environ["CONTENT_SAFETY_KEY"]
    endpoint = os.environ["CONTENT_SAFETY_ENDPOINT"]

    # Create a Blocklist client
    client = BlocklistClient(endpoint, AzureKeyCredential(key))

    blocklist_name = "TestBlocklist"
    block_item_text_1 = "k*ll"
    block_item_text_2 = "h*te"

    block_items = [TextBlocklistItem(text=block_item_text_1), TextBlocklistItem(text=block_item_text_2)]
    try:
        result = client.add_or_update_blocklist_items(
            blocklist_name=blocklist_name, options=AddOrUpdateTextBlocklistItemsOptions(blocklist_items=block_items)
        )
        for block_item in result.blocklist_items:
            print(
                f"BlockItemId: {block_item.blocklist_item_id}, Text: {block_item.text}, Description: {block_item.description}"
            )
    except HttpResponseError as e:
        print("\nAdd block items failed: ")
        if e.error:
            print(f"Error code: {e.error.code}")
            print(f"Error message: {e.error.message}")
            raise
        print(e)
        raise

Listar blockItems


    import os
    from azure.ai.contentsafety import BlocklistClient
    from azure.core.credentials import AzureKeyCredential
    from azure.core.exceptions import HttpResponseError

    key = os.environ["CONTENT_SAFETY_KEY"]
    endpoint = os.environ["CONTENT_SAFETY_ENDPOINT"]

    # Create a Blocklist client
    client = BlocklistClient(endpoint, AzureKeyCredential(key))

    blocklist_name = "TestBlocklist"

    try:
        block_items = client.list_text_blocklist_items(blocklist_name=blocklist_name)
        if block_items:
            print("\nList block items: ")
            for block_item in block_items:
                print(
                    f"BlockItemId: {block_item.blocklist_item_id}, Text: {block_item.text}, "
                    f"Description: {block_item.description}"
                )
    except HttpResponseError as e:
        print("\nList block items failed: ")
        if e.error:
            print(f"Error code: {e.error.code}")
            print(f"Error message: {e.error.message}")
            raise
        print(e)
        raise

Obter blockItem


    import os
    from azure.ai.contentsafety import BlocklistClient
    from azure.core.credentials import AzureKeyCredential
    from azure.ai.contentsafety.models import TextBlocklistItem, AddOrUpdateTextBlocklistItemsOptions
    from azure.core.exceptions import HttpResponseError

    key = os.environ["CONTENT_SAFETY_KEY"]
    endpoint = os.environ["CONTENT_SAFETY_ENDPOINT"]

    # Create a Blocklist client
    client = BlocklistClient(endpoint, AzureKeyCredential(key))

    blocklist_name = "TestBlocklist"
    block_item_text_1 = "k*ll"

    try:
        # Add a blockItem
        add_result = client.add_or_update_blocklist_items(
            blocklist_name=blocklist_name,
            options=AddOrUpdateTextBlocklistItemsOptions(blocklist_items=[TextBlocklistItem(text=block_item_text_1)]),
        )
        if not add_result or not add_result.blocklist_items or len(add_result.blocklist_items) <= 0:
            raise RuntimeError("BlockItem not created.")
        block_item_id = add_result.blocklist_items[0].blocklist_item_id

        # Get this blockItem by blockItemId
        block_item = client.get_text_blocklist_item(blocklist_name=blocklist_name, blocklist_item_id=block_item_id)
        print("\nGet blockitem: ")
        print(
            f"BlockItemId: {block_item.blocklist_item_id}, Text: {block_item.text}, Description: {block_item.description}"
        )
    except HttpResponseError as e:
        print("\nGet block item failed: ")
        if e.error:
            print(f"Error code: {e.error.code}")
            print(f"Error message: {e.error.message}")
            raise
        print(e)
        raise

Remover blockItems


    import os
    from azure.ai.contentsafety import BlocklistClient
    from azure.core.credentials import AzureKeyCredential
    from azure.ai.contentsafety.models import (
        TextBlocklistItem,
        AddOrUpdateTextBlocklistItemsOptions,
        RemoveTextBlocklistItemsOptions,
    )
    from azure.core.exceptions import HttpResponseError

    key = os.environ["CONTENT_SAFETY_KEY"]
    endpoint = os.environ["CONTENT_SAFETY_ENDPOINT"]

    # Create a Blocklist client
    client = BlocklistClient(endpoint, AzureKeyCredential(key))

    blocklist_name = "TestBlocklist"
    block_item_text_1 = "k*ll"

    try:
        # Add a blockItem
        add_result = client.add_or_update_blocklist_items(
            blocklist_name=blocklist_name,
            options=AddOrUpdateTextBlocklistItemsOptions(blocklist_items=[TextBlocklistItem(text=block_item_text_1)]),
        )
        if not add_result or not add_result.blocklist_items or len(add_result.blocklist_items) <= 0:
            raise RuntimeError("BlockItem not created.")
        block_item_id = add_result.blocklist_items[0].blocklist_item_id

        # Remove this blockItem by blockItemId
        client.remove_blocklist_items(
            blocklist_name=blocklist_name, options=RemoveTextBlocklistItemsOptions(blocklist_item_ids=[block_item_id])
        )
        print(f"\nRemoved blockItem: {add_result.blocklist_items[0].blocklist_item_id}")
    except HttpResponseError as e:
        print("\nRemove block item failed: ")
        if e.error:
            print(f"Error code: {e.error.code}")
            print(f"Error message: {e.error.message}")
            raise
        print(e)
        raise

Solução de problemas

Geral

Segurança de Conteúdo de IA do Azure biblioteca de clientes gerará exceções definidas no Azure Core. Os códigos de erro são definidos como abaixo:

Código do Erro Possíveis motivos Sugestões
InvalidRequestBody Um ou mais campos no corpo da solicitação não correspondem à definição de API. 1. Verifique a versão da API especificada na chamada à API.
2. Verifique a definição de API correspondente à versão de API selecionada.
InvalidResourceName O nome do recurso especificado na URL não atende aos requisitos, como o nome da lista de bloqueios, a ID do termo da lista de bloqueios etc. 1. Verifique a versão da API especificada na chamada à API.
2. Verifique se o nome fornecido tem caracteres inválidos de acordo com a definição de API.
ResourceNotFound O recurso especificado na URL talvez não exista, como o nome da lista de bloqueios. 1. Verifique a versão da API especificada na chamada à API.
2. Verifique a existência do recurso especificado na URL.
InternalError Algumas situações inesperadas no lado do servidor foram disparadas. 1. O ideal é tentar de novo algumas vezes após algum tempo e ver se o problema ocorre novamente.
2. Entre em contato com o Suporte do Azure caso o problema persista.
ServerBusy O lado do servidor não pode processar a solicitação temporariamente. 1. O ideal é tentar de novo algumas vezes após algum tempo e ver se o problema ocorre novamente.
2. Entre em contato com o Suporte do Azure caso o problema persista.
TooManyRequests O RPS atual excedeu a cota do SKU atual. 1. Verifique a tabela de preços para entender a cota de RPS.
2. Entre em contato com o Suporte do Azure caso precise obter mais QPS.

Registro em log

Essa biblioteca usa a biblioteca de log padrão para registro em log.

Informações básicas sobre sessões HTTP (URLs, cabeçalhos etc.) são registradas no INFO nível.

O log de nível detalhadoDEBUG, incluindo corpos de solicitação/resposta e cabeçalhos não redigidos, pode ser habilitado no cliente ou por operação com o logging_enable argumento palavra-chave.

Confira a documentação completa de registro em log do SDK com exemplos aqui.

Configuração opcional

Argumentos opcionais de palavra-chave podem ser passados no nível do cliente e por operação. A documentação de referência do azure-core descreve as configurações disponíveis para repetições, registro em log, protocolos de transporte e muito mais.

Próximas etapas

Documentação adicional

Para obter uma documentação mais abrangente sobre a Segurança de Conteúdo do Azure, consulte o Segurança de Conteúdo de IA do Azure no docs.microsoft.com.

Contribuição

Este projeto aceita contribuições e sugestões. A maioria das contribuições exige que você concorde com um CLA (Contrato de Licença do Colaborador) declarando que você tem o direito de nos conceder, e de fato concede, os direitos de usar sua contribuição. Para obter detalhes, visite https://cla.microsoft.com.

Quando você envia uma solicitação de pull, um bot do CLA determina automaticamente se você precisa fornecer um CLA e preencher a PR corretamente (por exemplo, rótulo, comentário). Basta seguir as instruções fornecidas pelo bot. Você só precisará fazer isso uma vez em todos os repositórios que usam nosso CLA.

Este projeto adotou o Código de Conduta de Software Livre da Microsoft. Para saber mais, confira as Perguntas frequentes sobre o Código de Conduta ou contate o opencode@microsoft.com caso tenha outras dúvidas ou comentários.