# Vector search

Vector search classifica as linhas pela proximidade entre um vetor armazenado e um vetor de consulta, enquanto uma busca tradicional compara palavras-chave em busca de uma correspondência exata. Os valores que ela compara são vector embeddings, as representações numéricas de texto, imagens ou outros dados. [SQL Database](/pt-br/documentacao/plataforma/sql-database/) implementa busca vetorial por meio do libSQL, que guarda cada vetor na classe de armazenamento BLOB nativa do SQLite. O tipo de vetor define quantos bits representam cada número de ponto flutuante do vetor.

Vector search atende a quatro tipos de carga de trabalho:

- Recomendações que encontram itens com características semelhantes, como produtos relacionados em um catálogo de e-commerce ou conteúdo em uma plataforma de streaming.
- Busca semântica de texto, em que um text embedding representa uma palavra ou uma frase como um vetor.
- Assistentes de voz e chatbots que aplicam processamento de linguagem natural (NLP).
- A etapa de recuperação de uma aplicação de retrieval-augmented generation (RAG) construída sobre [AI Inference](/pt-br/documentacao/plataforma/ai-inference/), com um framework como LangChain ou LangGraph.

Os vetores ficam no mesmo banco de dados que as demais linhas, então uma única instrução filtra por colunas comuns e classifica por distância vetorial. Nenhum serviço vetorial separado guarda uma cópia dos dados. Para saber como uma consulta chega aos dados, consulte [Como o SQL Database funciona](/pt-br/documentacao/plataforma/sql-database/como-funciona/).

---

## Colunas vetoriais

Uma coluna vetorial é declarada como um tipo blob que carrega o número de dimensões que cada vetor guarda. Uma coluna `F32_BLOB` guarda um array de números de ponto flutuante de 32 bits como um objeto binário grande (BLOB). Esta instrução declara uma coluna vetorial de três dimensões:

```sql
CREATE TABLE teams (
  name TEXT,
  year INT,
  stats_embedding F32_BLOB(3)
);
```

Os exemplos desta página usam três dimensões para que cada vetor seja legível por inteiro. Uma coluna de embedding real declara a quantidade de dimensões do modelo que a preenche. O modelo `text-embedding-3-small` retorna 1.536 dimensões, então sua coluna é declarada como `F32_BLOB(1536)`.

Cada tipo tem um alias, e as duas grafias declaram a mesma coluna:

| Tipo        | Alias        |
| ----------- | ------------ |
| `FLOAT1BIT` | `F1BIT_BLOB` |
| `FLOAT8`    | `F8_BLOB`    |
| `FLOATB16`  | `FB16_BLOB`  |
| `FLOAT16`   | `F16_BLOB`   |
| `FLOAT32`   | `F32_BLOB`   |
| `FLOAT64`   | `F64_BLOB`   |

`FLOAT32` é o ponto de partida recomendado.

---

## Funções

SQL Database adiciona seis funções SQL para dados vetoriais:

| Função                             | O que faz                                                                                           |
| ---------------------------------- | --------------------------------------------------------------------------------------------------- |
| `vector('[...]')`                  | Constrói um vetor a partir de sua forma de texto. Um vetor com mais de 65.536 dimensões é rejeitado |
| `vector_extract(column)`           | Retorna a forma de texto de um vetor armazenado                                                     |
| `vector_distance_cos(a, b)`        | Retorna a distância cosseno entre dois vetores, em que `0` é o mais próximo                         |
| `vector_distance_l2(a, b)`         | Retorna a distância euclidiana entre dois vetores. Não é suportada para vetores `FLOAT1BIT`         |
| `libsql_vector_idx(column)`        | Marca uma coluna para um índice de vizinhos aproximados mais próximos                               |
| `vector_top_k('index', vector, k)` | Retorna as `k` linhas mais próximas de um índice, para juntar em `rowid`                            |

`vector` constrói o valor que uma coluna vetorial armazena, e `vector_extract` o lê de volta. A forma de texto que `vector_extract` retorna não carrega espaços entre os elementos, então uma coluna que guarda `vector('[85, 25, 65]')` retorna `[85,25,65]`.

---

## Distância

Uma função de distância compara dois vetores e retorna um número. Um número menor significa que os dois vetores estão mais próximos.

`vector_distance_cos` retorna a distância cosseno, que é `1 - cosine similarity`. O valor varia de 0 a 2:

- Uma distância próxima de `0` significa que os vetores são quase idênticos, ou exatamente correspondentes.
- Uma distância próxima de `1` significa que os vetores são ortogonais, em ângulo reto entre si.
- Uma distância próxima de `2` significa que os vetores apontam em direções opostas.

`vector_distance_l2` retorna a distância euclidiana. Ela não é suportada para vetores `FLOAT1BIT`.

Ordene pela distância para classificar as linhas da mais próxima à mais distante. Esta consulta retorna os três times cujas estatísticas estão mais próximas de uma temporada de 82 gols marcados, 25 sofridos e 63% de posse de bola:

```sql
SELECT name,
       vector_distance_cos(stats_embedding, vector('[82, 25, 63]')) AS similarity
FROM teams
ORDER BY similarity ASC
LIMIT 3;
```

Uma consulta escrita dessa forma não consulta um índice vetorial. O índice é armazenado como uma tabela separada, e uma instrução chega a ele apenas por meio de `vector_top_k`. Para classificar uma tabela grande sem comparar o vetor de consulta com cada linha, consulte [Indexação](#indexacao).

---

## Indexação

Um índice vetorial responde a uma busca por vizinhos aproximados mais próximos (ANN) sem comparar o vetor de consulta com cada linha. SQL Database constrói o índice com o algoritmo DiskANN. Envolva a coluna vetorial em `libsql_vector_idx` para criar um:

```sql
CREATE INDEX teams_idx ON teams (libsql_vector_idx(stats_embedding));
```

A coluna dentro de `libsql_vector_idx` é a coluna vetorial da tabela sobre a qual o índice é criado. Um segundo argumento define a métrica de distância, como em `libsql_vector_idx(stats_embedding, 'metric=cosine')`.

Criar um índice vetorial adiciona uma tabela sombra nomeada a partir do índice, `teams_idx_shadow`. Uma listagem de tabelas a retorna ao lado das tabelas que você criou. O comando `.tables` do [EdgeSQL Shell](/pt-br/documentacao/plataforma/sql-database/edgesql-shell/) e a chamada `getTables` da [biblioteca azion/sql](/pt-br/documentacao/devtools/azion-lib/sql/) mostram essa tabela.

Um índice vetorial exige uma tabela com `ROWID` ou com uma `PRIMARY KEY` de coluna única. Uma `PRIMARY KEY` composta sem `ROWID` não é suportada.

---

## Consultas

Usar um índice vetorial não é automático. Selecione de `vector_top_k` e junte a tabela em `rowid` para que uma instrução consulte o índice.

`vector_top_k` recebe o nome do índice, o vetor de consulta e o número de linhas a retornar. Ela retorna essas linhas em uma única coluna chamada `id`, que carrega o `ROWID` ou a `PRIMARY KEY` de cada vizinho mais próximo.

Esta sequência cria a tabela, armazena quatro vetores, os indexa e retorna os dois times mais próximos do vetor de consulta:

```sql
CREATE TABLE teams (
  name TEXT,
  year INT,
  stats_embedding F32_BLOB(3)
);

INSERT INTO teams (name, year, stats_embedding)
VALUES
  ('Red', 2023, vector('[80, 30, 60]')),
  ('Blue', 2023, vector('[85, 25, 65]')),
  ('Yellow', 2023, vector('[78, 28, 62]')),
  ('Green', 2023, vector('[90, 20, 70]'));

CREATE INDEX teams_idx ON teams (libsql_vector_idx(stats_embedding));

SELECT name, year
FROM vector_top_k('teams_idx', vector('[82, 25, 63]'), 2)
JOIN teams ON teams.rowid = id;
```

Uma cláusula `WHERE` filtra as linhas que `vector_top_k` já retornou. Adicionar `WHERE year >= 2023` mantém as linhas de 2023 entre essas duas, e nunca faz o índice retornar mais de `k` linhas.

Gere o vetor de consulta com o mesmo modelo de embedding que produziu a coluna armazenada. Para um passo a passo que constrói uma busca semântica de ponta a ponta, consulte [Construa uma busca semântica com embeddings](/pt-br/documentacao/guias/desenvolvimento-de-aplicacoes/dados/edge-sql-vector-search/).

---

## Limites

Três limites se aplicam a dados vetoriais. Um vetor guarda no máximo 65.536 dimensões. `vector_distance_l2` não é suportada para vetores `FLOAT1BIT`. Um índice vetorial exige uma tabela com `ROWID` ou uma `PRIMARY KEY` de coluna única.

O teto de dimensões é aplicado quando um vetor é construído, e não quando uma coluna é declarada. A instrução `CREATE TABLE t (v F32_BLOB(65537));` tem sucesso, porque o SQLite não valida o parâmetro de um tipo de coluna. A instrução que chama `vector` com mais de 65.536 dimensões é a que falha, e ela responde `{"error":"vector: max size exceeded 65536"}` dentro de uma resposta HTTP `200`.

Para todos os demais limites que SQL Database aplica, consulte [Limites do SQL Database](/pt-br/documentacao/plataforma/sql-database/limites/).

---

## Recursos relacionados

- [Construa uma busca semântica com embeddings](/pt-br/documentacao/guias/desenvolvimento-de-aplicacoes/dados/edge-sql-vector-search.md): Um passo a passo que cria a coluna de embedding, a preenche, a indexa e a consulta.
- [SQL Database](/pt-br/documentacao/plataforma/sql-database.md): O produto a que pertencem as colunas e as funções vetoriais desta página.
- [Bancos de dados e consultas](/pt-br/documentacao/plataforma/sql-database/bancos-de-dados-e-consultas.md): O envelope que uma instrução retorna, e como uma instrução vetorial com falha informa seu erro.
- [Limites do SQL Database](/pt-br/documentacao/plataforma/sql-database/limites.md): Todos os limites que o produto aplica, incluindo os que se aplicam a dados vetoriais.
- [AI Inference](/pt-br/documentacao/plataforma/ai-inference.md): Onde uma aplicação RAG executa seu modelo, ao lado da busca vetorial que recupera o contexto.
