Adicionar uma habilidade personalizada a um pipeline de enriquecimento da Pesquisa de IA do Azure

Um pipeline de enriquecimento de IA pode incluir habilidades internas e habilidades personalizadas que você cria e publica pessoalmente. Seu código personalizado é executado externamente a partir do serviço de pesquisa (por exemplo, como uma função do Azure), mas aceita entradas e envia saídas para o conjunto de habilidades como qualquer outra habilidade.

As habilidades personalizadas podem parecer complexas, mas podem ser simples e diretas em termos de implementação. Se você tiver pacotes existentes que forneçam modelos de correspondência ou classificação de padrões, o conteúdo extraído de blobs poderá ser passado para esses modelos para processamento. Como o enriquecimento de IA é baseado no Azure, seu modelo também deve estar no Azure. Algumas metodologias comuns de hospedagem incluem o uso de Funções ou Contêineres do Azure.

Se você estiver criando uma habilidade personalizada, este artigo descreve a interface que você usa para integrar a habilidade no pipeline. O principal requisito é a capacidade de aceitar entradas e emitir saídas de maneiras que sejam consumíveis dentro do conjunto de habilidades como um todo. Como tal, o foco deste artigo está nos formatos de entrada e saída que o pipeline de enriquecimento exige.

Benefícios das habilidades personalizadas

Compilar uma competência personalizada dá-lhe uma forma de inserir transformações únicas no conteúdo. Por exemplo, pode compilar modelos de classificação personalizados para diferenciar contratos e documentos empresariais e financeiros ou adicionar uma competência de reconhecimento de voz para aceder mais detalhadamente aos ficheiros de áudio para obter conteúdo relevante. Para obter um exemplo passo a passo, consulte Exemplo: Criando uma habilidade personalizada para enriquecimento de IA.

Definir o ponto de extremidade e o intervalo de tempo limite

A interface para uma habilidade personalizada é especificada por meio da habilidade API Web personalizada.

"@odata.type": "#Microsoft.Skills.Custom.WebApiSkill",
"description": "This skill has a 230 second timeout",
"uri": "https://[your custom skill uri goes here]",
"authResourceId": "[for managed identity connections, your app's client ID goes here]",
"timeout": "PT230S",

O URI é o ponto de extremidade HTTPS da sua função ou aplicativo. Ao definir o URI, verifique se o URI é seguro (HTTPS). Se seu código estiver hospedado em um aplicativo de função do Azure, o URI deverá incluir uma chave de API no cabeçalho ou como um parâmetro de URI para autorizar a solicitação.

Se, em vez disso, sua função ou aplicativo usar identidades gerenciadas do Azure e funções do Azure para autenticação e autorização, a habilidade personalizada poderá incluir um token de autenticação na solicitação. Os pontos seguintes descrevem os requisitos para esta abordagem:

  • O serviço de pesquisa, que envia a solicitação em nome do indexador, deve ser configurado para usar uma identidade gerenciada (atribuída pelo sistema ou pelo usuário) para que o chamador possa ser autenticado pelo ID do Microsoft Entra.

  • Sua função ou aplicativo deve ser configurado para o Microsoft Entra ID.

  • Sua definição de habilidade personalizada deve incluir uma authResourceId propriedade. Esta propriedade usa um ID de aplicativo (cliente), em um formato suportado: api://<appId>.

Por padrão, a conexão com o ponto de extremidade expira se uma resposta não for retornada dentro de uma janela de 30 segundos (PT30S). O pipeline de indexação é síncrono e a indexação produzirá um erro de tempo limite se uma resposta não for recebida nesse período. Você pode aumentar o intervalo para um valor máximo de 230 segundos definindo o parâmetro de tempo limite (PT230S).

Formatar entradas da API Web

A API da Web deve aceitar uma matriz de registros a serem processados. Dentro de cada registro, forneça um pacote de propriedades como entrada para sua API da Web.

Suponha que você queira criar um enriquecimento básico que identifique a primeira data mencionada no texto de um contrato. Neste exemplo, a habilidade personalizada aceita uma única entrada "contractText" como o texto do contrato. A habilidade também tem uma única saída, que é a data do contrato. Para tornar o enriquecimento mais interessante, devolva este "contractDate" na forma de um tipo complexo de várias partes.

Sua API da Web deve estar pronta para receber um lote de registros de entrada. Cada membro da matriz "valores" representa a entrada para um registro específico. Cada registo deve conter os seguintes elementos:

  • Um membro "recordId" que é o identificador exclusivo de um registro específico. Quando o enriquecimento retorna os resultados, ele deve fornecer esse "recordId" para permitir que o chamador faça corresponder os resultados do registro à sua entrada.

  • Um membro "dados", que é essencialmente um conjunto de campos de entrada para cada registo.

A solicitação de API da Web resultante pode ter esta aparência:

{
    "values": [
      {
        "recordId": "a1",
        "data":
           {
             "contractText": 
                "This is a contract that was issues on November 3, 2023 and that involves... "
           }
      },
      {
        "recordId": "b5",
        "data":
           {
             "contractText": 
                "In the City of Seattle, WA on February 5, 2018 there was a decision made..."
           }
      },
      {
        "recordId": "c3",
        "data":
           {
             "contractText": null
           }
      }
    ]
}

Na prática, seu código pode ser chamado com centenas ou milhares de registros em vez de apenas os três mostrados aqui.

Formatar saídas da API Web

O formato da saída é um conjunto de registros contendo um "recordId" e um pacote de propriedades. Este exemplo específico tem apenas uma saída, mas você pode produzir mais de uma propriedade. Como prática recomendada, considere retornar mensagens de erro e aviso se um registro não puder ser processado.

{
  "values": 
  [
      {
        "recordId": "b5",
        "data" : 
        {
            "contractDate":  { "day" : 5, "month": 2, "year" : 2018 }
        }
      },
      {
        "recordId": "a1",
        "data" : {
            "contractDate": { "day" : 3, "month": 11, "year" : 2023 }                    
        }
      },
      {
        "recordId": "c3",
        "data" : 
        {
        },
        "errors": [ { "message": "contractText field required "}   ],  
        "warnings": [ {"message": "Date not found" }  ]
      }
    ]
}

Adicionar uma habilidade personalizada a um conjunto de habilidades

Ao criar um enriquecimento de API da Web, você pode descrever cabeçalhos e parâmetros HTTP como parte da solicitação. O trecho a seguir mostra como os parâmetros de solicitação e cabeçalhos HTTP opcionais podem ser incluídos na definição do conjunto de habilidades. Definir um cabeçalho HTTP é útil se você precisar passar definições de configuração para seu código.

{
    "skills": [
      {
        "@odata.type": "#Microsoft.Skills.Custom.WebApiSkill",
        "name": "myCustomSkill",
        "description": "This skill calls an Azure function, which in turn calls TA sentiment",
        "uri": "https://indexer-e2e-webskill.azurewebsites.net/api/DateExtractor?language=en",
        "context": "/document",
        "httpHeaders": {
            "DateExtractor-Api-Key": "foo"
        },
        "inputs": [
          {
            "name": "contractText",
            "source": "/document/content"
          }
        ],
        "outputs": [
          {
            "name": "contractDate",
            "targetName": "date"
          }
        ]
      }
  ]
}

Assistir a este vídeo

Para um vídeo de introdução e demonstração, assista à demonstração a seguir.

Próximos passos

Este artigo abordou os requisitos de interface necessários para integrar uma habilidade personalizada em um conjunto de habilidades. Continue com estes links para saber mais sobre habilidades personalizadas e composição de conjuntos de habilidades.