Поделиться через


клиентская библиотека Безопасность содержимого ИИ Azure для Python версии 1.0.0

Безопасность содержимого ИИ Azure обнаруживает в приложениях и службах вредоносное содержимое, созданное пользователем и СИ. Безопасность содержимого включает API текста и изображений, которые позволяют обнаруживать опасные материалы:

  • API анализа текста: сканирует текст на наличие сексуального содержимого, насилия, ненависти и причинения себе вреда с несколькими уровнями серьезности.
  • API анализа изображений. Проверяет изображения на наличие сексуального содержимого, насилия, ненависти и причинения себе вреда с несколькими уровнями серьезности.
  • API управления списками блокировок текста. Классификаторов ИИ по умолчанию достаточно для большинства требований к безопасности содержимого; однако может потребоваться просмотреть термины, относящиеся к вашему варианту использования. Вы можете создавать списки блокировок терминов для использования с API текста.

Документация

Вы можете приступить к работе с различными документами.

Начало работы

Предварительные требования

Установка пакета

pip install azure-ai-contentsafety

Аутентификация клиента

Получение конечной точки

Конечную точку для ресурса службы Безопасность содержимого ИИ Azure можно найти с помощью портала Azure или Azure CLI:

# 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"

Создание ContentSafetyClient/BlocklistClient с ключом API

Использование ключа API в credential качестве параметра.

  • Шаг 1. Получение ключа API. Ключ API можно найти на портале Azure или с помощью следующей команды Azure CLI :

    az cognitiveservices account keys list --name "<resource-name>" --resource-group "<resource-group-name>"
    
  • Шаг 2. Передайте ключ в виде строки в экземпляр 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)
    

Создание ContentSafetyClient/BlocklistClient с учетными данными маркера идентификатора Microsoft Entra

  • Шаг 1. Включение идентификатора Microsoft Entra для ресурса. Инструкции по включению идентификатора Microsoft Entra для ресурса см. в этом документе Проверка подлинности с помощью идентификатора Microsoft Entra.

    Ниже приведены main действия.

    • Создайте ресурс с пользовательским поддоменом.
    • Создайте субъект-службу и назначьте ему роль пользователя Cognitive Services.
  • Шаг 2. Задайте значения идентификатора клиента, идентификатора клиента и секрета клиента Microsoft Entra приложения в качестве переменных среды: AZURE_CLIENT_ID, AZURE_TENANT_ID, AZURE_CLIENT_SECRET.

    DefaultAzureCredential будет использовать значения из этих переменных среды.

    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)
    

Основные понятия

Доступные функции

В этой службе доступны различные типы анализа. В следующей таблице описаны доступные в настоящее время API.

Компонент Описание
API анализа текста Сканирует текст на наличие сексуального содержимого, насилия, ненависти и причинения себе вреда с несколькими уровнями серьезности.
API анализа изображений Сканирует изображения на наличие сексуального контента, насилия, ненависти и причинения себе вреда с несколькими уровнями серьезности.
API управления списком блокировок текста Классификаторов ИИ по умолчанию достаточно для большинства потребностей в безопасности содержимого. Однако может потребоваться проверка терминов, относящихся к вашему варианту использования. Вы можете создавать списки блокировок терминов для использования с API текста.

Категории вреда

Безопасность содержимого распознает четыре отдельные категории нежелательного содержимого.

Категория Описание
Ненавижу Вред, связанный с ненавистью и справедливостью, относится к любому контенту, который атакует или использует уничижительную или дискриминационную формулировку со ссылкой на человека или группу идентичности на основе определенных отличительных атрибутов этих групп, включая, помимо прочего, расу, этническую принадлежность, национальность, половую идентичность и самовыражение, сексуальную ориентацию, религию, иммиграционный статус, статус способностей, внешность и размер тела.
Сексуальной Сексуальный описывает язык, связанный с анатомическими органами и гениталиями, романтические отношения, действия, изображаемые в эротических или ласковых терминах, беременность, физические сексуальные акты, в том числе изображаемые как нападение или насильственный акт сексуального насилия против его воли, проституция, порнография и жестокое обращение.
Насилие Насилие описывает язык, связанный с физическими действиями, направленными на причинение вреда, ранение, повреждение или убийство кого-то или чего-то; описывает оружие, оружие и связанные с ним лица, такие как производители, ассоциации, законодательство и т. д.
Причинение себе вреда Самоповреждение описывает язык, связанный с физическими действиями, направленными на то, чтобы намеренно ранить, ранить, повредить свое тело или покончить с собой.

Классификация может быть многоэтапной. Например, когда образец текста проходит через модель модерации текста, его можно классифицировать как сексуальное содержимое и насилие.

Уровни серьезности

Каждая категория вреда, применяемая службой, также имеет оценку уровня серьезности. Уровень серьезности предназначен для указания серьезности последствий отображения помеченного содержимого.

Текст. Текущая версия текстовой модели поддерживает полную шкалу серьезности от 0 до 7. По умолчанию ответ выводит 4 значения: 0, 2, 4 и 6. Каждый из двух смежных уровней сопоставляется с одним уровнем. Пользователи могут использовать "outputType" в запросе и задать для него значение "EightSeverityLevels", чтобы получить 8 значений в выходных данных: 0,1,2,3;4;5;6,7. Дополнительные сведения см. в определениях уровней серьезности текстового содержимого .

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

Изображение. Текущая версия модели образа поддерживает сокращенную версию полной шкалы серьезности от 0 до 7. Классификатор возвращает только серьезность 0, 2, 4 и 6; каждый из двух смежных уровней сопоставляется с одним уровнем. Дополнительные сведения см. в определениях уровней серьезности содержимого изображений .

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

Управление списками блокировок текста

Для управления списком блокировок текста поддерживаются следующие операции:

  • Создание или изменение списка блокировок
  • Перечисление всех списков блокировок
  • Получение списка блокировок по blocklistName
  • Добавление blocklistItems в список блокировок
  • Удаление blocklistItems из списка блокировок
  • Перечисление всех blocklistItem в списке блокировок по blocklistName
  • Получение объекта blocklistItem в списке блокировок по blocklistItemId и blocklistName
  • Удаление списка блокировок и всех его объектов blocklistItems

Вы можете задать списки блокировок, которые вы хотите использовать при анализе текста, а затем получить результат соответствия списка блокировок из возвращенного ответа.

Примеры

В следующем разделе содержится несколько фрагментов кода, охватывающих некоторые из наиболее распространенных задач службы "Безопасность содержимого", в том числе:

Ознакомьтесь с примерами данных , используемых здесь. Дополнительные примеры см. в разделе Примеры.

Анализ текста

Анализ текста без списков блокировок


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

Анализ текста с помощью списков блокировок


    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

Анализ изображения


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

Управление списком блокировок текста

Создание или обновление списка блокировок текста


    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

Список списков блокировок текста


    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

Получение списка блокировок текста


    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

Удаление списка блокировок текста


    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

Добавление 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

Перечисление 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

Получение 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

Удаление 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

Устранение неполадок

Общие сведения

Безопасность содержимого ИИ Azure клиентская библиотека вызовет исключения, определенные в Azure Core. Коды ошибок определяются следующим образом:

Код ошибки Возможные причины Предложения
InvalidRequestBody Одно или несколько полей в тексте запроса не соответствуют определению API. 1. Проверьте версию API, указанную в вызове API.
2. Проверьте соответствующее определение API для выбранной версии API.
InvalidResourceName Имя ресурса, указанное в URL-адресе, не соответствует требованиям, таким как имя списка блокировок, идентификатор термина списка блокировок и т. д. 1. Проверьте версию API, указанную в вызове API.
2. Проверьте, содержит ли данное имя недопустимые символы в соответствии с определением API.
ResourceNotFound Ресурс, указанный в URL-адресе, может не существовать, например имя списка блокировок. 1. Проверьте версию API, указанную в вызове API.
2. Двойное проверка существования ресурса, указанного в URL-адресе.
InternalError Возникли некоторые непредвиденные ситуации на стороне сервера. 1. Вы можете повторить попытку несколько раз после небольшого периода и увидеть, что проблема повторится.
2. Если эта проблема не устранена, обратитесь в службу поддержки Azure.
ServerBusy Серверная сторона не может временно обработать запрос. 1. Вы можете повторить попытку несколько раз после небольшого периода и увидеть, что проблема повторится.
2.Если эта проблема не устранена, обратитесь в службу поддержки Azure.
TooManyRequests Текущая RPS превысила квоту для текущего номера SKU. 1. Ознакомьтесь с таблицей цен, чтобы понять квоту RPS.
2.Обратитесь в службу поддержки Azure, если вам требуется дополнительный QPS.

Ведение журнала

Эта библиотека использует стандартную библиотеку ведения журнала для ведения журнала.

Основные сведения о сеансах HTTP (URL-адреса, заголовки и т. д.) регистрируются на INFO уровне.

Подробное DEBUG ведение журнала на уровне, включая тексты запросов и ответов и неотредактированные заголовки, можно включить на клиенте или для каждой операции с помощью аргумента logging_enable ключевое слово.

См. полную документацию по ведению журнала пакета SDK с примерами здесь.

Дополнительная настройка

Необязательные аргументы ключевое слово можно передавать на уровне клиента и для каждой операции. В справочной документации по azure-core описаны доступные конфигурации для повторных попыток, ведения журнала, транспортных протоколов и многого другого.

Дальнейшие действия

Дополнительная документация

Более подробную документацию по безопасности содержимого Azure см. в Безопасность содержимого ИИ Azure на docs.microsoft.com.

Участие

На этом проекте приветствуются публикации и предложения. Для участия в большинстве процессов по разработке документации необходимо принять лицензионное соглашение участника (CLA), в котором указывается, что вы предоставляете нам права на использование ваших публикаций. Для получения подробных сведений посетите веб-страницу https://cla.microsoft.com.

При отправке запроса на включение внесенных изменений CLA-бот автоматически определит необходимость предоставления соглашения CLA и соответствующего оформления запроса на включение внесенных изменений (например, добавление метки, комментария). Просто следуйте инструкциям бота. Будет достаточно выполнить их один раз для всех репозиториев, поддерживающих соглашение CLA.

В рамках этого проекта действуют правила поведения в отношении продуктов с открытым исходным кодом Майкрософт. Дополнительные сведения: Вопросы и ответы по правилам поведения. С любыми другими вопросами или комментариями обращайтесь по адресу opencode@microsoft.com.