DEV Community

Cover image for Projeto J.A.R.V.I.S. - Como Criei um Assistente Virtual do Zero que Conversa e Executa Tarefas

Projeto J.A.R.V.I.S. - Como Criei um Assistente Virtual do Zero que Conversa e Executa Tarefas

Olá galera Dev!
Hoje quero compartilhar com a comunidade as últimas atualizações do meu projeto pessoal, que tem sido uma grande aventura no mundo da programação: meu assistente virtual, J.A.R.V.I.S., inspirado no assistente do Homem de Ferro.

Sempre tive o sonho de criar um assistente que interagisse comigo e me auxiliasse no dia a dia. Após muito estudo em desenvolvimento de software e programação, através de cursos, bootcamps e certificações, tive o insight de iniciar esse projeto. Combinando a API Google Gemini com um aplicativo Python que realiza reconhecimento de voz, texto para fala (text-to-speech) e fala para texto (speech-to-text), estou finalmente trazendo esse sonho à realidade.

O que é o J.A.R.V.I.S.?
O J.A.R.V.I.S. (Just A Rather Very Intelligent System) é um assistente virtual desenvolvido em Python, que combina diversas bibliotecas nativas e de terceiros para realizar tarefas automatizadas através de comandos de voz. A interface gráfica foi criada usando tkinter, e as funcionalidades incluem desde a abertura de aplicativos até a realização de buscas na web e a transcrição de textos.

Ao iniciar, o assitente faz uma paresentação inicial dizendo o texto abaixo:

"Bom dia Sr. Carlos, hoje é dataAtual, são horaAtual, a temperatura em seuEstado é de temperaturaAtual. Me chamo Jarvis, se precisar de mim, diga o meu nome.
Enter fullscreen mode Exit fullscreen mode

Image description

O assistente fica em modo de espera fazendo a captura de audio até que o usuário diga a palavra JARVIS, quando é dita o assistente retorna uma das sete resposta que adicionei para deixa-lo mais dinâmico, e depois aguarda que o usuário diga o qual dos comandos abaixo deseja que ele execute.

respostas = [
    "Como posso te ajudar?",
    "Sim senhor Carlos?",
    "Às suas ordens senhor?",
    "Pois não senhor?",
    "Estou aqui senhor?",
    "O que posso fazer pelo senhor?",
    "Pronto senhor?",
]
Enter fullscreen mode Exit fullscreen mode

Funcionalidades do J.A.R.V.I.S.
O J.A.R.V.I.S. é capaz de realizar uma série de comandos através de voz, que foram implementados para tornar o assistente mais interativo e útil no dia a dia. Abaixo, apresento todas as funcionalidades atribuidas ao meu assitente até o momento, vou criando e adiconando mais complexidade a medida que vou tendo insights, tornando-o mais completo:

Pesquisar na Web:

  • Pesquisar na Web: Ao dizer "Jarvis, pesquisar...", o assistente faz uma busca no Google utilizando a API Generative AI do Google com o que foi dito após a palavra pesquisar. Também criei um parâmetro no qual quando não é dito nada após a palavra pesquisar o assitente retorna uma pergunta perguntando o que eu desejo pesquisar. O comando é capturado e processado da seguinte forma:

  • Descrição: Realiza uma busca no Google sobre o termo solicitado e retorna uma resposta discursiva.

if "pesquisar" in comando:
   pesquisa = comando.split("pesquisar", 1)[1].strip()
   if pesquisa:
        self.label.config(text="Um momento, estou pesquisando.")
        falar("Um momento, estou pesquisando.")
        resposta = pesquisar_no_google(pesquisa)
        falar(resposta)
   else:
       self.label.config(text="Sobre o que deseja saber?")
       falar("Sobre o que deseja saber?")
       with sr.Microphone() as source:
           audio = microfone.listen(source)
      try:
          pesquisa = microfone.recognize_google(audio, language="pt-BR")
          self.label.config(text="Só um momento, estou pesquisando.")
          falar("Só um momento, estou pesquisando.")
          resposta = pesquisar_no_google(pesquisa)
          falar(resposta)
      except sr.UnknownValueError:
          self.label.config(text="Não consegui entender a pesquisa.")
          falar("Não consegui entender a pesquisa.")

Enter fullscreen mode Exit fullscreen mode

Modo Conversa:

  • Comando de voz: "Iniciar modo conversa"

  • Descrição: Entra em um modo onde o J.A.R.V.I.S. pode manter uma conversa contínua sobre diversos tópicos até que o usuário decida encerrar, utilizando o comando "encerrar modo conversa".

Abrir YouTube:

  • Comando de voz: "Abrir YouTube"

  • Descrição: Solicita o nome de uma música e abre a busca correspondente no YouTube, conforme detalharei melhor em explicão abaixo desta funcionalidade.

Consultar Temperatura:

  • Comando de voz: "Qual a temperatura em [cidade]"

  • Descrição: Informa a temperatura atual em uma cidade específica utilizando a API do OpenWeather, a conexão com esta API explico melhor na parte final deste artigo, porém segue abixo como utilizo esta solicitação de temperatura na estrutura de decisão.

elif "Qual a temperatura em" in comando:
    cidade = comando.split("Qual a temperatura em", 1)[1].strip()
    clima = obter_temperatura(cidade)
    falar(clima)
    print(clima)
Enter fullscreen mode Exit fullscreen mode

Consultar Previsão do Tempo:

  • Comando de voz: "Previsão do tempo em [cidade]"

  • Descrição: Fornece a previsão do tempo para o dia seguinte na cidade informada.

Abrir Navegador:

  • Comando de voz: "Abrir navegador"

  • Descrição: Abre o navegador padrão do sistema.

Abrir Calculadora:

  • Comando de voz: "Abrir calculadora"

  • Descrição: Abre a calculadora do sistema.

Abrir Paint:

  • Comando de voz: "Abrir Paint"

  • Descrição: Abre o Microsoft Paint.

Abrir Bloco de Notas:

  • Comando de voz: "Abrir bloco de notas"

  • Descrição: Abre o Bloco de Notas do sistema.

Abrir Excel:

  • Comando de voz: "Abrir Excel"

  • Descrição: Abre o Microsoft Excel.

Abrir Word:

  • Comando de voz: "Abrir Word"

  • Descrição: Abre o Microsoft Word.

Abrir CMD:

  • Comando de voz: "Abrir CMD"

  • Descrição: Abre o Prompt de Comando do Windows.

Consertar Internet:

  • Comando de voz: "Consertar internet"

  • Descrição: Inicia o solucionador de problemas de rede do Windows.

Consultar Horário:

  • Comando de voz: "Que horas são"

  • Descrição: Informa o horário atual.

Consultar Data:

  • Comando de voz: "Que dia é hoje"

  • Descrição: Informa a data atual.

Transcrever Texto:

  • Comando de voz: "Transcrever"

  • Descrição: Converte um comando de voz em texto e salva em um arquivo no desktop.

Desligar Sistema:

  • Comando de voz: "Desligar sistema"

  • Descrição: Finaliza a execução do J.A.R.V.I.S. e encerra o programa.

Como foram implementadas algumas da funções principais do J.A.R.V.I.S.

Interface Gráfica com Tkinter
Para criar a interface gráfica do J.A.R.V.I.S., utilizei a biblioteca tkinter. O código cria uma janela simples com um botão para iniciar o assistente e um círculo animado que muda de cor conforme o assistente "fala". O círculo foi desenhado em um Canvas, e a animação ocorre por meio de um loop que ajusta as coordenadas do círculo, simulando um movimento pulsante.

self.root = root
self.root.title("Jarvis")
self.root.geometry("200x190")
bg_color = "#006400"
fg_color = "#000000"
self.root.configure(bg=bg_color)
Enter fullscreen mode Exit fullscreen mode

Essas linhas definem o layout básico da janela, enquanto o botão para iniciar o assistente é configurado da seguinte maneira:

self.btn_iniciar = tk.Button(root, text="Iniciar Assistente", command=self.iniciar_assistente, bg=fg_color, fg=bg_color)
Enter fullscreen mode Exit fullscreen mode

Quando o botão é pressionado, o assistente é iniciado em uma thread separada para garantir que a interface continue responsiva.

Síntese de Voz e Reconhecimento de Fala
O motor de síntese de voz é criado usando a biblioteca pyttsx3, que permite que o assistente "fale" as respostas. O código a seguir inicializa o motor e define a função para falar:

engine = pyttsx3.init()
def falar(texto):
   engine.say(texto)
   engine.runAndWait()
Enter fullscreen mode Exit fullscreen mode

Para o reconhecimento de fala, utilizei a biblioteca speech_recognition. Ela permite capturar áudio do microfone e transcrever em texto usando a API do Google:

microfone = sr.Recognizer()
with sr.Microphone() as source:
   audio = microfone.listen(source)
   comando = microfone.recognize_google(audio, language="pt-BR")
Enter fullscreen mode Exit fullscreen mode

Implementação de Busca no YouTube
O assistente também pode buscar vídeos no YouTube. Isso é feito através da API do YouTube Data, onde uma consulta é feita e o link do vídeo é retornado. A implementação básica seria algo assim:

query = "o que você quer buscar"
search_url = f"https://www.googleapis.com/youtube/v3/search?part=snippet&q={query}&key=sua_chave_api"
response = requests.get(search_url)
Enter fullscreen mode Exit fullscreen mode

O J.A.R.V.I.S. então captura o link do primeiro resultado e o abre no navegador.

Como Obter e Configurar as APIs do OpenWeather e Google
Para integrar APIs ao J.A.R.V.I.S., é fundamental saber como obter as chaves e configurá-las corretamente. Abaixo, explico o processo para obter e configurar as APIs do OpenWeather e Google, com exemplos práticos de uso no código e de forma gratis. Porém deve ser evitada a divulgação de suas chaves API para terceiros, pois não sabemos como se manterá as políticas de gratuitidade de uso destas APIs ao longo do tempo.

Criação e Implementação da API de Previsão do Tempo
Neste Projeto usei a API do OpenWeather para obter informações sobre o clima. Após configurar a chave API, o J.A.R.V.I.S. pode fazer requisições HTTP para obter dados como temperatura e previsão do tempo para uma localização específica de forma gratuita e em tempo real, conforme o implementado na parte de código exemplificada abaixo:

api_key = "sua_chave_api"
base_url = "http://api.openweathermap.org/data/2.5/weather?"
cidade = "São Paulo"
complete_url = base_url + "appid=" + api_key + "&q=" + cidade + "&units=metric"
response = requests.get(complete_url)
Enter fullscreen mode Exit fullscreen mode

Essas informações são então processadas e comunicadas ao usuário através da síntese de voz.

Como Obter a Chave API do OpenWeather

Acesse o Site: Vá até o site do OpenWeather. - https://openweathermap.org/

  • Crie uma Conta: Se você ainda não possui uma conta, crie uma gratuitamente.

  • Obtenha a Chave de API: Após fazer login, navegue até a seção de "API Keys" no seu painel de usuário.

  • Clique em "Create Key" para gerar uma nova chave.

  • Anote a Chave: A chave gerada será usada em suas requisições para acessar os dados de previsão do tempo.

Criação e Implementação da API do Google
Para permitir que o J.A.R.V.I.S. realize pesquisas na web e interaja em modo conversa, utilizei a API Generative AI do Google. É necessário configurar uma chave API para autenticar as requisições.

Essa chave permite que o assistente envie consultas ao Google e receba as respostas que são posteriormente sintetizadas em voz.

Obtenção e Configuração da API do Google

  • Acesse o Google AI Studio: Vá até o site do Google AI Studio. - https://aistudio.google.com/app/apikey

  • Crie uma Conta ou Faça Login: Use sua conta Google para acessar a plataforma.

  • Obtenha a Chave de API: No painel, você poderá criar uma nova chave de API que será usada para acessar os serviços da Google AI.

  • Configure a Chave no Código: Utilize a chave gerada para configurar as requisições do seu assistente.

Exemplo de Configuração no Código:

Configurei uma API do google para realizar buscas com respostas estilizadas. Coloquei toda esta implematção dentro de uma função que é chamada quando é feito é iniciado o modo pesquisa ou modo conversa nas funcionalidades do assitente passando como parâmetros a fala do usuário a qual ele deseja pesquisar.

Para garantir uma resposta mais acertiva, passo na pesquisa elém da solicitação do usuário, as regras que vão junto da solicitação a ia do goole para obter uma resposta mais assertiva, conforme explicado no código abaixo:

def pesquisar_no_google(pesquisa):
   regras = """
   > Resposta em forma discursiva sem falar os asteristicos que fazem o negrito das respostas,
   > Você é o Jarvis, assistente pessoal do Carlos,
   > Use o mesmo tipo de humor do Jarvis IA do homem de ferro,
   > Se limite a respostas objetivas entre 20 a 40 palavras dependendo da complexidade da pergunta e responda a questão:"""

   # Configurando a API do Google
   google_api_key = "sua_chave_de_api_aqui"
   genai.configure(api_key=google_api_key)

   # Configurando a Temperatura das Respostas
   configurar_geracao = {
       "candidate_count": 1,
       "temperature": 0.9,
   }

   # Configurando os Níveis de Segurança das Respostas
   configurar_seguranca = {
       "HARASSMENT": "BLOCK_NONE",
       "HATE": "BLOCK_NONE",
       "SEXUAL": "BLOCK_NONE",
       "DANGEROUS": "BLOCK_NONE",
   }

   # Definindo o Modelo Usado para Pesquisa
   model = genai.GenerativeModel(
       model_name="gemini-1.0-pro",
       generation_config=configurar_geracao,
       safety_settings=configurar_seguranca,
   )

   # Configurando o Histórico de Pesquisa
   chat = model.start_chat(history=[])
   response = chat.send_message(regras + pesquisa)

   return response.text
Enter fullscreen mode Exit fullscreen mode

Configurações Específicas:
Modelo: Defino o modelo utilizado como o gemini-1.0-pro;
**Temperatura: **Ajustada para 0.9 para permitir respostas mais criativas.
**Níveis de Segurança: **Configurados para não bloquear qualquer conteúdo ofensivo, garantindo respostas sem filtros, caso seja necessário obter informações deste tipo de informações.

Conclusão
Esse projeto começou sem grandes pretensões, mas tem se tornado uma plataforma para testar e implementar novas funcionalidades à medida que avanço em minha jornada de aprendizado. Quem sabe, um dia, eu consiga ter um J.A.R.V.I.S. tão poderoso quanto o do Homem de Ferro!

Segue o link do repositório onde está todo o código deste projeto para ser clonado e utilizado por você para aprimora-lo e adpata-lo ao seu dia a dia: https://github.com/Carlos-CGS/Projeto_J.A.R.V.I.S./tree/main

"Vamos Disseminar os Conhecimentos e Transbordar tudo o que Aprendemos!"

Para acompanhar meu trabalho, sigam minhas redes sociais, onde posto conteúdos semanais:

LinkedIn: https://www.linkedin.com/in/carlos-cgs/

GitHub: https://github.com/Carlos-CGS

Top comments (0)