View a markdown version of this page

Criação e pesquisa de índices vetoriais - Amazon DynamoDB

Criação e pesquisa de índices vetoriais

Esta seção descreve como criar e gerenciar índices vetoriais, gravar itens com dados vetoriais e realizar pesquisas por similaridade usando a API SearchVectors.

Antes de começar

Antes de trabalhar com índices vetoriais, verifique o seguinte:

  • Sua tabela usa o modo de capacidade sob demanda (PAY_PER_REQUEST). Não há suporte para índices vetoriais em tabelas de capacidade provisionada.

  • Sua identidade do AWS Identity and Access Management (IAM) tem permissões dynamodb:CreateTable ou dynamodb:UpdateTable para criar índices vetoriais.

  • Sua identidade do IAM tem a permissão dynamodb:SearchVectors no recurso de índice vetorial para realizar pesquisas. O formato do ARN do recurso é arn:aws:dynamodb:region:account-id:table/table-name/index/index-name.

Endpoints de SearchVectors

As solicitações de SearchVectors usam endpoints dedicados de pesquisa vetorial, que são distintos dos endpoints padrão do DynamoDB que você usa para criar e gerenciar índices vetoriais (por exemplo, com CreateTable, UpdateTable e DescribeTable). Os SDKs da AWS e a AWS CLI encaminham as solicitações de SearchVectors para o endpoint correto automaticamente. Você não precisa configurar ou substituir o endpoint no código do seu aplicativo.

Se você estiver criando um cliente HTTP personalizado que chame a API do DynamoDB diretamente sem um SDK da AWS, use um dos seguintes endpoints de pesquisa vetorial, substituindo account-id e region conforme apropriado:

  • account-id.search-ddb.region.amazonaws.com: endpoint baseado em conta.

  • search-dynamodb.region.api.aws: endpoint de pilha dupla, compatível com IPv4 e IPv6.

Geração de incorporações vetoriais

O DynamoDB armazena e pesquisa incorporações vetoriais, mas não as gera. Você produz incorporações com um modelo de incorporação, como os modelos do Amazon Bedrock Titan Text Embeddings ou Cohere Embed, ou qualquer modelo de incorporação que opere. Em seguida, você armazena o vetor resultante em um item do DynamoDB e transmite um vetor de consulta para SearchVectors.

O vetor de consulta e os vetores armazenados devem usar o mesmo modelo

O vetor de consulta transmitido para SearchVectors e os vetores armazenados em seus itens devem ser produzidos pelo mesmo modelo de incorporação e devem ter o mesmo número de dimensões do índice vetorial. A combinação de modelos ou a consulta com um número de dimensões diferente daquele com o qual o índice foi criado produz resultados sem sentido ou um erro de validação.

O fluxo típico é:

  1. Envie o conteúdo de origem (por exemplo, uma descrição do produto) para um modelo de incorporação e receba um vetor.

  2. Armazene esse vetor em um item do DynamoDB, no atributo chamado pelo índice vetorial (VectorAttribute), como uma lista (L) de números (N).

  3. No momento da consulta, gere um vetor a partir do texto de pesquisa usando o mesmo modelo e transmita-o como o SearchVector.

Escolha o modelo de incorporação antes de criar o índice

Escolha o modelo de incorporação antes de criar o índice vetorial, pois o modelo determina o número de dimensões. Os modelos de incorporação comuns produzem 384, 768, 1024, 1536 ou 3072 dimensões. O DynamoDB é compatível com até 4.096 dimensões. Consulte Requisitos e limitações.

A função de distância escolhida interage com a forma como seu modelo produz incorporações. COSINE compara a direção e ignora a magnitude, então funciona com incorporações, estejam elas normalizadas ou não. DOT_PRODUCT é sensível à magnitude: se as incorporações não forem normalizadas para o comprimento da unidade, vetores maiores receberão pontuações mais altas, independentemente da direção. Se você usar DOT_PRODUCT e quiser similaridade baseada em direção, normalize as incorporações para o comprimento unitário antes de armazená-las. Consulte Como as funções de distância classificam os resultados.

Criar um índice vetorial

Você pode criar um índice vetorial ao criar uma nova tabela ou adicionar um a uma tabela existente.

Criação de uma tabela com um índice vetorial

Use a API CreateTable com o parâmetro VectorIndexes para criar uma tabela com um índice vetorial. O exemplo de AWS CLI a seguir cria uma tabela Products com um índice vetorial chamado 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\" } ]"

Neste exemplo:

  • VectorAttribute especifica Embedding como o atributo que contém dados vetoriais.

  • SearchSchema define Category como uma chave de partição de índice vetorial (HASH), o que particiona o índice por categoria para dimensionamento. Também define Brand como um INLINE_FILTER, o que permite filtrar os resultados da pesquisa por marca na camada de armazenamento. Como Category e Brand são referenciados no SearchSchema, eles também devem ser declarados em AttributeDefinitions, da mesma forma que os atributos de chave são declarados para um índice secundário global.

  • Dimensions está definido como 1536, correspondendo à saída de modelos de incorporação comuns.

  • DistanceFunction é definido como COSINE, onde pontuações mais baixas indicam maior semelhança.

Adição de um índice vetorial a uma tabela existente

Use a API UpdateTable com o parâmetro VectorIndexUpdates para adicionar um índice vetorial a uma tabela existente. Este exemplo adiciona um segundo índice independente chamado ProductEmbeddingIndexV2 à mesma tabela Products.

aws dynamodb update-table \ --table-name Products \ --vector-index-updates \ "[ { \"Create\": { \"IndexName\": \"ProductEmbeddingIndexV2\", \"VectorAttribute\": {\"AttributeName\": \"Embedding\"}, \"Projection\": {\"ProjectionType\": \"ALL\"}, \"Dimensions\": 1536, \"DistanceFunction\": \"EUCLIDEAN\" } } ]"

Quando você adiciona um índice vetorial a uma tabela existente, o DynamoDB relata o andamento do índice por meio de dois campos na resposta DescribeTable: um valor IndexStatus e um booleano separado Backfilling.

  1. IndexStatus é CREATING: o DynamoDB está configurando a infraestrutura de indexação.

  2. IndexStatus é ACTIVE com Backfilling definido como true: o DynamoDB está preenchendo o índice com os dados existentes da tabela de base. Novas gravações na tabela de base também são replicadas no índice durante essa fase. Enquanto um índice vetorial está sendo preenchido, SearchVectors retorna um erro. Espere até que Backfilling seja false antes de pesquisar.

  3. IndexStatus é ACTIVE com Backfilling definido como false (ou ausente): o índice está totalmente preenchido e pronto para operações de pesquisa.

Você não pode pesquisar enquanto o índice está sendo preenchido

SearchVectors retorna um erro enquanto um índice vetorial está sendo preenchido. Use DescribeTable para verificar o sinalizador IndexStatus e o sinalizador Backfilling e aguarde até que IndexStatus seja ACTIVE e Backfilling seja false antes de pesquisar. Não há valor de status de índice BACKFILLING.

Gravação de itens com dados vetoriais

Você grava itens com dados vetoriais usando as APIs de gravação padrão do DynamoDB (PutItem, UpdateItem, BatchWriteItem, TransactWriteItems). Armazene a incorporação vetorial como uma lista de números (tipo L contendo elementos N).

Como um vetor contém muitos valores, salve o item em um arquivo como item.json e, em seguida, transmita o arquivo para a 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
O comprimento do vetor deve corresponder às dimensões do índice

O vetor Embedding mostrado aqui é abreviado. Em item.json, ele deve conter 1.536 valores para corresponder às Dimensions que você definiu em ProductEmbeddingIndex. A gravação de um vetor com o número errado de dimensões é rejeitada.

O DynamoDB valida dados vetoriais quando você grava itens em uma tabela que tem um índice vetorial. A tabela a seguir descreve o comportamento de validação.

Condição Comportamento
O atributo vetorial tem o número errado de dimensões A gravação é rejeitada.
O atributo da chave de partição do índice vetorial está ausente A gravação é bem-sucedida na tabela de base, mas o item não é replicado no índice vetorial.
O tipo de atributo da chave de partição do índice vetorial não corresponde ao esquema do índice A gravação é rejeitada.
O atributo de filtro integrado está ausente A gravação é bem-sucedida e o item é replicado no índice vetorial.
Os valores vetoriais têm maior precisão do que o ponto flutuante de 32 bits (f32) A gravação é bem-sucedida. Os valores são armazenados como estão na tabela de base, mas perdem a precisão quando replicados no índice vetorial.
O atributo vetorial é excluído de um item A entrada correspondente no índice vetorial é excluída.
A falta da chave de partição causa uma desindexação silenciosa

Se o índice vetorial definir uma chave de partição no SearchSchema e você gravar um item sem esse atributo (ou removê-lo com UpdateItem), a gravação será bem-sucedida na tabela de base, mas o item será excluído silenciosamente do índice vetorial. Ele não aparecerá nos resultados de SearchVectors, mesmo que o item da tabela de base e a incorporação vetorial ainda existam. Cada item que você deseja que seja pesquisável deve conter o atributo da chave de partição do índice vetorial.

Incorporações obsoletas produzem resultados incorretos

O DynamoDB não recalcula as incorporações para você. Se você alterar o conteúdo de origem que produziu uma incorporação (por exemplo, editar a descrição de um produto), o vetor armazenado não será atualizado automaticamente. Você deve gerar novamente a incorporação com seu modelo de incorporação e gravar o novo vetor de volta no item. Caso contrário, o índice vetorial continuará retornando resultados com base no vetor antigo e obsoleto, que pode produzir correspondências incorretas silenciosamente.

Pesquisa com SearchVectors

Use a API SearchVectors para encontrar itens em um índice vetorial que sejam mais semelhantes a um vetor de consulta. Os resultados são classificados por relevância, com o item mais semelhante primeiro. Os resultados da pesquisa eventualmente são consistentes: pode haver um pequeno atraso entre gravar ou atualizar um vetor e ele aparecer nos resultados da pesquisa. Para obter mais informações, consulte Sincronização de gravações em andamento.

Pesquisa básica

O exemplo a seguir pesquisa os 10 itens mais semelhantes no índice ProductEmbeddingIndex. Como esse índice tem uma chave de partição de índice vetorial (Category) definida em SearchSchema, a SearchConditionExpression deve incluir o valor da chave de partição de índice vetorial.

Salve o vetor de consulta em um arquivo como query-vector.json, como uma matriz JSON simples 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\"}}"

A resposta inclui uma matriz SearchResults. Cada elemento contém o Item correspondente e uma Score que indica a semelhança do item com o vetor 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 } ] }
Os atributos vetoriais são excluídos dos resultados por padrão

Por padrão, os resultados de SearchVectors não incluem o atributo vetorial (a incorporação). Os dados vetoriais são grandes e normalmente não são necessários na resposta. Os resultados incluem os outros atributos projetados e o valor de Score. Para incluir o atributo vetorial, solicite-o com uma ProjectionExpression. Para obter mais informações, consulte Uso da ProjectionExpression.

SearchVector é uma lista simples, não um tipo L do DynamoDB

O parâmetro de solicitação SearchVector é uma matriz JSON simples de objetos numéricos ([{"N": "0.1234"}, ...]). Não o envolva em um tipo L do DynamoDB como você faria ao armazenar um vetor em um atributo de item. O wrapper L só é usado ao gravar ou ler dados vetoriais em atributos de item.

O significado da Score depende da função de distância escolhida ao criar o índice. Para COSINE e EUCLIDEAN, pontuações mais baixas indicam maior similaridade. Para DOT_PRODUCT, pontuações mais altas indicam maior similaridade.

Filtragem com SearchConditionExpression

Use SearchConditionExpression para filtrar os resultados da pesquisa com base na chave de partição do índice vetorial e nos atributos de filtro integrado definidos no SearchSchema. Essa expressão usa a mesma sintaxe de outros parâmetros de expressão do DynamoDB.

O exemplo a seguir pesquisa itens na categoria Electronics (chave de partição de índice vetorial) com um filtro integrado 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\"}}"

Se o índice vetorial tiver uma chave de partição definida no SearchSchema, você deverá incluí-la na SearchConditionExpression. Os atributos de filtro integrado são opcionais.

O operador de igualdade (=) é compatível com SearchConditionExpression tanto para a chave de partição do índice vetorial quanto para os atributos de filtro integrado. Os operadores de comparação, intervalo e associação por conjuntos (<>, <, <=, >, >=, IN) ainda não estão disponíveis.

Nessa filtragem, você define o escopo de uma pesquisa por similaridade em um subconjunto de seus dados, um requisito comum em aplicativos multilocatários e de geração aumentada via recuperação (RAG). Por exemplo, para encontrar documentos semelhantes a uma consulta, mas somente dentro de um locatário, defina o atributo do locatário como uma chave de partição de índice vetorial (HASH) no SearchSchema e transmita seu valor em cada pesquisa. Isso isola os resultados desse locatário. Também melhora o desempenho, porque a pesquisa examina somente os dados relevantes. Use atributos de filtro integrado para restrições de igualdade adicionais, como um tipo ou status de documento, que você deseja aplicar na partição roteada.

O escopo da chave de partição não é um limite de segurança

Usar uma chave de partição para definir o escopo das pesquisas como um único locatário é uma otimização de localidade de dados e desempenho, não um mecanismo de controle de acesso. Qualquer entidade principal que tenha a permissão dynamodb:SearchVectors no índice pode pesquisar qualquer valor de chave de partição. Como as chaves de condição de controle de acesso refinado (FGAC), como dynamodb:LeadingKeys, não se aplicam a SearchVectors, você não pode restringir o acesso a valores de chave de partição individuais no nível da política do IAM. Se a workload exigir isolamento estrito do locatário na camada de dados, use tabelas ou índices separados com concessões distintas do IAM para cada locatário.

Uso da ProjectionExpression

Use ProjectionExpression para retornar apenas atributos específicos nos resultados da pesquisa. Isso pode reduzir o tamanho da resposta quando você não precisa de todos os atributos projetados. Como ProductEmbeddingIndex define uma chave de partição de índice vetorial (Category) em SearchSchema, esse exemplo ainda inclui o valor da chave de partição de índice vetorial em 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"
Somente atributos projetados podem ser retornados

Você pode retornar apenas os atributos projetados no índice vetorial. Os atributos que não estão na projeção do índice não podem ser retornados por SearchVectors.

Excluir um índice de vetores

Use a API UpdateTable com o parâmetro VectorIndexUpdates para excluir um índice vetorial.

aws dynamodb update-table \ --table-name Products \ --vector-index-updates \ "[ {\"Delete\": {\"IndexName\": \"ProductEmbeddingIndex\"}} ]"

Quando você exclui um índice vetorial, o DynamoDB remove o índice e todos os dados. Essa operação não afeta a tabela de base nem os itens.