Habilidade de API Web personalizada em um pipeline de enriquecimento do Pesquisa de IA do Azure 

Observação

Pesquisa de IA do Azure  está disponível por meio do portal Azure, APIs REST e SDKs do Azure. Ele também sustenta o IQ do Foundry, a camada de conhecimento gerenciado que transforma o conteúdo da empresa em bases de conhecimento reutilizáveis e com reconhecimento de permissão para agentes no portal do Microsoft Foundry.

Use a habilidade de API Web personalizada para estender o enriquecimento de IA chamando um ponto de extremidade da API Web que fornece operações personalizadas. Assim como as habilidades internas, uma habilidade de API Web Personalizada tem entradas e saídas. Dependendo das entradas, sua API Web recebe um conteúdo JSON quando o indexador é executado e retorna um conteúdo JSON como resposta, juntamente com um código de status de êxito. A resposta deve incluir as saídas especificadas por sua habilidade personalizada. Qualquer outra resposta é considerada um erro e nenhum aprimoramento é executado. A estrutura do conteúdo JSON é descrita posteriormente neste documento.

A habilidade de API Web Personalizada também é usada na implementação do recurso Azure OpenAI On Your Data. Se Azure OpenAI estiver configurado para acesso baseado em função e você receber 403 Forbidden erros ao criar o índice de vetor, verifique se Pesquisa de IA do Azure  tem uma identidade atribuída pelo sistema e é executado como um serviço confiável em Azure OpenAI.

Observação

O indexador tenta mais duas vezes determinados códigos de status HTTP padrão retornados da API Web. Esses códigos de status HTTP são:

  • 502 Bad Gateway
  • 503 Service Unavailable
  • 429 Too Many Requests

@odata.type

Microsoft.Skills.Custom.WebApiSkill

Parâmetros de habilidade

Os parâmetros diferenciam maiúsculas de minúsculas.

Nome do parâmetro Description
uri O URI da API Web para o qual o conteúdo JSON é enviado. Somente o esquema do URI https é permitido. Quando você recupera o conjunto de habilidades com GET, o serviço retorna o valor ?code= do ?code=<redacted> parâmetro de consulta para evitar a exposição de chaves de função. Para atualizar a habilidade sem alterar o URI armazenado, defina uri como <unchanged>.
authResourceId (Opcional) Uma cadeia de caracteres que, quando definida, indica que essa habilidade deve usar uma identidade gerenciada pelo sistema na conexão com a função ou aplicativo que hospeda o código. Essa propriedade usa uma ID de aplicativo (cliente) ou o registro de um aplicativo em Microsoft Entra ID em qualquer um destes formatos: api://<appId>, <appId>/.defaultou api://<appId>/.default. Esse valor é usado para definir o escopo do token de autenticação recuperado pelo indexador e é enviado junto com a solicitação de habilidade de API Web personalizada para a função ou o aplicativo. Definir essa propriedade requer que seu serviço de pesquisa esteja configurado para identidade gerenciada e seu aplicativo de funções do Azure esteja configurado para um logon do Microsoft Entra. Para usar esse parâmetro, chame a API com api-version=2023-10-01-preview ou posterior. Para obter diretrizes sobre como escolher o valor correto, consulte Noções básicas sobre o authResourceId valor.
authIdentity (Opcional) Uma identidade gerenciada pelo usuário usada pelo serviço de pesquisa para se conectar à função o aplicativo que hospeda o código. Você pode usar um sistema ou uma identidade gerenciada pelo usuário. Para usar uma identidade gerenciada pelo sistema, deixe authIdentity em branco.
httpMethod O método a ser usado ao enviar o conteúdo. Os métodos permitidos são PUT ou POST
httpHeaders Uma coleção de pares chave-valor em que as chaves representam os nomes de cabeçalho e os valores representam valores de cabeçalho que são enviados para sua API Web, juntamente com o conteúdo. Os seguintes cabeçalhos são proibidos de estarem nesta coleção: Accept, Accept-Charset, Accept-Encoding, Content-Length, Content-Type, Cookie, Host, TE, Upgrade, Via. Quando você recupera o conjunto de habilidades com GET, o serviço retorna <redacted> para todos os valores de cabeçalho para evitar a exposição de credenciais, como tokens de portador e chaves de API. Para atualizar a habilidade sem alterar os valores de cabeçalho armazenados, defina cada valor como <unchanged>. O serviço restaura o valor armazenado original.
timeout (Opcional) Quando especificado, indica o tempo limite para o cliente http que fez a chamada à API. Ele deve ser formatado como um valor XSD de "dayTimeDuration" (um subconjunto restrito de um valor de duração ISO 8601 ). Por exemplo, PT60S por 60 segundos. Se não for definido, um valor padrão de 30 segundos será escolhido. O tempo limite pode ser definido para um máximo de 230 segundos e um mínimo de 1 segundo.
batchSize (Opcional) Indica quantos “registros de dados” (veja estrutura de conteúdo JSON abaixo) são enviados por chamada à API. Se não for definido, um padrão de 1.000 será escolhido. Use esse parâmetro para obter uma compensação adequada entre a taxa de transferência de indexação e a carga em sua API.
degreeOfParallelism (Opcional) Quando especificado, indica o número de chamadas que o indexador faz em paralelo ao ponto de extremidade que você fornece. Você poderá diminuir esse valor se o ponto de extremidade estiver falhando sob pressão ou elevá-lo se o ponto de extremidade conseguir manipular a carga. Se não for definido, um valor padrão de 5 segundos será usado. O degreeOfParallelism pode ser definido como um máximo de 10 e um mínimo de 1.

Entender o authResourceId valor

Quando uma habilidade de API Web personalizada usa a autenticação de identidade gerenciada, Pesquisa de IA do Azure  obtém um token de acesso Microsoft Entra e o envia para o ponto de extremidade de habilidade personalizado. A authResourceId propriedade especifica o identificador de recurso, também conhecido como público-alvo ou URI da ID do aplicativo, para o qual o token é solicitado. O valor deve corresponder ao que o aplicativo de destino espera durante a validação do token. Caso contrário, a autenticação falhará com uma 401 Unauthorized resposta.

O authResourceId valor identifica o aplicativo que hospeda sua habilidade personalizada. Não é a URL do seu serviço de pesquisa ou indexador.

A tabela a seguir mostra formatos comuns:

Aplicativo de destino authResourceId valor
Microsoft Entra aplicativo Web protegido api://<application-client-id>
Aplicativo configurado com um URI de ID de Aplicativo personalizado URI da ID do aplicativo personalizado, como api://contoso-customskill
Função Azure protegida por Microsoft Entra ID URI da ID do aplicativo configurado para o registro de aplicativo do aplicativo de funções, como api://contoso-funcapp

A propriedade aceita formatos com e sem o .default sufixo de escopo. Use api://<appId> para corresponder diretamente ao URI da ID do Aplicativo. Se você incluir um .default sufixo, por api://<appId>/.defaultexemplo, a declaração do token de aud acesso conterá o URI de ID do aplicativo base sem o sufixo.

Para obter etapas para configurar Microsoft Entra autenticação para uma função Azure e definirauthResourceId, consulte Usar uma identidade gerenciada do serviço de pesquisa para se conectar a um aplicativo de funções Azure.

Exemplo: função Azure protegida por Microsoft Entra ID

Neste exemplo, Pesquisa de IA do Azure  adquire um token de acesso para o público especificado authResourceId e inclui o token ao invocar o ponto de extremidade de habilidade personalizado.

{
  "@odata.type": "#Microsoft.Skills.Custom.WebApiSkill",
  "uri": "https://contoso-function.azurewebsites.net/api/enrich",
  "authResourceId": "api://contoso-customskill"
}

Entradas de competências

Essa habilidade não tem entradas predefinidas. As entradas são qualquer campo existente ou qualquer nó na árvore de enriquecimento que você queira passar para a habilidade personalizada.

Resultados de competências

Essa habilidade não tem saídas predefinidas. Defina um mapeamento de campo de saída no indexador se a saída da habilidade deve ser enviada para um campo no índice de pesquisa.

Definição de exemplo

{
  "@odata.type": "#Microsoft.Skills.Custom.WebApiSkill",
  "description": "A custom skill that can identify positions of different phrases in the source text",
  "uri": "https://contoso.count-things.com",
  "batchSize": 4,
  "context": "/document",
  "inputs": [
    {
      "name": "text",
      "source": "/document/content"
    },
    {
      "name": "language",
      "source": "/document/languageCode"
    },
    {
      "name": "phraseList",
      "source": "/document/keyphrases"
    }
  ],
  "outputs": [
    {
      "name": "hitPositions"
    }
  ]
}

Observação

Quando você recupera um conjunto de habilidades usando GET, o serviço retorna <redacted> para todos os httpHeaders valores e ?code=<redacted> para qualquer ?code= parâmetro de consulta no uri. Ambos os valores impedem a exposição de credenciais a chamadores que detêm a função Colaborador do Serviço de Pesquisa, mas nenhuma função no serviço externo. Para atualizar a habilidade sem alterar esses valores armazenados, passe <unchanged> para cada campo afetado.

O exemplo a seguir mostra uma resposta GET para uma habilidade que usa autenticação baseada em cabeçalho e um URI de função Azure:

{
  "@odata.type": "#Microsoft.Skills.Custom.WebApiSkill",
  "uri": "https://contoso.example.org/api?code=<redacted>",
  "httpMethod": "POST",
  "name": "myCustomSkill",
  "httpHeaders": {
    "Authorization": "<redacted>",
    "Ocp-Apim-Subscription-Key": "<redacted>"
  }
}

Para atualizar essa habilidade sem alterar os valores existentes, use <unchanged>:

{
  "uri": "<unchanged>",
  "httpHeaders": {
    "Authorization": "<unchanged>",
    "Ocp-Apim-Subscription-Key": "<unchanged>"
  }
}

Estrutura JSON de entrada de exemplo

Essa estrutura JSON representa o conteúdo que você envia para sua API Web. Ele sempre segue essas restrições:

  • A entidade de nível superior é chamada values é uma matriz de objetos. O número desses objetos é, no máximo, o batchSize.

  • Cada objeto na matriz values tem:

    • Uma recordId propriedade que é uma cadeia de caracteres exclusiva , usada para identificar esse registro.

    • Uma data propriedade que é um objeto JSON. Os campos da propriedade data correspondem aos “nomes” especificados na seção inputs da definição de habilidade. Os valores desses campos são provenientes source desses campos (que podem ser de um campo no documento ou potencialmente de outra habilidade).

{
    "values": [
      {
        "recordId": "0",
        "data":
           {
             "text": "Este es un contrato en Inglés",
             "language": "es",
             "phraseList": ["Este", "Inglés"]
           }
      },
      {
        "recordId": "1",
        "data":
           {
             "text": "Hello world",
             "language": "en",
             "phraseList": ["Hi"]
           }
      },
      {
        "recordId": "2",
        "data":
           {
             "text": "Hello world, Hi world",
             "language": "en",
             "phraseList": ["world"]
           }
      },
      {
        "recordId": "3",
        "data":
           {
             "text": "Test",
             "language": "es",
             "phraseList": []
           }
      }
    ]
}

Estrutura JSON de saída de exemplo

A "saída" corresponde à resposta retornada da sua API Web. A API Web deve retornar apenas um conteúdo JSON (verificado examinando o cabeçalho de resposta Content-Type) e deve atender às seguintes restrições:

  • Deve haver uma entidade de nível superior chamada values, que deve ser uma matriz de objetos.

  • O número de objetos na matriz deve ser o mesmo que o número de objetos enviados para a API Web.

  • Cada objeto deve ter:

    • Uma propriedade recordId.

    • Uma propriedade data, que é um objeto no qual os campos são aprimoramentos correspondendo aos "nomes" no output e cujo valor é considerado o aprimoramento.

    • Uma propriedade errors, uma matriz listando os erros encontrados que são adicionados ao histórico de execução do indexador. Essa propriedade é necessária, mas pode ter um valor null.

    • Uma propriedade warnings, uma matriz listando os avisos encontrados que são adicionados ao histórico de execução do indexador. Essa propriedade é necessária, mas pode ter um valor null.

  • A ordenação de objetos no values na solicitação ou na resposta não é importante. No entanto, recordId é usado para correlação, de modo que qualquer registro na resposta que contenha um recordId, que não fazia parte da solicitação original para a API Web, seja descartado.

{
    "values": [
        {
            "recordId": "3",
            "data": {
            },
            "errors": [
              {
                "message" : "'phraseList' should not be null or empty"
              }
            ],
            "warnings": null
        },
        {
            "recordId": "2",
            "data": {
                "hitPositions": [6, 16]
            },
            "errors": null,
            "warnings": null
        },
        {
            "recordId": "0",
            "data": {
                "hitPositions": [0, 23]
            },
            "errors": null,
            "warnings": null
        },
        {
            "recordId": "1",
            "data": {
                "hitPositions": []
            },
            "errors": null,
            "warnings": [
              {
                "message": "No occurrences of 'Hi' were found in the input text"
              }
            ]
        },
    ]
}

Casos de erro

Além de sua API Web estar indisponível ou enviar códigos de status não bem-sucedidos, considere os seguintes casos como erros:

  • Se a API Web retornar um código de status de êxito, mas a resposta indicar que não application/jsoné, a resposta será inválida e nenhum enriquecimento será executado.

  • Se a matriz de resposta values contiver registros inválidos (por exemplo, ausentes ou duplicados recordId), os registros inválidos não serão enriquecidos. Ao desenvolver habilidades personalizadas, siga o contrato de habilidade da API Web. Você pode consultar este exemplo fornecido no Repositório do Power Skill que segue o contrato esperado.

Para casos em que a API Web não está disponível ou retorna um erro HTTP, o histórico de execução do indexador inclui um erro amigável com quaisquer detalhes disponíveis sobre o erro HTTP.

Considerações de segurança para autenticação de identidade gerenciada

Ao usar a autenticação de identidade gerenciada com uma habilidade de API Web personalizada, Pesquisa de IA do Azure  obtém um token de acesso Microsoft Entra para o aplicativo identificado authResourceId e inclui esse token em solicitações enviadas ao ponto de extremidade especificado por uri. O ponto de extremidade referenciado normalmente uri é sua função Azure, Serviço de Aplicativo do Azure, Gerenciamento de API do Azure ponto de extremidade ou outro aplicativo protegido por Microsoft Entra. Você é responsável por configurar e manter a relação entre o ponto de extremidade e o aplicativo identificado por authResourceId.

Independentemente do método de autenticação, as entradas de habilidade personalizadas podem conter valores de documentos ou valores fornecidos pelo cliente derivados desses documentos. Trate todas as entradas de habilidade personalizadas como não confiáveis. Pesquisa de IA do Azure  encaminha as entradas configuradas no conjunto de habilidades para o ponto de extremidade sem interpretar, validar ou restringir o conteúdo para sua implementação personalizada.

Valide e restrinja valores derivados de documento em sua habilidade personalizada antes de usá-los em solicitações de saída ou outras operações sensíveis à segurança. Use validação de entrada, listas de permissões de destino, validação de URL e nome do host, restrições de protocolo e acesso à rede com privilégios mínimos que permitem apenas os destinos e portas que a habilidade exige. Para obter mais informações, consulte estratégias de arquitetura para rede e conectividade.

Para ajudar a manter uma implantação segura, siga estas práticas:

  • Configure a uri propriedade para apontar apenas para pontos de extremidade confiáveis destinados a receber solicitações de Pesquisa de IA do Azure .
  • Configure authResourceId para identificar o aplicativo Microsoft Entra que deve receber e validar o token de acesso.
  • Verifique se o aplicativo que recebe solicitações valida declarações de token padrão, incluindo audiência (aud), emissor (iss), locatário (tid) e quaisquer funções ou permissões de aplicativo necessárias, antes de processar solicitações.
  • Aplique o princípio de privilégio mínimo ao conceder permissões ao Pesquisa de IA do Azure  identidade gerenciada.
  • Examine periodicamente as definições de habilidade da API Web personalizada, Microsoft Entra registros de aplicativo e atribuições de função de aplicativo e permissões concedidas a Pesquisa de IA do Azure  identidades gerenciadas. Examine as alterações de configuração por meio dos processos estabelecidos de gerenciamento de alterações e revisão de segurança.
  • Examine periodicamente as configurações de ponto de extremidade para Azure Functions, Serviços de Aplicativo, APIs e gateways de API.
  • Monitore logs de entrada do aplicativo, eventos de autenticação e logs de acesso à API para atividades inesperadas ou não autorizadas.
  • Remova pontos de extremidade não utilizados, permissões, registros de aplicativo e atribuições de função que não são mais necessárias.

Restringir o acesso à configuração do conjunto de habilidades

Os usuários que podem criar, modificar ou executar conjuntos de habilidades podem controlar o ponto de extremidade de destino e a configuração de autenticação usada por uma habilidade de API Web personalizada. Restrinja essas permissões a administradores confiáveis e siga seus processos padrão de revisão de segurança e gerenciamento de alterações ao configurar habilidades personalizadas habilitadas para identidade gerenciada.

Importante

O authResourceId valor identifica o aplicativo destinatário pretendido para o token de acesso. Verifique se o ponto de extremidade especificado uri é o ponto de extremidade que deve receber e validar tokens para esse aplicativo. A configuração incorreta pode resultar em falhas de autenticação ou solicitações sendo enviadas para um ponto de extremidade não intencional.

Consulte também