Compartir vía


Crear un índice vectorial

En la Búsqueda de Azure AI, un almacén vectorial tiene un esquema de índice que define los campos vectoriales y no vectoriales, una configuración vectorial para los algoritmos que crean y comprimen el espacio de inserción y la configuración en las definiciones de los campos vectoriales que se usan en las solicitudes de consulta.

La API Crear o actualizar índice crea el almacén de vectores. Sigue estos pasos para indexar los datos vectoriales:

  • Defina un esquema con algoritmos vectoriales y compresión opcional.
  • Agregue definiciones de campos vectoriales.
  • Cargue los datos prevectorizados como un paso independiente, o bien use la vectorización integrada para la fragmentación y codificación de datos durante la indexación.

En este artículo se explica el flujo de trabajo y se usa REST para fines de ilustración. Una vez que comprenda el flujo de trabajo básico, continúe con los ejemplos de código del SDK de Azure en el repositorio azure-search-vector-samples para obtener instrucciones sobre cómo usar estas características en código de prueba y producción.

Sugerencia

Use Azure Portal para crear un índice de vectores y probar la fragmentación y vectorización de datos integrados.

Requisitos previos

  • Azure AI Search, en cualquier región y en cualquier nivel. La mayoría de los servicios existentes admiten el vector de búsqueda. En el caso de los servicios creados antes de enero de 2019, hay un subconjunto pequeño que no puede crear un índice vectorial. En esta situación, se debe crear un nuevo servicio. Si usa la vectorización integrada (conjuntos de aptitudes que llaman a Azure AI), Búsqueda de Azure AI debe estar en la misma región que Azure OpenAI o los servicios de Azure AI.

  • Use incrustaciones de vectores preexistentes o la vectorización integrada, donde se llama a los modelos de inserción desde la canalización de indexación.

  • Debe conocer el límite de dimensiones del modelo usado para crear las inserciones. Los valores válidos son de 2 a 3072 dimensiones. En Azure OpenAI, para text-embedding-ada-002, la longitud del vector numérico es 1536. Para text-embedding-3-small o text-embedding-3-large, la longitud del vector es 3072.

  • También debe saber cuáles son las métricas de similitud admitidas. Para Azure OpenAI, la similitud se calcula mediante cosine.

  • Debes estar familiarizado con la creación de un índice. El esquema debe incluir un campo para la clave de documento, otros campos que quieras buscar o filtrar, y otras configuraciones para comportamientos necesarios durante la indexación y las consultas.

Preparación de documentos para la indexación

Antes de la indexación, reúne una carga de documentos que incluyan campos de datos vectoriales y no vectoriales. La estructura del documento debe ajustarse al esquema de índice.

Asegúrate de que los documentos:

  1. Proporcionen un campo o una propiedad de metadatos que identifique de forma única cada documento. Todos los índices de búsqueda requieren una clave de documento. Para satisfacer los requisitos de clave del documento, un documento de origen debe tener un campo o propiedad que pueda identificarlo de forma única en el índice. Este campo de origen debe asignarse a un campo de índice de tipo Edm.String y key=true en el índice de búsqueda.

  2. Proporciona datos vectoriales (una matriz de números de punto flotante de precisión sencilla) en los campos de origen.

    Los campos vectoriales contienen una matriz generada por modelos de inserción, con una inserción por campo, donde el campo es un campo de nivel superior (no forma parte de un tipo anidado o complejo). Para una integración más sencilla, se recomiendan los modelos de inserción en Azure OpenAI, como text-embedding-ada-002 para documentos de texto o la Image Retrieval REST API para imágenes.

    Si puede tomar una dependencia de indexadores y conjuntos de aptitudes, considere la posibilidad de usar la vectorización integrada que codifica imágenes y contenido textual durante la indexación. Sus definiciones de campo son para campos vectoriales, pero los datos de origen entrantes pueden ser texto o imágenes, representados como matrices vectoriales creadas durante la indexación.

  3. Proporciona otros campos con contenido legible para la respuesta de consulta y para escenarios de consulta híbrida que incluyan búsqueda de texto completo o clasificación semántica en la misma solicitud.

El índice de búsqueda debe incluir campos y contenido para todos los escenarios de consulta que quieras admitir. Supongamos que quieres buscar o filtrar por nombres de producto, versiones, metadatos o direcciones. En este caso, la búsqueda de similitud no es especialmente útil. La búsqueda de palabras clave, la búsqueda geográfica o los filtros sería una mejor opción. Un índice de búsqueda que incluye una colección completa de campos de datos vectoriales y no vectoriales proporciona máxima flexibilidad para la construcción de consultas y la composición de respuestas.

Un breve ejemplo de una carga de documentos que incluye campos vectoriales y no vectoriales se encuentra en la sección de carga de datos vectoriales de este artículo.

Añadir una configuración de vector de búsqueda

Una configuración de vector especifica los parámetros usados durante la indexación para crear información sobre el "vecino más próximo" entre los nodos vectoriales:

  • Mundos pequeños navegables jerárquicos (HNSW)
  • KNN exhaustivo

Si eliges HNSW en un campo, puedes optar por un KNN exhaustivo en el momento de la consulta. Pero en la otra dirección no funciona: si elige exhaustivo, más adelante no puede solicitar la búsqueda de HNSW porque las estructuras de datos adicionales que habilitan la búsqueda aproximada no existen.

Una configuración de vector también especifica métodos de cuantificación para reducir el tamaño del vector:

  • Scalar
  • Binario (disponible solo en 2024-07-01 y en paquetes más recientes del SDK de Azure)

Para obtener instrucciones sobre cómo migrar a la versión más reciente, consulte Actualización de la API REST.

2024-07-01 está disponible con carácter general. Admite una configuración de vectores que tiene lo siguiente:

  • vectorSearch.algorithms admite HNSW y KNN exhaustivo.
  • vectorSearch.compressions admite la cuantificación escalar y binaria, el sobremuestreo y la reclasificación con vectores originales.
  • vectorSearch.profiles proporciona varias combinaciones de configuraciones de algoritmo y compresión.

Asegúrate de tener una estrategia para vectorizar el contenido. Se recomienda la vectorización integrada y los vectorizadores en tiempo de consulta para la codificación integrada.

  1. Usa la API Crear o actualizar un índice para crear el índice.

  2. Añade una sección vectorSearch en el índice que especifique los algoritmos de búsqueda usados para crear el espacio de inserción.

     "vectorSearch": {
         "compressions": [
             {
                 "name": "scalar-quantization",
                 "kind": "scalarQuantization",
                 "rerankWithOriginalVectors": true,
                 "defaultOversampling": 10.0,
                     "scalarQuantizationParameters": {
                         "quantizedDataType": "int8"
                     }
             },
             {
                 "name": "binary-quantization",
                 "kind": "binaryQuantization",
                 "rerankWithOriginalVectors": true,
                 "defaultOversampling": 10.0,
             }
         ],
         "algorithms": [
             {
                 "name": "hnsw-1",
                 "kind": "hnsw",
                 "hnswParameters": {
                     "m": 4,
                     "efConstruction": 400,
                     "efSearch": 500,
                     "metric": "cosine"
                 }
             },
             {
                 "name": "hnsw-2",
                 "kind": "hnsw",
                 "hnswParameters": {
                     "m": 8,
                     "efConstruction": 800,
                     "efSearch": 800,
                     "metric": "hamming"
                 }
             },
             {
                 "name": "eknn",
                 "kind": "exhaustiveKnn",
                 "exhaustiveKnnParameters": {
                     "metric": "euclidean"
                 }
             }
    
         ],
         "profiles": [
           {
             "name": "vector-profile-hnsw-scalar",
             "compression": "scalar-quantization",
             "algorithm": "hnsw-1"
           }
         ]
     }
    

    Puntos clave:

    • Los nombres de cada configuración de compresión, algoritmo y perfil deben ser únicos para su tipo dentro del índice.

    • vectorSearch.compressions.kind puede ser scalarQuantization o binaryQuantization.

    • vectorSearch.compressions.rerankWithOriginalVectors usa los vectores originales sin comprimir para recalcular la similitud y volver a generar los resultados principales devueltos por la consulta de búsqueda inicial. Los vectores sin comprimir existen en el índice de búsqueda aunque stored sea false. Esta propiedad es opcional. El valor predeterminado es true.

    • vectorSearch.compressions.defaultOversampling considera un conjunto más amplio de resultados potenciales para compensar la reducción de la información de la cuantificación. La fórmula para los posibles resultados consta de la k en la consulta, con un multiplicador de sobremuestreo. Por ejemplo, si la consulta especifica una k de 5 y el sobremuestreo es 20, la consulta solicita eficazmente 100 documentos para su uso en la reedición, y utiliza el vector sin comprimir original para ese propósito. Solo se devuelven los mejores k resultados reclasificados. Esta propiedad es opcional. El valor predeterminado es 4.

    • vectorSearch.compressions.scalarQuantizationParameters.quantizedDataType se debe establecer en int8. Este es el único tipo de datos primitivo que se admite en este momento. Esta propiedad es opcional. El valor predeterminado es int8.

    • vectorSearch.algorithms.kind son "hnsw" o "exhaustiveKnn". Estos son los algoritmos de vecinos más próximos aproximados (ANN) que se usan para organizar el contenido vectorial durante la indexación.

    • vectorSearch.algorithms.m es el recuento de vínculos bidireccionales. El valor predeterminado es 4. El rango es de 4 a 10. Los valores inferiores deben devolver menos ruido en los resultados.

    • vectorSearch.algorithms.efConstruction es el número de vecinos más próximos usados durante la indexación. El valor predeterminado es 400. El rango va de 100 a 1000.

    • "vectorSearch.algorithms.fSearch es el número de vecinos más próximos usados durante la búsqueda. El valor predeterminado es 500. El rango va de 100 a 1000.

    • vectorSearch.algorithms.metric debe ser "coseno" si usas Azure OpenAI; de lo contrario, usa la métrica de similitud asociada al modelo de inserción que estás usando. Los valores admitidos son cosine, dotProduct, euclidean y hamming (se usan para indexar datos binarios).

    • vectorSearch.profiles añaden una capa de abstracción para acomodar definiciones más enriquecidas. Un perfil se define en vectorSearch y, a continuación, se hace referencia por nombre en cada campo vectorial. Es una combinación de configuraciones de compresión y algoritmo. Esta es la propiedad que se asigna a un campo vectorial y determina el algoritmo y la compresión de los campos.

Añadir un campo vectorial a la colección de campos

La colección de campos debe incluir un campo para la clave de documento, los campos vectoriales y cualquier otro campo que necesites para escenarios de búsqueda híbrida.

Los campos vectoriales se caracterizan por su tipo de datos, una propiedad dimensions basada en el modelo de inserción usado para generar los vectores y un perfil de vector.

2024-07-01 está disponible con carácter general.

  1. Usa Crear o actualizar un índice para crear el índice.

  2. Define un campo vectorial con los atributos siguientes. Puedes almacenar una inserción generada por campo. Para cada campo vectorial:

    • type debe ser un tipo de dato vectorial. Collection(Edm.Single) es el más común para insertar modelos.
    • dimensions es el número de dimensiones generadas en el modelo de inserción. Para text-embedding-ada-002, es 1536.
    • vectorSearchProfile es el nombre de un perfil definido en otra parte del índice.
    • searchable debe ser true.
    • retrievable puede ser true o false. True devuelve los vectores sin formato (1536) como texto sin formato y consume espacio de almacenamiento. Establécelo en true si vas a pasar un resultado vectorial a una aplicación de nivel inferior.
    • stored puede ser true o false. Determina si se almacena una copia adicional de vectores para la recuperación. Para obtener más información, vea Reducción del tamaño del vector.
    • filterable, facetable, sortable deben ser false.
  3. Añade campos no vectoriales filtrables a la colección, como "title" con filterable establecido en true, si deseas invocar un prefiltro o postfiltro en la consulta vectorial.

  4. Añade otros campos que definan la sustancia y la estructura del contenido textual que estás indexando. Como mínimo, necesitas una clave de documento.

    También debes agregar campos que sean útiles en la consulta o en su respuesta. En el ejemplo siguiente se muestran campos vectoriales para el título y el contenido ("titleVector", "contentVector") que son equivalentes a los vectores. También proporciona campos para contenido textual equivalente ("title", "content") útil para ordenar, filtrar y leer en un resultado de búsqueda.

    En el ejemplo siguiente se muestra la colección de campos:

    PUT https://my-search-service.search.windows.net/indexes/my-index?api-version=2024-07-01&allowIndexDowntime=true
    Content-Type: application/json
    api-key: {{admin-api-key}}
    {
        "name": "{{index-name}}",
        "fields": [
            {
                "name": "id",
                "type": "Edm.String",
                "key": true,
                "filterable": true
            },
            {
                "name": "title",
                "type": "Edm.String",
                "searchable": true,
                "filterable": true,
                "sortable": true,
                "retrievable": true
            },
            {
                "name": "titleVector",
                "type": "Collection(Edm.Single)",
                "searchable": true,
                "retrievable": true,
                "stored": true,
                "dimensions": 1536,
                "vectorSearchProfile": "vector-profile-1"
            },
            {
                "name": "content",
                "type": "Edm.String",
                "searchable": true,
                "retrievable": true
            },
            {
                "name": "contentVector",
                "type": "Collection(Edm.Single)",
                "searchable": true,
                "retrievable": false,
                "stored": false,
                "dimensions": 1536,
                "vectorSearchProfile": "vector-profile-1"
            }
        ],
        "vectorSearch": {
            "algorithms": [
                {
                    "name": "hnsw-1",
                    "kind": "hnsw",
                    "hnswParameters": {
                        "m": 4,
                        "efConstruction": 400,
                        "efSearch": 500,
                        "metric": "cosine"
                    }
                }
            ],
            "profiles": [
                {
                    "name": "vector-profile-1",
                    "algorithm": "hnsw-1"
                }
            ]
        }
    }
    

Carga de datos vectoriales para la indexación

El contenido que proporciones para la indexación debe ajustarse al esquema de índice e incluir un valor de cadena único para la clave de documento. Los datos vectorizados previamente se cargan en uno o varios campos vectoriales, que pueden coexistir con otros campos que contienen contenido no vectorial.

Puedes usar metodologías de incorporar o extracción para la ingesta de datos.

Use Documents - Index para cargar datos vectoriales y no vectoriales en un índice. Las API de inserción para la indexación son idénticas en todas las versiones estables y en versión preliminar. Use cualquiera de las API siguientes para cargar documentos:

POST https://{{search-service-name}}.search.windows.net/indexes/{{index-name}}/docs/index?api-version=2024-07-01

{
    "value": [
        {
            "id": "1",
            "title": "Azure App Service",
            "content": "Azure App Service is a fully managed platform for building, deploying, and scaling web apps. You can host web apps, mobile app backends, and RESTful APIs. It supports a variety of programming languages and frameworks, such as .NET, Java, Node.js, Python, and PHP. The service offers built-in auto-scaling and load balancing capabilities. It also provides integration with other Azure services, such as Azure DevOps, GitHub, and Bitbucket.",
            "category": "Web",
            "titleVector": [
                -0.02250031754374504,
                 . . . 
                        ],
            "contentVector": [
                -0.024740582332015038,
                 . . .
            ],
            "@search.action": "upload"
        },
        {
            "id": "2",
            "title": "Azure Functions",
            "content": "Azure Functions is a serverless compute service that enables you to run code on-demand without having to manage infrastructure. It allows you to build and deploy event-driven applications that automatically scale with your workload. Functions support various languages, including C#, F#, Node.js, Python, and Java. It offers a variety of triggers and bindings to integrate with other Azure services and external services. You only pay for the compute time you consume.",
            "category": "Compute",
            "titleVector": [
                -0.020159931853413582,
                . . .
            ],
            "contentVector": [
                -0.02780858241021633,
                 . . .
            ],
            "@search.action": "upload"
        }
        . . .
    ]
}

Comprobación del contenido de los campos vectoriales

Para fines de validación, puede consultar el índice mediante el Explorador de búsqueda en Azure Portal o mediante una llamada a la API REST. Dado que Azure AI Search no puede convertir un vector en texto legible, intenta devolver campos del mismo documento que proporcionen evidencia de la coincidencia. Por ejemplo, si la consulta vectorial tiene como destino el campo "titleVector", puedes seleccionar "title" para los resultados de la búsqueda.

Los campos se deben atribuir como "retrievable" para incluirlos en los resultados.

  • Revise los índices de Administración de búsquedas>Índices para ver el tamaño del índice total y el tamaño del índice vectorial. Un tamaño de índice vectorial positivo indica que los vectores están presentes.

  • Use el Explorador de búsqueda para consultar un índice. El Explorador de búsqueda tiene dos vistas: vista de consulta (valor predeterminado) y vista JSON.

    • Establezca Opciones de consulta>Ocultar valores vectoriales en los resultados de la búsqueda para obtener resultados más legibles.

    • Use la vista JSON para las consultas vectoriales. Puede pegar una definición JSON de la consulta vectorial que quiere ejecutar o usar la conversión integrada de texto a vector o de imagen a vector si el índice tiene una asignación de vectorizador. Para obtener más información sobre la búsqueda de imágenes, consulte Inicio rápido: Búsqueda de imágenes en el Explorador de búsqueda.

    • Usa la vista de consulta predeterminada para obtener una confirmación rápida de que el índice contiene vectores. La vista de consulta es para la búsqueda de texto completo. Aunque no se puede usar para las consultas vectoriales, puedes enviar una búsqueda vacía (search=*) para comprobar el contenido. El contenido de todos los campos, incluidos los campos vectoriales, se devuelve como texto sin formato.

    • Consulte Creación de una consulta vectorial para obtener más detalles.

Actualizar un almacén de vectores

Para actualizar un almacén de vectores, modifique el esquema y, si es necesario, vuelva a cargar documentos para rellenar nuevos campos. Las API para las actualizaciones de esquema incluyen Crear o actualizar índice (REST), CreateOrUpdateIndex en el SDK de Azure para .NET, create_or_update_index en el SDK de Azure para Python y métodos similares en otros SDK de Azure.

Las instrucciones estándar para actualizar un índice se tratan en Actualización o recompilación de un índice.

Entre los puntos clave se incluyen:

  • La eliminación y recompilación suele ser necesaria para las actualizaciones de los campos existentes y su eliminación.

  • Sin embargo, se puede actualizar un esquema existente con las siguientes modificaciones, sin que se requiera ninguna recompilación:

    • Agregue nuevos campos a una colección de campos.
    • Agregue nuevas configuraciones de vector, asignadas a nuevos campos, pero no a los campos existentes que ya se hayan vectorizado.
    • Cambie "retrievable" (recuperable, los valores son true o false) en un campo existente. Los campos vectoriales deben ser buscables y recuperables, pero si quiere deshabilitar el acceso a un campo vectorial en situaciones en las que la eliminación y la recompilación no son factibles, puede establecer que se pueda recuperar en false.

Pasos siguientes

Como paso siguiente, se recomienda Datos vectoriales de consulta en un índice de búsqueda.

Los ejemplos de código del repositorio azure-search-vector muestran flujos de trabajo de un extremo a otro que incluyen definición de esquema, vectorización, indexación y consultas.

Hay código de demostración para Python, C# y JavaScript.