Creación de un conjunto de aptitudes en Azure AI Search

indexer stages

Un conjunto de aptitudes define operaciones que generan contenido textual y estructura a partir de documentos que contienen imágenes o texto no estructurado. Algunos ejemplos son OCR para imágenes, reconocimiento de entidades para texto no diferenciado y traducción de texto. Un conjunto de aptitudes se ejecuta después de extraer texto e imágenes de un origen de datos externo y después de procesar las asignaciones de campos.

En este artículo se explica cómo crear un conjunto de aptitudes mediante API de REST, pero los mismos conceptos y pasos se aplican a otros lenguajes de programación.

Las reglas para la definición del conjunto de aptitudes incluyen:

  • Un nombre único dentro de la colección de conjuntos de aptitudes. Un conjunto de aptitudes es un recurso de nivel superior que cualquier indexador puede usar.
  • Al menos una aptitud. Las habilidades de tres a cinco son típicas. El valor máximo es 30.
  • Un conjunto de aptitudes puede repetir las aptitudes del mismo tipo (por ejemplo, varias aptitudes de conformador).
  • Los conjuntos de aptitudes admiten operaciones encadenadas, bucles y ramas.

Los indizadores impulsan la ejecución del conjunto de aptitudes. Necesita un indexador, origen de datos, y un índice antes de poder probar el conjunto de aptitudes.

Sugerencia

Habilite el almacenamiento en caché de enriquecimiento para reutilizar el contenido que ya ha procesado y reducir el costo de desarrollo.

Adición de una definición de conjunto de aptitudes

Comience con la estructura básica. En la API REST Create Skillset, el cuerpo de la solicitud se crea en JSON y tiene las secciones siguientes:

{
   "name":"skillset-template",
   "description":"A description makes the skillset self-documenting (comments aren't allowed in JSON itself)",
   "skills":[
       
   ],
   "cognitiveServices":{
      "@odata.type":"#Microsoft.Azure.Search.CognitiveServicesByKey",
      "description":"An Azure AI services resource in the same region as Azure AI Search",
      "key":"<Your-Cognitive-Services-Multiservice-Key>"
   },
   "knowledgeStore":{
      "storageConnectionString":"<Your-Azure-Storage-Connection-String>",
      "projections":[
         {
            "tables":[ ],
            "objects":[ ],
            "files":[ ]
         }
      ]
    },
    "encryptionKey":{ }
}

Después del nombre y la descripción, un conjunto de aptitudes tiene cuatro propiedades principales:

  • Matriz de skills, una colección desordenada de aptitudes. Las aptitudes pueden ser utilitarias (como dividir texto), transformacionales (basadas en la inteligencia artificial de los servicios de Azure AI), o bien aptitudes personalizadas que proporcione. En la sección siguiente se proporciona un ejemplo de una matriz de aptitudes.

  • cognitiveServices se usa para las aptitudes facturables que llaman a las API de los servicios de Azure AI. Quite esta sección si no va a usar aptitudes facturables ni búsqueda de entidades personalizada. En caso contrario, asocie un recurso.

  • knowledgeStore (opcional): especifica una cuenta de Azure Storage y la configuración para proyectar la salida del conjunto de aptitudes en tablas, blobs y archivos de Azure Storage. Quite esta sección si no la necesita; de lo contrario, especifique un almacén de conocimiento.

  • encryptionKey (opcional): especifica una instancia de Azure Key Vault y las claves administradas por el cliente que se usan para cifrar contenido confidencial (descripciones, cadenas de conexión, claves) en una definición de conjunto de aptitudes. Quite esta propiedad si no va a usar el cifrado administrado por el cliente.

Adición de aptitudes

Dentro de una definición de conjunto de aptitudes, la matriz de aptitudes especifica las aptitudes que se ejecutarán. Tres a cinco aptitudes son comunes, pero puede agregar tantas aptitudes como sea necesario, sujeto a límites de servicio.

El resultado final de una canalización de enriquecimiento es el contenido textual en un índice de búsqueda o en un almacén de conocimiento. Por este motivo, la mayoría de las aptitudes crean texto a partir de imágenes (texto OCR, subtítulos, etiquetas) o analizan texto existente para crear información nueva (entidades, frases clave, sentimiento). Las aptitudes que funcionan de forma independiente se procesan en paralelo. Las aptitudes que dependen entre sí especifican la salida de una aptitud (como frases clave) como la entrada de la segunda aptitud (como la traducción de texto). El servicio de búsqueda determina el orden y entorno de ejecución de la aptitud.

Todas las aptitudes tienen un tipo, contexto, entradas y salidas. Opcionalmente, una aptitud puede tener un nombre y una descripción. En el ejemplo siguiente se muestran dos aptitudes integradas no relacionadas para poder comparar la estructura básica.

"skills": [
    {
        "@odata.type": "#Microsoft.Skills.Text.V3.EntityRecognitionSkill",
        "name": "#1",
        "description": "This skill detects organizations in the source content",
        "context": "/document",
        "categories": [
            "Organization"
        ],
        "inputs": [
            {
                "name": "text",
                "source": "/document/content"
            }
        ],
        "outputs": [
            {
                "name": "organizations",
                "targetName": "orgs"
            }
        ]
    },
    {
        "name": "#2",
        "description": "This skill detects corporate logos in the source files",
        "@odata.type": "#Microsoft.Skills.Vision.ImageAnalysisSkill",
        "context": "/document/normalized_images/*",
        "visualFeatures": [
            "brands"
        ],
        "inputs": [
            {
                "name": "image",
                "source": "/document/normalized_images/*"
            }
        ],
        "outputs": [
            {
                "name": "brands"
            }
        ]
    }
]

Cada aptitud es única en términos de sus valores de entrada y los parámetros que acepta. En la documentación de referencia de habilidades se describen todos los parámetros y propiedades de una aptitud determinada. Aunque hay diferencias, la mayoría de las aptitudes comparten un conjunto común y tienen un patrón similar.

Nota:

Puede crear conjuntos de aptitudes complejos con bucles y ramificaciones mediante la aptitud condicional para crear las expresiones. La sintaxis está basada en la notación de ruta del puntero JSON con algunas modificaciones para identificar los nodos del árbol de enriquecimiento. "/" atraviesa un nivel inferior en el árbol y "*" actúa como un operador for-each en el contexto. En los numerosos ejemplos de este artículo se muestra la sintaxis.

Establecimiento del contexto de aptitud

Cada aptitud tiene una propiedad del contexto que determina el nivel en el que se realizan las operaciones. Si la propiedad "context" no se establece explícitamente, el valor predeterminado es "/document", donde el contexto es todo el documento (se llama a la aptitud una vez por documento).

"skills":[
  {
    "@odata.type": "#Microsoft.Skills.Text.V3.EntityRecognitionSkill",
    "context": "/document",
    "inputs": [],
    "outputs": []
  },
  {
      "@odata.type": "#Microsoft.Skills.Vision.ImageAnalysisSkill",
      "context": "/document/normalized_images/*",
      "visualFeatures": [],
      "inputs": [],
      "outputs": []
  }
]

El contexto normalmente se establece en uno de los ejemplos siguientes:

Ejemplo de contexto Descripción
"context": "/document" (Valor predeterminado) Las entradas y salidas se encuentran en el nivel de documento.
"context": "/document/pages/*" Algunas aptitudes, como el análisis de sentimiento, tienen un mejor rendimiento que los fragmentos de texto más pequeños. Si va a dividir un campo de contenido grande en páginas u oraciones, el contexto debe estar sobre cada parte del componente.
"context": "/document/normalized_images/*" Para el contenido de las imágenes, las entradas y salidas son una por imagen en el documento principal.

El contexto también determina dónde se generan las salidas en el árbol de enriquecimiento. Por ejemplo, la aptitud Reconocimiento de entidades devuelve una propiedad denominada "organizations", capturada como orgs. Si el contexto es "/document", se agrega un nodo "organizations" como elemento secundario de "/document". Si después quisiera hacer referencia a este nodo en las aptitudes de nivel inferior, la ruta de acceso sería "/document/orgs".

Definir las entradas

Aptitudes leídas y escrituras en un documento enriquecido. Las entradas de aptitud especifican el origen de los datos entrantes. A menudo es el nodo raíz del documento enriquecido. En el caso de los blobs, una entrada de aptitud típica es la propiedad de contenido del documento.

La documentación de referencia de cada aptitud describe las entradas que puede consumir. Cada entrada tiene un "nombre" que identifica una entrada específica y un "origen" que especifica la ubicación de los datos del documento enriquecido. El ejemplo siguiente es de la aptitud Reconocimiento de entidades:

"inputs": [
    {
        "name": "text", 
        "source": "/document/content"
    },
    {
        "name": "languageCode", 
        "source": "/document/language"
    }
]
  • Las aptitudes pueden tener varias entradas. El "nombre" es la entrada específica. Para el reconocimiento de entidades, las entradas específicas son "text" y "languageCode".

  • La propiedad "origen" especifica qué campo o fila proporciona el contenido que se va a procesar. En el caso de las aptitudes basadas en el texto, la fuente es un campo del documento o de la fila que proporciona el texto. Para las aptitudes basadas en imágenes, el nodo que proporciona la entrada es imágenes normalizadas.

    Ejemplo de origen Descripción
    "source": "/document" Para un conjunto de datos tabulares, un documento corresponde a una fila.
    "source": "/document/content" En el caso de los blobs, el origen suele ser la propiedad de contenido del blob.
    "source": "/document/some-named-field" Para las aptitudes basadas en texto, como el reconocimiento de entidades o la extracción de frases clave, el origen debe ser un campo que contenga texto suficiente para analizar, como "description" o "summary".
    "source": "/document/normalized_images/*" En el caso del contenido de la imagen, el origen es una imagen que se ha normalizado durante el descifrado de documentos.

Si la aptitud recorre en iteración una matriz, el contexto y el origen de entrada deben incluir /* en las posiciones correctas.

Definir las salidas

Cada aptitud está diseñada para emitir tipos específicos de salida, a los que se hace referencia por el nombre en el conjunto de aptitudes. Una salida de aptitud tiene un "nombre" y un "targetName" opcional.

La documentación de referencia de cada aptitud describe los resultados que puede producir. El ejemplo siguiente es de la aptitud Reconocimiento de entidades:

"outputs": [
    {
        "name": "persons", 
        "targetName": "people"
    },
    {
        "name": "organizations", 
        "targetName": "orgs"
    },
    {
        "name": "locations", 
        "targetName": "places"
    }
]
  • Las aptitudes pueden tener varias salidas. El "nombre" identifica una salida específica. Por ejemplo, para Reconocimiento de entidades, la salida puede ser "personas", "ubicaciones", "organizaciones", entre otras.

  • "targetName" especifica el nombre que desea que este nodo tenga en el documento enriquecido. Esto resulta útil si las salidas de aptitud tienen el mismo nombre. Si tiene varias aptitudes que devuelven la misma salida, use "targetName" para eliminar la ambigüedad con los nombres de las rutas de acceso del nodo de enriquecimiento. Si no se especifica el nombre de destino, se usa la propiedad "nombre" para ambos.

Algunas situaciones requieren que se haga referencia a cada elemento de una matriz por separado. Por ejemplo, imagine que quiere pasar cada elemento de "/document/orgs" por separado a otra aptitud. Para ello, agregue un asterisco a la ruta de acceso: "/document/orgs/*".

La salida de la aptitud se escribe en el documento enriquecido como un nuevo nodo en el árbol de enriquecimiento. Puede ser un valor simple, como una puntuación de opinión o un código de idioma. También podría ser una colección, como una lista de organizaciones, personas o ubicaciones. La salida de la aptitud también es una estructura compleja, como es el caso de la aptitud "Shaper". Las entradas de la aptitud determinan la composición de la forma, pero la salida es el objeto con nombre, al que se puede hacer referencia en un índice de búsqueda, en una proyección del almacén de conocimientos o en otra aptitud por su nombre.

Incorporación de una aptitud personalizada

En esta sección se incluye un ejemplo de una aptitud personalizada. El URI apunta a una función de Azure, que, a su vez, invoca el modelo o la transformación que se proporciona. Para más información, consulte Definición de una interfaz personalizada.

Aunque la aptitud personalizada ejecuta código externo a la canalización, en una matriz de aptitudes, es simplemente otra aptitud. Al igual que las aptitudes integradas, tiene un tipo, un contexto y entradas y salidas. También lee y escribe en un árbol de enriquecimiento, igual que lo hacen las aptitudes integradas. Tenga en cuenta que el campo "context" está establecido en "/document/orgs/*" con un asterisco, lo que significa que se llama al paso de enriquecimiento para cada organización bajo "/document/orgs".

La salida, como la descripción de la empresa en este ejemplo, se genera para cada organización que se identifica. Cuando se hace referencia al nodo en un paso de bajada (por ejemplo, en la extracción de frases clave), se usaría la ruta de acceso "/document/orgs/*/companyDescription" para hacerlo.

{
  "@odata.type": "#Microsoft.Skills.Custom.WebApiSkill",
  "description": "This skill calls an Azure function, which in turn calls custom code",
  "uri": "https://indexer-e2e-webskill.azurewebsites.net/api/InvokeCode?code=foo",
  "httpHeaders": {
      "Ocp-Apim-Subscription-Key": "foobar"
  },
  "context": "/document/orgs/*",
  "inputs": [
    {
      "name": "query",
      "source": "/document/orgs/*"
    }
  ],
  "outputs": [
    {
      "name": "description",
      "targetName": "companyDescription"
    }
  ]
}

Envío de salida a un destino

Aunque la salida de la aptitud se puede almacenar opcionalmente en caché con fines de reutilización, normalmente es temporal y solo existe mientras la ejecución de aptitudes está en curso.

  • Para enviar la salida a un campo de un índice de búsqueda, cree una asignación de campos de salida en un indexador.

  • Para enviar la salida a un almacén de conocimiento, cree una proyección.

  • Para enviar la salida a una aptitud de nivel inferior, haga referencia a la salida por su nombre de nodo, como "/document/organization", en la propiedad de origen de entrada de la aptitud de nivel inferior. Para ver ejemplos, consulte Referencia a una anotación.

Sugerencias para un primer conjunto de aptitudes

  • Pruebe el Asistente para importar datos.

    El asistente automatiza varios pasos que pueden ser complicados la primera vez. Define el conjunto de aptitudes, el índice y el indexador, incluidas las asignaciones de campos y las asignaciones de campos de salida. También define proyecciones en un almacén de conocimiento si usa una. Para algunas aptitudes, como OCR o análisis de imágenes, el asistente agrega aptitudes de utilidad que combinan el contenido de imagen y texto que se separó durante el descifrado de documentos.

    Una vez ejecutado el asistente, puede abrir cada objeto en el Azure Portal para ver su definición JSON.

  • Pruebe a Depurar sesiones para invocar la ejecución del conjunto de aptitudes a través de un documento de destino e inspeccione el documento enriquecido que crea el conjunto de aptitudes. Puede ver y modificar la configuración y los valores de entrada y salida. Este tutorial es un buen punto de partida: Tutorial: Depuración de un conjunto de aptitudes mediante sesiones de depuración.

Pasos siguientes

Los campos de contexto y origen de entrada son rutas de acceso a los nodos de un árbol de enriquecimiento. Como paso siguiente, conozca mejor la sintaxis de la ruta de acceso a los nodos de un árbol de enriquecimiento.