Início rápido 2: pesquisa vetorial com MongoDB e OpenAI
Avalie esse Início rápido
Este início rápido orientará você sobre como realizar uma pesquisa vetorial usando o MongoDB Atlas e a API OpenAI. Código (notebook Python): Visualizar no Github ou Abrir no CoLab
- Criando um índice de vetores no Atlas
- Executando Atlas Search vetorial usando incorporações OpenAI
- Uma conta Atlas gratuita — crie uma agora!
- Um ambiente de bloco de notas Python Jupyter — recomendamos o Google CoLab. É um ambiente gratuito, baseado em cloud e muito fácil de entrar e executar.
Este início rápido pode ser útil para executar o Atlas e um cliente Python: Introdução ao MongoDB Atlas e Python.
No domínio da recuperação de informações, a pesquisa por palavras-chave é o padrão há muito tempo. Esse método envolve combinar palavras exatas em textos para encontrar informações relevantes. Por exemplo, se você estiver tentando localizar um filme, mas só consegue lembrar que o título inclui a palavra "battle (batalha)," uma pesquisa por palavra-chave permite filtrar o conteúdo para encontrar correspondências.
No entanto, e se sua memória de um filme for vaga, limitada a um enredo ou tema geral, em vez de títulos ou palavras-chave específicos? É aqui que a pesquisa vetorial entra em cena, revolucionando a forma como encontramos informações. Ao contrário da pesquisa por palavra-chave, a pesquisa vetorial mergulha no reino da semântica, permitindo a recuperação do conteúdo com base nos significados por trás das palavras.
Considere que você está tentando encontrar um filme novamente, mas desta vez, tudo o que você lembra é de uma descrição ampla do enredo, como " humanos lutam contra alienígenas. " Os métodos de pesquisa tradicionais podem fazer com que você vasculhe infinitos resultados irrelevantes. A pesquisa vetorial, no entanto, usa algoritmos avançados para entender o significado contextual de sua consulta, capazes de guiá-lo para filmes que se alinham à sua descrição — como " Terminator " — mesmo que as palavras exatas não sejam usadas em seus termos de pesquisa.
Vamos entender como todas as peças se encaixam.
Vamos usar a coleçãoembedded_movies nos dados de amostra do Atlas. Esse já tem embeddings calculados para plots, facilitando a nossa vida.
Veja como tudo funciona. Quando uma query de pesquisa semântica é emitida (por exemplo, "filmes de ficção científica fatalísticos"):
- Etapas 1 e 2: chamamos a API OpenAI para obter incorporações para o texto da query.
- Etapa 3: Envie a incorporação para o Atlas para executar uma pesquisa vetorial.
- Etapa 4: o Atlas retorna resultados de pesquisa relevantes usando a pesquisa vetorial.
Aqui está um visual:
As incorporações são uma maneira interessante de transformar diferentes tipos de dados - seja texto, imagens, áudio ou vídeo - em um formato numérico, especificamente, em uma matriz conhecida como "vector." Essa conversão permite que os dados sejam processados e compreendidos pelas máquinas.
Tomemos como exemplo os dados de texto: As palavras podem ser convertidas em números, sendo que cada palavra única recebe seu próprio valor numérico distinto. Estas representações numéricas podem variar em tamanho, variando de 128 a 4096 elementos.
No entanto, o que diferencia os embeddings é sua capacidade de capturar mais do que apenas sequências aleatórias de números. Na verdade, eles preservam parte do significado inerente dos dados originais. Por exemplo, palavras que compartilham significados semelhantes tendem a ter incorporações mais próximas no espaço numérico.
Para ilustrar, considere um cenário simplificado onde plotamos as incorporações de várias palavras em um gráfico bidimensional para facilitar a visualização. Embora na prática os embeddings possam abranger muitas dimensões (de 128 a 4096), este exemplo ajuda a esclarecer o conceito. No gráfico, você notará que itens com contextos ou significados semelhantes – como diferentes tipos de frutas ou vários animais de estimação – estão posicionados mais próximos uns dos outros. Esse agrupamento é um ponto forte dos embeddings, destacando sua capacidade de capturar e refletir as nuances de significado e similaridade nos dados.
Então, como criamos Go incorporações úteis? Felizmente, há uma variedade de modelos de incorporação projetados para transformar seus dados de texto, áudio ou vídeo em representações numéricas significativas.
Alguns desses modelos são proprietários, o que significa que pertencem a determinadas empresas e são acessíveis principalmente por meio de suas APIs. A OpenAI é um exemplo notável de um provedor que oferece esses modelos.
Também existem modelos de código aberto disponíveis. Eles podem ser baixados gratuitamente e operados em seu próprio computador. Se você optar por um modelo proprietário ou uma opção de código aberto, depende de suas necessidades e recursos específicos.
A tabela de classificação de modelos de incorporação do Hugging Face é um ótimo lugar para começar a procurar modelos de incorporação. Eles testam periodicamente os modelos de incorporação disponíveis e os classificam de acordo com vários critérios.
Você pode ler mais sobre embeddings:
- Explore algumas das opções de incorporação: Série RAG Parte 1: Como escolher o modelo de incorporação correto para sua aplicação, por Apoorva Joshi
Aqui está um guia rápido adotado da documentação oficial. Consulte a documentação para obter detalhes completos.
- Você pode escolher qualquer instância de nuvem.
- Escolha o nível "FREE " para não incorrer em custos.
- Siga o assistente de configuração e atribua um nome à sua instância.
- Anote seu nome de usuário e senha para se conectar à instância.
- Configurando o acesso IP: adicione 0.0.0.0/0 para a lista de acesso IP. Isso disponibiliza a conexão do Google Colab. (Observação: isso torna a instância disponível a partir de qualquer endereço IP, o que é bom para uma instância de teste). Veja a captura de tela abaixo para saber como adicionar o IP:
Em seguida, carregaremos os conjuntos de dados de amostra padrão no Atlas, o que pode levar alguns minutos.
Na interface do usuário do Atlas, explorar a coleçãoembedded_movies no banco de dadossample_mflix para visualizar detalhes do documento como título, ano e gráfico.
Felizmente, o conjunto de dadossample_mflix.embedded_movies já inclui incorporações vetoriais para gráficos, gerados com o modelo text-embedding-ada-002do OpenAI. Ao inspecionar o atributoplot_embedding na UI do Atlas, conforme mostrado na captura de tela abaixo, você verá que ele é composto por uma array de 1536 números.
Parabéns! Agora você tem um agrupamento do Atlas, com alguns dados de amostra. 👏
Antes de executarmos uma pesquisa vetorial, precisamos criar um índice vetorial. Criar um índice permite ao Atlas executar queries mais rapidamente. Veja como criar um índice vetorial.
Vamos definir um índice vetorial conforme abaixo. Aqui está o que os parâmetros significam.
- "type": "vector" — Isso indica que estamos definindo um índice vetorial.
- "path": "plot_embedding" - Esse é o atributo que estamos indexando - no nosso caso, os dados de incorporação do gráfico.
- "numDimensions": 1536 - Indica a dimensão do campo de incorporação. Ele precisa corresponder ao modelo de incorporação que usamos (no nosso caso, o modelo OpenAI).
- " similarity ": "dotProduct" — Finalmente, estamos definindo o algoritmo de correspondência a ser usado pelo índice vetorial. As opções são euclidean, cossenoe dotProduct. Você pode ler mais sobre essas opções em Como indexar campos para o Vector Search.
Nome do índice: idx_plot_embedding
Definição de Índice
1 { 2 "fields": [ 3 { 4 "type": "vector", 5 "path": "plot_embedding", 6 "numDimensions": 1536, 7 "similarity": "dotProduct" 8 } 9 ] 10 }
Aguarde até que o índice esteja pronto para ser usado
Começaremos definindo os seguintes parâmetros de configuração:
- Credenciais de conexão Atlas — veja abaixo um guia passo a passo.
- Chave de API OpenAI - obtenha-a no dashboard do OpenAI.
Veja como você obtém a configuraçãoATLAS_URI.
- Navegue até a IU do Atlas.
- Selecione seu banco de dados.
- Escolha a opção "Connect " para continuar.
- Na seção de conexão, clique em “Drivers” para ver os detalhes da conexão.
- Por fim, copie o valor ATLAS_URI exibido para uso na configuração do aplicativo.
Veja estas capturas de tela como orientação.
Agora, vamos dar uma olhada no código. Iremos percorrer e executar o código passo a passo. Você também pode acessar o notebook Python totalmente funcional no início deste guia.
Comece definindo configurações para ATLAS_URI e OPENAI_API_KEY.
(Execute este bloco de código em seu Google Colab na Etapa 3.)
1 # We will keep all global variables in an object to not pollute the global namespace. 2 class MyConfig(object): 3 pass 4 5 MY_CONFIG = MyConfig() 6 7 MY_CONFIG.ATLAS_URI = "Enter your Atlas URI value here" ## TODO 8 MY_CONFIG.OPENAI_API_KEY = "Enter your OpenAI API Key here" ## TODO
Dica profissional 💡 Manteremos todas as variáveis globais em um objeto chamado MY_CONFIG para não poluir o namespace global. MyConfig é apenas uma classe de espaço reservado para armazenar nossas variáveis e configurações.
Vamos instalar as dependências necessárias. Estamos instalando dois pacotes:
- pymongo: Biblioteca Python para conexão com instâncias do MongoDB Atlas
- openai: Para chamar a biblioteca OpenAI
(Execute este bloco de código em seu Google Colab na Etapa 4.)
1 !pip install openai==1.13.3 pymongo==4.6.2
Tip Pro } Você notará que estamos especificando uma versão (openai==1.13.3) para os pacotes que estamos instalando. Isso garante que as versões que estamos instalando sejam compatíveis com nosso código. Essa é uma boa prática e é chamada de fixação ou congelamentode versão.
AtlasClient Esta classe lida com o estabelecimento de conexões, a execução de queries e a realização de uma pesquisa vetorial no MongoDB Atlas.
(Execute este bloco de código em seu Google Colab na Etapa 5.)
1 from pymongo import MongoClient 2 3 4 class AtlasClient (): 5 6 7 def __init__ (self, altas_uri, dbname): 8 self.mongodb_client = MongoClient(altas_uri) 9 self.database = self.mongodb_client[dbname] 10 11 12 ## A quick way to test if we can connect to Atlas instance 13 def ping (self): 14 self.mongodb_client.admin.command('ping') 15 16 17 def get_collection (self, collection_name): 18 collection = self.database[collection_name] 19 return collection 20 21 22 def find (self, collection_name, filter = {}, limit=10): 23 collection = self.database[collection_name] 24 items = list(collection.find(filter=filter, limit=limit)) 25 return items 26 27 28 # https://www.mongodb.com/pt-br/docs/atlas/atlas-vector-search/vector-search-stage/ 29 def vector_search(self, collection_name, index_name, attr_name, embedding_vector, limit=5): 30 collection = self.database[collection_name] 31 results = collection.aggregate([ 32 { 33 '$vectorSearch': { 34 "index": index_name, 35 "path": attr_name, 36 "queryVector": embedding_vector, 37 "numCandidates": 50, 38 "limit": limit, 39 } 40 }, 41 ## We are extracting 'vectorSearchScore' here 42 ## columns with 1 are included, columns with 0 are excluded 43 { 44 "$project": { 45 '_id' : 1, 46 'title' : 1, 47 'plot' : 1, 48 'year' : 1, 49 "search_score": { "$meta": "vectorSearchScore" } 50 } 51 } 52 ]) 53 return list(results) 54 55 56 def close_connection(self): 57 self.mongodb_client.close()
Inicializando classe: A função do construtor (init) usa dois argumentos: URI do Atlas (que obtivemos das configurações) Banco de dados para conectar
Ping: esse é um método útil para testar se podemos nos conectar ao Atlas.
encontrar Esta é a função "search ". Especificamos a coleção para pesquisar e quaisquer critérios de pesquisa usando filtros.
vector_search Esta é uma função chave que executa pesquisa vetorial no MongoDB Atlas. Ele recebe os seguintes parâmetros:
- collection_name: embedded_movies
- index_name: idx_plot_embedding
- attr_name: "plot_embedding"
- embedding_vector: incorporações retornadas da chamada de API OpenAI
- limite: Quantos resultados retornar
A seção$project extrai os atributos que queremos retornar como resultados de pesquisa.
(Este bloco de código é para fins de revisão. Não há necessidade de executar.)
1 results = collection.aggregate([ 2 { 3 '$vectorSearch': { 4 "index": index_name, 5 "path": attr_name, 6 "queryVector": embedding_vector, 7 "numCandidates": 50, 8 "limit": limit, 9 } 10 }, 11 ## We are extracting 'vectorSearchScore' here 12 ## columns with 1 are included, columns with 0 are excluded 13 { 14 "$project": { 15 '_id' : 1, 16 'title' : 1, 17 'plot' : 1, 18 'year' : 1, 19 "search_score": { "$meta": "vectorSearchScore" } 20 } 21 } 22 ])
Além disso, observe esta linha:
1 "search_score": { "$meta": "vectorSearchScore" }
Esta linha específica extrai a pontuação de pesquisa da pesquisa vetorial. A pontuação da pesquisa varia de 0.0 a 1.0. Pontuações próximas de 1.0 são uma ótima combinação.
Esta é uma aula útil para interação OpenAI.
(Execute este bloco de código em seu Google Colab na Etapa 5.)
1 from openai import OpenAI 2 3 4 class OpenAIClient(): 5 def __init__(self, api_key) -> None: 6 self.client = OpenAI( 7 api_key= api_key, # defaults to os.environ.get("OPENAI_API_KEY") 8 ) 9 # print ("OpenAI Client initialized!") 10 11 12 13 14 def get_embedding(self, text: str, model="text-embedding-ada-002") -> list[float]: 15 text = text.replace("\n", " ") 16 resp = self.client.embeddings.create ( 17 input=[text], 18 model=model ) 19 20 21 return resp.data[0].embedding
Classe de inicialização: Essa classe é inicializada com a chave da API OpenAI.
Método get_embedding:
- texto: Esse é o texto para o qual estamos tentando obter embeddings.
- modelo: este é o modelo de incorporação. Aqui estamos especificando o modelo text-embedding-ada-002 porque este é o modelo utilizado para criar incorporações em nossos dados de amostra. Então, queremos usar o mesmo modelo para codificar nossa string de query.
Inicialize o Atlas e faça um teste rápido de conectividade. Estamos conectando ao banco de dadossample_mflix e à collectionembedded_movies. Este conjunto de dados é carregado como parte da configuração (Etapa 1).
Se tudo correr bem, a conexão será bem-sucedida.
(Execute este bloco de código em seu Google Colab na Etapa 6.)
1 MY_CONFIG.DB_NAME = 'sample_mflix' 2 MY_CONFIG.COLLECTION_NAME = 'embedded_movies' 3 MY_CONFIG.INDEX_NAME = 'idx_plot_embedding' 4 5 6 atlas_client = AtlasClient (MY_CONFIG.ATLAS_URI, MY_CONFIG.DB_NAME) 7 atlas_client.ping() 8 print ('Connected to Atlas instance! We are good to go!')
Soluçãode problemas Se você receber um erro "connection failed ", certifique-se 0.0.0.0/0 é adicionado como um endereço IP permitido para se conectar (consulte a etapa 1).
Inicialize o cliente OpenAI com a chave de API OpenAI.
(Execute este bloco de código em seu Google Colab na Etapa 7.)
1 openAI_client = OpenAIClient (api_key=MY_CONFIG.OPENAI_API_KEY) 2 print ("OpenAI client initialized")
Agora que temos tudo configurado, vamos fazer uma pesquisa vetorial! Vamos fazer query de plots de filmes, não apenas com base em palavras-chave, mas também em significado. Por exemplo, procuraremos filmes em que o argumento seja "Humanos enfrentando extraterrestres".
Esta função usa um argumento: string dequery .
- Convertemos a query em incorporações. Fazemos isso chamando a API OpenAI. Também programamos a chamada de API (t1b - t1a) para entender as latências da rede.
- Enviamos os embeddings (que acabamos de receber da OpenAI) ao Atlas para realizar uma pesquisa vetorial e obter os resultados.
- Estamos imprimindo os resultados retornados pela pesquisa vetorial.
(Execute este bloco de código em seu Google Colab na Etapa 8.)
1 import time 2 3 # Handy function 4 def do_vector_search (query:str) -> None: 5 query = query.lower().strip() # cleanup query string 6 print ('query: ', query) 7 8 9 # call openAI API to convert text into embedding 10 t1a = time.perf_counter() 11 embedding = openAI_client.get_embedding(query) 12 t1b = time.perf_counter() 13 print (f"Getting embeddings from OpenAI took {(t1b-t1a)*1000:,.0f} ms") 14 15 16 # perform a vector search on Atlas 17 # using embeddings (returned from OpenAI above) 18 t2a = time.perf_counter() 19 movies = atlas_client.vector_search(collection_name=MY_CONFIG.COLLECTION_NAME, index_name=MY_CONFIG.INDEX_NAME, attr_name='plot_embedding', embedding_vector=embedding,limit=10 ) 20 t2b = time.perf_counter() 21 22 23 # and printing out the results 24 print (f"Altas query returned {len (movies)} movies in {(t2b-t2a)*1000:,.0f} ms") 25 print() 26 27 28 for idx, movie in enumerate (movies): 29 print(f'{idx+1}\nid: {movie["_id"]}\ntitle: {movie["title"]},\nyear: {movie["year"]}' + 30 f'\nsearch_score(meta):{movie["search_score"]}\nplot: {movie["plot"]}\n')
Aqui está nossa primeira consulta. Queremos encontrar filmes em que o enredo seja sobre humanos " lutando contra alienígenas. "
(Execute este bloco de código em seu Google Colab na Etapa 8.)
1 query="humans fighting aliens" 2 do_vector_search (query=query)
Veremos resultados de pesquisa como este:
1 query: humans fighting aliens 2 using cached embeddings 3 Altas query returned 10 movies in 138 ms 4 5 6 1 7 id: 573a1398f29313caabce8f83 8 title: V: The Final Battle, 9 year: 1984 10 search_score(meta):0.9573556184768677 11 plot: A small group of human resistance fighters fight a desperate guerilla war against the genocidal extra-terrestrials who dominate Earth. 12 13 14 2 15 id: 573a13c7f29313caabd75324 16 title: Falling Skies, 17 year: 2011è 18 search_score(meta):0.9550596475601196 19 plot: Survivors of an alien attack on earth gather together to fight for their lives and fight back. 20 21 22 3 23 id: 573a139af29313caabcf0cff 24 title: Starship Troopers, 25 year: 1997 26 search_score(meta):0.9523435831069946 27 plot: Humans in a fascistic, militaristic future do battle with giant alien bugs in a fight for survival. 28 29 30 ... 31 year: 2002 32 search_score(meta):0.9372057914733887 33 plot: A young woman from the future forces a local gunman to help her stop an impending alien invasion which will wipe out the human race.
Observe a pontuação Além dos atributos do filme (title, ano, lote etc.), também estamos exibindo search_score. Este é um atributo meta — não realmente parte da coleção de filmes, mas gerado como resultado da pesquisa vetorial. Este é um número entre 0 e 1. Valores mais próximos de 1 representam uma correspondência melhor. Os resultados são classificados da melhor correspondência para baixo (mais próximo de 1 primeiro). Leia mais sobre pontuação de pesquisa.
Soluçãode problemas Não há resultados de pesquisa? Certifique-se de que o índice de pesquisa vetorial esteja definido e ativo (Etapa 2)!
(Execute este bloco de código em seu Google Colab na Etapa 8.)
1 query="relationship drama between two good friends" 2 do_vector_search (query=query)
Os resultados de amostra ficarão assim:
1 query: relationship drama between two good friends 2 using cached embeddings 3 Altas query returned 10 movies in 71 ms 4 5 6 1 7 id: 573a13a3f29313caabd0dfe2 8 title: Dark Blue World, 9 year: 2001 10 search_score(meta):0.9380425214767456 11 plot: The friendship of two men becomes tested when they both fall for the same woman. 12 13 14 2 15 id: 573a13a3f29313caabd0e14b 16 title: Dark Blue World, 17 year: 2001 18 search_score(meta):0.9380425214767456 19 plot: The friendship of two men becomes tested when they both fall for the same woman. 20 21 22 3 23 id: 573a1399f29313caabcec488 24 title: Once a Thief, 25 year: 1991 26 search_score(meta):0.9260045289993286 27 plot: A romantic and action packed story of three best friends, a group of high end art thieves, who come into trouble when a love-triangle forms between them. 28 29 30 ... 31 year: 1987 32 search_score(meta):0.9181452989578247 33 plot: A modern day Romeo & Juliet story is told in New York when an Italian boy and a Chinese girl become lovers, causing a tragic conflict between ethnic gangs.
Aqui Go nós! Realizamos com sucesso uma pesquisa vetorial combinando Atlas e a API OpenAI.
Resumindo, neste início rápido, realizamos o seguinte:
- Configurar o Atlas na nuvem
- Os dados de amostra foram carregados em nosso cluster do Atlas
- Configure um índice de pesquisa vetorial
- Realizou uma pesquisa vetorial usando incorporações OpenAI e Atlas
Como podemos ver, a pesquisa vetorial é muito poderosa, pois pode buscar resultados com base no significado semântico dos termos de pesquisa, em vez de apenas na correspondência de palavras-chave. A pesquisa vetorial nos permite criar aplicativos mais avançados.
Aqui estão alguns recursos sugeridos para você explorar:
Principais comentários nos fóruns
Ainda não há comentários sobre este artigo.