Impulsionar o 4D com OpenAI!

A Inteligência Artificial está a modificar rapidamente a nossa vida quotidiana, e não apenas a dos programadores. Muitos de vocês, se não todos, já ouviram falar do ChatGPT da OpenAI. Este post é sobre uma prova de conceito feita com o Qodly Studio, num caso de uso prático: como usar IA para gerar conjuntos de dados críveis e realistas para as suas aplicações. Em outras palavras: como encher rapidamente a sua aplicação com dados para testar ou demonstrar. Preparem-se!

Quem é quem

O ChatGPT é uma variante do modelo GPT (Generative Pre-trained Transformer) que foi aperfeiçoado para a compreensão e geração de linguagem natural num contexto de conversação. Foi concebido para participar em conversas baseadas em texto com os usuários, fornecendo respostas semelhantes às humanas e gerando texto coerente e contextualmente relevante. O ChatGPT pode ser utilizado para uma vasta gama de aplicações, incluindo chatbots, assistentes virtuais, apoio ao cliente, etc., em que é necessário interagir com os usuários através de linguagem natural.

A API OpenAI é a interface de programação que permite aos programadores acessar e utilizar as capacidades do ChatGPT e de outros modelos fornecidos pela OpenAI. Funciona como uma ponte entre o modelo e as aplicações dos programadores, permitindo-lhes enviar mensagens de texto e receber respostas geradas pelo modelo.

O que é que eu ganho com isso?

Sendo uma API Rest, é muito fácil usá-la com 4D, e veremos isso através de um caso de uso interessante. Vamos supor que esteja trabalhando numa aplicação nova. Desenha sua estrutura: classes de dados, atributos e relações. Desenha suas telas e transações, seja através de telas de desktop ou webforms Qodly. O que é que falta agora? Os dados, claro!

Nem sempre tem um arquivo csv ou json pronto a importar, nem tempo para recolher e limpar um conjunto de dados relevante. É aí que a IA pode ser útil. Nesta prova de conceito, mostramos-lhe o que poderia ser uma utilização simples, mas útil e prática da IA para si, enquanto programador.

Imagine que pode simplesmente dizer “dê-me nomes próprios franceses” ou “dê-me comentários típicos de folhas de horas” e a sua base de dados é preenchida em conformidade. Veja o vídeo abaixo para ver mais exemplos de como produzir dados úteis com uma aplicação criada com o Qodly Studio.

Está ficando curioso? Pode obter o código da demo aqui (mínimo 4D v20 R2):

4D, Qodly e OpenAI

Sinta-se à vontade para brincar com ele, melhorá-lo ou adaptá-lo aos seus casos. E não se esqueça de contribuir!

COMO FUNCIONA?

De fato, é bastante simples, nada de especial.

Além de listar as classes de dados e os seus atributos – o que é bastante comum na programação genérica 4D, o coração desta demonstração gira em torno da consulta da API OpenAI.

Isso é feito em uma classe de usuário dedicada, em uma função chamada queryOpenAI().

Function queryOpenAI() : Text
  var $url : Text
  var $headers; $data; $opts : Object
  var $request : 4D.HTTPRequest
	
  $url:="https://api.openai.com/v1/chat/completions"
  $headers:=New object("Authorization"; "Bearer "+This.apiKey; "Content-Type"; "application/json")
	
  $data:={}
  $data.model:="gpt-3.5-turbo"
  $data.messages:=This.messages.copy()
  $data.messages.push({role: "user"; content: This.userPrompt})
	
  $opts:={method: "POST"; headers: $headers; body: $data}
	
  $request:=4D.HTTPRequest.new($url; $opts)
  $request.wait()
	
  This.fetchStatusCode:=$request.response.status
	
  If (This.fetchStatusCode=200)
    return $request.response.body.choices[0].message.content
  Else 
    return ""
  End if 

Se está habituado a usar a classe 4D.HTTPRequest, esta função não tem segredo para você (note que tem de usar a sua própria chave API após o registo). Nenhum segredo? Exceto pelas propriedades This.messages e This.userPrompt, usadas para consultar OpenAI, colocando-as no corpo do pedido.

Bem, é nestas duas propriedades que sua criatividade começa a funcionar. Dê uma olhada no construtor da classe para obter a resposta:

This.systemPrompt:="You are data generator. "
This.systemPrompt+="You will be provided with a description values to generate; and your task is to generate as many values as requested. "
This.systemPrompt+="Generated values must be separated by the character separator ¶. "
This.systemPrompt+="The list must start with 2 characters: ¶¶. "
This.systemPrompt+="The list must end with 2 characters: ¶¶. "
	
This.messages:=[]
This.messages.push({role: "system"; content: This.systemPrompt})
This.messages.push({role: "user"; content: "Generate a list of exactly 10 values for \"firstname\" of type Text."})
This.messages.push({role: "assistant"; content: "¶¶Alice¶Oliver¶Elsa¶Liam¶Maja¶Noah¶Ella¶Lucas¶Wilma¶Hugo¶¶"})
This.messages.push({role: "user"; content: "Generate a list of exactly 10 values for \"amount\" of type number."})
This.messages.push({role: "assistant"; content: "¶¶35¶64797¶101246¶3¶119¶4477¶647779¶357769¶94¶77¶¶"})
This.messages.push({role: "user"; content: "Generate a list of exactly 5 values for \"birthdate\" of type date."})
This.messages.push({role: "assistant"; content: "¶¶1980-10-05¶2035-05-02¶1995-12-15¶2022-10-14¶2011-05-23¶¶"})
	
This.userPrompt:="Generate a list of exactly "+String($quantity)+" values for \""+String($attributeName)+"\" of type "+This.attributeType+"."
This.userPrompt+=($remark#"") ? (" Remark: "+$remark) : ""
If ($attributeType="date")
  This.userPrompt+=". Date format: YYYY-MM-DD"
End if

Este conjunto de linhas tem 3 partes:

  1. Pedido do sistema: aqui define-se o contexto, o panorama geral. Aponta o modelo para a direção que quer que ele siga. Neste caso, escrevo um tipo de requisitos.
  2. Conversa preliminar: depois pode imitar uma conversa entre o usuário (você) e o assistente (a IA). Não se esqueça que a OpenAI é “apenas” um modelo generativo dedicado a fornecer respostas coerentes com o seu contexto. Ao escrever o início de uma discussão, aumenta as suas hipóteses de obter uma resposta estável. Aqui simulo 3 perguntas e respostas, para aumentar as minhas hipóteses de obter sempre uma resposta bem formatada, na quantidade desejada.
  3. Pedido do utilizador: esta é a pergunta real. Uma réplica das 3 perguntas simuladas anteriormente, mas desta vez a pergunta é inicializada com o que o usuário definiu na IU de demonstração.

Como descrito acima, o prompt do sistema, a conversa preliminar e o prompt do usuário são todos colocados em uma coleção $data, e enviados como o corpo do HTTPRequest para o OpenAI.

O resto é apenas a clássica divisão de strings.

Conclusões

Ao ver a demonstração e ao jogar com ela, perceberá que a consulta do OpenAI pode demorar algum tempo. Pode consultar https://status.openai.com/ se suspeitar de um período de inatividade. Um aspecto que tem muito impacto nos tempos de resposta: a quantidade de tokens na resposta da API. Quanto mais longas forem as respostas, mais lenta será a sua obtenção. Mas, em muitos casos, deixar a máquina funcionando, mesmo que por algum tempo, é mais rápido do que recolher, limpar e importar um conjunto de dados relevante.

Há espaço para otimização desta demonstração, de muitas formas. A API OpenAI oferece um modo de streaming que pode melhorar a sua experiência, permitindo que a geração de registos na base de dados comece muito mais depressa do que atualmente.

Esperamos que este exemplo o inspire! Veja a referência da API OpenAI, que está cheia de características interessantes e outros casos de utilização. Não hesite em contribuir e a enviar-nos sugestões!

Avatar
• Líder da equipe Produto 4D - Mathieu entrou a 4D em 2020 como líder de equipe de produtos. Sua equipe é composta por Proprietários de Produto, a voz dos usuários de 4D. Trabalhando lado a lado com o time de engenharia, seu papel implica na priorização, o alcance e a verificação de que as novas funcionalidades coincidam com as expectativas dos usuários de 4D. Mathieu atuou anteriormente como diretor de projetos e gerente de equipe em várias divisões de TI de indústrias líderes - automotriz, segurança, publicidade, especializado em contextos internacionais e serviços orientados à nuvem.