Inteligência Artificial (IA)

Construindo Aplicações RAG de Ponta a Ponta com a Busca Vetorial do Couchbase

Grandes Modelos de Linguagem, popularmente conhecidos como LLMs, é um dos tópicos mais discutidos na indústria de IA. Todos nós estamos cientes das possibilidades e capacidades do ChatGPT da OpenAI. No final das contas, usar esses LLMs a nosso favor revela muitas novas possibilidades usando os dados.

Mas você não pode simplesmente esperar tudo dos LLMs por causa de suas limitações de design e de muitos outros fatores. Mas usando o conceito de Busca Vetorial nos dá um novo tipo de aplicativo chamado Aplicações de Geração Aumentada por Recuperação (RAG). Então, vamos ver o que são as aplicações RAG, como elas podem ser usadas para resolver novos problemas, como podem ser desenvolvidas usando o Couchbase e ter uma visão geral detalhada de como a Pesquisa Vetorial ajuda a criar essas aplicações.

Antes de entrarmos no contexto da aplicação, aqui está um diagrama de arquitetura do que estamos construindo e de como o LangChain se conecta a ele:

Geração Aumentada por Recuperação (RAG

O RAG fornece uma maneira de aprimorar a saída de um LLM com informações direcionadas, sem modificar o modelo subjacente em si, de modo que as informações direcionadas possam ser mais atualizadas do que o LLM, bem como específicas para uma determinada organização e setor. Isso significa que o IA gerativa o sistema pode fornecer respostas mais contextualmente apropriadas aos comandos, bem como basear essas respostas em dados extremamente atuais. Vamos entender esse conceito usando um exemplo da vida real.

Digamos que você pertença à organização X, que possui uma tonelada de dados armazenados em seu banco de dados, e você seja o responsável por desenvolver um aplicativo que solicita a entrada do usuário e fornece a saída com base nos dados presentes no seu banco de dados.

Inicialmente você pode pensar que isso parece fácil, certo? Se você conhece os LLMs e sabe como aproveitá-los para as suas necessidades, então é uma tarefa simples. Você simplesmente escolhe os LLMs da OpenAI ou os modelos Llama e Mistral, se quiser ser econômico, e simplesmente envia as perguntas do usuário para o LLM e obtém os resultados. 

Mas há um grande problema aqui...

Por exemplo, digamos que você esteja usando o Llama 2 LLM 8B tipo.

Agora este modelo é treinado com quase todos os dados presentes na internet pública. Você faz qualquer pergunta, até mesmo perguntas sobre a sua organização X, e ele lhe dá a resposta correta mais próxima.

Agora vamos fazer uma pequena alteração na declaração do seu problema. A tonelada de dados presente no seu banco de dados não é mais pública, mas sim privada. O que significa que o Llama 2 desconhece os seus dados e você não dará mais respostas corretas.

Tendo o cenário acima em mente, considere a pergunta do usuário:“Quais são as atualizações do componente C na organização X?

Então, como resolver isso?

Você pode pensar, por que não passamos todos os dados presentes no banco de dados, junto com o prompt, para que a LLM possa usar os dados como contexto e responder à pergunta. Mas aqui está o grande problema, todas as LLMs têm uma restrição chamada limite de tokens. Sem entrar no mérito do que são tokens, etc., por enquanto considere que 1 token == 1 palavra. 

Infelizmente, o limite de tamanho de token do Llama 2 é de 4096 tokens (palavras). Suponha que todos os dados presentes no seu banco de dados tenham 10 milhões de palavras, então torna-se impossível passar todos os dados para fins de contexto. 

A solução para o problema acima é chamada de RAG. No RAG, selecionamos uma proporção de dados presentes em sua base de dados que está muito estreitamente relacionada à consulta do usuário. O tamanho dessa proporção é tal que:

Proporção do tamanho < limite de tokens

Agora passamos os dados extraídos como contexto junto com a consulta e obtemos bons resultados. Isto é RAG. Mas como obtemos a proporção de dados que está estreitamente relacionada à consulta do usuário e, ao mesmo tempo, cujo tamanho não excede o limite de tokens? Isso é resolvido usando o conceito de Busca Vetorial.

O que é busca vetorial?

A busca vetorial aproveita o aprendizado de máquina (ML) para capturar o significado e o contexto de dados não estruturados, incluindo texto e imagens, transformando-os em uma representação numérica. Frequentemente. 

As versões 7.6.0 e superiores do Couchbase vêm com isso Recurso de busca vetorial. O importante aqui é que nenhuma biblioteca, módulo ou configuração externa são necessários. Basta ter pelo menos 1 pesquisar o node dá conta do recado.

O Couchbase usa internamente o Estrutura FAISS fornecido pelo Facebook para realizar busca vetorial.

Construindo uma aplicação RAG

Agora vamos ao que interessa no desenvolvimento de uma aplicação RAG de ponta a ponta usando o Funcionalidade de Pesquisa Vetorial do Couchbase.

Neste passo a passo, vamos desenvolver um converse com seus PDFs aplicação.

Antes de prosseguir, existem várias maneiras de criar o aplicativo. Uma delas é usando o framework LangChain, que usaremos para desenvolver a aplicação RAG.

Aplicativo 1: Construindo usando o framework LangChain

Passo 1: Configurando um banco de dados Couchbase 

Você pode configurar o servidor Couchbase no EC2, em uma máquina virtual, na sua máquina local, etc.

Siga este link para configurar o cluster do Couchbase. Certifique-se de que estes serviços estão ativados, os outros são opcionais:

  • Data
  • Pesquisar

Note: Make sure you install Couchbase Server version 7.6.0 or above to perform vector search. Also we will develop this application using Python in the Mac OS environment.

Once the cluster is up and running, create a new project <project_name> and create a new Python file call app.py.

Now in the project terminal, execute the below command:

Now go to the UI and create a bucket named project. For this walkthrough, we will go with the default scope and collection.

Now there are different ways to generate vector embeddings. The popular one being OpenAI and we will be using that to generate vector embeddings.

Copy the below code to app.py:

If you hosted Couchbase in a VM, Then make sure you replace the word localhost para o public ip of the VM.

Step 2: Importing the search index

The vector search feature in Couchbase requires a search index to perform.  There are multiple ways to create the index, but to make things easy and fast, below is the index JSON. Copy the below code and paste it in:

  • Interface do usuário > Pesquisar > Add index (top right) > Import

Index.json

Step 3: Loading the data

Now it’s time to store all the PDFs data as chunks along with its vector embeddings in the database.


Note: Read this detailed blog on chunking, data gathering, etc. It’s highly recommended to go through the blog to have a clear understanding of what we will be covering in the later steps.


There are libraries for different types of documents you want to upload. For example, if your source data is in .txt format then add the following code to your app.py:

But suppose say your source type is PDF, then:

Not only PDFs are support, LangChain offers support for multiple types such as: 

  • CSV
  • HTML
  • JSON
  • Markdown, and more

Saiba mais sobre Langchain document loaders.

Step 4: Inferring results

Now we are ready to send queries to our application:

App 2: Creating the app from scratch

Before starting, as described in the previous section, spin up your cluster with a bucket named project. Also, follow Step 2 of the previous section, making sure to import the search index.

Step 1: Setting up Couchbase

If you are going with defaults, then your app.py should look something like this:

Now that the Couchbase collection links and search index are ready, let’s move to the data loading part.

Step 2: Data loading

To keep things modularized, create a new Python file named load.py.

There are multiple ways to extract data from PDFs. To make it easy, lets use the pypdf package from Langchain:

load.py

Now this pages variable is a list of text blocks extracted from the pdf. Let’s merge all the content into one variable:

Before chunking, we need to set up the embedding model. In this case, let’s go with the sentence-transformers/paraphrase-distilroberta-base-v1 from hugging face.

This model gives you vector embeddings of 768 dimensions.

load.py

0

Now our model is ready. Let’s push the documents. We can use the package recursive character text splitter from Langchain.

This package gives you chunks of the provided size, then we will find the vector embedding for each chunk using the above model and push the document into the database.

So, the document will have two fields:

1

load.py

2

Now that our chunks are ready, we can find the embeddings for each chunk and push it to the database.

load.py

3

Wonder where the cb_coll came from? It’s the collection connector we created in app.py. To pass it, let’s wrap this entire thing in load.py to a function which accepts cb_coll as parameter.

So, finally your load.py should look like this:

4

Now let’s go to app.py, import this and call the load_data function.

app.py

5

Now this will push the docs in the required format and our search index will also get mutated. Now it’s time to do vector search.

Step 3: Vector Search

In Couchbase you have multiple ways to do it, one of them being the Curl method.

6

A result.stdout contains the k nearest Doc IDs. You can extend the script to perform a get request on all the IDs returned and combine the results to get the final context. Then we pass this context along with the prompt to the LLM to get the desired results.

References

Compartilhe este artigo

Autor

Uma resposta

Deixe um comentário

Pronto para começar com o Couchbase Capella?

Começar a construir

Confira nosso portal para desenvolvedores para explorar o NoSQL, navegar por recursos e começar com tutoriais.

Use o Capella free

Coloque a mão na massa com o Couchbase em apenas alguns cliques. O Capella DBaaS é a maneira mais fácil e rápida de começar.

Entre em contato

Quer saber mais sobre as ofertas do Couchbase? Deixe-nos ajudar.