terça-feira, 30 de dezembro de 2025

Sistema inteligente de gestão de documentos (com Python, SQLite3, QT Designer, PySide6 e LLMLite)

1. O problema

Um colega de Ministério Público, integrante de um grupo de atuação especial, disse-me numa conversa casual que vinha tendo muito trabalho nas prorrogações de prazos de inquéritos civis.

Nessas ocasiões, ele precisava fazer um relatório minucioso de tudo que havia sido incorporado aos autos, o que se afigurava bastante desafiador, considerados o volume de documentos, a complexidade dos procedimentos e a quantidade de casos sob sua responsabilidade.

Imaginei que o problema poderia ser mitigado se a inclusão de documentos aos expedientes pudesse ser registrada uma a uma, ao longo do tempo, num sistema que os resumisse automaticamente, com o uso de inteligência artificial, e que, no momento oportuno, gerasse o relatório desejado.

Prototipei essa ideia no recesso forense de 2025/2026 e compartilho por aqui todo o código e o aprendizado acumulado.


2. O programa

O programa concebido consiste numa aplicação desktop que registra cada inclusão de documento a algum procedimento, no momento em que ela acontece.

Na tela principal, o usuário localiza o procedimento em curso ou cadastra um novo. Seguindo, carrega o documento a ele relacionado e que será juntado aos autos. Uma chamada à LLM permite que a solução identifique automaticamente a natureza do documento e apresente o resumo estruturado de seu conteúdo, de acordo com o prompt definido num arquivo ".env", que também contém a chave da API. O usuário poderá editar esses campos antes de salvar o registro.

O sistema disponibiliza consultas ou gera relatórios editáveis dos documentos incorporados a determinado procedimento, por ordem cronológica, ou dos documentos cadastrados, independentemente do procedimento, também por ordem cronológica.


3. Tecnologias empregadas

O programa foi escrito em Python, linguagem de alto nível e de propósito geral. 

Para o banco de dados, optamos pelo SQLite3, que é leve e armazena os dados em um único arquivo em disco. 

A interface gráfica foi gerada pelo Qt Designer. Para a conexão da GUI com a lógica do programa, usamos o PySide6

Para as chamadas à API de IA Generativa, optamos pelo LiteLLM, que funciona como uma camada de abstração que facilita o intercâmbio de provedores de LLM (com a mesma sintaxe, pode-se  fazer idênticas requisições para os principais provedores do mercado).

Assim sendo, tudo o que você precisa fazer para rodar o programa é instalar as bibliotecas citadas, lembrando que o SQLite3 já está integrado nativamente ao Python.

pip install PySide6 litellm

O Qt Designer é instalado, automaticamente, com o pacote PySide6. Normalmente você consegue acessá-lo digitando, desde que esteja no ambiente nos quais foram instalados os pacotes mencionados:

pyside6-designer

Acrescente a biblioteca python-dotenv se você pretende que a API-KEY e outras variáveis, incluindo o prompt, sejam configuradas no arquivo .env. Neste caso, digite:

pip install python-dotenv

Um arquivo .env poderia conter o seguinte:

# Configurações do usuário

pasta_relatorios = '~\\Downloads'

modelo_selecionado = 'gpt-5-mini'

OPENAI_API_KEY = 'sk-XYZ...'

prompt = 'Atue como um Analista Jurídico especializado. Sua análise deve ser estritamente técnica, objetiva e precisa, utilizando o vocabulário jurídico adequado ao documento fornecido (laudos, decisões, BOs ou procedimentos).\n\nREGRAS DE FORMATAÇÃO E CONTEÚDO:\n1. ESTRUTURA: O resumo deve ter exatamente 4 parágrafos de texto corrido. Não utilize bullet points ou listas.\n2. PARÁGRAFO 1 (Visão Geral): Descreva a natureza do documento, sua origem e como ele está estruturado formalmente.\n3. PARÁGRAFO 2 (Tópicos): Analise detalhadamente as questões tratadas em cada divisão ou tópico do texto original.\n4. PARÁGRAFO 3 (Conclusão): Apresente uma síntese fundamentada que resuma o teor e o desfecho do documento.\n5. PARÁGRAFO 4 (Pendências): Indique apenas pendências que estejam escritas de forma explícita. Se não houver menção direta a providências futuras ou pendências, escreva: \'Não constam pendências explicitamente informadas no documento\'.\n\nDIRETRIZES CRÍTICAS:\n- Use e referencie os termos técnicos encontrados no próprio documento.\n- Proibido inferir, deduzir ou interpretar fatos não escritos. Se não souber ou não constar, não invente.\n- Mantenha um tom impessoal e profissional.\n- Não use bullet points, listas ou formatações especiais.'

4. Arquitetura

A arquitetura do programa foi orientada pelo MVC, que consiste na concepção do sistema em três camadas com responsabilidades distintas: o Model, responsável pelo gerenciamento dos dados e regras de negócio; a View, que cuida da interface e da interação com o usuário; e o Controller, que atua como intermediário, processando as ações do usuário e coordenando a comunicação entre o modelo e a interface.

5. Modelagem dos dados (Model)

Estruturamos o banco de dados em duas tabelas relacionadas: procedimentos e documentos.

A tabela procedimentos contém o conjunto de procedimentos administrativos, mediante a inserção de um número identificador único e a natureza do procedimento. A tabela documentos armazena os registros de documentos individuais por meio de seus títulos e resumos, incluindo automaticamente a data de criação de cada registro.

Utiliza-se o relacionamento de "um para muitos", vinculando cada documento a um procedimento específico através de uma Chave Estrangeira (Foreign Key), que aponta para a Chave Primária da tabela de procedimentos. Pela regra de integridade configurada (ON DELETE SET NULL), caso um procedimento seja excluído, os documentos associados a ele permanecem no sistema com o vínculo removido (campo preenchido como nulo), preservando-se o histórico documental.

As tabelas podem ser geradas pelo código SQL abaixo, que vem precedido da ativação do suporte a chaves estrangeiras:

-- Habilita o suporte a chaves estrangeiras no SQLite     PRAGMA foreign_keys = ON; 

-- Tabela: procedimentos
    CREATE TABLE IF NOT EXISTS procedimentos (
        id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, 
        numero TEXT NOT NULL UNIQUE, 
        descricao TEXT
    );

-- Tabela: documentos
    CREATE TABLE IF NOT EXISTS documentos (
        id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, 
        titulo TEXT NOT NULL, 
        resumo TEXT, 
        data_criacao TEXT DEFAULT CURRENT_TIMESTAMP, 
        procedimento TEXT REFERENCES procedimentos (numero) ON DELETE SET NULL
    );
   

6. Montando a interface (View)

As interfaces (tela principal e tela de cadastro) foram desenhadas com o Qt Designer. Esse programa permite que os componentes sejam arrastados para as janelas e nela posicionados de forma prática e direta.


As telas criadas são salvas no formato "ui". 

O PySide6 possui método para converter o arquivo "ui" em "py", embora isso não seja estritamente necessário. Para isso, digite:

pyside6-uic <seu_arquivo.ui> -o <seu_arquivo.py>

Obtido o arquivo "py" da interface, você pode se dedicar ao arquivo main.py e escrever a lógica do programa. Assegure-se de importar a classe MainWindow do arquivo "py" gerado pelo PySide6, para estabelecer as conexões entre botões e campos e funções do programa.

O "esqueleto" do main.py é o seguinte.

import sys
from PySide6.QtWidgets import QApplication, QMainWindow
from ui import Ui_MainWindow 

class MainWindow(QMainWindow, Ui_MainWindow):

    def __init__(self):
        super().__init__()
        self.setupUi(self)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    app.setStyle("Fusion")
    window = MainWindow()
    window.show()
    sys.exit(app.exec())

Ao executá-lo, você já poderá visualizar a sua janela em loop.


7. Ligando a interface ao BD (Controller)

Para criar a lógica do programa, precisamos entender duas coisas:
  • As conexões devem ser feitas preferencialmente dentro do método __init__, logo após a chamada do self.setupUi(self). Isso garante que todos os widgets já foram criados antes de você tentar conectar algo a eles.
  • As funções que executam a lógica (ex: o que acontece ao clicar em um botão) devem ser criadas como métodos da classe. Isso permite que elas acessem os elementos da interface através do self.
Na prática, isso acontece assim:

import sys
from PySide6.QtWidgets import QApplication, QMainWindow
from ui import Ui_MainWindow 

class MainWindow(QMainWindow, Ui_MainWindow):
    
    def __init__(self):
        super().__init__()
        self.setupUi(self)
        
        # --- CONEXÕES ---
        self.botao_enviar.clicked.connect(self.ao_clicar_no_botao)

    # --- DEFINIÇÃO DAS FUNÇÕES (COMO MÉTODOS DA CLASSE) ---

    def ao_clicar_no_botao(self):
        print("O botão foi clicado!")

        # EXEMPLO DE ACESSO A OUTROS WIDGETS:
        # texto = self.campo_input.text()

A maior complexidade reside na exibição e edição da tabela documentos, da qual são extraídos os relatórios. A estratégia se aproveita da classe QSqlTableModel do Qt, que funciona como um intermediário reativo entre o banco de dados e a interface gráfica. Essa abordagem permite que a tableView reflita automaticamente o conteúdo da tabela "documentos", simplificando a implementação de filtros dinâmicos através do método setFilter. Sempre que um critério de busca é alterado no sistema, o comando select() é invocado para sincronizar a visualização com o estado atual do banco de dados, garantindo que o usuário visualize apenas as informações pertinentes de forma eficiente.

Para a atualização e inserção de registros, o código adota uma abordagem híbrida: permite a edição direta de células na interface via OnFieldChange e utiliza a classe QSqlQuery com prepared statements para cadastrar novos procedimentos e documentos. Após cada inserção, o método select() do modelo é chamado novamente para atualizar a grade de exibição, mantendo a consistência entre o que está armazenado no SQLite3 e o que é apresentado na tela.

8. Conclusão

A criação deste protótipo funcional é um exemplo claro de como ferramentas de IA podem contribuir para a otimização de fluxos de trabalho e economia de tempo, liberando o Promotor de Justiça para tarefas mais estratégicas e de maior relevância.

Atualmente, soluções tecnológicas pontuais costumam surgir na ponta, criadas por quem lida diariamente com a burocracia e já experimenta ferramentas de IA e low-code voltadas para o usuário final. Nesse cenário, cabe aos departamentos de TI focar sua atuação na sustentação dos sistemas do core business, na governança de dados e na integração harmoniosa com essa nova realidade.

Como trabalho futuro, poderíamos incorporar ao sistema a busca semântica de documentos, incorporando a técnica de RAG (Retrieval-Augmented Generation) ao banco de dados.


Código

Você encontra o código completo dessa aplicação em: https://github.com/jespimentel/pj_docs

Não se esqueça de acrescentar o arquivo .env, nos moldes sugeridos acima.

terça-feira, 23 de dezembro de 2025

Instalação do Python e do gerenciador de pacotes uv em equipamento funcional (sem privilégios de administrador)

 1. Instalação do Python

- Abra a Microsoft Store e pesquise por Python.

- Selecione a versão desejada (ex: Python 3.13) e clique em Adquirir ou Instalar. A instalação via Microsoft Store não exige privilégios de administrador.




2. Instalação do uv

- Abra o Prompt de Comando.

- Execute o comando: 

pip install uv --user 

(o parâmetro --user garante a instalação apenas para o seu usuário atual).


3. Localização do Executável uv

- Como a instalação é local, você precisa encontrar onde o arquivo uv.exe foi salvo para adicioná-lo ao seu caminho de sistema (Path):

- No Prompt, para ver o local da instalação, digite:

pip show uv


- Copie o caminho indicado em "Location" e cole no Explorador de Arquivos.

- Suba um nível de pasta até encontrar a pasta Scripts, onde estará o arquivo uv.exe.

- Copie o caminho completo desta pasta Scripts (exemplo: C:\Users\...\Python313\Scripts) para o bloco de notas. Você pode usar o botão direito do mouse para isso.




4. Configuração das Variáveis de Ambiente

- Pressione a tecla Windows e pesquise por "Editar as variáveis de ambiente para sua conta".


- Selecione a variável Path e clique em Editar.

- Adicione o caminho da pasta Scripts que você copiou anteriormente. Importante: não inclua o nome do arquivo uv.exe, apenas o caminho da pasta.

5. Verificação Final

- Feche e reabra o Prompt de Comando.

- Digite uv e pressione Enter. Se a lista de comandos aparecer, a instalação foi concluída com sucesso.