Usando Inteligência Artificial para Pesquisar seus próprios documentos PDF por meio do LangChain

Usando Inteligência Artificial para Pesquisar seus próprios documentos PDF por meio do LangChain




Os aplicativos de Inteligência Artificial, tais como o ChatGPT da OpenAI ou o Gemini da Google permitem que qualquer pessoa faça consultas ou pesquise sobre uma vasta gama de assuntos. No entanto, em algumas situações precisamos pesquisar ou obter respostas  sobre informações que não estão disponíveis para essas aplicações, mas se encontram em documentos particulares ou de pouco acesso.  Mesmo nesses casos, podemos nos utilizar do grande poder de processamento de linguagem dessas aplicações para pesquisar nesses documentos e obter informações, nos poupando da necessidade de ler todo o documento. 

O uso um modelo de linguagem para pesquisar informações fora de sua base de treinamento é uma das aplicações da técnica chamada de RAG (Retrieval-Augmented Generation ou geração aumentada de recuperação, em português). Neste post iremos mostra como é possível fazer, com facilidade, uma aplicação para para pesquisar documento locais.  No nosso exemplo, utilizaremos um documento em PDF, mas o exemplo pode ser adaptado para documentos de variados tipos, tais como TXT, MD, JSON, etc.

Para nos auxiliar na construção de nosso exemplo utilizaremos a biblioteca LangChain.  

LangChain

O LangChain é um framework opensource poderoso que facilita a construção de pipelines de processamento de linguagem natural (NLP) utilizando grandes modelos de linguagem (LLMs). O LangChain se destaca pela sua capacidade de construir cadeias de processos complexos, combinando diferentes etapas de manipulação de texto e processamento de dados de forma modular e escalável.

Como ambiente de desenvolvimento usaremos o Google Colab Notebook. O notebook pode ser visualizado neste link.


Passo 1 - Baixar o documento em PDF

No nosso exemplo usaremos um documento de análise regional econômica realizada pelo Banco do Brasil. No Notebook o documento pode ser baixado com o seguinte comando: 

!wget https://www.bb.com.br/docs/portal/utg/ResenhaRegional.pdf .


Passo 2- Instalar as bibliotecas

Depois, é necessário instalar as bibliotecas necessárias utilizando o pip:


LangChain install

Segue a explicação de cada biblioteca:

LangChain é a biblioteca principal para a construção de pipelines de processamento de linguagem natural (NLP) utilizando grandes modelos de linguagem (LLMs). Esta biblioteca facilita a integração de diferentes etapas de manipulação de texto e processamento de dados, permitindo a criação de aplicações avançadas de NLP.


LangChain-Community é uma extensão da biblioteca LangChain que inclui módulos e funcionalidades adicionais desenvolvidos pela comunidade. 


LangChain-OpenAI é um módulo específico para integração com os modelos de linguagem da OpenAI, como o GPT-3 e GPT-4. Este pacote permite que os desenvolvedores utilizem a API da OpenAI de maneira eficiente dentro do ecossistema LangChain, facilitando a construção de pipelines que envolvem os poderosos modelos de linguagem da OpenAI.


ChromaDB é uma biblioteca de banco de dados voltada para o armazenamento e gerenciamento eficiente de dados vetorizados. Ela é importante porque os os elementos textuais são representados na forma de vetores de números (embeddings) para que possam ser analisados pelo modelo de linguagem.


PyPDF2 - é uma biblioteca Python que permite a leitura, manipulação e extração de texto de arquivos PDF. Esta biblioteca é essencial quando se trabalha com documentos PDF em aplicações de NLP, permitindo que você carregue e processe o conteúdo de PDFs de maneira programática.


Passo 3- Importar os módulos que serão utilizados


O módulo pprint (abreviação de "pretty-print") é usado para formatar estruturas de dados complexas de uma maneira que seja mais legível e organizada para humanos. O módulo os será usado para armazenar em uma variável de ambiente, o valor da chave para acessar a API da OpenAI. Usa-se userdata no Google Colab para acessar e manipular dados do usuário, facilitando operações que envolvem a troca de dados entre o notebook e o ambiente de usuário do Colab. Nesse caso vamos utilizar para obter a  chave para acessar a API da OpenAI que deve ser registrada no espaço secrets do Colab. Os outros módulos iremos explicar no momento da utilização. 


Passo 4- Ler o documento e transformar em texto

No trecho de código abaixo é realizada a leitura de um arquivo PDF, a extração do texto contido em cada uma de suas páginas, e é exibido um trecho desse texto.



Abaixo é Exibido os primeiros 2000 caracteres do texto extraído do PDF (pdf_text[:2000]). 



Passo 5 - Particionar o texto



O próximo passo é particionar o texto antes de submetê-lo à vetorização, ou seja, antes de transformar as palavras em vetores. O particionamento é importante, uma vez que  modelos de linguagem, especialmente aqueles baseados em Transformers como BERT, GPT, etc., têm um limite no número de tokens (palavras ou caracteres) que podem processar de uma vez. Textos longos que excedem esse limite precisam ser divididos em partes menores para serem processados corretamente. Além disso, dividir o texto em partes menores permite que cada segmento mantenha um contexto coerente. Se um texto for muito longo e não for dividido, o modelo pode perder o contexto ou ignorar partes importantes do texto. Dividindo-o em segmentos, garantimos que cada parte seja significativa e compreensível por si só. 

No nosso exemplo usaremos o RecursiveCharacterTextSplitter do LangChain. Ele foi projetado para dividir o texto em pedaços menores, garantindo que os pedaços sejam coerentes e significativos. 



No exemplo usamos um chunk_size de 1000,  definindo o tamanho máximo de cada segmento, e chunk_overlap de 100,  definindo o número de caracteres que se sobrepõem entre segmentos consecutivos. A sobreposição ajuda a manter o contexto entre os segmentos.

Passo 6 - Vetorização do texto

O trecho de código abaixo configura um ambiente para usar a API da OpenAI e cria um banco de dados vetorial (vector database) usando o ChromaDB para armazenar embeddings de textos. 



  • os.environ: É um dicionário no Python que contém as variáveis de ambiente do sistema.
  • userdata.get("OPENAI_API_KEY"): Recupera a chave de API da OpenAI dos dados do usuário registrado no secrets  Google Colab.
  • persist_directory: Define o caminho do diretório onde os dados persistentes serão armazenados. Neste caso, é definido como 'db'.
  • OpenAIEmbeddings(): Cria uma instância de embeddings (vetores) fornecida pela OpenAI
  • Chroma.from_texts(...): Método da biblioteca ChromaDB que cria um banco de dados vetorial a partir de uma lista de textos.
  • texts=texts: Passa a lista de textos que serão convertidos em vetores e armazenados no banco de dados.
  • embedding=embedding: Especifica o objeto de embeddings da OpenAI a ser usado para converter os textos em representações vetoriais.
  • persist_directory=persist_directory: Define o diretório onde o banco de dados será salvo e persistido.

Passo 7 - Criar objeto para consulta


 Vamos agora cria o objeto para consultar o texto. No trecho de código abaixo é criada uma instância de RetrievalQA usando um tipo específico de cadeia (chain type). O RetrievalQA é uma classe usada para responder perguntas com base em um índice de documentos. É uma classe utilizada para configurar um sistema de perguntas e respostas que combina a capacidade de recuperação de informações (retrieval) com um modelo de linguagem LLM.



O método from_chain_type(...) dessa classe que cria uma instância  com base no tipo de cadeia especificado.

Argumentos:

  • llm=OpenAI(): Cria uma instância do modelo de linguagem da OpenAI. Esta instância será utilizada para gerar respostas baseadas no texto recuperado.
  • OpenAI(): Este comando chama a classe ou função que cria uma conexão com o modelo de linguagem da OpenAI, usando a chave de API configurada anteriormente.
  • chain_type="stuff": O tipo de cadeia é definido como “stuff”. Isso indica como os documentos recuperados serão combinados para formar a resposta final. No caso de “stuff”, os documentos são simplesmente concatenados.
  • retriever=vectordb.as_retriever(): vectordb é uma base de dados vetorial que está sendo usada para recuperar documentos relevantes. O método as_retriever() transforma essa base de dados em um objeto que pode ser usado para buscar documentos.

Passo 8 - Realizando a pesquisa

Neste último passo realizamos a consulta. No caso vamos perguntar "Qual região do Brasil possui a melhor projeção de crescimento PIB em 2024?". Lembre-se de perguntar com educação. 



  • response = qa.invoke(query): Essa linha utiliza o objeto qa (criado no código anterior) para buscar a resposta para a pergunta. O método invoke() recebe a pergunta como parâmetro e retorna uma resposta na variável response.
  • pprint(response['result']): Essa linha imprime a resposta armazenada na chave result do dicionário response. A função pprint() formata a saída para que seja mais fácil de ler, indentando e alinhando o texto.

Segue abaixo a saída emitida pela consulta:




Chegamos ao final deste Post.  Se esse Post foi útil para você, por favor, considere deixar um comentário.



Comentários

Postagens mais visitadas