Simplifique a pesquisa semântica do Atlas com LangChain e MongoDB
Brian Leonard4 min read • Published Sep 23, 2024 • Updated Oct 28, 2024
APLICATIVO COMPLETO
Avalie esse Tutorial
Habilitar a pesquisa semântica em dados específicos do usuário é um processo de várias etapas que inclui carregar, transformar, incorporar e armazenar dados antes que eles possam ser consultados.
![](/developer/_next/image/?url=https%3A%2F%2Fpython.langchain.com%2Fv0.1%2Fassets%2Fimages%2Fdata_connection-95ff2033a8faa5f3ba41376c0f6dd32a.jpg&w=3840&q=75)
Esse gráfico é da equipe da LangChain, cujo objetivo é fornecer um conjunto de utilitários para simplificar bastante esse processo.
Neste tutorial, percorreremos cada uma dessas etapas, usando o MongoDB Atlas como nossa loja. Especificamente, usaremos as páginas daAt&T e do Banco da América Wikipedia como nossa fonte de dados. Em seguida, usaremos bibliotecas do LangChain para Carregar, Transformar, Incorporar e Armazenar:
![](/developer/_next/image/?url=https%3A%2F%2Fraw.githubusercontent.com%2Fwbleonard%2Fatlas-langchain%2Fmain%2Fimages%2Fflow-store.png&w=3840&q=75)
Depois que o armazenamento de origem for armazenado no MongoDB, podemos recuperar os dados que nos interessam:
![](/developer/_next/image/?url=https%3A%2F%2Fraw.githubusercontent.com%2Fwbleonard%2Fatlas-langchain%2Fmain%2Fimages%2Fflow-retrieve.png&w=3840&q=75)
- Assinatura do MongoDB Atlas (o plano gratuito já serve)
- Chave de API Open AI
- Obtenha o código:
1 git clone https://github.com/wbleonard/atlas-langchain.git
- Criar um novo ambiente Python
1 python3 -m venv env
- Ativar o novo ambiente Python
1 source env/bin/activate
- Instale os requisitos
1 pip3 install -r requirements.txt
- Carregar, transformar, incorporar e armazenar
1 python3 vectorize.py
- Recuperar
1 python3 query.py -q "Who started AT&T?"
Não faltam fontes de dados: Slack, Youtube, Git, Excel, Reddit, Twitter etc., e o LangChain fornece uma lista crescente de integrações que inclui esta lista e muito mais.
Para este exercício, vamos usar o WebBaseLoader para carregar as páginas da Wikipedia para a At&T e o Banco da América.
1 from langchain_community.document_loaders import WebBaseLoader 2 3 # Step 1: Load 4 loaders = [ 5 WebBaseLoader("https://en.wikipedia.org/wiki/AT%26T"), 6 WebBaseLoader("https://en.wikipedia.org/wiki/Bank_of_America") 7 ] 8 9 docs = [] 10 11 for loader in loaders: 12 for doc in loader.lazy_load(): 13 docs.append(doc)
Agora que temos um monte de texto carregado, ele precisa ser divisão em blocos menores para que possamos extrair a parte relevante com base em nossa query de pesquisa. Para este exemplo , usaremos o RecursiveChaacterTextSplitterrecomendado. Conforme eu o configurei, ele tenta divisão em números (
"\n\n"
), depois em frases ("(?<=\. )"
) e, em seguida, em palavras (" "
) usando um tamanho de bloco de 1000 caracteres. Portanto, se um número não couber em 1000 caracteres, ele será truncado na próxima palavra que puder caber para manter o tamanho do bloco abaixo 1000 caracteres. Você pode ajustar o chunk_size
ao seu preferência. Números menores levarão a mais documentos e vice-versa.1 # Step 2: Transform (Split) 2 from langchain.text_splitter import RecursiveCharacterTextSplitter 3 text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=0, separators=[ 4 "\n\n", "\n", r"(?<=\. )", " "], length_function=len) 5 docs = text_splitter.split_documents(docs)
Incorporação é onde você usa um LLM para criar um texto de representação vetorial. Há muitas opções para escolher, como OpenAI e Abraçando a Face, e o LangChang fornece uma interface padrão para interagir com todas elas.
Para este exercício, usaremos a popular incorporação OpenAI. Antes de prosseguir, você precisará de uma chave de API para a plataforma OpenAI, que definirá em params.py.
Vamos simplesmente carregar o incorporador nesta etapa. O verdadeiro poder vem quando armazenamos as incorporações na Etapa 4.
1 # Step 3: Embed 2 from langchain_openai import OpenAIEmbeddings 3 embeddings = OpenAIEmbeddings(openai_api_key=params.OPENAI_API_KEY)
Você precisará de um banco de dados vetorial para armazenar as incorporações e, para sua sorte, o MongoDB se encaixa nesse perfil. Para sua sorte ainda maior, o pessoal da LangChain tem um módulo do MongoDB Atlas que fará todo o trabalho pesado para você! Não se esqueça de adicionar sua string de conexão do MongoDB Atlas ao params.py.
1 # Step 4: Store 2 from pymongo import MongoClient 3 from langchain_mongodb.vectorstores import MongoDBAtlasVectorSearch 4 5 client = MongoClient(params.MONGODB_CONN_STRING) 6 collection = client[params.DB_NAME][params.COLL_NAME] 7 8 # Insert the documents in MongoDB Atlas with their embedding 9 docsearch = MongoDBAtlasVectorSearch.from_documents( 10 docs, embeddings, collection=collection, index_name=index_name 11 )
A etapa final antes de podermos fazer uma query nos dados é criar um índice de pesquisa nas incorporações armazenadas.
Se você estiver em computação dedicada do Atlas , a Langchain pode fazer isso por você.
1 # Step 5: Create Vector Search Index 2 # THIS ONLY WORKS ON DEDICATED CLUSTERS (M10+) 3 docsearch.create_vector_search_index(dimensions=1536, update=True)
Se você estiver em computação compartilhada (M0, M2 ou M5), no console do Atlas , crie um Atlas Vector Search
langchain_vsearch_index
com a seguinte definição:1 { 2 "fields": [ 3 { 4 "type": "vector", 5 "path": "embedding", 6 "numDimensions": 1536, 7 "similarity": "cosine" 8 } 9 ] 10 }
![](/developer/_next/image/?url=https%3A%2F%2Fraw.githubusercontent.com%2Fwbleonard%2Fatlas-langchain%2Fmain%2Fimages%2Fcreate-search-index.png&w=3840&q=75)
![](/developer/_next/image/?url=https%3A%2F%2Fraw.githubusercontent.com%2Fwbleonard%2Fatlas-langchain%2Fmain%2Fimages%2Fcreate-search-index2.png&w=3840&q=75)
![](/developer/_next/image/?url=https%3A%2F%2Fraw.githubusercontent.com%2Fwbleonard%2Fatlas-langchain%2Fmain%2Fimages%2Fcreate-search-index3.png&w=3840&q=75)
Você encontrará o script completo em vectorize.py, que precisa ser executado apenas uma vez ou quando novas fontes de dados forem adicionadas.
1 python3 vectorize.py
Agora poderíamos executar uma pesquisa, usando métodos como similirity_search ou max_marginal_relevance_search e isso retornaria a fatia relevante de dados, que em nosso caso seria um número inteiro. No entanto, podemos continuar a aproveitar o poder do LLM para comprimir contextualmente a resposta, para que ela tente responder mais diretamente à nossa pergunta.
1 from pymongo import MongoClient 2 from langchain_mongodb.vectorstores import MongoDBAtlasVectorSearch 3 from langchain.embeddings.openai import OpenAIEmbeddings 4 from langchain.llms import OpenAI 5 from langchain.retrievers import ContextualCompressionRetriever 6 from langchain.retrievers.document_compressors import LLMChainExtractor 7 8 # Initialize MongoDB python client 9 client = MongoClient(params.MONGODB_CONN_STRING) 10 collection = client[params.DB_NAME][params.COLL_NAME] 11 12 # initialize vector store 13 vectorStore = MongoDBAtlasVectorSearch( 14 collection, OpenAIEmbeddings(openai_api_key=params.OPENAI_API_KEY), index_name=params.INDEX_NAME 15 ) 16 # perform a search between the embedding of the query and the embeddings of the documents 17 print("\nQuery Response:") 18 print("---------------") 19 docs = vectorStore.max_marginal_relevance_search(query, K=1) 20 #docs = vectorStore.similarity_search(query, K=1) 21 22 print(docs[0].metadata['title']) 23 print(docs[0].page_content) 24 25 # Contextual Compression 26 llm = OpenAI(openai_api_key=params.OPENAI_API_KEY, temperature=0) 27 compressor = LLMChainExtractor.from_llm(llm) 28 29 compression_retriever = ContextualCompressionRetriever( 30 base_compressor=compressor, 31 base_retriever=vectorStore.as_retriever() 32 )
1 python3 query.py -q "Who started AT&T?" 2 3 Your question: 4 ------------- 5 Who started AT&T? 6 7 AI Response: 8 ----------- 9 AT&T - Wikipedia 10 "AT&T was founded as Bell Telephone Company by Alexander Graham Bell, Thomas Watson and Gardiner Greene Hubbard after Bell's patenting of the telephone in 1875."[25] "On December 30, 1899, AT&T acquired the assets of its parent American Bell Telephone, becoming the new parent company."[28]
Principais comentários nos fóruns
Ainda não há comentários sobre este artigo.