Adicionar src-py/renatoxsr/scripts/avaliar_dataset.py
This commit is contained in:
@@ -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()
|
||||
Reference in New Issue
Block a user