Creación y búsqueda de índices vectoriales
En esta sección se describe cómo crear y administrar índices vectoriales, escribir elementos con datos vectoriales y realizar búsquedas de similitud mediante la API SearchVectors.
Temas
Antes de empezar
Antes de trabajar con índices vectoriales, verifique lo siguiente:
-
La tabla utiliza el modo de capacidad bajo demanda (
PAY_PER_REQUEST). Los índices vectoriales utilizan solo el modo de capacidad bajo demanda y requieren una tabla que también utilice el modo de capacidad bajo demanda, por lo que no puede mezclar los dos modos de capacidad. -
La identidad AWS Identity and Access Management (IAM) tiene permisos
dynamodb:CreateTableodynamodb:UpdateTablepara crear índices vectoriales. -
La identidad de IAM tiene permiso
dynamodb:SearchVectorsen el recurso de índice vectorial para realizar búsquedas. El formato del ARN del recurso esarn:aws:dynamodb:.region:account-id:table/table-name/index/index-name
Puntos de conexión de SearchVectors
Las solicitudes de SearchVectors utilizan puntos de conexión de búsqueda vectorial, que son distintos de los puntos de conexión estándar de DynamoDB que se utilizan para crear y administrar índices vectoriales (por ejemplo, con CreateTable, UpdateTable y DescribeTable). Los AWS SDK y AWS CLI dirigen las solicitudes de SearchVectors al punto de conexión correcto automáticamente. No es necesario configurar ni invalidar el punto de conexión en el código de la aplicación.
Si va a crear un cliente HTTP personalizado que llame directamente a la API de DynamoDB sin un AWS SDK, utilice uno de los siguientes puntos de conexión de búsqueda vectorial y sustituya account-id y region según corresponda:
-
: punto de conexión basado en cuentas.account-id.search-ddb.region.amazonaws.com -
search-dynamodb.: punto de conexión de doble pila, compatible con IPv4 e IPv6.region.api.aws
Generación de incrustaciones vectoriales
DynamoDB almacena y busca incrustaciones vectoriales, pero no las genera. Se producen incrustaciones con un modelo de incrustación, como los modelos Amazon Bedrock Titan Text Embeddings o Cohere Embed, o cualquier modelo de incrustación que se utilice. A continuación, se almacena el vector resultante en un elemento de DynamoDB y se pasa un vector de consulta a SearchVectors.
El vector de consulta y los vectores almacenados deben usar el mismo modelo
El vector de consulta que pase a SearchVectors y los vectores almacenados en los elementos deben generarse con el mismo modelo de incrustación y deben tener el mismo número de dimensiones que el índice vectorial. Al mezclar modelos o realizar consultas con un número de dimensiones diferente al que se creó el índice, se obtienen resultados sin sentido o se produce un error de validación.
El flujo típico es:
-
Envíe el contenido original (por ejemplo, la descripción de un producto) a un modelo de incrustación y reciba un vector.
-
Guarde ese vector en un elemento de DynamoDB, en el atributo denominado por el índice vectorial (
VectorAttribute), como una lista (L) de números (N). -
En el momento de la consulta, genere un vector a partir del texto de búsqueda mediante el mismo modelo y páselo como
SearchVector.
Elección del modelo de incrustación antes de crear el índice
Elija el modelo de incrustación antes de crear el índice vectorial, ya que el modelo determina el número de dimensiones. Los modelos de incrustación comunes producen 384, 768, 1024, 1536 o 3072 dimensiones. DynamoDB admite hasta 4096 dimensiones. Consulte Requisitos y limitaciones.
La función de distancia que elija interactúa con la forma en que el modelo produce las incrustaciones. COSINE compara la dirección e ignora la magnitud, por lo que funciona con las incrustaciones estén o no normalizadas. DOT_PRODUCT es sensible a la magnitud: si las incrustaciones no están normalizadas a una unidad de longitud, los vectores más grandes reciben puntuaciones más altas independientemente de la dirección. Si utiliza DOT_PRODUCT y desea una similitud basada en la dirección, normalice las incrustaciones a unidades de longitud antes de almacenarlas. Consulte Cómo clasifican los resultados las funciones de distancia.
Creación de un índice vectorial
Puede crear un índice vectorial al crear una tabla nueva o agregar uno a una tabla existente.
Creación de una tabla con un índice vectorial
Utilice la API CreateTable con el parámetro VectorIndexes para crear una tabla con un índice vectorial. En el ejemplo de AWS CLI siguiente, se crea una tabla de Products con un índice vectorial denominado ProductEmbeddingIndex.
aws dynamodb create-table \ --table-name Products \ --attribute-definitions AttributeName=ProductId,AttributeType=S \ AttributeName=Category,AttributeType=S \ AttributeName=Brand,AttributeType=S \ --key-schema AttributeName=ProductId,KeyType=HASH \ --billing-mode PAY_PER_REQUEST \ --vector-indexes \ "[ { \"IndexName\": \"ProductEmbeddingIndex\", \"VectorAttribute\": {\"AttributeName\": \"Embedding\"}, \"SearchSchema\": [{\"AttributeName\":\"Category\",\"SearchSchemaElementType\":\"HASH\"}, {\"AttributeName\":\"Brand\",\"SearchSchemaElementType\":\"INLINE_FILTER\"}], \"Projection\": {\"ProjectionType\": \"ALL\"}, \"Dimensions\": 1536, \"DistanceFunction\": \"COSINE\" } ]"
En este ejemplo:
-
VectorAttributeespecificaEmbeddingcomo el atributo que contiene los datos vectoriales. -
SearchSchemadefineCategorycomo una clave de partición de índice vectorial (HASH), que divide el índice por categorías para escalarlo. También se defineBrandcomo unINLINE_FILTER, que permite filtrar los resultados de búsqueda por marca en la capa de almacenamiento. Como se hace referencia aCategoryyBranden el SearchSchema, también deben declararse enAttributeDefinitions, del mismo modo que se declaran los atributos clave en un índice secundario global. -
Dimensionsse establece en 1536, lo que coincide con el resultado de los modelos de incrustación comunes. -
DistanceFunctionse establece enCOSINE, donde las puntuaciones más bajas indican una mayor similitud.
Adición de un índice vectorial a una tabla existente
Use la API de UpdateTable con el parámetro VectorIndexUpdates para agregar un índice vectorial a una tabla existente. En este ejemplo, se agrega un segundo índice independiente denominado ProductEmbeddingIndexV2 a la misma tabla de Products.
aws dynamodb update-table \ --table-name Products \ --vector-index-updates \ "[ { \"Create\": { \"IndexName\": \"ProductEmbeddingIndexV2\", \"VectorAttribute\": {\"AttributeName\": \"Embedding\"}, \"Projection\": {\"ProjectionType\": \"ALL\"}, \"Dimensions\": 1536, \"DistanceFunction\": \"EUCLIDEAN\" } } ]"
Al agregar un índice vectorial a una tabla existente, DynamoDB informa del progreso del índice mediante dos campos de la respuesta DescribeTable: un valor IndexStatus y un booleano independiente Backfilling.
-
IndexStatusestáCREATINGyBackfillingestá ausente ofalse. DynamoDB aprovisiona la infraestructura de índices. -
IndexStatusestáCREATINGyBackfillingestrue. DynamoDB rellena el índice con los datos existentes de la tabla base. Las nuevas escrituras en la tabla base se replican en el índice durante esta fase.SearchVectorsdevuelve unaValidationException. Esta fase puede conllevar una cantidad considerable de tiempo, incluso cuando la tabla base contiene muy pocos elementos. -
IndexStatusestáACTIVEyBackfillingya no se notifica. El índice está listo para la búsqueda.
No puede buscar mientras el índice se está reponiendo
SearchVectors devuelve una ValidationException mientras un índice vectorial se está reponiendo. Use DescribeTable para comprobar el indicador IndexStatus y Backfilling y espere hasta que IndexStatus sea ACTIVE y Backfilling no sea true antes de realizar la búsqueda. No hay ningún valor de estado del índice BACKFILLING; un índice que está rellenando notifica IndexStatus CREATING con Backfilling establecido en true.
Un índice recién preparado no se puede buscar inmediatamente
Las solicitudes SearchVectors las sirve un punto de conexión de búsqueda dedicado, independiente del punto de conexión que sirve DescribeTable. Después de que DescribeTable informe primero de IndexStatus ACTIVE, el punto de conexión de búsqueda puede necesitar más tiempo antes de empezar a servir el índice. Durante ese intervalo, SearchVectors devuelve una ValidationException, normalmente The table does not have
the specified index.
Trate una ValidationException en las primeras búsquedas posteriores a la creación del índice como reintentable y no como un error. Puede parecer que el código que busca inmediatamente después de observar ACTIVE funciona en un entorno y produce un error en otro. El intervalo es breve y varía.
Para una comprobación de disponibilidad que no dependa de ninguno de los campos de estado, emita una solicitud SearchVectors real en un bucle de reintento. Trate la primera respuesta correcta como la señal de que el índice está listo.
Puede crear o eliminar solo un índice vectorial por tabla a la vez. Este límite se comparte con la creación de índices secundarios globales en la misma tabla. Una segunda solicitud UpdateTable que crea o elimina un índice mientras hay otra operación de indexación en curso produce un error con LimitExceededException: Subscriber limit exceeded: Only 1 online index
can be created or deleted simultaneously per table.
Esto también se aplica a una sola solicitud: una llamada UpdateTable que contiene dos acciones Create en su parámetro VectorIndexUpdates produce un error con el mismo error. Cree índices vectoriales de uno en uno, esperando a que cada uno alcance ACTIVE antes de comenzar con el siguiente. Como cada índice debe terminar de rellenarse antes de que el siguiente pueda empezar, crear varios índices vectoriales en una tabla lleva mucho más tiempo que crear uno solo.
Una solicitud CreateTable puede definir varios índices vectoriales a la vez, hasta el límite de cinco por tabla. Si se supera ese límite, se produce un error con ValidationException: One or more parameter values were invalid:
VectorIndex count exceeds the per-table limit of 5.
Escritura de elementos con datos vectoriales
Los elementos se escriben con datos vectoriales mediante las API de escritura estándar de DynamoDB (PutItem, UpdateItem, BatchWriteItem, TransactWriteItems). Almacene la incrustación vectorial como una lista de números (tipo L que contiene N elementos).
Como un vector contiene muchos valores, guarde el elemento en un archivo como item.json, por ejemplo, y pase el archivo a la AWS CLI.
{ "ProductId": { "S": "prod-123" }, "Category": { "S": "Electronics" }, "Title": { "S": "Wireless Headphones" }, "Embedding": { "L": [ { "N": "0.1234" }, { "N": "-0.5678" }, { "N": "0.9012" }, ... ] } }
aws dynamodb put-item \ --table-name Products \ --item file://item.json
La longitud del vector debe coincidir con las dimensiones del índice
El vector de Embedding que se muestra aquí está abreviado. En item.json, debe contener 1536 valores para que coincidan con las Dimensions que ha establecido en ProductEmbeddingIndex. Se rechaza escribir un vector con un número de dimensiones incorrecto.
DynamoDB valida los datos vectoriales al escribir elementos en una tabla que tiene un índice vectorial. En la tabla siguiente, se describe el comportamiento de validación.
| Condición | Comportamiento |
|---|---|
| El atributo vectorial tiene un número de dimensiones incorrecto | Se rechaza la escritura. |
| Falta el atributo clave de partición del índice vectorial | La escritura se realiza correctamente en la tabla base, pero el elemento no se replica en el índice vectorial. |
| El tipo de atributo clave de partición del índice vectorial no coincide con el esquema del índice | Se rechaza la escritura. |
| Falta el atributo de filtro en línea | La escritura se realiza correctamente y el elemento se replica en el índice vectorial. |
| Los valores vectoriales tienen una precisión superior a la del punto flotante de 32 bits (f32) | La escritura se realiza correctamente. Los valores se almacenan tal cual en la tabla base, pero pierden precisión cuando se replican en el índice vectorial. |
| El atributo vectorial se elimina de un elemento | Se elimina la entrada correspondiente del índice vectorial. |
La falta de la clave de partición provoca una desindexación silenciosa
Si el índice vectorial define una clave de partición en el SearchSchema y escribe un elemento sin ese atributo (o lo elimina con UpdateItem), la escritura se realiza correctamente en la tabla base, pero el elemento se excluye silenciosamente del índice vectorial. No aparecerá en los resultados de SearchVectors aunque el elemento de la tabla base y su incrustación vectorial sigan existiendo. Asegúrese de que cada elemento que desee buscar contiene el atributo de clave de partición del índice vectorial.
Las incrustaciones obsoletas producen resultados incorrectos
DynamoDB no vuelve a calcular las incrustaciones por usted. Si cambia el contenido de origen que produjo una incrustación (por ejemplo, edita la descripción de un producto), el vector almacenado no se actualiza automáticamente. Debe regenerar la incrustación con el modelo de incrustación y volver a escribir el nuevo vector en el elemento. De lo contrario, el índice vectorial sigue arrojando resultados basados en el vector antiguo y obsoleto, lo que puede producir coincidencias incorrectas de forma silenciosa.
Búsqueda con SearchVectors
Utilice la API SearchVectors para buscar los elementos de un índice vectorial que se parezcan más a un vector de consulta. Los resultados se clasifican por relevancia, y el elemento más similar se coloca primero. Los resultados de la búsqueda tienen coherencia final: es posible que transcurra un breve intervalo entre la escritura o actualización de un vector y su aparición en los resultados de la búsqueda. Para obtener más información, consulte Sincronización de escritura continua.
Búsqueda básica
En el siguiente ejemplo, se buscan los 10 elementos más similares del índice ProductEmbeddingIndex. Como este índice tiene una clave de partición de índice vectorial (Category) definida en su SearchSchema, SearchConditionExpression debe incluir el valor de la clave de partición de índice vectorial.
Guarde el vector de consulta en un archivo, por ejemplo query-vector.json, como una matriz JSON simple de valores numéricos.
[ { "N": "0.1234" }, { "N": "-0.5678" }, { "N": "0.9012" }, ... ]
aws dynamodb search-vectors \ --table-name Products \ --index-name ProductEmbeddingIndex \ --search-vector file://query-vector.json \ --top-k 10 \ --search-condition-expression "Category = :cat" \ --expression-attribute-values "{\":cat\": {\"S\": \"Electronics\"}}"
La respuesta incluye una matriz de SearchResults. Cada elemento contiene la coincidencia Item y una Score que indica el nivel de similitud del elemento al vector de consulta.
{ "SearchResults": [ { "Item": { "ProductId": { "S": "prod-456" }, "Category": { "S": "Electronics" }, "Title": { "S": "Bluetooth Speaker" } }, "Score": 0.0023 }, { "Item": { "ProductId": { "S": "prod-789" }, "Category": { "S": "Electronics" }, "Title": { "S": "Noise Cancelling Earbuds" } }, "Score": 0.0145 } ] }
Los atributos vectoriales se excluyen de los resultados de forma predeterminada
De forma predeterminada, los resultados de SearchVectors no incluyen el atributo vectorial (la incrustación). Los datos vectoriales son grandes y, por lo general, no los necesita en la respuesta. Los resultados incluyen los demás atributos proyectados y el valor Score. Para incluir el atributo vectorial, solicítelo con una ProjectionExpression. Para obtener más información, consulte Uso de ProjectionExpression.
SearchVector es una lista simple, no del tipo DynamoDB L
El parámetro de solicitud SearchVector es una matriz JSON simple de objetos numéricos ([{"N": "0.1234"}, ...]). No lo envuelva en un tipo L de DynamoDB como lo haría al almacenar un vector en un atributo de elemento. El contenedor L solo se usa al escribir o leer datos vectoriales en los atributos de los elementos.
El significado de Score depende de la función de distancia que haya elegido al crear el índice. Para COSINE y EUCLIDEAN, las puntuaciones más bajas indican una mayor similitud. Para DOT_PRODUCT, las puntuaciones más altas indican una mayor similitud.
Filtro con SearchConditionExpression
Use SearchConditionExpression para filtrar los resultados de la búsqueda en función de la clave de partición del índice vectorial y los atributos de filtro en línea definidos en el SearchSchema. Esta expresión utiliza la misma sintaxis que otros parámetros de expresión de DynamoDB.
En el siguiente ejemplo, se buscan los elementos de la categoría Electronics (clave de partición del índice vectorial) con un filtro en línea Brand.
aws dynamodb search-vectors \ --table-name Products \ --index-name ProductEmbeddingIndex \ --search-vector file://query-vector.json \ --top-k 10 \ --search-condition-expression "Category = :cat AND Brand = :brand" \ --expression-attribute-values "{\":cat\": {\"S\": \"Electronics\"}, \":brand\": {\"S\": \"Acme\"}}"
Si el índice vectorial tiene una clave de partición definida en el SearchSchema, debe incluirla en SearchConditionExpression. Los atributos de filtro en línea son opcionales.
El operador de igualdad (=) se admite en SearchConditionExpression para los atributos de clave de partición de índice vectorial y filtro en línea. Los operadores de comparación, rango y pertenencia a conjuntos (<>, <, <=, >, >=, IN) aún no están disponibles.
Este filtrado permite aplicar una búsqueda por similitud a un subconjunto de datos, un requisito habitual en las aplicaciones multiusuario y en las aplicaciones de generación aumentada por recuperación (RAG). Por ejemplo, para encontrar documentos similares a una consulta pero solo dentro de un inquilino, defina el atributo de inquilino como una clave de partición de índice vectorial (HASH) en el SearchSchema y pase su valor en cada búsqueda. Esto aísla los resultados para ese inquilino. También mejora el rendimiento, ya que la búsqueda examina solo los datos relevantes. Utilice los atributos de filtro en línea para establecer restricciones de igualdad adicionales, como el tipo o el estado del documento, que desee aplicar dentro de la partición enrutada.
El alcance de las claves de partición no es un límite de seguridad
El uso de una clave de partición para limitar las búsquedas a un único inquilino es una optimización de la localidad de los datos y del rendimiento, no un mecanismo de control de acceso. Cualquier entidad principal que tenga el permiso dynamodb:SearchVectors en el índice puede buscar cualquier valor de clave de partición. Como las claves de condición de control de acceso detallado (FGAC) como dynamodb:LeadingKeys no se aplican a SearchVectors, no se puede restringir el acceso a valores de clave de partición individuales por política de IAM. Si la carga de trabajo requiere un aislamiento estricto de los inquilinos en la capa de datos, utilice tablas o índices independientes con distintas concesiones de IAM para cada inquilino.
Uso de ProjectionExpression
Utilice ProjectionExpression para devolver solo atributos específicos en los resultados de búsqueda. Esto puede reducir el tamaño de la respuesta cuando no necesite todos los atributos proyectados. Como ProductEmbeddingIndex define una clave de partición de índice vectorial (Category) en su SearchSchema, este ejemplo todavía incluye el valor de la clave de partición de índice vectorial en SearchConditionExpression.
aws dynamodb search-vectors \ --table-name Products \ --index-name ProductEmbeddingIndex \ --search-vector file://query-vector.json \ --top-k 5 \ --search-condition-expression "Category = :cat" \ --expression-attribute-values "{\":cat\": {\"S\": \"Electronics\"}}" \ --projection-expression "ProductId, Title"
Solo se pueden devolver los atributos proyectados
Solo puede devolver los atributos proyectados en el índice vectorial. Los atributos que no están en la proyección del índice no se pueden devolver mediante SearchVectors.
Eliminación de un índice vectorial
Utilice la API de UpdateTable con el parámetro VectorIndexUpdates para eliminar un índice vectorial.
aws dynamodb update-table \ --table-name Products \ --vector-index-updates \ "[ {\"Delete\": {\"IndexName\": \"ProductEmbeddingIndex\"}} ]"
Cuando elimina un índice vectorial, DynamoDB elimina el índice y todos sus datos. Esta operación no afecta a la tabla base ni a sus elementos.