Importante

Você está vendo a versão anterior da nova experiência da Alura que estamos preparando para você. Em breve, ela ganha uma identidade visual novinha totalmente pensada em potencializar seus estudos!

1
resposta

Desafio final

import json
import os
import re
from groq import Groq

client = Groq(
    base_url="http://localhost:1234/v1",
    api_key="lm-studio"
)

def carregar_dados_txt(caminho_arquivo):
    linhas_lista = []
    with open(caminho_arquivo, "r", encoding="utf-8") as arquivo:
        for linha in arquivo:
            linha_limpa = linha.strip()
            if linha_limpa:
                linhas_lista.append(linha_limpa)
    return linhas_lista

def extrair_dados_com_llm(lista_resenhas):
    texto_entrada = "\n".join(lista_resenhas)
    
    prompt_sistema = (
        "Você é um assistente focado em extração de dados estruturados. "
        "Analise o texto fornecido onde cada linha contém 'id$usuario$resenha_original'. "
        "Para cada linha, extraia as informações e retorne EXCLUSIVAMENTE um array JSON de objetos válidos. "
        "Não adicione nenhuma explicação, texto complementar ou blocos de código Markdown. Retorne apenas o JSON puro. "
        "Cada objeto dentro do array JSON deve possuir exatamente as seguintes chaves:\n"
        "- 'usuario': Nome do usuário obtido na linha.\n"
        "- 'resenha original': O texto da resenha exatamente como escrito no idioma original.\n"
        "- 'resenha_pt': Tradução da resenha para o português do Brasil.\n"
        "- 'avaliacao': Classificação do sentimento estritamente como 'Positiva', 'Negativa' ou 'Neutra'."
    )
    
    completion = client.chat.completions.create(
        model="local-model",
        messages=[
            {"role": "system", "content": prompt_sistema},
            {"role": "user", "content": texto_entrada}
        ],
        temperature=0.1
    )
    
    resposta_raw = completion.choices[0].message.content.strip()
    return resposta_raw

def converter_para_dicionarios(json_string):
    json_limpo = re.sub(r'^```json\s*|```$', '', json_string, flags=re.MULTILINE).strip()
    return json.loads(json_limpo)

def processar_resultados(lista_dicionarios, separador=" | "):
    contagem_avaliacoes = {"Positiva": 0, "Negativa": 0, "Neutra": 0}
    strings_formatadas = []
    
    for item in lista_dicionarios:
        status_avaliacao = item.get("avaliacao", "Neutra")
        if status_avaliacao in contagem_avaliacoes:
            contagem_avaliacoes[status_avaliacao] += 1
        else:
            contagem_avaliacoes["Neutra"] += 1
            
        linha_formatada = (
            f"Usuário: {item.get('usuario')} "
            f"({item.get('avaliacao')}) -> "
            f"PT: {item.get('resenha_pt')}"
        )
        strings_formatadas.append(linha_formatada)
        
    string_unida = separador.join(strings_formatadas)
    return contagem_avaliacoes, string_unida

caminho_do_txt = "Resenhas_App_ChatGPT.txt"
dados_linhas = carregar_dados_txt(caminho_do_txt)

resposta_json_modelo = extrair_dados_com_llm(dados_linhas)
lista_de_dados = converter_para_dicionarios(resposta_json_modelo)
contagem, texto_consolidado = processar_resultados(lista_de_dados, separador="\n---\n")

print("=== a) Contagem das Avaliações ===")
print(contagem)

print("\n=== b) String unida ===")
print(texto_consolidado)
1 resposta

Oi, Julia! Como vai?

Agradeço por compartilhar seu código e sua solução para o desafio final com a comunidade Alura.

Seu projeto demonstra uma boa organização e aplica corretamente os conceitos vistos em Python: Inteligência Artificial Aplicada. A divisão do código em funções como carregar_dados_txt, extrair_dados_com_llm, converter_para_dicionarios e processar_resultados facilita tanto a leitura quanto a manutenção da aplicação. Esse tipo de estrutura é muito útil quando trabalhamos com processamento de resenhas com Inteligência Artificial, pois cada etapa fica responsável por uma tarefa específica, tornando o código mais reutilizável e simples de evoluir.

Um ponto que vale considerar é o tratamento de possíveis erros na conversão do retorno do modelo para JSON. Mesmo utilizando um prompt bem definido, um modelo local pode responder com algum texto inesperado. Adicionar um tratamento de exceções ajuda a identificar rapidamente o motivo do problema e evita que a aplicação seja interrompida durante a execução.

Veja este exemplo:


def converter_para_dicionarios(json_string):
    json_limpo = re.sub(r'^```json\s*|```$', '', json_string, flags=re.MULTILINE).strip()

    try:
        return json.loads(json_limpo)
    except json.JSONDecodeError as erro:
        print("Erro ao converter JSON")
        print(erro)
        return []

Esse código remove possíveis marcações Markdown, tenta converter a resposta para um objeto JSON e, caso ocorra algum erro, retorna uma lista vazia para que o restante do programa continue funcionando de forma controlada.

Outra sugestão é utilizar nomes de chaves sem espaços, como resenha_original. Essa prática facilita o acesso aos dados e torna o código mais padronizado ao longo do projeto.

No geral, seu desafio final ficou muito bem desenvolvido e demonstra uma boa compreensão do fluxo de leitura do arquivo, envio das informações para o modelo de linguagem, processamento das resenhas e análise dos resultados obtidos.

Para continuar evoluindo seu projeto, que tal experimentar incluir uma nova classificação ou gerar um resumo automático das resenhas utilizando Inteligência Artificial? Como você imagina que essa funcionalidade poderia enriquecer sua aplicação?