Normalmente, o uso de grandes modelos de linguagem (LLMs) na empresa se enquadra em duas grandes categorias. O primeiro é onde o LLM automatiza uma tarefa relacionada ao idioma, como escrever uma postagem no blog, redigir um e-mail ou melhorar a gramática ou o tom de um e-mail que você já redigiu. Na maioria das vezes, esse tipo de tarefa não envolve informações confidenciais da empresa.

A segunda categoria envolve o processamento de informações internas da empresa, como uma coleção de documentos (PDFs, planilhas, apresentações, etc.) que precisam ser analisados, resumidos, consultados ou de outra forma usados ​​em uma tarefa orientada por linguagem. Essas tarefas incluem fazer perguntas detalhadas sobre as implicações de uma cláusula em um contrato, por exemplo, ou criar uma visualização de projeções de vendas para o próximo lançamento de um projeto.

Há dois motivos pelos quais o uso de um LLM disponível publicamente, como o ChatGPT, pode não ser apropriado para o processamento de documentos internos. A confidencialidade é a primeira e óbvia. Mas a segunda razão, também importante, é que os dados de treinamento de um LLM público não incluíam informações internas da sua empresa. Portanto, é improvável que o LLM forneça respostas úteis quando questionado sobre essas informações.

Insira geração aumentada de recuperação ou RAG. RAG é uma técnica usada para aumentar um LLM com dados externos, como documentos da sua empresa, que fornecem ao modelo o conhecimento e o contexto necessário para produzir resultados precisos e úteis para o seu caso de uso específico. RAG é uma abordagem pragmática e eficaz para o uso de LLMs na empresa.

Neste artigo, explicarei brevemente como o RAG funciona, listarei alguns exemplos de como o RAG está sendo usado e fornecerei um exemplo de código para configurar uma estrutura RAG simples.

Como funciona a geração aumentada por recuperação

Como o nome sugere, o RAG consiste em duas partes – uma recuperação e a outra geração. Mas isso não esclarece muito. É mais útil pensar no RAG como um processo de quatro etapas. A primeira etapa é executada uma vez e as outras três etapas são executadas quantas vezes forem necessárias.

As quatro etapas da geração aumentada por recuperação:

  1. Ingestão dos documentos internos em um banco de dados vetorial. Esta etapa pode exigir muita limpeza, formatação e fragmentação de dados, mas esse é um custo inicial único. (Para uma introdução rápida sobre bancos de dados vetoriais, consulte este artigo.)
  2. Uma consulta em linguagem natural, ou seja, a pergunta que um ser humano deseja fazer ao LLM.
  3. Aumento da consulta com dados recuperados usando pesquisa por similaridade do banco de dados vetorial. Esta etapa é onde o contexto do armazenamento de documentos é adicionado à consulta antes que ela seja enviada ao LLM. O prompt instrui o LLM a responder no contexto do conteúdo adicional. A estrutura RAG faz esse trabalho nos bastidores por meio de um componente chamado recuperador, que executa a pesquisa e anexa o contexto relevante.
  4. Geração da resposta à consulta aumentada pelo LLM.

Ao focar o LLM no corpus documental, o RAG ajuda a garantir que o modelo produza respostas relevantes e precisas. Ao mesmo tempo, o RAG ajuda a prevenir respostas arbitrárias ou sem sentido, que são comumente referidas na literatura como “alucinações”.

Da perspectiva do usuário, a geração de recuperação aumentada não parecerá diferente de fazer uma pergunta a qualquer LLM com interface de chat – exceto que o sistema saberá muito mais sobre o conteúdo em questão e dará melhores respostas.

O processo RAG do ponto de vista do usuário:

  1. Um humano faz uma pergunta ao LLM.
  2. O sistema RAG consulta o armazenamento de documentos (banco de dados vetorial) e extrai conteúdos que possam ser relevantes.
  3. O sistema RAG passa a pergunta do usuário, além do conteúdo adicional recuperado do armazenamento de documentos, para o LLM.
  4. Agora o LLM “sabe” fornecer uma resposta que faça sentido no contexto do conteúdo recuperado do armazenamento de documentos (banco de dados vetorial).
  5. O sistema RAG retorna a resposta do LLM. O sistema RAG também pode fornecer links para os documentos utilizados para responder à consulta.

Casos de uso para geração aumentada de recuperação

Os casos de uso do RAG são variados e estão crescendo rapidamente. Estes são apenas alguns exemplos de como e onde o RAG está sendo usado.

Mecanismos de busca

Os mecanismos de pesquisa implementaram o RAG para fornecer trechos de destaque mais precisos e atualizados em seus resultados de pesquisa. Qualquer aplicação de LLMs que deva acompanhar informações constantemente atualizadas é uma boa candidata para RAG.

Sistemas de resposta a perguntas

O RAG tem sido usado para melhorar a qualidade das respostas em sistemas de resposta a perguntas. O modelo baseado em recuperação encontra passagens ou documentos relevantes que contêm a resposta (usando pesquisa por similaridade) e, em seguida, gera uma resposta concisa e relevante com base nessas informações.

Comércio eletrônico

O RAG pode ser usado para aprimorar a experiência do usuário no comércio eletrônico, fornecendo recomendações de produtos mais relevantes e personalizadas. Ao recuperar e incorporar informações sobre as preferências do usuário e detalhes do produto, o RAG pode gerar recomendações mais precisas e úteis para os clientes.

Assistência médica

A RAG tem um grande potencial no setor da saúde, onde o acesso a informações precisas e oportunas é crucial. Ao recuperar e incorporar conhecimento médico relevante de fontes externas, o RAG pode ajudar a fornecer respostas mais precisas e conscientes do contexto em aplicações de saúde. Tais aplicações aumentam as informações acessíveis a um clínico humano, que em última análise faz a chamada e não o modelo.

Jurídico

O RAG pode ser aplicado de forma poderosa em cenários jurídicos, como fusões e aquisições, onde documentos jurídicos complexos fornecem contexto para consultas, permitindo uma navegação rápida através de um labirinto de questões regulatórias.

Apresentando tokens e incorporações

Antes de mergulharmos em nosso exemplo de código, precisamos examinar mais de perto o processo de ingestão de documentos. Para poder ingerir documentos em um banco de dados vetorial para uso no RAG, precisamos pré-processá-los da seguinte forma:

  1. Extraia o texto.
  2. Tokenize o texto.
  3. Crie vetores a partir dos tokens.
  4. Salve os vetores em um banco de dados.

O que isto significa?

Um documento pode ser PDF ou HTML ou algum outro formato, e não nos importamos com a marcação ou o formato. Tudo o que queremos é o conteúdo – o texto bruto.

Depois de extrair o texto, precisamos dividi-lo em pedaços, chamados tokens, e então mapear esses tokens para vetores de alta dimensão de números de ponto flutuante, normalmente 768 ou 1024 de tamanho ou até maiores. Esses vetores são chamados de incorporações, aparentemente porque estamos incorporando uma representação numérica de um pedaço de texto em um espaço vetorial.

Existem muitas maneiras de converter texto em incorporações vetoriais. Geralmente isso é feito usando uma ferramenta chamada modelo de incorporação, que pode ser um LLM ou um modelo de codificador independente. Em nosso exemplo RAG abaixo, usaremos o modelo de incorporação do OpenAI.

Uma nota sobre LangChain

LangChain é uma estrutura para Python e TypeScript/JavaScript que facilita a construção de aplicativos baseados em modelos de linguagem. Essencialmente, LangChain permite encadear agentes ou tarefas para interagir com modelos, conectar-se a fontes de dados (incluindo armazenamentos de dados vetoriais) e trabalhar com seus dados e respostas de modelo.

LangChain é muito útil para iniciar a exploração de LLM, mas está mudando rapidamente. Como resultado, é necessário algum esforço para manter todas as bibliotecas sincronizadas, especialmente se seu aplicativo tiver muitas partes móveis com diferentes bibliotecas Python em diferentes estágios de evolução. Uma estrutura mais recente, LlamaIndex, também surgiu. LlamaIndex foi projetado especificamente para aplicativos de dados LLM, portanto, tem uma tendência mais empresarial.

Tanto LangChain quanto LlamaIndex possuem extensas bibliotecas para ingestão, análise e extração de dados de uma vasta gama de fontes de dados, desde texto, PDFs e e-mail até sistemas de mensagens e bancos de dados. O uso dessas bibliotecas elimina a dificuldade de analisar cada tipo de dados diferente e extrair o conteúdo da formatação. Isso por si só vale o preço da entrada.

Um exemplo simples de RAG

Construiremos um aplicativo RAG simples “Hello World” usando Python, LangChain e um modelo de bate-papo OpenAI. Combinando o poder linguístico de um LLM com o conhecimento de domínio de um único documento, nosso pequeno aplicativo nos permitirá fazer perguntas modelo em inglês e responderá às nossas perguntas referindo-se ao conteúdo do nosso documento.

Para o nosso documento, usaremos o texto do discurso do presidente Biden de 7 de fevereiro de 2023, sobre o estado da União. Se quiser tentar em casa, você pode baixar um documento de texto do discurso no link abaixo.

download

Arquivo de texto do discurso do presidente Biden de 7 de fevereiro de 2023, sobre o estado da União

Uma versão de nível de produção deste aplicativo permitiria que coleções privadas de documentos (documentos do Word, PDFs, etc.) fossem consultadas com perguntas em inglês. Aqui estamos construindo um sistema simples e que não possui privacidade, pois envia o documento para um modelo público. Por favor, não execute este aplicativo usando documentos privados.

Usaremos os modelos de linguagem e incorporação hospedados da OpenAI e a biblioteca de código aberto FAISS (Facebook AI Similarity Search) como nosso armazenamento de vetores, para demonstrar um aplicativo RAG de ponta a ponta com o menor esforço possível. Em um artigo subsequente, construiremos um segundo exemplo simples usando um LLM totalmente local, sem dados enviados para fora do aplicativo. Usar um modelo local envolve mais trabalho e mais peças móveis, por isso não é o primeiro exemplo ideal.

Para construir nosso sistema RAG simples, precisamos dos seguintes componentes:

  1. Um corpus documental. Aqui usaremos apenas um documento.
  2. Um carregador para o documento. Este código extrai o texto do documento e o pré-processa (tokeniza) para gerar uma incorporação.
  3. Um modelo de incorporação. Este modelo pega o documento pré-processado e cria embeddings que representam os pedaços do documento.
  4. Um armazenamento de dados vetoriais com um índice para pesquisa de similaridade.
  5. Um LLM otimizado para resposta a perguntas e instrução.
  6. Um modelo de chat para interagir com o LLM.

As etapas preparatórias:

pip install -U  langchain
pip install -U langchain_community
pip install -U langchain_openai

O código fonte do nosso sistema RAG:

# We start by fetching a document that loads the text of President Biden’s 2023 State of the Union Address

from langchain_community.document_loaders import TextLoader
loader = TextLoader('./stateOfTheUnion2023.txt')

from langchain.text_splitter import CharacterTextSplitter
from langchain_community.vectorstores import FAISS
from langchain_openai.embeddings import OpenAIEmbeddings
import os
os.environ("OPENAI_API_KEY") =<you will need to get an API ket from OpenAI>

# We load the document using LangChain’s handy extractors, formatters, loaders, embeddings, and LLMs

documents = loader.load()
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
texts = text_splitter.split_documents(documents)

# We use an OpenAI default embedding model
# Note the code in this example does not preserve privacy

embeddings = OpenAIEmbeddings()

# LangChain provides API functions to interact with FAISS

db = FAISS.from_documents(texts, embeddings)  

# We create a 'retriever' that knows how to interact with our vector database using an augmented context
# We could construct the retriever ourselves from first principles but it's tedious
# Instead we'll use LangChain to create a retriever for our vector database

retriever = db.as_retriever()
from langchain.agents.agent_toolkits import create_retriever_tool
tool = create_retriever_tool(
    retriever,
    "search_state_of_union",
    "Searches and returns documents regarding the state-of-the-union."
)
tools = (tool)

# We wrap an LLM (here OpenAI) with a conversational interface that can process augmented requests

from langchain.agents.agent_toolkits import create_conversational_retrieval_agent

# LangChain provides an API to interact with chat models

from langchain_openai.chat_models import ChatOpenAI
llm = ChatOpenAI(temperature = 0)
agent_executor = create_conversational_retrieval_agent(llm, tools, verbose=True)

input = "what is NATO?"
result = agent_executor.invoke({“input": input})

# Response from the model

input = "When was it created?"
result = agent_executor.invoke({“input": input})

# Response from the model 

Conforme mostrado na captura de tela acima, a resposta do modelo à nossa primeira pergunta é bastante precisa:

NATO significa Organização do Tratado do Atlântico Norte. É uma aliança militar intergovernamental formada em 1949. O objectivo principal da NATO é garantir a defesa colectiva dos seus países membros. É composto por 30 países membros, principalmente da América do Norte e da Europa. A organização promove valores democráticos, cooperação e segurança entre seus membros. A OTAN também desempenha um papel crucial na gestão de crises e nas operações de manutenção da paz em todo o mundo.

Corrente finalizada.

E a resposta do modelo à segunda pergunta está exatamente correta:

A OTAN foi criada em 4 de abril de 1949.

Corrente finalizada.

Como vimos, o uso de uma estrutura como LangChain simplifica muito nossos primeiros passos em aplicações LLM. LangChain é fortemente recomendado se você está apenas começando e deseja experimentar alguns exemplos de brinquedos. Isso o ajudará a ir direto ao ponto principal da geração de recuperação aumentada, ou seja, a ingestão de documentos e as interações entre o banco de dados vetorial e o LLM, em vez de ficar preso no encanamento.

Para escalar para um corpus maior e implantar um aplicativo de produção, será necessário um mergulho mais profundo em LLMs locais, bancos de dados de vetores e incorporações. Naturalmente, as implantações de produção envolverão muito mais nuances e customização, mas os mesmos princípios se aplicam. Exploraremos LLMs locais, bancos de dados de vetores e incorporações com mais detalhes em artigos futuros aqui.