Incorporación de una aptitud personalizada a una canalización de enriquecimiento de Azure AI Search

Una canalización de enriquecimiento con IA puede incluir aptitudes integradas y aptitudes personalizadas que cree y publique personalmente. El código personalizado se ejecuta externamente en el servicio de búsqueda (por ejemplo, como una función de Azure), pero acepta entradas y envía salidas al conjunto de aptitudes como cualquier otra aptitud.

Las aptitudes personalizadas pueden parecer complejas, pero pueden ser sencillas y directas en términos de implementación. Si ya tiene paquetes que proporcionan coincidencia de patrones o modelos de clasificación, el contenido que extraiga de los blobs podría pasarse a estos modelos para su procesamiento. Dado que el enriquecimiento con IA se basado en Azure, el modelo debe estar también en Azure. Algunas metodologías de hospedaje comunes son funciones o contenedores de Azure.

Si va a crear una aptitud personalizada, en este artículo se describe la interfaz que hay que usar para integrar la aptitud en la canalización. El requisito principal es la capacidad de aceptar entradas y emitir salidas de manera que se puedan consumir dentro del conjunto de aptitudes en conjunto. Por tanto, este artículo se centra en los formatos de entrada y salida que necesita la canalización de enriquecimiento.

Ventajas de las aptitudes personalizadas

Crear una aptitud personalizada le otorga una forma de insertar transformaciones únicas en el contenido. Una aptitud personalizada se ejecuta de forma independiente; además, puede aplicar cualquier paso de enriquecimiento que quiera. Por ejemplo, puede crear modelos de clasificación personalizados para diferenciar contratos y documentos comerciales y financieros, o agregar una aptitud de reconocimiento de voz para profundizar en el contenido relevante de los archivos de audio. Para obtener un ejemplo paso a paso, consulte Ejemplo: crear una aptitud personalizada para el enriquecimiento con IA.

Establecimiento del punto de conexión y del intervalo de tiempo de espera

La interfaz de una aptitud personalizada se especifica mediante la aptitud 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",

El URI es el punto de conexión HTTPS de la función o aplicación. Al establecer el URI, asegúrese de que sea seguro (HTTPS). Si el código se hospeda en una aplicación de funciones de Azure, el URI debe incluir una clave de API en el encabezado o como un parámetro URI para autorizar la solicitud.

Si, en lugar de eso, la función o aplicación usa identidades administradas de Azure y roles de Azure para la autenticación y autorización, la aptitud personalizada puede incluir un token de autenticación en la solicitud. En los puntos siguientes se describen los requisitos para este enfoque:

De forma predeterminada, el tiempo de expiración de la conexión al punto de conexión se agotará si no se devuelve una respuesta en un plazo de 30 segundos. La canalización de indexación es sincrónica y la indexación generará un error de tiempo de expiración si no se recibe una respuesta en ese período de tiempo. Puede aumentar el intervalo a un valor máximo de 230 segundos estableciendo el parámetro de tiempo de espera:

Dar formato a las entradas de API web

Web API debe aceptar la matriz de registros que se va a procesar. Cada registro debe tener un contenedor de propiedades que será la entrada proporcionada a la API web.

Supongamos que quiere crear una opción de enriquecimiento básica que identifique la primera fecha mencionada en el texto de un contrato. En este ejemplo, la aptitud personalizada acepta una sola entrada "contractText" como texto del contrato. Asimismo, la aptitud también tiene un único resultado, que es la fecha del contrato. Para que la opción de enriquecimiento sea más interesante, devuelva "contractDate" en la forma de un tipo complejo de varias partes.

Web API debería estar lista para recibir un lote de registros de entrada. Cada miembro de la matriz de "valores" representa la entrada de un registro en particular. Es necesario que cada registro tenga los siguientes elementos:

  • Un miembro "recordId" que sea el identificador único de un registro en particular. Cuando la operación de enriquecimiento devuelva los resultados, debe proporcionar el miembro "recordId" para permitir que el autor de la llamada haga coincidir los resultados del registro con los elementos de entrada.

  • Un miembro "data", que es esencialmente una colección de campos de entrada de cada registro.

La solicitud de API web resultante podría tener el siguiente aspecto:

{
    "values": [
      {
        "recordId": "a1",
        "data":
           {
             "contractText": 
                "This is a contract that was issues on November 3, 2017 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
           }
      }
    ]
}

En la práctica, es posible llamar al código con cientos o miles de registros en lugar de usar solo los tres que se muestran aquí.

Dar formato a las salidas de API web

El formato de salida es un conjunto de registros que contiene un miembro "recordId" y un contenedor de propiedades. Este ejemplo en particular solo tiene una salida, pero puede generar más de una propiedad. Como procedimiento recomendado, considere la posibilidad de devolver mensajes de error y advertencia si algún registro no se pudo procesar.

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

Adición de una aptitud personalizada a un conjunto de aptitudes

Cuando crea una opción de enriquecimiento de Web API, puede describir encabezados y parámetros de HTTP como parte de la solicitud. El siguiente fragmento de código muestra cómo se pueden incluir los parámetros de solicitud y los encabezados HTTP opcionales en la definición del conjunto de aptitudes. Establecer un encabezado HTTP es útil si necesita pasar valores de configuración al 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"
          }
        ]
      }
  ]
}

Vea este vídeo

Para ver una introducción en vídeo y una demostración, vea la siguiente demostración.

Pasos siguientes

En este artículo se han tratado los requisitos de la interfaz necesarios para integrar una aptitud personalizada en un conjunto de aptitudes. Continúe con estos vínculos para obtener más información sobre las aptitudes personalizadas y la composición del conjunto de aptitudes.