1
resposta

[Projeto] Duvida com desafio de Inteligência Artificial Aplicada com Python

Gostaria de saber se alguém tem alguma sugestão/critica ao meu código. No momento ele não esta retornando a resposta da LLM de forma correta (sempre falta ou duplica alguma das resenhas). Acredito que o problema seja no prompt, que ja mudei varias vezes, alem de testar o gemma 1B e 2B com varias temperatures diferentes. Porem de resto acredito que ele esteja funcional, falta apenas tratar com try except em caso de erros com o json.loads, por exemplo. Qualquer ajuda e bem vinda, obrigado.
.txt de entrada: https://cdn3.gnarususercontent.com.br/4790-python/Resenhas_App_ChatGPT.txt

Imports

import pandas
from openai import OpenAI
import json
import re

Abre o resenhas.txt e salva cada linha como um item da lista_resenhas.

def passo_1(): ### Retorna lista_resenhas.
lista_resenhas = []
with open("resenhas.txt", "r", encoding="utf-8") as txt_resenhas:
for linha in txt_resenhas:
lista_resenhas.append(linha.replace("\n", ''))
return lista_resenhas

Define o client_openai com o endereco do LM Studio

def iniciar_ia(): ### Retorna client_openai
client_openai = OpenAI(
base_url="http://127.0.0.1:1234/v1",
api_key="lm-studio"
)
return client_openai

Envia o prompt com a lista_resenhas para o LM Studio.

Prompt: pede que separe cada item da lista em formato de JSON.

def passo_2(client_openai, lista_resenhas): ### Retorna json_llm
resposta_do_llm = client_openai.chat.completions.create(
model="google/gemma-3-1b",
messages=[
{"role": "user", "content": f"""A partir da lista em python,
retorne um texto em formato de documento JSON valido. Este texto
deve separar cada item dessa lista em 5 partes:
'codigo' (codigo que antecede o nome de usuario),
'usuario'(nome do usuario sem o codigo),
'resenha_original' (resenha original),
'resenha_pt'(resenha traduzida para o portugues),
'avaliacao'(Positiva, Negativa ou Neutra).
VOCE deve decidir qual das 3 classificacoes escolher para cada resenha

    Utilize apenas esta lista: {lista_resenhas}
    IMPORTANTE: Faca isso para TODOS os itens da lista 
    SEM REPETIR OU PULAR NENHUM, mantendo a ordem original.
    use APENAS JSON válido com aspas duplas, na mesma ordem 
    da lista, não invente, não repita, não omita.
     """}
],
temperature=0.5
)
json_llm = resposta_do_llm.choices[0].message.content
return json_llm

Limpa json_llm e transforma em uma lista de dicionarios

def passo_3(json_llm):### Retorna lista_dicionarios
#limpar json_llm
lista_llm_limpa = json_llm.replace("json", "").replace("", "").strip()

#transformar lista limpa em lista de dicionarios
match = re.search(r'\[.*\]', lista_llm_limpa, re.S)  # re.S = considera que '.' pega quebras de linha
if match:
    json_llm_texto = match.group(0)  # string só com o JSON válido
    lista_dicionarios = json.loads(json_llm_texto)
    return lista_dicionarios
else:
    print("Nenhum JSON encontrado")

Percorre a lista_dicionarios e conta quantas avaliacoes pos, neg e neutr

def passo_4(lista_dicionarios):###
quantidade_positiva = 0
quantidade_negativa = 0
quantidade_neutra = 0

for a in lista_dicionarios:
    avaliacao = a.get("avaliacao", "").strip().lower()  # remove espaços e ignora maiúsculas

    if avaliacao in ("positiva", "positivo"):
        quantidade_positiva += 1
    elif avaliacao in ("negativa", "negativo"):
        quantidade_negativa += 1
    elif avaliacao in ("neutra", "neutro"):
        quantidade_neutra += 1

print(
    f"Quantidade de avaliações positivas: {quantidade_positiva} \n"
    f"Quantidade de avaliações negativas: {quantidade_negativa} \n"
    f"Quantidade de avaliações neutras: {quantidade_neutra} \n"
)

sep_kv = "="

texto = "\n \n".join(
    "\n".join(f"{k}{sep_kv}{v}" for k, v in d.items())
    for d in lista_dicionarios
)
print(texto)

def main():
lista_resenhas = passo_1()#----------------------#1
print(f"LOG 1:\n {lista_resenhas}\n")
client_openai = iniciar_ia()#--------------------#client
print(f"LOG 2:\n IA iniciada.\n")
json_llm = passo_2(client_openai, lista_resenhas)#2
print(f"LOG 3:\n {json_llm}\n")
lista_dicionarios = passo_3(json_llm)#-----------#3
print(f"LOG 4:\n {lista_dicionarios}\n")
passo_4(lista_dicionarios)#----------------------#4

main()

1 resposta

Oi, Yuri! Como vai?

Agradeço por compartilhar seu código com a comunidade Alura.

Do jeito que você explicou, ficou bem legal como você separou o fluxo em passo_1 até passo_4, deixando claro onde entra o OpenAI(base_url=...) e onde acontece o json.loads. Um ponto importante neste ponto é que LLMs podem omitir ou duplicar itens em saídas longas, então ajuda muito pedir um array JSON com um id (índice) por item e validar depois pelo tamanho e pelos índices.

Outra dica interessante para o futuro é pedir ao modelo para devolver id + campos, e depois conferir se veio de 0 até n-1 sem repetição, antes de seguir o processamento. Veja este exemplo:


import json

def validar_itens(json_texto, n):
    dados = json.loads(json_texto)  # converte texto JSON em lista de dicts
    ids = [item.get("id") for item in dados]
    faltando = [i for i in range(n) if i not in ids]
    repetidos = [i for i in set(ids) if ids.count(i) > 1]
    return faltando, repetidos

Esse código faz o json.loads e verifica itens faltando e itens repetidos comparando os id com o tamanho esperado da lista.

Alura Conte com o apoio da comunidade Alura na sua jornada. Abraços e bons estudos!