Entendendo RAG: Melhorando e dando contexto às respostas do ChatGPT
Postado originalmente em 18 de setembro de 2024
Já aconteceu com você de, ao usar o ChatGPT, e após fazer uma série de perguntas, ele começar a alucinar? Quer dizer, começar a entregar uma série de respostas sem sentido, parecendo criar conexões espúrias com o assunto tratado, ou simplesmente inventando coisas que não existem? Muitas vezes, este tipo de “alucinação” acontece pela perda do contexto da conversa. É sobre como melhorar estes contextos que falaremos neste texto.
Além do problema de alucinação, há algo mais fundamental: Muitas empresas recentemente têm procurado “entrar no hype” dos modelos de linguagem, após o mundo executivo tomar conhecimento dos modelos de GPT. Algumas pessoas, sem conhecimento na área do aprendizado de máquina, pensaram até em criar seus próprios modelos de linguagem. Mas não é tão simples. É estimado que o treinamento do primeiro modelo do GPT (GPT-1) exigiu dezenas de milhares de dólares, enquanto o primeiro modelo a ficar famoso no ChatGPT, o GPT-3, custou milhões de dólares, além de ter sido lançado quase 5 anos depois da criação da sua empresa criadora OpenAI (revelando que além de dinheiro, modelos custam tempo). Se criar um novo LLM (Large-Language Model) é inviável, como utilizar aquilo que já existe em contextos empresariais menores?
O que é Retrieval Augmented Generation?
Ambos estes dois problemas podem ser solucionados com RAG, Retrieval Augmented Generation, ou “Geração de Recuperação Aumentada”, em tradução livre. Este tipo de técnica foi publicada pelo Facebook em 2020, e pretende ser um método para melhorar os resultados retornados por modelos de linguagem generativa, em especial dando contexto, fazendo as respostas serem melhor direcionadas a certos contextos e limitando o tipo de informação que pode ser devolvida, sem perder todas as capacidades pré-existentes no modelo de LLM.
É importante notar que o RAG depende de dois fatores: Primeiro, acesso a um modelo de linguagem pré-estabelecido, como GPT ou Gemini. Além disso, é preciso estabelecer uma base de dados que servirá de contexto. Por exemplo, é possível criar um modelo específico que responde perguntas sobre notícias relacionadas à bolsa de valores. Neste caso, o banco de dados deveria ser a mais extensa coleção de notícias possíveis sobre bolsa de valores. O banco também deve ser limpo, já que utilizaremos aqueles dados para devolver respostas. Não queremos que, por exemplo, texto relacionado a códigos HTML sejam “aprendidos” e devolvidos como resposta para uma pergunta.
Quais as vantagens do RAG?
Uma vez que o RAG se trata de usar um modelo de linguagem pré-existente no contexto de um banco de dados específico, isso cria uma série de oportunidades e melhorias ao utilizar a técnica. Em primeiro lugar, é possível retornar informações específicas através de uma interface de modelo de linguagem, como chatbots. Sem RAG, talvez o modelo de linguagem não tivesse aquela informação no seu repertório ou, mesmo que tivesse, não poderia encontrá-la em um mar de informações. Algumas ferramentas usam RAG para encontrar trechos específicos em documentos, como exemplo.
Além disso, como o que o RAG faz “por trás dos panos” é na verdade encontrar textos específicos no banco de dados, algo parecido com um bibliotecário procurando um livro, isto se torna uma ferramenta útil para lidar com enormes conjuntos de dados que seriam de outra forma difícil de serem manejados para fazer buscas e encontrar relações específicas.
Criamos dessa forma um modelo específico para uma área de negócio. Nosso exemplo foi de um modelo de linguagem que é “especialista” em notícias do mercado financeiro, mas podemos estender esse conceito e pensar em um modelo especialista em questões médicas, legais, técnicas, etc, além de podermos restringir para casos de uso específicos para empresas pequenas e médias. Tudo isso pode ser feito com baixíssimo custo de processamento interno, já que nos apoiamos nos gigantescos modelos de linguagem dos LLMs.
Como o RAG funciona na prática?
Você já entendeu o poder que o RAG tem de criação de novas ferramentas. Vamos agora entender como o RAG consegue entregar estes resultados. Para isso, abordamos aqui uma aplicação simples de RAG, focada na parte do “retrieval“, isto é, de encontrar os dados corretos para geração de respostas significativas. Neste mesmo site haverá outros textos explorando formas mais complexas de se usar o RAG.
Nossa ideia aqui é construir um modelo que toma uma pergunta de um usuário, pesquisa em um banco de dados o que é relevante em relação àquela pergunta, e passa tanto a pergunta quanto textos relevantes a um modelo de linguagem, requisitando-o que crie uma resposta para aquela pergunta se baseando naquelas informações encontradas nos textos passados. A ideia é que o modelo de linguagem apenas irá reformular aquilo que passamos em uma resposta estruturada.
Em primeiro lugar, iremos então supor que já temos nosso banco de dados com os textos que usaremos como contexto, e chamamos o conjunto de todos os nossos textos de $C$. Queremos resolver o seguinte problema: “Dada uma determinada pergunta, qual é o texto que mais se aproxima daquela pergunta?”. Para resolver isso, utilizaremos algo chamado cálculo de similaridade, ou seja: Dada uma determinada query (pergunta), encontre os textos que são mais similares a esta query.
Podemos entender que a probabilidade de, dado uma query $q$, retornarmos um texto específico $d$ é dado por:
$$P(d|q) = \frac{exp(sim(q, d))}{\sum\limits_{d_{i}\in C}^{n} exp(sim(q, d_{i}))}$$
Ou seja, utilizamos a função softmax para estimar as probabilidades de encontrar um texto dado determinado prompt. Aqui $sim()$ representa a função de similaridade, que pode ser escolhida conforme a conveniência, como por exemplo distância euclidiana ou correlação de Pearson. Mas, usualmente, utilizamos como função de similaridade a função de cosseno:
$$sim(q,d) = \frac{q \cdot d}{||q||\text{ }||d||}$$
É nítido que para executar estes cálculos precisaremos transformar nossos textos em representações matemáticas de texto. Existem boas bibliotecas do Python como word2vec ou FAISS que se encarregam disso, e uma simples aplicação destas é suficiente para transformarmos nosso banco de dados em texto para vetores dentro de um espaço vetorial. O que fazemos então é gerar um objeto que contém um espaço vetorial e vetores hiperdimensionais, cada um representando um texto de nosso banco de dados.
Uma vez que temos nosso campo vetorial pronto e fixo, tomamos uma query e transformamos ela também em um vetor, para checar a similaridade vetorial entre a query e os textos do banco de dados. As bibliotecas mencionadas já possuem algumas funções de similaridade, e também podemos utilizar funções próprias. Ao realizar o cálculo, poderemos retornar os vetores que, naquele campo vetorial, tem mais similaridade ao vetor da query passada. No caso de usar a função cosseno como similaridade, iremos recuperar (retrieve) os vetores cujos cossenos são menores em relação ao vetor da query passada.
Dessa forma conseguimos retornar $n$ textos (quanto maior o $n$, mais textos serão recuperados) que servirão como contexto específico daquela pergunta passada como query. É dessa forma que podemos gerar uma resposta com modelo de linguagem ao mesmo tempo que nos atemos a informações específicas e relevantes para aquela pergunta.
Vejamos um exemplo: No contexto de um modelo sobre notícias sobre o mercado financeiro, por exemplo, teríamos uma série de textos, cada um representando uma notícia. Este conjunto é transformado num espaço vetorial, onde cada vetor representa um texto e portanto, uma notícia. Caso uma pessoa pergunte, por exemplo, “Qual era o preço da ação da VALE3 no final de janeiro de 2023?”, o nosso RAG irá transformar esta pergunta em um vetor, incluí-la no espaço vetorial, e encontrar $n$ notícias que sejam similares a esta questão (se $n=1$, muito provavelmente será uma notícia sobre esta ação nesta data). Dessa forma, passamos para nosso modelo de linguagem (como GPT) um prompt parecido com o abaixo:
Responda a pergunta a seguir utilizando as informações contidas nos textos de referência abaixo.
Pergunta: "Qual era o preço da ação da Vale3 no final de janeiro de 2023?"
Texto referência 1: [...]
Texto referência 2: [...]
Texto referência [...]
Assim podemos ter respostas extremamente precisas, retornando informações e dando contexto com modelos de linguagem, o que de outra forma seria muito difícil ou impossível. Neste texto, focamos apenas em entender as ideias por trás do RAG. Não deixe de conferir neste site o texto sobre como utilizar RAG na prática!