Pesquisa semântica com Jina Embeddings v2 e MongoDB Atlas
Avalie esse Tutorial
A pesquisa semântica é uma ótima aliada para incorporações de AI.
O uso de vetores para identificar e classificar correspondências faz parte do Atlas Search há mais tempo do que a AI. O venerável algoritmo tf/idf, que remonta ao 1960s, usa a contagem de palavras e, às vezes, partes de palavras e combinações curtas de palavras, para criar vetores representativos para documentos de texto. Em seguida, ele usa a distância entre os vetores para localizar e classificar possíveis correspondências de query e comparar documentos entre si. Forma a base de muitos sistemas de recuperação de informação.
Chamamos isso de "semantic search" porque esses vetores já possuem informações sobre o significado dos documentos embutidos neles. A pesquisa com incorporações semânticas funciona da mesma maneira, mas, em vez disso, os vetores vêm de modelos de AI que fazem um trabalho muito melhor em entender os documentos.
Como a recuperação baseada em vetores é uma técnica de recuperação consagrada pelo tempo, há plataformas de banco de dados que já possuem todos os mecanismos para fazer isso. Tudo que você precisa fazer é conectar seu modelo de incorporações de AI.
Este artigo mostrará como aprimorar o MongoDB Atlas — uma solução baseada na cloud e pronta para uso para recuperação de documentos — com a AI top de linha da Jina Embeddings para produzir sua própria solução de pesquisa matadora.
Primeiro, você precisará de uma conta do MongoDB Atlas. Registre-se para uma nova conta ou faça login usando sua conta do Google diretamente no site.
Depois de fazer login, você deverá ver sua páginaProjetos. Caso contrário, use o menu de navegação à esquerda para acessá-lo.
Crie um novo projeto clicando no botão Novo Projeto à direita.
Você pode adicionar novos membros conforme desejar, mas não precisa fazer isso neste tutorial.
Isso deve levá-lo de volta à páginaVisão geral, onde agora você pode criar uma implantação. Clique no botão+Criar para fazer isso.
Selecione a camadaM0 grátis para esse projeto e o fornecedor de sua escolha e clique no botãoCriar na parte inferior da tela.
Na próxima tela, você precisará criar um usuário com nome de usuário e senha segura para essa implantação. Não perca esta senha e nome de usuário! Eles são a única maneira de você acessar seu trabalho.
Em seguida, selecione as opções de acesso. Recomendamos, para este tutorial, selecionar Meu ambiente locale clicar no botão Adicionar meu endereço IP atual.
Se você tiver uma VPN ou uma topologia de segurança mais complexa, talvez seja necessário consultar o administrador do sistema para descobrir qual número IP deve inserir aqui em vez do atual.
Depois disso, clique em Concluir e implantar na parte inferior da página. Após uma breve pausa, agora você terá um banco de MongoDB database vazio implantado no Atlas para você utilizar.
Nota: Se você tiver dificuldade em acessar seu banco de dados de fora, poderá se livrar da Lista de Acesso IP e aceitar conexões de todos os endereços IP. Normalmente, essa seria uma prática de segurança muito ruim, mas como esse é um tutorial que usa dados de amostra disponíveis publicamente, há pouco risco real.
Para fazer isso, clique na guiaAcesso à rede em Segurança no lado esquerdo da página:
Em seguida, clique em ADICIONAR endereço IP no lado direito da página:
Você obterá uma janela modal. Clique no botão permitir acesso de qualquer lugare clique em Confirmar.
Sua aba Acesso à rede agora deve ter uma entrada rotulada
0.0.0.0/0
. Isso permitirá que qualquer endereço IP acesse seu banco de dados se ele tiver o nome de usuário e a senha corretos.
Neste tutorial, usaremos um banco de dados de amostra de avaliações do Airbnb. Você pode adicionar isso ao seu banco de dados na aba Banco de Dados em Sistemas no menu no lado esquerdo da tela. Quando estiver na página "Database Deployments ", encontre seu cluster (na camada grátis, você só tem permissão para um, então deve ser fácil). Em seguida, clique no botão "three dots " e escolha Carregar dados de amostra" . Pode levar alguns minutos para carregar os dados.
Isso adicionará uma collection de fontes de dados gratuitas à sua instância do MongoDB para você experimentar, incluindo um banco de dados de avaliações do Airbnb.
No restante deste tutorial, usaremos Python e PyMongo para acessar seu novo banco de dados MongoDB Atlas.
Certifique-se de que o PyMongo esteja instalado em seu ambiente Python. Você pode fazer isso com o seguinte comando:
1 pip install pymongo
Você também precisará saber:
- O nome de usuário e a senha que você define ao configurar o banco de dados.
- O URL para acessar sua implantação de banco de dados.
Se você perdeu seu nome de usuário e senha, clique na guiaDatabase Access (Acesso ao banco de dados) em Security (Segurança), no lado esquerdo da página. Essa página permitirá que você redefina sua senha.
Para obter o URL de acesso ao seu banco de dados, volte à guiaDatabase (Banco de dados ) em Deployment (Implantação), no lado esquerdo da tela. Localize seu cluster e procure o botão denominado Connect (Conectar). Clique nele.
Você verá uma janela pop-up modal como a abaixo:
Clique emDrivers em Conectar ao seu aplicativo. Você verá uma janela modal como a abaixo. Abaixo do número três, você verá o URL de que precisa, mas sem sua senha. Você precisará adicionar sua senha ao usar este URL.
Crie um arquivo para um novo script Python. Você pode chamá-lo de
test_mongo_connection.py
.Escreva neste arquivo o seguinte código, que usa o PyMongo para criar uma conexão de cliente com seu banco de dados:
1 from pymongo.mongo_client import MongoClient 2 3 client = MongoClient("<URL from above>")
Lembre-se de inserir a URL para se conectar ao seu banco de dados, incluindo o nome de usuário e a senha corretos.
Em seguida, adicione código para se conectar ao conjunto de dados de avaliação do Airbnb que foi instalado como dados de exemplo:
1 db = client.sample_airbnb 2 collection = db.listingsAndReviews
A variável
collection
é um iterável que retornará todo o conjunto de dados item por item. Para testar se funciona, adicione a seguinte linha e execute test_mongo_connection.py
:1 print(collection.find_one())
Isso imprimirá o texto formatado em JSON que contém as informações em uma entrada do banco de dados, qualquer que tenha sido encontrada primeiro. Deve ser semelhante a isto:
1 {'_id': '10006546', 2 'listing_url': 'https://www.airbnb.com/rooms/10006546', 3 'name': 'Ribeira Charming Duplex', 4 'summary': 'Fantastic duplex apartment with three bedrooms, located in the historic 5 area of Porto, Ribeira (Cube) - UNESCO World Heritage Site. Centenary 6 building fully rehabilitated, without losing their original character.', 7 'space': 'Privileged views of the Douro River and Ribeira square, our apartment offers 8 the perfect conditions to discover the history and the charm of Porto. 9 Apartment comfortable, charming, romantic and cozy in the heart of Ribeira. 10 Within walking distance of all the most emblematic places of the city of Porto. 11 The apartment is fully equipped to host 8 people, with cooker, oven, washing 12 machine, dishwasher, microwave, coffee machine (Nespresso) and kettle. The 13 apartment is located in a very typical area of the city that allows to cross 14 with the most picturesque population of the city, welcoming, genuine and happy 15 people that fills the streets with his outspoken speech and contagious with 16 your sincere generosity, wrapped in a only parochial spirit.', 17 'description': 'Fantastic duplex apartment with three bedrooms, located in the historic 18 area of Porto, Ribeira (Cube) - UNESCO World Heritage Site. Centenary 19 building fully rehabilitated, without losing their original character. 20 Privileged views of the Douro River and Ribeira square, our apartment 21 offers the perfect conditions to discover the history and the charm of 22 Porto. Apartment comfortable, charming, romantic and cozy in the heart of 23 Ribeira. Within walking distance of all the most emblematic places of the 24 city of Porto. The apartment is fully equipped to host 8 people, with 25 cooker, oven, washing machine, dishwasher, microwave, coffee machine 26 (Nespresso) and kettle. The apartment is located in a very typical area 27 of the city that allows to cross with the most picturesque population of 28 the city, welcoming, genuine and happy people that fills the streets with 29 his outspoken speech and contagious with your sincere generosity, wrapped 30 in a only parochial spirit. We are always available to help guests', 31 ... 32 }
Obter uma resposta de texto como essa mostrará que você pode se conectar ao seu banco de dados MongoDB Atlas.
Copie a chave API desta página. Ele fornece a você 10,000 tokens de incorporação gratuita utilizando modelos Jina Embeddings. Devido a essa limitação do número de tokens permitidos para uso na camada gratuita, incorporaremos apenas uma pequena parte da coleção de avaliações do Airbnb. Você pode comprar cota adicional clicando na guia "Top up " na página da Web daJina Embeddings se quiser incorporar a coleção inteira no MongoDB Atlas ou aplicar essas etapas a outro conjunto de dados.
Teste sua chave de API criando um novo script, chame-o
test_jina_ai_connection.py
e coloque o seguinte código nele, inserindo seu código de API onde marcado:1 import requests 2 3 url = 'https://api.jina.ai/v1/embeddings' 4 5 headers = { 6 'Content-Type': 'application/json', 7 'Authorization': 'Bearer <insert your API key here>' 8 } 9 10 data = { 11 'input': ["Your text string goes here"], 12 'model': 'jina-embeddings-v2-base-en' 13 } 14 15 response = requests.post(url, headers=headers, json=data) 16 17 print(response.content)
Execute o script test_jina_ai_connection.py. Você deve obter algo como isto:
1 b'{"model":"jina-embeddings-v2-base-en","object":"list","usage":{"total_tokens":14, 2 "prompt_tokens":14},"data":[{"object":"embedding","index":0,"embedding":[-0.14528547, 3 -1.0152762,1.3449358,0.48228237,-0.6381836,0.25765118,0.1794826,-0.5094953,0.5967494, 4 ..., 5 -0.30768695,0.34024483,-0.5897042,0.058436804,0.38593403,-0.7729841,-0.6259417]}]}'
Isso indica que você tem acesso à Jina Embeddings por meio de sua API.
Agora, vamos colocar todas essas peças juntas com algumas funções Python para usar oJina Embeddings para atribuir vetores de incorporação a descrições no conjunto de dados do Airbnb.
Crie um novo script Python, chame-o
index_embeddings.py
e insira algum código para importar bibliotecas e declarar algumas variáveis:1 import requests 2 from pymongo.mongo_client import MongoClient 3 4 jinaai_token = "<your Jina token here>" 5 mongo_url = "<your MongoDB Atlas database URL>" 6 embedding_url = "https://api.jina.ai/v1/embeddings"
Em seguida, adicione o código para configurar um cliente MongoDB e conecte-se ao conjunto de dados do Airbnb:
1 client = MongoClient(mongo_url) 2 db = client.sample_airbnb
Agora, adicionaremos ao script uma função para converter listas de textos em incorporações usando o modelo de AI
jina-embeddings-v2-base-en
:1 def generate_embeddings(texts): 2 payload = {"input": texts, 3 "model": "jina-embeddings-v2-base-en"} 4 try: 5 response = requests.post( 6 embedding_url, 7 headers={"Authorization": f"Bearer {jinaai_token}"}, 8 json=payload 9 ) 10 except Exception as e: 11 raise ValueError(f"Error in calling embedding API: {e}/nInput: {texts}") 12 if response.status_code != 200: 13 raise ValueError(f"Error in embedding service {response.status_code}: {response.text}, {texts}") 14 embeddings = [d["embedding"] for d in response.json()["data"]] 15 return embeddings
E criaremos uma função que itera até documentos 30 no banco de dados de listagens, criando incorporações para as descrições e resumos e adicionando-os a cada entrada no banco de dados:
1 def index(): 2 collection = db.listingsAndReviews 3 docs_to_encode = collection.find({ "embedding_summary" : { "$exists" : False } }).limit(30) 4 for i, doc in enumerate(docs_to_encode): 5 if i and i%5==0: 6 print("Finished embedding", i, "documents") 7 try: 8 embedding_summary, embedding_description = generate_embeddings([doc["summary"], doc["description"]]) 9 except Exception as e: 10 print("Error in embedding", doc["_id"], e) 11 continue 12 doc["embedding_summary"] = embedding_summary 13 doc["embedding_description"] = embedding_description 14 collection.replace_one({'_id': doc['_id']}, doc)
Com isso em vigor, agora podemos indexar a coleção:
1 index()
Execute o script
index_embeddings.py
. Isso pode levar alguns minutos. Quando isso terminar, teremos adicionado incorporações a 30 dos itens do Airbnb.Retorne ao site do MongoDB e clique em Banco dedados em Sistema no lado esquerdo da tela.
Clique no link do seu cluster (Cluster0 na imagem acima). Encontre a guia Pesquisa na página do cluster e clique nela para obter uma página como esta:
Clique no botão marcado como **Criar índice de pesquisa**.
Agora, clique em JSON Editor e depois em Next:
Agora, execute as seguintes etapas:
- Em Banco de dados e collection, localize sample_airbnbe, abaixo dele, verifique listagensAndReviews.
- Em Nome do índice, preencha o nome
listings_comments_semantic_search
. - Abaixo disso, nas linhas numeradas, adicione o seguinte texto JSON:
1 { 2 "mappings": { 3 "dynamic": true, 4 "fields": { 5 "embedding_description": { 6 "dimensions": 768, 7 "similarity": "dotProduct", 8 "type": "knnVector" 9 }, 10 "embedding_summary": { 11 "dimensions": 768, 12 "similarity": "dotProduct", 13 "type": "knnVector" 14 } 15 } 16 } 17 }
Sua tela deve ficar assim:
Agora, clique em Next e, em seguida, emCreate Search Index na próxima tela :
Isso agendará a indexação no MongoDB Atlas. Você pode ter que esperar vários minutos para que seja concluído.
Quando concluído, a seguinte janela modal será exibida:
Retorne ao seu cliente Python e realizaremos uma pesquisa.
Agora que nossas incorporações estão indexadas, realizaremos uma pesquisa.
Vamos escrever uma função de pesquisa que faz o seguinte:
- Pegue uma string de query e converta-a em uma incorporação usando oJina Embeddings e nossa função gerar_embeddings existente.
- Consulte o índice no MongoDB Atlas usando a conexão de cliente que já configuramos.
- Imprima nomes, resumos e descrições das partidas.
Defina as funções de pesquisa da seguinte maneira:
1 def search(query): 2 query_embedding = generate_embeddings([query])[0] 3 results = db.listingsAndReviews.aggregate([ 4 { 5 '$search': { 6 "index": "listings_comments_semantic_search", 7 "knnBeta": { 8 "vector": query_embedding, 9 "k": 3, 10 "path": ["embedding_summary", "embedding_description"] 11 } 12 } 13 } 14 ]) 15 for document in results: 16 print(f'Listing Name: {document["name"]}\nSummary: {document["name"]}\nDescription: {document["description"]}\n\n')
E agora, vamos fazer uma pesquisa:
1 search("an amazing view and close to amenities")
Seus resultados podem variar porque este tutorial não indexou todos os documentos no conjunto de dados, e quais foram indexados podem variar drasticamente. Você deve obter um resultado como este:
1 Listing Name: Rented Room 2 Summary: Rented Room 3 Description: Beautiful room and with a great location in the city of Rio de Janeiro 4 5 6 Listing Name: Spacious and well located apartment 7 Summary: Spacious and well located apartment 8 Description: Enjoy Porto in a spacious, airy and bright apartment, fully equipped, in a 9 building with lift, located in a region full of cafes and restaurants, close to the subway 10 and close to the best places of the city. The apartment offers total comfort for those 11 who, besides wanting to enjoy the many attractions of the city, also like to relax and 12 feel at home, All airy and bright, with a large living room, fully equipped kitchen, and a 13 delightful balcony, which in the summer refreshes and in the winter protects from the cold 14 and rain, accommodating up to six people very well. It has 40-inch interactive TV, internet 15 and high-quality wi-fi, and for those who want to work a little, it offers a studio with a 16 good desk and an inspiring view. The apartment is all available to guests. I leave my guests 17 at ease, but I am available whenever they need me. It is a typical neighborhood of Porto, 18 where you have silence and tranquility, little traffic, no noise, but everything at hand: 19 good restaurants and c 20 21 22 Listing Name: Panoramic Ocean View Studio in Quiet Setting 23 Summary: Panoramic Ocean View Studio in Quiet Setting 24 Description: Luxury studio unit is located in a family-oriented neighborhood that lets you 25 experience Hawaii like a local! with tranquility and serenity, while in close proximity to 26 beaches and restaurants! The unit is surrounded by lush tropical vegetation! High-speed 27 Wi-Fi available in the unit!! A large, private patio (lanai) with fantastic ocean views is 28 completely under roof and is part of the studio unit. It's a great space for eating outdoors 29 or relaxing, while checking our the surfing action. This patio is like a living room 30 without walls, with only a roof with lots and lots of skylights!!! We provide Wi-Fi and 31 beach towels! The studio is detached from the main house, which has long-term tenants 32 upstairs and downstairs. The lower yard and the front yard are assigned to those tenants, 33 not the studio guests. The studio has exclusive use of its large (600 sqft) patio - under 34 roof! Check-in and check-out times other than the ones listed, are by request only and an 35 additional charges may apply; 36 37 38 Listing Name: GOLF ROYAL RESIDENCE SUİTES(2+1)-2 39 Summary: GOLF ROYAL RESIDENCE SUİTES(2+1)-2 40 Description: A BIG BED ROOM WITH A BIG SALOON INCLUDING A NICE BALAKON TO HAVE SOME FRESH 41 AIR . OUR RESIDENCE SITUATED AT THE CENTRE OF THE IMPORTANT MARKETS SUCH AS NİŞANTAŞİ, 42 OSMANBEY AND TAKSIM SQUARE, 43 44 45 Listing Name: DOUBLE ROOM for 1 or 2 ppl 46 Summary: DOUBLE ROOM for 1 or 2 ppl 47 Description: 10m2 with interior balkony kitchen, bathroom small but clean and modern metro 48 in front of the building 7min walk to Sagrada Familia, 2min walk TO amazing Gaudi Hospital 49 Sant Pau SAME PRICE FOR 1 OR 2 PPL-15E All flat for your use, terrace, huge TV.
Experimente suas próprias queries para ver o que obtém.
Agora você criou o núcleo de um mecanismo de busca semântica baseado no MongoDB Atlas Search, alimentado pela tecnologia de incorporação de última geração da Jina AI. Para qualquer projeto, você seguirá essencialmente as mesmas etapas descritas acima:
- Crie uma instância do Atlas e preencha-a com seus dados.
- Crie incorporações para seus itens de dados usando a API de incorporações doJina e armazene-os em sua instância do Atlas.
- Indexe as incorporações usando o indexador vetorial do MongoDB.
- Implemente a pesquisa semântica usando incorporações.
Esse código Python padrão se integrará facilmente aos seus próprios projetos, e você pode criar um código equivalente em Java, JavaScript ou código para qualquer outra estrutura de integração compatível com HTTPS.
Para ver a documentação completa da API do MongoDB Atlas, para que você possa integrá-la em suas próprias ofertas, consulte a seção API do Atlas do site do MongoDB.
Para saber mais sobre a Jina Embeddings e suas ofertas de assinatura, consulte a página Embeddings do site da Jina AI. Você pode encontrar as últimas notícias sobre os modelos de incorporação da Jina AI no site da Jina AI e noX/Twitter, e pode contribuir para as discussões no Discord.