Criando um backend robusto de assistente de IA!
Com o avanço da tecnologia de IA, espera-se que os assistentes de IA desempenhem um papel cada vez mais significativo no gerenciamento do suporte ao cliente empresarial. A maioria das empresas já integrou algum tipo de IA em seus fluxos de trabalho.
Neste artigo, discutiremos os assistentes de IA, destacando seus incríveis benefícios e possíveis desvantagens.
Além disso, forneceremos um guia passo a passo abrangente sobre como criar um assistente baseado em IA usando o OpenAI e o Back4app.
Contents
O que é um assistente de IA?
Um assistente de IA é um software que recebe uma solicitação por meio de texto ou voz e gera uma resposta.
Entre outras coisas, essa tecnologia utiliza processamento de linguagem natural (NLP) e aprendizado de máquina.
O objetivo dos assistentes de IA é imitar a conversação humana.
Ao longo do artigo, usaremos as palavras assistente de IA e chatbot de IA de forma intercambiável. No entanto, algumas pessoas podem argumentar que um assistente é uma versão mais complexa de um chatbot que também pode executar tarefas.
Alguns exemplos de assistentes de IA populares são o ChatGPT, o Claude e o Gemini.
Alguns aplicativos de assistente de IA incluem:
- Suporte ao cliente (os assistentes de IA podem ser treinados para responder às dúvidas dos clientes)
- Ajuda ao desenvolvedor (os assistentes de IA podem gerar código e ajudar os desenvolvedores a trabalhar com eficiência)
- Educação (os assistentes podem ser usados para fins educacionais e de integração de usuários)
- Marketing e análise (os assistentes podem gerar material de marketing e analisar dados)
- Entretenimento (os chatbots com IA podem criar respostas divertidas ou criativas)
Benefícios dos assistentes de IA
Os assistentes de IA trazem uma série de benefícios. Vamos dar uma olhada neles!
Aumentar a produtividade
Os assistentes de IA permitem que você aumente muito a produtividade de sua empresa.
Eles podem ser utilizados para organização de tarefas, operações comerciais, suporte ao cliente, marketing etc.
Ao utilizar a IA, você pode criar um suporte ao cliente autônomo e altamente escalável, disponível 24 horas por dia, 7 dias por semana.
Além disso, os desenvolvedores podem aproveitar os assistentes de IA para escrever, revisar e documentar o código. Já existem várias ferramentas especializadas para essa finalidade, incluindo o GitHub Copilot, o OpenAI Codex e o CodePal.
Facilidade de uso
Os assistentes de IA estão entre os softwares mais acessíveis porque “entendem” o texto humano. Quase qualquer pessoa, independentemente de seu conhecimento técnico, pode usá-los.
Corte de custos
Os assistentes de IA podem ajudá-lo a reduzir significativamente os custos, otimizando seus processos de trabalho e automatizando o suporte ao cliente. Alguns estudos descobriram que a IA ajuda as empresas a reduzir os custos em até 20%.
Recuperação de informações
Uma das melhores vantagens dos assistentes de IA é sua capacidade de buscar informações. Eles podem consultar rapidamente vários documentos e retornar uma resposta simples e legível para o usuário.
Além disso, eles podem acompanhar as respostas com as fontes.
Graças aos recentes avanços na API da OpenAI, agora você pode treinar bots usando seus dados comerciais sem esforço.
Personalização e customização
Os assistentes de IA são altamente personalizáveis. Reaproveitar um assistente é tão fácil quanto alterar as instruções ou o chamado prompt inicial.
Além disso, os assistentes de IA podem retornar respostas personalizadas com base na pessoa com quem estão se comunicando.
Por exemplo, eles podem responder à consulta do usuário em seu idioma nativo ou considerar o contexto de conversas anteriores.
Desvantagens dos assistentes de IA
Nada vem sem desvantagens.
Alucinações
Os chatbots de IA às vezes geram informações falsas ou sem sentido. Quando isso acontece, dizemos que o chatbot teve uma alucinação.
A razão por trás disso é que os bots não entendem realmente o que estão dizendo – eles estão apenas gerando a próxima palavra mais provável com base nas palavras anteriores.
Se você estiver curioso para saber como funcionam os chatbots de IA como o ChatGPT, dê uma olhada neste artigo.
Não é capaz de realizar operações complexas
Os assistentes de IA são ótimos para tarefas simples e repetitivas, mas falham miseravelmente quando solicitados a realizar tarefas complexas.
Falta-lhes bom senso e inteligência humana em geral. Se a resposta não estiver dentro do material de aprendizagem do chatbot, ele provavelmente retornará uma resposta incorreta.
Além disso, não há garantia de que eles produzam resultados ideais.
Manutenção
Para garantir que os chatbots treinados em documentos comerciais forneçam informações precisas e atuais, você deve atualizá-los regularmente com os documentos mais recentes. Sem essa manutenção contínua, o chatbot pode fornecer respostas desatualizadas.
Preocupações com privacidade e segurança
Às vezes, os assistentes precisam lidar com informações comerciais confidenciais ou dados pessoais de usuários. Isso levanta algumas questões éticas e possibilita que o assistente vaze informações confidenciais.
Como criar um assistente de IA?
Nesta parte do tutorial, criaremos um assistente virtual com tecnologia GPT.
Nosso assistente virtual se especializará em responder a perguntas sobre matemática. Ele utilizará threads, o que lhe permitirá responder a perguntas de acompanhamento.
Além disso, o código será projetado para facilitar o reaproveitamento e a adaptação a outros aplicativos.
No back-end, usaremos o OpenAI e o Back4app, e o front-end será criado usando o React (com o TailwindCSS).
Pré-requisitos
- Conhecimento básico de JavaScript ES6
- Experiência com React e React Hooks
- Uma conta OpenAI com alguns créditos
- Uma conta gratuita no Back4app
Objetivos
# | Backend | Front-end |
1 | Criar um aplicativo Back4app | Crie um novo projeto de bootstrap |
2 | Atualizar a versão do Node.js do aplicativo | Instalar o TailwindCSS |
3 | Criar uma chave secreta da OpenAI | Codifique a interface do usuário |
4 | Adicione a chave secreta como uma variável de ambiente | Instalar e configurar o Parse SDK |
5 | Criar funções do Cloud Code | Conectar-se ao backend |
Vamos começar a programar!
Backend
Nesta etapa do tutorial, cuidaremos do backend. Criaremos um aplicativo Back4app, criaremos chaves secretas OpenAI, as adicionaremos como variáveis de ambiente e escreveremos as funções necessárias do Cloud Code.
Criar o aplicativo Back4app
Primeiro, faça login na sua conta do Back4app ou crie uma, se ainda não tiver uma.
Ao fazer login, você será redirecionado para a sua lista de aplicativos. Clique em “Build new app” (Criar novo aplicativo) para criar um aplicativo.
A plataforma Back4app permite que você implemente dois tipos de aplicativos: Backend as a Service (BaaS) e Containers as a Service (CaaS). Estamos criando um backend, portanto, opte pelo BaaS.
Em seguida, dê ao seu aplicativo um nome informativo, deixe o banco de dados como NoSQL e clique em “Create”.
Aguarde cerca de três minutos para que a plataforma crie o aplicativo. A Back4app cuidará de tudo, desde a criação da camada do aplicativo até a configuração do banco de dados, segurança, dimensionamento e muito mais.
Uma vez feito isso, você será redirecionado para a interface do banco de dados do seu aplicativo.
Alterar a versão do nó
Por padrão, os aplicativos Back4app são alimentados pelo Parse v4.10.4. Essa versão do Parse Server usa o Node v14, que é incompatível com a biblioteca do OpenAI, que requer o Node v18+.
Vamos atualizar a versão do Parse Server.
Primeiro, selecione “Server Settings” (Configurações do servidor) na barra lateral e, em seguida, navegue até as configurações de “Manage Parse Server” (Gerenciar servidor Parse), conforme mostrado na imagem abaixo.
Altere a versão do Parse Server para 5.2.3
ou mais recente.
Clique em “Save” (Salvar) e aguarde alguns minutos para que o Back4app atualize a versão do servidor.
Para verificar a versão do Node.js, você pode definir a seguinte função do Cloud Code:
Parse.Cloud.define("getNodeVersion", async(request) => {
return process.version;
});
Em seguida, acione-o por meio da “API > Console > REST” integrada, enviando uma solicitação POST
para functions/getNodeVersion
.
Chaves da API da OpenAI
Continuando, vamos criar uma chave de API do OpenAI para nos conectarmos ao OpenAI a partir do nosso backend.
Navegue até o painel do OpenAI e crie um novo projeto clicando em “Default project” (Projeto padrão) e, em seguida, em “Create project” (Criar projeto).
Dê ao seu projeto um nome descritivo – eu vou usar “back4app”. Depois disso, clique em “Create” (Criar).
O OpenAI deve mudar automaticamente para o projeto recém-criado.
Em seguida, vá para a seção “API keys” (Chaves de API) selecionando “Dashboard” (Painel) na barra de navegação e, em seguida, “API keys” (Chaves de API) na barra lateral. Clique em “Create new secret key” (Criar nova chave secreta) para iniciar o processo de criação da chave de API.
Deixe todas as configurações como padrão e clique em “Create secret key” (Criar chave secreta) para confirmar a criação da chave.
Anote a chave secreta, pois você só poderá vê-la uma vez.
Trate sua chave secreta com a mesma segurança com que trataria uma senha. Se outra pessoa a obtiver, ela poderá gerar cobranças substanciais da OpenAI. Além disso, sugiro definir limites de uso.
Definir variáveis ambientais
Para evitar a exposição de nossa chave secreta no código-fonte, nós a adicionaremos como uma variável ambiental.
Navegue até “Server Settings > Environment Variables > Settings” (Configurações do servidor > Variáveis de ambiente > Configurações).
Em seguida, defina a variável ambiental OPENAI_API_KEY
como faria em um arquivo .env:
OPENAI_API_KEY=<your_openai_api_key>
Certifique-se de substituir <your_openai_api_key> pela sua chave secreta OpenAI da etapa anterior.
Por fim, clique em “Save” para salvar as variáveis ambientais.
Agora você pode acessar a chave secreta das funções do Cloud Code da seguinte forma:
const secretKey = process.env.OPENAI_API_KEY;
console.log(secretKey);
// sk-proj-...
Cloud Code
Para implementar a lógica de backend, utilizaremos as funções do Cloud Code. As funções do Cloud Code são um recurso robusto do Parse Server que permite que os desenvolvedores executem código JavaScript personalizado no lado do servidor.
Eles podem ser acionados via REST, usando o Parse SDK, ou programados em uma base de tempo.
Confira o artigo O que são funções sem servidor? para saber mais sobre as funções como serviço.
Primeiro, selecione “Cloud Code > Functions & Web Hosting” na barra lateral para acessar o Cloud Code.
Você perceberá que a tela está dividida em duas seções. Você tem a estrutura de diretórios no lado esquerdo e o editor de código JavaScript no lado direito. Por padrão, há dois diretórios:
- pasta de nuvem usada para implementar funções do Cloud Code e outros códigos personalizados
- pasta pública usada para implantar conteúdo estático (por exemplo, imagens, vídeos, ícones)
Instalar a biblioteca OpenAI
Para interagir com a API da OpenAI, instalaremos a biblioteca JavaScript da OpenAI.
Instalar pacotes NPM usando o Cloud Code é fácil. Para fazer isso, crie um arquivo package.json na pasta da nuvem listando os pacotes que você deseja instalar.
// cloud/package.json
{
"dependencies": {
"openai": "^4.51.0"
}
}
Para obter a versão mais recente do pacote
openai
, consulte a página do pacote NPM.
Em seguida, clique em “Deploy” (Implantar) no canto superior direito da tela.
Se a instalação for bem-sucedida, você verá um package-lock.json recém-gerado na pasta da nuvem. O arquivo de bloqueio deve conter o pacote openai
.
Funções do Cloud Code
Em seguida, vamos cuidar das funções do Cloud Code.
Criaremos as quatro funções a seguir:
setup()
criará um assistente virtual e salvará sua configuração no banco de dadoscreateThread()
criará um novo thread de assistente virtualdeleteThread(threadId)
excluirá um thread de assistente virtual existenteaddMessage(threadId, message)
adicionará uma mensagem ao thread e gerará uma resposta
Vá em frente e cole o seguinte código em cloud/main.js:
// cloud/main.js
const OpenAI = require("openai");
const openai = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
});
const ASSISTANT_INITIAL_MESSAGE = "Hi, my name is Math Bot. How can I help you?";
const ASSISTANT_SETTINGS = {
name: "Math Bot",
instructions: "Very smart math bot that answers math questions.",
model: "gpt-3.5-turbo-0125",
tools: [],
};
Parse.Cloud.define("setup", async (request) => {
const Assistant = Parse.Object.extend("Assistant");
const query = await new Parse.Query(Assistant);
const count = await query.count();
// Check if virtual assistant already exists
if (count !== 0) {
throw new Parse.Error(
Parse.Error.VALIDATION_ERROR,
"A virtual assistant already exists!",
);
}
// Use OpenAI's API to create an assistant
const openAssistant = await openai.beta.assistants.create(
ASSISTANT_SETTINGS,
);
// Store the assistant in Back4app database
const assistant = new Assistant();
for (const key in ASSISTANT_SETTINGS) {
assistant.set(key, ASSISTANT_SETTINGS[key]);
}
assistant.set("initialMessage", ASSISTANT_INITIAL_MESSAGE);
assistant.set("assistantId", openAssistant.id);
await assistant.save();
return assistant.get("assistantId");
});
Parse.Cloud.define("createThread", async (request) => {
const thread = await openai.beta.threads.create();
return thread.id;
});
Parse.Cloud.define("deleteThread", async (request) => {
const _threadId = request.params.threadId;
return await openai.beta.threads.del(_threadId);
});
Parse.Cloud.define("addMessage", async (request) => {
const _threadId = request.params.threadId;
const _message = request.params.message;
// Verify all the parameters are provided
if (!_threadId || !_message) {
throw new Parse.Error(
Parse.Error.VALIDATION_ERROR,
"You need to provide: threadId & message.",
);
}
const Assistant = Parse.Object.extend("Assistant");
const query = await new Parse.Query(Assistant);
const count = await query.count();
// Check if a virtual assistant exists
if (count === 0) {
throw new Parse.Error(
Parse.Error.VALIDATION_ERROR,
"A virtual assistant does not exist!",
);
}
const assistant = await new Parse.Query(Assistant).first();
const assistantId = assistant.get("assistantId");
// Get the thread, add the message, and generate a response
let buffer = "";
const message = await openai.beta.threads.messages.create(
_threadId, {role: "user", content: _message},
);
let run = await openai.beta.threads.runs.createAndPoll(
_threadId, {assistant_id: assistantId},
);
// Add the last message to the buffer
if (run.status === "completed") {
const messages = await openai.beta.threads.messages.list(run.thread_id);
buffer += messages.data[0].content[0].text.value;
} else {
console.error("Failed to run the assistant.");
}
return buffer;
});
Resumo do código
- O código importa e inicializa a biblioteca OpenAI.
- Em seguida, ele define as configurações do assistente (por exemplo,
nome
,instruções
einitialMessage
). - O Code oferece quatro funções do Cloud Code, descritas acima.
- Em
setup()
, buscamos o assistente e o thread e, em seguida, adicionamos uma mensagem ao thread. Em seguida, usamos uma execução para gerar uma resposta usando o assistente.
Teste as funções do Cloud Code
Antes de passar para o frontend, precisamos garantir que o backend funcione conforme o esperado.
Para fins de teste, usaremos o console integrado do Back4app. Navegue até “API > Console > REST” na barra lateral.
Primeiro, acione a função setup()
:
- Que tipo de solicitação:
POST
- Qual endpoint:
functions/setup
- Usar chave mestra:
false
- Executar como: deixar em branco
- Parâmetros de consulta: deixar em branco
Isso criará um novo assistente e o salvará no banco de dados. Se você navegar até a visualização do banco de dados, verá que a classe Assistant
agora tem uma linha.
Continuando, vamos testar os pontos de extremidade da conversa.
POST
parafunctions/createThread
para criar um thread. Anote o ID do thread.POST
uma pergunta parafunctions/addMessage
com os seguintes parâmetros{"threadId": "", "message": "What is 2+2?"}
. Verifique se a resposta gerada está correta.POST
parafunctions/deleteThread
com os seguintes parâmetros{"threadId": ""}
para excluir o thread.
Ótimo, o backend parece estar funcionando bem!
Front-end
Nesta seção do tutorial, criaremos um novo projeto React, instalaremos o TailwindCSS, implementaremos a interface do usuário, configuraremos o Parse SDK e implementaremos a lógica necessária.
Criar aplicativo Vite
Comece criando um novo projeto Vite usando o modelo React:
$ npm create vite@latest frontend -- --template react
Altere o diretório para a pasta recém-criada e instale as dependências:
$ cd frontend
$ npm install
Execute o servidor de desenvolvimento:
$ npm run dev
Abra seu navegador da Web favorito e navegue até http://localhost:5174/. Você deverá ver a página de destino padrão do Vite + React.
TailwindCSS
Para simplificar nosso trabalho, usaremos o TailwindCSS, uma estrutura CSS que prioriza a utilidade e permite que você crie rapidamente designs personalizados sem sair do HTML.
A estrutura oferece uma abordagem altamente personalizável e responsiva ao estilo.
Para instalar o TailwindCSS, siga o guia oficial.
Visualizações
Continuando, vamos implementar a interface do usuário.
Para tornar nosso código mais organizado, primeiro criaremos alguns componentes. Primeiro, crie uma pasta de componentes dentro da pasta src e coloque os três arquivos a seguir dentro dela:
Além disso, adicione este avatar.png à pasta src/assets.
Nesse ponto, sua estrutura de diretórios deve ter a seguinte aparência:
frontend/
└── src/
├── components/
│ ├── Spinner.jsx
│ ├── AssistantMessage.jsx
│ └── UserMessage.jsx
├── assets/
│ └── avatar.png
└── ...
Em seguida, coloque o seguinte código em src/App.jsx:
// src/App.jsx
import {useEffect, useState} from "react";
import AssistantMessage from "./components/AssistantMessage.jsx";
import UserMessage from "./components/UserMessage.jsx";
import Spinner from "./components/Spinner.jsx";
function App() {
const [initialMessage, setInitialMessage] = useState(undefined);
const [loading, setLoading] = useState(true);
const [threadId, setThreadId] = useState(undefined);
const [message, setMessage] = useState("");
const [messages, setMessages] = useState([
{role: "assistant", content: "Welcome! How can I help you today?"},
{role: "user", content: "What is 2+2?"},
{role: "assistant", content: "2+2 is 4."},
]);
async function getInitialMessage() {
// TODO: get the initial message
}
async function reset(message) {
// TODO: create a new thread
}
useEffect(() => {
setLoading(false);
// TODO: get the initial message
}, []);
function onSubmit(event) {
// TODO: add the message to the thread and generate response
}
function onNewThread() {
// TODO: create a new thread
}
return (
<main className="container mx-auto py-8 px-8 md:px-32 lg:px-64 h-[100vh]">
<div className="pb-12 space-y-2">
<h1 className="text-3xl font-bold">
back4app-openai-virtual-assistant
</h1>
<p>
An AI-powered virtual assistant built using OpenAI + Back4app.
</p>
</div>
<div className="space-y-2">
{messages.map((message, index) => {
switch (message.role) {
case "assistant":
return <AssistantMessage key={index} content={message.content}/>;
case "user":
return <UserMessage key={index} content={message.content}/>;
default:
return <></>;
}
})}
{loading && <Spinner/>}
</div>
<form className="inline-block flex flex-row pt-12" onSubmit={onSubmit}>
<input
type="text"
className="w-full p-2 border border-gray-300 rounded-md outline-none"
placeholder="Type a message..."
value={message}
onChange={(event) => setMessage(event.target.value)}
/>
<button
type="submit"
className="bg-blue-500 hover:bg-blue-600 text-white p-2 px-3 rounded-md ml-2"
>
Send
</button>
<button
type="button"
className="bg-green-500 text-white p-2 px-3 rounded-md ml-2"
onClick={onNewThread}
>
New
</button>
</form>
</main>
);
}
export default App;
Esse código cria uma interface de usuário simples, que renderiza mensagens do estado de mensagens
. Além disso, ele fornece uma caixa de texto e um botão para enviar mensagens ao assistente virtual.
Inicie o servidor de desenvolvimento mais uma vez e navegue até http://localhost:5174/. Você deverá ver uma interface de usuário semelhante à do ChatGPT.
Instalar o Parse SDK
Para conectar-se ao nosso backend baseado no Back4app, usaremos o Parse SDK.
O SDK do Parse permite que os desenvolvedores interajam perfeitamente com back-ends baseados no Parse, possibilitando consultas de dados eficientes, autenticação de usuários, notificações, manipulação de dados em tempo real e muito mais.
Primeiro, instale o Parse via npm:
$ npm install parse
Em seguida, navegue até o aplicativo Back4app. Selecione “App Settings > Security & Keys” (Configurações do aplicativo > Segurança e chaves) na barra lateral. Em seguida, anote o “Application ID” (ID do aplicativo) e a “JavaScript Key” (chave JavaScript).
Em vez de expor as chaves secretas no código-fonte, crie um arquivo .env na raiz do projeto:
VITE_BACK4APP_APPLICATION_ID=<your_back4app_application_id>
VITE_BACK4APP_JAVASCRIPT_KEY=<your_back4app_javascript_key>
Certifique-se de substituir as variáveis por suas chaves reais.
Em seguida, navegue até src/main.jsx e inicialize o Parse usando as variáveis de ambiente:
// src/main.jsx
// ...
import Parse from "parse/dist/parse.min.js";
// Initialize Parse SDK using the Back4app API keys
Parse.initialize(
import.meta.env.VITE_BACK4APP_APPLICATION_ID,
import.meta.env.VITE_BACK4APP_JAVASCRIPT_KEY,
);
Parse.serverURL = "https://parseapi.back4app.com/";
ReactDOM.createRoot(document.getElementById("root")).render(
// ...
);
Agora você pode usar a instância do Parse em todas as suas exibições, importando-a:
import Parse from "parse/dist/parse.min.js";
Lógica
Por fim, substitua os hooks do React em src/App.jsx pelo seguinte:
// src/App.jsx
// ...
import Parse from "parse/dist/parse.min.js";
function App() {
// ...
async function getInitialMessage() {
const Assistant = Parse.Object.extend("Assistant");
const assistant = await new Parse.Query(Assistant).first();
return assistant.get("initialMessage");
}
async function reset(message) {
setMessages([
{role: "assistant", content: message},
]);
setMessage("");
const threadId = await Parse.Cloud.run("createThread");
setThreadId(threadId);
}
useEffect(() => {
(async () => {
const assistantInitialMessage = await getInitialMessage();
setInitialMessage(assistantInitialMessage);
await reset(assistantInitialMessage);
setLoading(false);
})();
}, []);
function onSubmit(event) {
event.preventDefault();
if (loading || !threadId || !message) return;
setMessages([
...messages,
{role: "user", content: message},
]);
setMessage("");
setLoading(true);
(async () => {
const response = await Parse.Cloud.run("addMessage", {threadId, message});
setMessages(messages => [
...messages,
{role: "assistant", content: response},
]);
setLoading(false);
})();
}
function onNewThread() {
if (loading || !threadId) return;
setLoading(true);
(async () => {
await reset(initialMessage);
setLoading(false);
})();
}
return (
// ...
);
}
export default App;
Esse código trata a mensagem e a envia para o backend. Ele também permite que os usuários criem um novo tópico clicando em um botão.
Pronto! O front-end agora está completo.
Reinicie o servidor de desenvolvimento e teste o aplicativo para garantir que tudo esteja funcionando.
Se você deseja implantar o front-end do assistente, consulte Como hospedar um aplicativo React?
Conclusão
Este artigo ensinou tudo o que você precisa saber para criar assistentes personalizados baseados em IA.
Agora você deve poder usar a API do Assistente da OpenAI e o Back4app para fazer backup e implantar seus assistentes de IA,
O código-fonte final está disponível no repositório back4app-openai-virtual-assistant do GitHub.