Adicionar src-py/renatoxsr/scripts/avaliar_dataset.py

This commit is contained in:
2026-09-24 17:44:18 -03:00
parent 25c0517cf7
commit 80427878f7
+143
View File
@@ -0,0 +1,143 @@
#vim: ts=4 sw=4 et ft=python :
import requests
import json
from pathlib import Path
# --- CONFIGURAÇÕES ---
OLLAMA_URL = "http://192.168.14.20:11434/api/generate"
MODEL_NAME = "gemma4:e4b"
INPUT_FILE_PATH = Path("dataset.jsonl")
OUTPUT_FILE_PATH = Path("avaliado.jsonl")
# O System Prompt que criamos, definido como a regra mestra.
SYSTEM_PROMPT = """
Você é um Assistente Jurídico Sênior e especialista em Direito brasileiro. Sua função é realizar uma análise técnica, crítica e altamente estruturada de documentos jurídicos. Você deve manter o tom de voz de um profissional qualificado, objetivo e conciso.
SEU OBJETIVO: Analisar o documento jurídico fornecido e extrair quatro informações cruciais.
REGRAS OBRIGATÓRIAS:
1. Tom: O tom de todas as respostas deve ser técnico, formal e imparcial.
2. Formato: A saída deve ser ESTREITAMENTE um objeto JSON válido. Nenhum texto introdutório, explicação ou texto fora do JSON é permitido.
3. Detalhe: Mantenha a clareza e a profundidade técnica em todos os campos.
AS CHAVES E AS REGRAS DE CADA CAMPO:
(1) `tipo`: Deve identificar a categoria jurídica principal do documento (ex: Contrato de Prestação de Serviços, Petição Inicial, Escritura Pública, Contrato de Compra e Venda, Procuração Ad Judicia). Seja o mais específico possível.
(2) `resumo`: Um resumo executivo do objeto do documento, contendo no máximo 3 frases. Deve ser extremamente conciso, focado no tema central.
(3) `argumentos`: Lista em formato de array (JSON array) dos principais pontos jurídicos, premissas ou teses argumentativas que sustentam o documento.
(4) `qualidade`: Avaliação da qualidade do documento sob o ponto de vista técnico-jurídico. Você deve escolher *somente* um dos seguintes termos: "ótimo", "bom" ou "médio".
* "Ótimo": Documento juridicamente impecável, claro, completo e em conformidade com a melhor prática do direito.
* "Bom": Documento funcional, com clareza e cobertura dos pontos principais, mas pode ter pequenas imprecisões ou omissões.
* "Médio": Documento que apresenta falhas significativas de linguagem, inconsistências jurídicas graves ou que não cumpre seu propósito principal sem intervenção.
"""
def get_llm_response(prompt_full: str) -> str:
"""
Envia o prompt para o Ollama local e retorna a resposta em string.
"""
print("🤖 Enviando requisição para o Ollama...")
try:
payload = {
"model": MODEL_NAME,
"prompt": prompt_full,
"options": {
"temperature": 0.1, # Temperatura baixa para respostas determinísticas e factuais
"num_predict": 2048 # Aumenta o limite de tokens
}
}
response = requests.post(OLLAMA_URL, json=payload)
response.raise_for_status() # Levanta exceção para códigos de erro HTTP
# O Ollama retorna os resultados dentro do campo 'response'
return response.json()['response'].strip()
except requests.exceptions.ConnectionError:
print("\n" + "="*80)
print(f"❌ ERRO DE CONEXÃO: Não foi possível conectar ao Ollama em {OLLAMA_URL}.")
print("Por favor, verifique se o serviço Ollama está rodando e se a porta e o IP estão corretos.")
print("="*80 + "\n")
return None
except requests.exceptions.RequestException as e:
print(f"\n❌ ERRO GERAL ao comunicar com a API: {e}")
return None
def run_evaluation_cycle():
"""
Processa o arquivo e executa a análise para cada documento.
"""
if not INPUT_FILE_PATH.exists():
print(f"ERRO: Arquivo de entrada '{INPUT_FILE_PATH.name}' não encontrado. Execute o passo anterior primeiro.")
return
print(f"Iniciando a avaliação de {INPUT_FILE_PATH.name} contra o modelo {MODEL_NAME}...")
results = []
try:
with open(INPUT_FILE_PATH, 'r', encoding='utf-8') as f:
lines = f.readlines()
except Exception as e:
print(f"Erro ao ler o arquivo: {e}")
return
for i, line in enumerate(lines):
try:
data = json.loads(line.strip())
markdown_content = data.get("markdown", "")
if not markdown_content:
continue
# 1. Montar o Prompt Completo
full_prompt = f"""
DOCUMENTO JURÍDICO PARA ANÁLISE:
---
{markdown_content}
---
"""
# 2. Adicionar o prompt ao System Prompt
final_prompt = f"{SYSTEM_PROMPT}\n\n{full_prompt}"
# 3. Chamar o LLM
llm_output = get_llm_response(final_prompt)
# 4. Estruturar e Salvar Resultados
if llm_output:
result_record = {
"hash": data.get("hash", "unknown_id"),
"documento_original": markdown_content[:200] + "...", # Trunca para melhor visualização
"resultado_ollama": llm_output
}
results.append(result_record)
print(f"[{i+1}/{len(lines)}] ✅ Processado com sucesso. Salvando resultado.")
else:
results.append({
"hash": data.get("hash", "unknown_id"),
"documento_original": markdown_content[:200] + "...",
"resultado_ollama": "FALHA: Verifique os logs de erro acima."
})
print(f"[{i+1}/{len(lines)}] ❌ FALHA no processamento.")
except json.JSONDecodeError:
print(f"AVISO: Linha {i+1} inválida JSON encontrada e pulada.")
except Exception as e:
print(f"ERRO inesperado ao processar a linha {i+1}: {e}")
# Salvando todos os resultados
if results:
with open(OUTPUT_FILE_PATH, 'w', encoding='utf-8') as f:
for record in results:
f.write(json.dumps(record, ensure_ascii=False) + '\n')
print("\n=======================================================================")
print("✅ Avaliação concluída!")
print(f"Total de documentos processados e salvos em: {OUTPUT_FILE_PATH.name}")
print("Examine este arquivo para identificar padrões de erro ou sucesso.")
print("=======================================================================")
# Executar o ciclo completo
run_evaluation_cycle()