No cenário em rápida evolução da Inteligência Artificial e do Processamento de Linguagem Natural ao criar aplicações Inteligentes, o uso da técnica de Retrieval Augmented Generation (RAG) emergiu como uma solução poderosa para melhorar a precisão e a relevância das respostas geradas por modelos de linguagem.
Neste artigo, vamos explorar a palestra dada durante o evento Hack Together: RAG Hack, a qual Glaucia Lemos, que é Cloud Advocate na Microsoft e Yohan Lasorsa, que é Senior Cloud Advocate também na Microsoft, apresentaram como o LangChain.Js está revolucionando o desenvolvimento de aplicações RAG, facilitando a criação de aplicações inteligentes que combinam grandes modelos de linguagem (LLMs) com suas prórias fontes de dados.
O Hack Together: RAG Hack é um hackathon global e gratuito que está acontecendo entre os dias 03 à 16 de Setembro de 2024, focado em explorar e desenvolver aplicações utilizando a técnica de Retrieval Augmented Generation (RAG).
Este evento reunirá desenvolvedores, pesquisadores e entusiastas de IA de todo o munndo com o intuito de criar aplicações inovadoras e inteligentes que combinam grandes modelos de linguagem (LLMs) com suas próprias fontes de dados usando o RAG.
O evento contará com 25 transmissões ao vivo, demonstrando como criar aplicações RAG utilizando Azure AI em diferentes linguagens de programação, tais como: Python, Java, JavaScript/TypeScript e C#. E, incluso também com diversos serviços de IA do Azure tais como: AI Search, PostgreSQL, Azure SQL e Azure CosmosDB. Os participantes tem a oportunidade de aprender sobre frameworks populares como o LangChain e Semantic Kernel, além de tecnologias de ponta como agentes e modelos de visão.
A melhor parte é que, caso a sua aplicação seja escolhida você pode ganhar um prêmio de USD 500,00! Nas seguintes categorias:
Quer saber mais sobre todos os detalhes do evento, como participar e como submeter a sua aplicação? Acesse o site do evento aqui e participe!
No último dia 04 de Setembro de 2024, aconteceu a live session com o tema: Criando Aplicações RAG com LangChain.Js, onde Glaucia Lemos e Yohan Lasorsa explicaram a importância do uso do LangChain.Js para o desenvolvimento de aplicações RAG com uma baita demonstração de um AI Chat Serverless.
Se você perdeu essa live, não se preocupe! Você pode assistir a gravação abaixo:
Durante a live session, Glaucia Lemos e Yohan Lasorsa apresentaram uma aplicação de exemplo chamada Contoso Real Estate AI Chat, que é uma aplicação de chatbot que permite aos usuários fazer perguntas sobre imóveis disponíveis para venda.
Vocês podem ver a aplicação em ação no gif abaixo:
Inclusive, você pode acessar a aplicação diretamente no repositório do GitHub aqui!
Curtiu? Então, fork agora mesmo o projeto direto no repositório e faça a sua própria versão da aplicação Contoso Real Estate AI Chat! E, não esqueça de dar uma estrela no repositório!
Bom... vamos agora ao que foi apresentado durante a live session!
Durante a primeira parte da live session, Glaucia Lemos explorou o desafio da IA e a solução com uso do RAG.
Ao trabalhar com modelos LLMs, nos deparamos com vários desafios. Esses modelos, apesar de sua capacidade impressionante de gerar linguagem natural, às vezes produzem informações imprecisas e não tão acuradas. Justo porque utilizam dados desatualizados ou se baseiam em fontes não confiáveis.
É justo aí que entra a técnica RAG, pois ela permite que os desenvolvedores combinem grandes modelos de linguagem com suas próprias fontes de dados, melhorando a precisão e a relevância das respostas geradas.
RAG, ou Retrieval Augmented Generation, é uma técnica que combina dois componentes principais:
O processo do RAG pode ser dividido em algumas etapas. Mas, principalmente, ele funciona da seguinte forma:
O gif abaixo ilustra perfeitamente todo o processo do RAG:
E, um dos fatores mais importantes nesse processo é a criação da base de conhecimento. Mas, como ele é implementado? Vamos ver a seguir!
A base de conhecimento é um conjunto de documentos que contém informações relevantes para responder perguntas. Esses documentos podem ser de diferentes tipos, como: texto, imagens, tabelas, etc.
Tudo isso se resume a um processo de duas etapas:
1. Construção da Base de Conhecimento
2. Processo de Recuperação e Geração
Além desse processo se repetir, ele também permite obter respostas mais precisas e relevantes, utilizando dados específicos em vez de aprender apenas dos dados do modelo de linguagem.
Se ficou confuso como todo esse processo funciona, o gif abaixo ilustra perfeitamente como ocorre:
Depois que você criou sua base de conhecimento, é a vez de fazer uso da recuperação e aumento de contexto. E, esse processo se resumo em três etapas:
Deixemos que o gif demonstre como ocorre todo esse processo:
As vantagens do uso do RAG são inúmeras, mas podemos destacar algumas, tais como:
1. Não Requer Treinamento Adicional: você pode utilizar modelos de linguagem existentes, economizando tempo e recursos significativos.
2. Dados Sempre Atualizados: A base de conhecimento pode ser facilmente atualizada sem necessidade de retreinar o modelo, garantindo informações sempre atuais.
3. Fundamentação Sólida: As respostas são baseadas em fontes específicas e confiáveis, aumentando a precisão e confiabilidade.
4. Aumento da Confiança do Usuário: É possível mostrar aos usuários as fontes utilizadas para gerar as respostas, proporcionando transparência e credibilidade.
Agora que entendemos profundamente como o RAG funciona e suas vantagens, vamos ver como o LangChain.Js auxilia no desenvolvimento de Aplicações RAG!
Nessa segunda parte da live session, Yohan Lasorsa apresentou o LangChain.js, um framework open-source que simplifica o desenvolvimento de aplicações RAG. E, como foi simples a implementação de um AI Chat Serverless com o LangChain.js.
O Langchain.js é uma biblioteca JavaScript de código aberto projetada para simplificar o trabalho com grandes modelos de linguagem (LLMs) e implementar técnicas avançadas como RAG. Ela oferece abstrações de alto nível para todos os componentes necessários ao criar aplicações de IA, facilitando a integração de modelos, bancos de dados vetoriais e agentes complexos.
O Langchain.js permite a criação de fluxos de trabalho de inteligência artificial (IA) altamente personalizados e flexíveis, combinando diferentes etapas de processamento em uma sequência lógica. Vamos entender como isso funciona através de um exemplo prático que gera uma piada baseada em um tema específico usando um modelo de linguagem natural.
type Joke = { joke: string };
const model = new ChatOpenAI({ model: "gpt-4o-mini" });
const prompt = ChatPromptTemplate.fromTemplate(
"Tell a joke about {topic}. Answer with valid JSON, containing one field: 'joke'"
);
const parser = new JsonOutputParser<Joke>();
const chain = prompt
.pipe(model)
.pipe(parser);
await chain.invoke({ topic: "bears" });
O código acima utiliza o LangChain.js para criar um fluxo de trabalho de IA que gera uma piada sobre um tema específico. Primeiro, define-se o tipo de saída como um objeto Joke
. Em seguida, inicializa-se o modelo de linguagem gpt-4o-mini
e cria-se um template de prompt que instrui o modelo a retornar uma piada em formato JSON. Um parser é configurado para transformar a resposta em um objeto JavaScript. Por fim, o fluxo de trabalho é montado encadeando o prompt, o modelo e o parser, e é executado com o tema “bears”.
Você pode aprender mais sobre o LangChain.js e como usá-lo em sua aplicação acessando a documentação oficial aqui.
Agora, vamos explorar como foi implementado um sistema RAG completo usando Langchain.js, baseado no projeto de exemplo apresentado durante a live. O projeto é um chatbot de suporte para uma empresa fictícia de aluguel de imóveis chamada Contoso Real Estate.
O projeto foi desenvolvido fazendo uso de uma arquitetura serverless, utilizando vários serviços Azure:
As principais tecnologias utilizadas foram:
O melhor ponto desse projeto é que todos os serviços utilizados do Azure estão na camada gratuita, o que significa que você pode testar e experimentar sem custos adicionais. Sensacional, não é mesmo?
O primeiro passo na implementação do RAG é o processamento dos documentos que formarão nossa base de conhecimento. Vejamos como isso é feito usando Langchain.js com base no código desenvolvido no projeto:
(... some imports here...)
export async function postDocuments(request: HttpRequest, context: InvocationContext): Promise<HttpResponseInit> {
const storageUrl = process.env.AZURE_STORAGE_URL;
const containerName = process.env.AZURE_STORAGE_CONTAINER_NAME;
const azureOpenAiEndpoint = process.env.AZURE_OPENAI_API_ENDPOINT;
try {
// Get the uploaded file from the request
const parsedForm = await request.formData();
if (!parsedForm.has('file')) {
return badRequest('"file" field not found in form data.');
}
// Type mismatch between Node.js FormData and Azure Functions FormData
const file = parsedForm.get('file') as any as File;
const filename = file.name;
// Extract text from the PDF
const loader = new PDFLoader(file, {
splitPages: false,
});
const rawDocument = await loader.load();
rawDocument[0].metadata.source = filename;
// Split the text into smaller chunks
const splitter = new RecursiveCharacterTextSplitter({
chunkSize: 1500,
chunkOverlap: 100,
});
const documents = await splitter.splitDocuments(rawDocument);
(... more code ...)
Esse arquivo, documents-post.ts
, é responsável por processar os documentos enviados pelo usuário. Primeiro, ele extrai o texto de um arquivo PDF usando a biblioteca PDFLoader
. Em seguida, divide o texto em chunks menores com o RecursiveCharacterTextSplitter
. Por fim, os documentos são armazenados no Azure Blob Storage para uso posterior.
O coração do sistema RAG está na função de chat
, onde as perguntas dos usuários são processadas e respondidas com base nos documentos relevantes recuperados. Vejamos como isso é implementado:
(... some imports here...)
const systemPrompt = `Assistant helps the Consto Real Estate company customers with questions and support requests. Be brief in your answers. Answer only plain text, DO NOT use Markdown.
Answer ONLY with information from the sources below. If there isn't enough information in the sources, say you don't know. Do not generate answers that don't use the sources. If asking a clarifying question to the user would help, ask the question.
If the user question is not in English, answer in the language used in the question.
Each source has the format "[filename]: information". ALWAYS reference the source filename for every part used in the answer. Use the format "[filename]" to reference a source, for example: [info1.txt]. List each source separately, for example: [info1.txt][info2.pdf].
Generate 3 very brief follow-up questions that the user would likely ask next.
Enclose the follow-up questions in double angle brackets. Example:
<<Am I allowed to invite friends for a party?>>
<<How can I ask for a refund?>>
<<What If I break something?>>
Do no repeat questions that have already been asked.
Make sure the last question ends with ">>".
SOURCES:
{context}`;
export async function postChat(request: HttpRequest, context: InvocationContext): Promise<HttpResponseInit> {
const azureOpenAiEndpoint = process.env.AZURE_OPENAI_API_ENDPOINT;
try {
const requestBody = (await request.json()) as AIChatCompletionRequest;
const { messages } = requestBody;
if (!messages || messages.length === 0 || !messages.at(-1)?.content) {
return badRequest('Invalid or missing messages in the request body');
}
let embeddings: Embeddings;
let model: BaseChatModel;
let store: VectorStore;
if (azureOpenAiEndpoint) {
const credentials = getCredentials();
const azureADTokenProvider = getAzureOpenAiTokenProvider();
// Initialize models and vector database
embeddings = new AzureOpenAIEmbeddings({ azureADTokenProvider });
model = new AzureChatOpenAI({
// Controls randomness. 0 = deterministic, 1 = maximum randomness
temperature: 0.7,
azureADTokenProvider,
});
store = new AzureCosmosDBNoSQLVectorStore(embeddings, { credentials });
} else {
// If no environment variables are set, it means we are running locally
context.log('No Azure OpenAI endpoint set, using Ollama models and local DB');
embeddings = new OllamaEmbeddings({ model: ollamaEmbeddingsModel });
model = new ChatOllama({
temperature: 0.7,
model: ollamaChatModel,
});
store = await FaissStore.load(faissStoreFolder, embeddings);
}
// Create the chain that combines the prompt with the documents
const combineDocsChain = await createStuffDocumentsChain({
llm: model,
prompt: ChatPromptTemplate.fromMessages([
['system', systemPrompt],
['human', '{input}'],
]),
documentPrompt: PromptTemplate.fromTemplate('[{source}]: {page_content}\n'),
});
// Create the chain to retrieve the documents from the database
const chain = await createRetrievalChain({
retriever: store.asRetriever(3),
combineDocsChain,
});
const lastUserMessage = messages.at(-1)!.content;
const responseStream = await chain.stream({
input: lastUserMessage,
});
const jsonStream = Readable.from(createJsonStream(responseStream));
return data(jsonStream, {
'Content-Type': 'application/x-ndjson',
'Transfer-Encoding': 'chunked',
});
(... more code ...)
Nesse arquivo, chat-post.ts
, a função postChat
processa as mensagens enviadas pelo usuário e retorna respostas baseadas nos documentos relevantes recuperados. O código cria uma cadeia de processamento que combina o prompt do sistema com os documentos disponíveis e, em seguida, recupera os documentos relevantes do banco de dados vetorial. Por fim, a resposta é gerada e enviada de volta ao usuário.
Uma característica notável deste projeto é a capacidade de executá-lo localmente, sem depender do Azure OpenAI. Isso é possível graças ao Ollama, uma ferramenta que permite executar modelos de linguagem open-source localmente.
O arquivo constants.ts
contém as configurações necessárias para executar o projeto localmente com Ollama:
export const ollamaEmbeddingsModel = 'all-minilm:l6-v2';
export const ollamaChatModel = 'mistral:v0.2';
export const faissStoreFolder = '.faiss';
Aqui, vemos que o projeto utiliza o modelo all-minilm:l6-v2
para embeddings e mistral:v0.2
para chat. Isso permite que os desenvolvedores experimentem com o sistema RAG usando modelos de código aberto, como o Mistral, diretamente em suas máquinas locais.
Para usar esses modelos localmente, os desenvolvedores precisam instalar o Ollama e baixar os modelos especificados. Isso proporciona uma experiência de desenvolvimento flexível e acessível, especialmente útil para fases iniciais de desenvolvimento e testes.
Nota: O Ollama é uma ferramenta open-source que permite executar modelos de linguagem localmente. Para saber mais sobre o Ollama e como usá-lo, acesse o site oficial aqui. Para fazer uso desse modelo requer uma máquina com uma GPU NVIDIA e CUDA instalado.
Para implantação em produção, o projeto utiliza o Azure Developer CLI (azd), simplificando o processo de provisionamento e implantação dos recursos necessários na Azure. Com apenas alguns comandos, é possível implantar toda a infraestrutura e o código:
azd auth login --use-device-code
azd env new
azd up
Esses comandos criam um novo ambiente de desenvolvimento, implantam os recursos necessários na Azure e iniciam o projeto localmente. O Azure Static Web Apps é usado para hospedar o frontend, enquanto o Azure Functions hospeda o backend API.
Se desejar entender melhor como isso foi implementado no projeto há uma pasta chamada infra
que contém todos os arquivos de configuração necessários para implantar o projeto na Azure e nesse caso foi utilizado o BicepLang para provisionar a infraestrutura.
Depois que você implementa a aplicação você verá ela em ação, como mostra o gif abaixo:
O Langchain.js, como demonstrado neste projeto com o RAG, oferece uma plataforma robusta e flexível para a implementação de sistemas de IA avançados. Combinando o poder dos grandes modelos de linguagem com a capacidade de recuperar informações relevantes de fontes externas, o Langchain.js permite criar aplicações de IA mais inteligentes e contextuais.
Se você gostou do projeto e deseja experimentar por conta própria, pode acessar o repositório do GitHub aqui e seguir as instruções para executá-lo localmente ou implantá-lo na Azure. O projeto é uma excelente oportunidade para aprender mais sobre RAG, Langchain.js e como integrar modelos de linguagem em suas aplicações. Sem contar que você pode executar o projeto localmente com Ollama e experimentar com modelos de código aberto.
A jornada para criar aplicações de IA mais inteligentes e contextuais começa aqui. O RAG e o LangchainJ.js abrem um mundo de possibilidades para desenvolvedores, permitindo a criação de sistemas de IA que não apenas respondem perguntas, mas o fazem com precisão, relevância e confiabilidade baseadas em dados específicos e atualizados.
Agora chegou a sua vez de explorar o projeto e quem sabe até mesmo participar do Hack Together: RAG Hack para criar sua própria aplicação RAG e concorrer a prêmios incríveis! Acesse o site do evento aqui e participe!
E, até a próxima!
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.