sábado, 11 de julho de 2026

Roteiro de automação com Skills no VS Code + Claude Code

Neste post, vou mostrar o passo a passo de uma automação completa feita com o auxílio do Claude Code, rodando no VS Code, para o reaproveitamento das teses jurídicas contidas em peças processuais da Promotoria de Justiça. 

1. Inicialmente, abrimos um chat e discutimos nossa necessidade com o Claude. Ali amadurecemos nossas ideias e analisamos as alternativas possíveis para chegarmos ao melhor resultado. É a fase de planejamento, muito importante.



2. Queremos uma automação que permita extrair as teses de nossas peças processuais e generalizá-las, preservando os argumentos jurídicos e a jurisprudência nelas contidas. Vamos gerar uma base de conhecimento em arquivos Markdown estruturados que será consultada pelo agente para, no futuro, auxiliar na elaboração de outras peças processuais.

3. No nosso chat do Claude, definimos o fluxo de trabalho, o tipo de peça processual que será analisado pelo agente, o formato de saída e de que forma os scripts entrarão em ação.

4. A conversa no chat termina com o pedido explícito do prompt que vai organizar a pasta de trabalho, criar o ambiente virtual Python, instalar as bibliotecas necessárias, gerar os scripts de automação e estabelecer o roteiro no formato de Skill. Esse processo de gerar a estrutura inicial de pastas, ambiente e arquivos a partir de uma especificação é o que se chama de scaffold do projeto. Isso tudo será gerado na pasta do projeto aberta no VS Code.

5. Então, abrimos o VS Code, selecionamos a pasta do projeto, e executamos o Claude Code (extensão da própria Anthropic) com o prompt obtido no passo anterior.

6. Toda a estrutura de pastas, o ambiente virtual e os scripts são criados. O arquivo SKILL.md é gravado na pasta correta. Depois disso, conferimos objetivamente se ele corresponde ao fluxo planejado.



7. Com tudo isso pronto, carregamos as peças na pasta definida como entrada e, no chat do Claude Code, solicitamos explicitamente o processamento (ou invocamos a Skill diretamente, ex.: /extrair-teses).

8. Se tudo correr como planejado, as teses devem aparecer generalizadas, sem referência ao caso concreto, porém com a jurisprudência contida na peça original, prontas para reaproveitamento por uma futura skill dedicada à elaboração, por exemplo, de contrarrazões.




quinta-feira, 21 de maio de 2026

A IA na Promotoria: um singelo pensamento após a participação numa POC (prova de conceito)

Quando migramos do processo em papel para o digital, mudamos apenas o suporte. Todos os termos (certidões, vistas, ciências, "carimbos") foram mantidos. O novo processo era mais do mesmo, porém digitalizado. De início, o consumo de papel até aumentou, porque simplesmente resistíamos a ler telas de computador.

Foram necessários mais de 10 anos para percebermos que o processo digital pode ser diferente. Os atos processuais clássicos finalmente cederam lugar aos "eventos". E está tudo bem.

Tenho a impressão de que o mesmo acontece hoje com a IA. Tudo o que fazemos é submeter o processo e um prompt a uma API.

Seria muito mais produtivo repensar nossos fluxos de trabalho e adaptá-los a essa nova tecnologia. Superar a cultura institucional e o nosso imenso apego ao formalismo é essencial para, efetivamente, extrairmos valor da IA generativa e aumentarmos nossa produtividade.

quarta-feira, 29 de abril de 2026

Aplicações desktop com padrão MVC

Visão geral

Uma boa estratégia para o desenvolvimento de aplicações desktop modernas é o uso do padrão MVC (Model-View-Controller), que permite que o projeto escale sem maior dificuldade.

Model: camada de dados

O arquivo database.py concentra toda a inteligência da persistência dos dados.

O sqlite3 pode ser uma boa alternativa para o gerenciamento de um banco local.

Uma classe Database única pode concentrar os métodos para realizar todas as operações de CRUD.

O uso de sys e os para identificar o caminho (path) do banco de dados garante a portabilidade entre diferentes sistemas operacionais.

Controller: lógica da aplicação

Os arquivos de controle atuam como intermediários, importando o Model para processar as regras de negócio.

Cada tabela do banco possui seu próprio arquivo "py" controlador (exemplo: viagem-controler.py, despesa-controler.py etc)

Para as importações entre pastas, recomenda-se o uso do sys.path.insert para garantir o caminho da pasta src (fonte).

View: interface do usuário

A interface de apresentação pode ser construída com PySide6.

Um arquivo main_window.py deve gerenciar as transições entre janelas, sendo estas associadas a outros arquivos "py" (exemplo: viagem_window.py, config_dialog.py etc).

O design visual fica separado em arquivos "ui" dentro da pasta Forms.

Obs.: a View nunca deve acessar o Banco de Dados diretamente (ela apenas exibe o que o Controller envia).

Conclusão

O padrão MVC permite que cada componente tenha uma responsabilidade única na aplicação. Isso facilita o trabalho em equipe, a realização de testes e a manutenção futura do software.

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.



domingo, 16 de novembro de 2025

FFmpeg para manipulação de arquivos de áudio e vídeo (inclusive de audiências judiciais no formato "asf")

O que é o FFmpeg?

O FFmpeg é um aplicativo de linha de comando gratuito para manipular arquivos de áudio e vídeo. 

Ele permite converter formatos de arquivo, editar (cortar, unir, redimensionar), aplicar filtros, extrair áudio/vídeo/imagens e muito mais. É bastante poderoso e versátil: lida com praticamente qualquer formato de mídia.

Como instalar o FFmpeg (mesmo que você não possua privilégios de administrador)?


1. Procure pela versão portátil (zipada) do FFmpeg no site oficial do desenvolvedor: https://www.ffmpeg.org/download.html

2. Baixe a versão mais recente e descompacte o arquivo.



3. Mova a pasta descompactada para o local de sua preferência e que não possua restrições, como por exemplo a pasta C:\Users\SeuNomeDeUsuario\ffmpeg.

4. No menu Iniciar, digite "Variáveis de ambiente" e selecione a opção "Editar as variáveis de ambiente para a sua conta".


 
5. Selecione "Path" e "Ok".



6. Selecione "Editar" e inclua uma linha com o caminho completo para a pasta ("bin") onde se encontra o executável "ffmpeg.exe".


7. Se tudo deu certo, você será capaz de executar o programa digitando ffmpeg no "Prompt de Comando":



Comandos úteis

1. Converter arquivo de um formato para outro:

- De "asf" para "mp4":
ffmpeg -i arquivo_original.asf arquivo_modificado.mp4

- De "asf" para "mp3":
ffmpeg -i arquivo_original.asf -vn arquivo_modificado.mp3

Obs.: o parâmetro "-vn" (sem vídeo) é opcional, mas é uma boa prática incluí-lo.

Atualização (07/12/2025):
Para converter (ou, mais precisamente, reempacotar) um arquivo de um formato para outro sem recodificar o vídeo e o áudio, use o comando abaixo (isso torna o processo mais rápido e preserva a qualidade original):

ffmpeg -i VTS_01_4.VOB -c:v copy -c:a copy VTS_01_4.mp4

2. Dividir um arquivo grande em outros menores

Considerar que "-ss 00:00:00" indica tempo de início do corte e "-t 00:10:00" o tempo do final do corte. Sem o "-ss" ou o "-t", o programa considera o início ou o fim do arquivo.

- Segmentando os primeiros 10 minutos de um vídeo:
ffmpeg -i arquivo_original.asf -t 00:10:00 parte_1.asf

- Segmentando dos 10 aos 20 minutos de um vídeo:
ffmpeg -i arquivo_original.asf -ss 00:10:00 -t 00:20:00 parte_2.asf

- Segmentando dos 20 minutos ao final de um vídeo:
ffmpeg -i arquivo_original.asf -ss 00:20:00 parte_final.asf

3. Extrair um frame em tempo específico
ffmpeg -i arquivo_original.asf -ss 00:10:00 -vframes 1 frame.jpg

4. Extrair um frame a cada 60 segundos do vídeo
ffmpeg -i arquivo_original.asf -vf fps=1/60 output_frame_%04d.jpg  (ou png)

sábado, 27 de setembro de 2025

Por que eu deveria habilitar o "interpretador de código" do M365 Copilot?

Você criou um "agente" no M365 Copilot que esquematiza as informações que constam de um processo judicial (confira o prompt). Ao configurá-lo, você deveria habilitar o "Interpretador de código", como indicada a figura:




Essa opção permite que a aplicação execute alguns scripts em Python, contribuindo para que a ferramenta forneça funcionalidades que são próprias da linguagem, como a de criar e manipular arquivos, fazer cálculos e operações matemáticas, criar visualizações gráficas etc.




No exemplo dos prints, após produzir um relatório de um processo judicial qualquer, o M365 Copilot ofereceu ao usuário a possibilidade de fornecer a mesma resposta em arquivo docx ou PDF, gerado pelo Python.  




M365 Copilot atuando como agente autônomo

O M365 Copilot pode ser programado pelo chat para realizar tarefas de forma autônoma, automatizando alguns fluxos de trabalho. Nesses casos ele atua como agente autônomo.

O app reconhece em certos prompts solicitação de tarefas e as incluem na área da "Memória do Copilot" (acesse pelos "Settings") para atender aos pedidos do usuário.

Eis um exemplo de solicitação, feita diretamente no chat (nova conversa):

Todos os dias, às 13h30, vá ao site do MPSP (mpsp.mp.br), do TJSP, do CNJ e do CNMP colete as principais notícias. Encaminhe-as por e-mail para mim e para o usuário fulano_de_tal@mpsp.mp.br, com os links respectivos e em formato PDF.

Os prints abaixo mostram como é fácil fazer essa programação. 

Você pode desabilitar todas as tarefas ou tarefas específicas na área de "Memória do Copilot".






Instalação do aplicativo "Microsoft 365 Copilot" no PC funcional

1. Na Microsoft Store, procure pelo "Microsoft 365 Copilot".


2. Clique em "Adquirir" e, depois, em "Abrir".


3. Logue-se na conta institucional (se requerido) e conceda as permissões necessárias.


4. O aplicativo está pronto para o uso.


5. Opcionalmente, prossiga com os seguintes passos: 

- Clique em "M365 Copilot" (à esquerda), "..." (à direita) e "Settings" para a personalização. 

- Forneça as "Instruções Personalizadas", como por exemplo: 

"Use linguagem clara e objetiva nas suas respostas. Não infira ou deduza respostas ao analisar documentos jurídicos, ou seja, se não souber a resposta, diga "não sei" sobre o tópico que gerou dúvida." 


- Revise a memória do Copilot (saiba como incluir tarefas no próximo post).




Usando o PDFsam com as IAs Generativas

No dia-a-dia da Promotoria, não é raro nos depararmos com a necessidade de analisarmos processos muito extensos, que extrapolam os limites de carregamento de arquivos nas soluções de IA Generativa disponíveis.

Este post trata do uso do PDFsam Basic para lidar com esses casos.

Digamos que você baixou a íntegra de um processo e o PDF resultante possui 8.313 páginas ou 1,3GB (caso do proc. n. 1003155-68.2022.8.26.0019, não sigiloso).

Para submeter o documento gerado às ferramentas de IA, temos que dividi-lo em arquivos menores.

Uma das maneiras mais fáceis de fazer isso é utilizando a solução PDFsam Basic, gratuita e de código aberto, que mantém o documento privado no seu computador (sem a necessidade, portanto, de fazer o upload para serviços de terceiros).

No site do desenvolvedor há diversas opções do download. Optamos, no entanto, pela versão portátil da aplicação (fornecida em arquivo zipado), que não precisa ser instalada e, geralmente, roda sem problemas no equipamento funcional.

Com o software em execução, selecionamos a opção "Dividir pelo tamanho" e a definimos em 200MB, que é compatível, por exemplo, com a "Tilene" ou o "NotebookLM". 

Assim, podemos prosseguir com o trabalho de análise.
 








quarta-feira, 14 de maio de 2025

Transcrição de audiência longa com o Clipchamp

    Neste vídeo, mostro mais uma estratégia de transcrição de audiência judicial. 


  •     Fizemos o upload do arquivo "asf" no Clipchamp.
  •     Adicionamos o vídeo na linha do tempo.
  •     Geramos a legenda com IA (funcionalidade do programa).
  •     Exportamos a legenda e renomeamos o arquivo para "txt".
  •     Submetemos o arquivo "txt" ao Gemini, para outras análises.



terça-feira, 13 de maio de 2025

Agentes do Copilot

    Neste vídeo, mostro como criar "agentes" do Copilot.

    Você pode acessá-los pelo Teams e compartilhá-los com equipes ou integrantes da sua Instituição.




domingo, 11 de maio de 2025

Resumo da nossa palestra de 08/05/2025 na ESMP (gerado pelo NotebookLM)

    Nosso amigo Rodrigo Lima Silva, da APMP - Regional de São José do Rio Preto, fez um bom uso do NotebookLM e criou um podcast que resume os principais pontos da nossa palestra online de 08/05/2025, em evento promovido pela ESMP. 

    A experiência mostra o poder do NotebookLM para identificar os pontos relevantes da exposição e os resumir de maneira bastante efetiva e, principalmente, interessante ao ouvinte.



segunda-feira, 3 de fevereiro de 2025

IA e Low-Code nas Organizações

A tecnologia disponível hoje em dia, em particular a Inteligência Artificial e soluções low-code (e no-code), empodera os usuários de uma forma geral (incluindo os do chamado "chão de fábrica"), tornando-os aptos a automatizar alguns fluxos de trabalho, analisar dados e tomar melhores decisões.

De um modo geral, os departamentos de TI não conseguem mais atender à totalidade das demandas corporativas, que crescem em número e complexidade. Precisam mudar seu foco para aspectos mais estratégicos das organizações e propiciar condições (dados e licenças de software) para que as soluções para o negócio também possam florescer nas pontas, pelas mãos do pessoal encarregado da execução.

sábado, 1 de fevereiro de 2025

O poder das LLMs na análise de inquéritos policiais

Introdução
O vídeo apresenta um programa escrito em Python que faz uso de LLMs, mediadas pela biblioteca litellm, para analisar uma coleção de inquéritos policiais em formato PDF.

Estratégias
Usamos o PyPDF para extrair textos dos PDFs. Preservamos a numeração das páginas para referenciar as respostas.
O texto extraído dos PDFs compõe o prompt, com as perguntas à LLM dirigidas à analise de cada caso.
A biblioteca litellm facilitou o desenvolvimento e abstraiu toda a complexidade das chamadas a APIs. Com ela, é fácil substituir um provedor de LLM por outro.

Privacidade
Provedores de LLMs, como a OpenAI, afirmam que não utilizam os dados de entrada e saída de suas APIs para treinamento. Também garantem que permanecem privados.

Avalie sempre os riscos
Prefira testar a ferramenta com processos não gravados de sigilo ou que serão elegíveis aos bancos públicos de sentenças.

Alucina?
LLMs ainda alucinam bastante.
O emprego da ferramenta no campo profissional deve ser avaliado caso a caso.

Restrições
Observe o número máximo de tokens de entrada e saída do modelo selecionado.
Faça sempre uma avaliação de custo-benefício.




 

segunda-feira, 2 de setembro de 2024

Por que proibir VPNs é um desafio para o STF?

É muito complicado para o STF proibir e fiscalizar o uso de VPNs para acessar o X. Por esse motivo, a primeira decisão de Alexandre de Moraes ordenava que a Apple e o Google retirassem de suas lojas de aplicativos ferramentas como Proton VPN, ExpressVPN, NordVPN, Surfshark, TOTALVPN, Atlas VPN e Bitdefender VPN, que poderiam ser facilmente empregadas para esse fim.

As VPNs são amplamente utilizadas por tribunais, ministérios públicos, polícias, empresas e pessoas físicas como meio de acesso a recursos corporativos ou redes privadas a partir de conexões menos seguras ou redes abertas, como as de aeroportos, hotéis e restaurantes. Recomendo que as utilizem quando se conectarem à Internet por meio de um Wi-Fi público. As VPNs criptografam o tráfego entre o usuário e o servidor VPN, ocultando o IP de origem. Nem mesmo o seu provedor de internet pode afirmar com certeza se você acessou ou não determinada plataforma; ele apenas saberá que você acessou uma VPN.

Ocorre que os serviços de VPN podem ou não coletar logs de uso (incluindo sites visitados) ou de conexão. Muitos provedores se limitam a registrar os dados da conexão necessários à tarifação, desconsiderando as atividades do usuário.

Não seria trivial ao STF emitir uma ordem genérica a essas empresas, a maioria sediada no exterior, obrigando-as a fornecer a relação de usuários que utilizaram VPNs para acessar o X. Tal medida, aliás, não alcançaria uma parte dos "infratores", já que não é difícil construir a própria VPN ou — por conta e risco — utilizar VPNs alternativas e menos colaborativas com as autoridades. Além disso, o emprego da técnica conhecida como Onion over VPN, que combina o uso de VPN com a rede Tor, pode adicionar uma camada extra de criptografia, escondendo a navegação até mesmo do provedor de VPN.

Na minha opinião, a primeira decisão monocrática sobre a suspensão do X, que, incidentalmente, inviabilizaria o uso de VPN em dispositivos móveis, revela as dificuldades operacionais aqui apontadas. Essa medida não se sustentaria sem comprometer gravemente a Segurança da Informação de um modo geral e, provavelmente por isso, já foi reconsiderada nesse aspecto.

segunda-feira, 22 de julho de 2024

Degravação de Conversas Exportadas do WhatsApp com Python e Whisper

Na semana passada, precisei instruir um processo criminal com uma conversa de WhatsApp que continha mensagens de texto, de áudio e de vídeo.

Para proceder à transcrição, observando a integridade dos arquivos e a sequência cronológica das mensagens, recorremos ao Python e à Inteligência Artificial, usando o Whisper, que é um modelo de fala de código aberto.

O script encontra os arquivos de áudio (opus) e vídeo (mp4) na pasta da conversa de WhatsApp exportada. Na sequência, lê o arquivo do chat, linha a linha. Quando acha referência às mídias, chama o método do Whisper para fazer a transcrição e a incorpora no texto.

Como de costume, compartilhei o código no GitHub, no repositório [transcreve_zap](https://github.com/jespimentel/transcreve_zap), para que possa ser reusado e aprimorado.

Também deixei uma demonstração de seu funcionamento no YouTube:[Degravação do WhatsApp com Python]( https://www.youtube.com/watch?v=M1hxhwUWl0M).

Fico à disposição para conversarmos sobre as estratégias usadas nesse programa.

sábado, 8 de junho de 2024

Usando o difflib do Python para configurar reuniões virtuais

Introdução

O difflib é um módulo da biblioteca padrão do Python que permite comparar sequências, tais como arquivos, listas, strings e outros dados. Ele é especialmente útil para identificar e destacar diferenças entre essas sequências.

Neste post, focaremos na função get_close_matches(). Vale a pena, porém, conhecer outras funções contidas no módulo. 

Estrutura da função

difflib.get_close_matches(word, possibilities, n=3, cutoff=0.6)

A função get_close_matches retorna uma lista das melhores correspondências entre uma sequência de caracteres (geralmente palavras) e uma lista de possibilidades. As n respostas mais prováveis são retornadas em ordem decrescente de semelhança. O parâmetro n deve ser maior que 0, sendo 3 o valor padrão.

O ponto de corte (cutoff) é um valor float do intervalo [0, 1], com padrão em 0.6. Pontuações inferiores ao ponto de corte são ignoradas.

Um caso de uso

Durante a última campanha para Procurador-Geral, precisávamos criar reuniões virtuais no MS Teams com um número variado de colegas, às vezes ultrapassando a centena.

Possuíamos uma planilha Excel que relacionava nomes de colegas a seus respectivos e-mails funcionais. Era um documento oficial, de acesso permitido a qualquer membro da Instituição.

Então, listávamos num arquivo texto os nomes aproximados de quem, deveria ser convidado para as reuniões de campanha (às vezes incompletos ou mesmo com algum erro de grafia) e incumbíamos o Python de nos entregar os e-mails correspondentes aos nomes da lista oficial que mais se assemelhassem  aos fornecidos. O acerto chegava próximo dos 100%! 

O script relacionava os e-mails em arquivo texto, de forma que bastava colá-los no campo próprio do MS Teams para que a reunião já estivesse configurada.

O código

import pandas as pd
import difflib

df = pd.read_excel('emails_dos_membros_2024_01.xlsx')
df['Nome'] = df['Nome'].str.lower()
df['E-mail'] = df['E-mail'].str.lower()

# Relação de nomes para a reunião
arq = open("emails.txt", "r")
nomes_para_a_reuniao = ['antonio carlos']

# Itera sobre cada linha do arquivo
for linha in arq:
# Adiciona a linha à lista
nomes_para_a_reuniao.append(linha.rstrip("\n").lower())

# Fecha o arquivo
arq.close()

# Imprime a lista
print(f'Total de nomes: {len(nomes_para_a_reuniao)}')
relacao_oficial = df['Nome'].to_list()

lista_correspondencia = []

for nome in nomes_para_a_reuniao:
correspondencia = difflib.get_close_matches(nome, relacao_oficial, 1, 0.3)
try:
nome_encontrado = correspondencia[0]
lista_correspondencia.append(nome_encontrado)
print(nome, ">>>", nome_encontrado.strip())
except:
print(f'\nPulamos {nome}!!!\n')

print(f"Nomes encontrados: {len(lista_correspondencia)}")
e_mails = []

for index, row in df.iterrows():
for nome in lista_correspondencia:
if row['Nome']==nome:
e_mails.append(row['E-mail'])

# Saída
nome_arquivo = "saida.txt"

with open(nome_arquivo, 'w') as arquivo:
for e_mail in e_mails:
arquivo.write(e_mail + '\n')


Explicação do código

Primeiro, o código importa as bibliotecas necessárias (pandas para manipulação de dados e difflib para comparação de strings). Em seguida, carrega um arquivo Excel contendo nomes e e-mails, converte os valores das colunas 'Nome' e 'E-mail' para letras minúsculas para garantir a consistência nas comparações, e exibe uma amostra dos dados.

Depois, abre um arquivo de texto contendo nomes adicionais e adiciona esses nomes a uma lista preexistente, convertendo cada nome para minúsculas. Em seguida, imprime o total de nomes nessa lista combinada.

Para cada nome na lista combinada, o código usa difflib.get_close_matches para encontrar a correspondência mais próxima na lista de nomes do DataFrame (lista oficial), com um índice de similaridade mínimo. Se encontrar uma correspondência, adiciona o nome correspondente a uma nova lista e imprime a correspondência. Se não encontrar, imprime uma mensagem indicando que o nome foi pulado, para que se possa fazer a inclusão manual. Após isso, imprime o total de nomes encontrados.

Em seguida, o código percorre cada linha do DataFrame, verificando se o nome na linha corresponde a algum nome na lista de correspondência. Se houver correspondência, adiciona o e-mail correspondente a uma lista de e-mails.

Finalmente, o código escreve os e-mails encontrados em um arquivo de texto, um por linha.

Em conclusão: o código compara listas de nomes (lista oficial e lista fornecida), encontra as correspondências e extrai os e-mails associados.

quinta-feira, 28 de março de 2024

Consulta com Python à API pública do DataJud (Base de Dados do Poder Judiciário) do CNJ

O Conselho Nacional de Justiça - CNJ disponibiliza uma API pública que fornece os metadados e movimentações dos processos judiciais não gravados de sigilo. A documentação da ferramenta está disponível aqui.

A API permite pesquisas pelo número de processo ou por classe processual e órgão julgador. A resposta pode conter até 10.000 registros por página.

Cada tribunal tem seu "endpoint" específico. Na documentação da API encontramos a URL do TJSP e a chave pública para a consulta. Usando o Python, criamos uma solicitação POST para obter os dados sobre ANPPs.

Sabendo que a API utiliza o Elasticsearch - uma linguagem de consulta que permite recuperar informações segundo determinados critérios de pesquisa - restringimos a requisição à classe 12729 (que corresponde à "Execução de Medidas Alternativas"). Com o método response.json(), convertemos a resposta da API (em JSON) em dicionário Python, facilitando a criação do dataframe.
Mais à frente, utilizamos a busca pela string "Acordo de Não Persecução Penal" na coluna "assuntos" para restringir o dataframe ao que, de fato, nos interessava (dados sobre os ANPPs).

O código também converteu todos os horários para o fuso de São Paulo.

A partir desse ponto, foi possível agrupar as informações por períodos de tempo e horários, para as devidas análises e plotagens.
Descobrimos, assim, que; - 23,31% dos ajuizamentos de ANPP ocorrem fora do horário de expediente.
- De agosto de 2023 para cá houve uma sensível queda do número de ANPPs ajuizados no Estado de São Paulo, o que talvez se explique em razão da nova regulamentação do ANPP que foi estabelecida no âmbito do MPSP.

O notebook com o código usado na análise pode ser acessado a partir do meu GitHub. Experimente rodá-lo no Colab.

Uma vez que a coluna "movimentos" do dataframe pode conter o Cód: 12735, relativo à extinção da punibilidade pelo cumprimento do ANPP, pode ser interessante, num projeto futuro, verificar qual a porcentagem de acordos cumpridos e o tempo médio para que isso ocorra.