guia completo · arquitetura ponta a ponta
Como o sistema funciona por dentro
1 O problema e o fluxo ponta a ponta
Quando um advogado descreve os fatos de um caso, ele precisa descobrir quais artigos de lei e súmulas fundamentam a decisão no Tribunal de Justiça de São Paulo (TJSP). Buscar o acórdão inteiro falha por dois motivos: o inteiro teor é grande demais para enviar a uma LLM (~2.300 a 3.400 tokens por acórdão, 3,5× mais que os trechos recortados) e 14,3% das citações aparecem apenas no relatório — onde o juiz resume o que as partes alegaram (inclusive a tese derrotada, sendo 51,6% mero relato F3).
BAAI/bge-m3.
denso.npy + denso_leis.npy
P(B|A).
servidor.py
2 Anatomia de um acórdão e por que descartamos o Relatório
Um acórdão do TJSP tem estrutura fixa, mas uma armadilha escondida na folha de rosto: na página 1 aparece a frase tabelada "de conformidade com o voto do Relator", enquanto o relatório de fato só termina páginas depois na frase "É o relatório.".
1. Ementa (~8% do texto)
Resumo oficial do julgamento. Excelente para recuperar o tema geral do caso, mas cita poucos artigos (média de 0,48 dispositivo por acórdão).
2. Relatório (~22% do texto)
Narra o que o autor pediu, o que o réu contestou e o que o MP opinou. Vai até o marcador "É o relatório.". Concentra 14,3% de citações exclusivas que o tribunal não adotou no voto.
3. Fundamentação / Voto (~65% do texto)
Começa logo após "É o relatório.". É onde o desembargador aplica a lei ao caso concreto: concentra 4,66 dispositivos por acórdão (85,7% do que o acórdão cita é de fato usado pelo tribunal).
4. Dispositivo (~5% do texto)
Começa em "Ante o exposto, nego/dou provimento...". Define o resultado final do recurso e a fixação de honorários/regime.
scrapers/secoes_v2.py: O código antigo começava o "relatório" depois de "É o relatório", invertendo relatório e fundamentação em 95,3% dos acórdãos. Ao ancorar o fim do relatório em FIM_RELATORIO ("É o relatório...") e pular a assinatura eletrônica da capa, destravamos a verdadeira fundamentação:
- Passagens no índice
- 296.014 antes: 296.014 (+112%)
- Passagens com citação
- 135.142 (47%) antes: 30.378 (22%) · 4,4× mais
- Dispositivos na fundamentação
- 4,66 / acórdão 85,7% usados · 14,3% só relatório
- Dependências no grafo (usado)
- 2.841 arestas 500 nós (698 no corte estrito)
3 Extração e normalização canônica de dispositivos
Os desembargadores citam a mesma norma de dezenas de formas diferentes. O módulo scrapers/dispositivos_v3.py e o scrapers/precedentes.py convertem qualquer menção em um identificador canônico único (art<N>-<DIPLOMA>, SUM<N>-<TRIB>, TEMA<N>-<TRIB>).
| Como aparece no acórdão | Rótulo canônico | Regra aplicada pelo extrator |
|---|---|---|
| "nos termos do art. 33, § 4º, da Lei de Drogas" | art33-LEI11343 |
Reconhece apelido doutrinário (Lei de Drogas → LEI11343) e agrupa no caput do artigo. |
| "CF/1988, art. 227. CP, arts. 33 e 44." | art227-CF, art33-CP, art44-CP |
Suporta o formato CNJ invertido (DIPLOMA, art. X) sem deixar o diploma cruzar o ponto final da frase anterior. |
| "art. 186 do Código Civil. Já o art. 927..." | art186-CC, art927-CC |
Herança controlada de diploma: quando o artigo seguinte não repete a lei em até 260 caracteres, herda o último diploma inequívoco. |
| "art. 20, § 3º, do CPC" (julgado em 2014) | art20-CPC1973 |
Desambiguação temporal: acórdãos anteriores a 18/03/2016 convertem CPC ambíguo para CPC1973 (e antes de 11/01/2003, CC → CC1916). |
| "Súmulas 719 do E. STF e 440 do C. STJ" | SUM719-STF, SUM440-STJ |
Expande súmulas no plural, ignora abreviaturas honoríficas (E., C.) e associa cada número ao seu respectivo tribunal. |
| "Tema 688 do STJ (atual Tema 988)" | TEMA988-STJ |
Unifica temas renumerados no número atual para não dividir as citações em dois nós no grafo. |
4 Enriquecimento com os artigos de verdade (Catálogo + BGE-M3)
Diferente de um sistema que trata art927-CC apenas como uma string, nós cruzamos cada citação com o catálogo oficial da equipe (dados/catalogo.json e dados/catalogo_textos.json), contendo 294 diplomas legais e o texto integral de 25.913 artigos.
4.1. As 3 funções do catálogo real
| Camada | O que faz | Exemplo prático |
|---|---|---|
1. Teto e Validação (_cabe / enriquecer) |
Verifica se o artigo citado existe de verdade naquela lei. Elimina erros de digitação do acórdão ou números de processo capturados por engano. | Se um texto diz "art. 2.500 da CF", o catálogo sabe que a CF só vai até o art. 250 e barra o falso positivo (reduziu erros fora do teto de 6.530 para 18). |
2. Cosseno lei↔caso (denso_leis.npy) |
O script indexar_leis.py gera embeddings BAAI/bge-m3 do texto real de cada artigo. Na busca, medimos o cosseno entre o texto da norma e o relato do advogado. |
Num relato de acidente de trânsito, o art. 927 do CC ("causar dano a outrem, fica obrigado a repará-lo") tem cosseno alto (~0,48), enquanto o art. 85 do CPC (honorários) tem cosseno baixo (~0,18). |
3. Aba Legislação Citada (legislacao.json) |
Reúne os 11.068 artigos efetivamente citados pelo TJSP com o texto da lei e acórdãos de exemplo em /acervo. | Permite ler o caput do artigo sem sair do sistema e conferir se ele é confirmado no diploma. |
5 Modelos da Equipe: DeBERTinha (NER v2), Laya-ft-v1 (Destilado) e V·F·S
Integramos os três desenvolvimentos de pesquisa da equipe diretamente no pipeline e nas telas de /busca, /grafo, /extracao e /graficos:
| Componente | O que é | Velocidade / Escala | Onde está sendo usado no sistema |
|---|---|---|---|
NER v2 (debertinha_xsmall_lenerbr)pacote jus-referencias |
Reconhecedor neural de entidades jurídicas (DeBERTa-v3 xsmall). Corrigimos o offset de espaço inicial do SentencePiece ([[ artigo...]] → [[artigo...]]). |
31,3 ms / acórdão (tempo medido em 3.000 acórdãos com a GPU livre, 121,8 s na RX 6700 XT; cobertura e recall medidos em 27.000) |
Atua no modo híbrido Regex ∪ DeBERTinha (NER v2) (resgatando diplomas distantes que o regex sozinho deixava como -?), selecionável em /busca e /grafo. |
Laya-ft-v1 (1B Destilado)substituto local do JEV |
Modelo de 1 bilhão de parâmetros destilado localmente para classificar se um trecho marcado [[...]] é um dispositivo válido (sim/não) e seu tipo (LEGISLACAO / JURISPRUDENCIA). |
72,4 ms / trecho 0,67s / acórdão (56× mais rápido que LLM 14B · custo US$ 0) |
1) Barra 95% dos falsos positivos de enumeração; 2) Gera o grafo limpo Regex + Laya destilado em /busca e /grafo;3) Painel de auditoria em /extracao. |
Algoritmo V·F·S (Kenor)metodo-classificacao-juridica |
Árvore de decisão retórica em 3 eixos: Voz (quem fala), Função (F1 mérito, F2 processual/rito, F3 mero relato/alegação) e Sentido/Polaridade. | 1.200 citações auditadas na GPU com Laya + filtro de rito em 32.636 acórdãos | 1) Provou que 51,6% das citações do relatório são F3 (ruído) contra 71,5% F2/F1 na fundamentação; 2) Fonte V·F·S (Kenor · só mérito F1) selecionável ao vivo em /busca e /grafo. |
6 Busca Híbrida e Grafo de Dependências P(B | A)
A recomendação combina recuperação de passagens (achar casos parecidos) com filtragem colaborativa por grafo (descobrir artigos complementares que sempre caminham juntos no TJSP).
6.1. Os dois motores de busca
• TF-IDF (léxico, instantâneo em CPU): transforma consulta e passagens em vetores esparsos de 120.000 unigramas/bigramas com peso sublinear e ranqueia pelo cosseno. Ideal para termos técnicos exatos.
• Híbrido (4 etapas em GPU): combina BM25 (casamento léxico exato) + BGE-M3 (vetores densos de 1.024 dimensões em dados/denso.npy, que entendem sinônimos e paráfrases), funde os dois rankings via RRF (Reciprocal Rank Fusion) e reordena o top-50 com um Cross-Encoder Reranker (bge-reranker-v2-m3).
6.2. Como o grafo sugere dispositivos (os nós verdes)
Quando a busca retorna $k$ passagens, contamos os dispositivos citados nelas (citado nos trechos). Em seguida, olhamos para o grafo global do acervo: se quem cita o artigo A também cita o artigo B com alta probabilidade condicional:
conf(A → B) = P(B | A) = acórdãos(A ∩ B) / acórdãos(A)Para evitar que um único desembargador repetindo seu modelo de voto fabrique uma seta artificial, exigimos suporte mínimo em relatores distintos (≥ 6 relatores),
lift ≥ 1,5 e penalizamos acórdãos "cesta gigante" pelo peso 2 / (k × (k - 1)).
Os artigos com maior confiança que ainda não tinham vindo nos trechos aparecem em verde (sugerido pelo grafo) tanto no mapa de setas quanto no gráfico de barras logo abaixo.
7 Guia rápido: o que fazer em cada aba do sistema
| Aba | Para que serve | Controles principais |
|---|---|---|
| Visão geral | Resumo executivo do projeto com os números vivos do corpus e a síntese dos achados experimentais. | Cards automáticos alimentados por /api/visao. |
| Busca | Tela principal do usuário: digite os fatos do caso, veja o grafo + gráfico de barras dos artigos e leia os trechos mais próximos. | • Motor: TF-IDF vs híbrido• Sliders: nº de passagens, nº de sugeridos e corte de relação c/ o caso ( lei↔caso)• Extrator / Fonte: escolha Regex + Laya, DeBERTinha e filtro V·F·S (só mérito F1)• Clique numa barra: filtra os trechos daquele artigo. |
| Mapa de dependência | Exploração visual completa do grafo de co-citação do TJSP. | • Busca por artigo (ex.: art. 33)• Sliders de confiança, relatores distintos, lift e acórdãos • Botões de fonte: inteiro teor, o que foi usado, V·F·S (mérito F1) e ementa. |
| Acervo | Inspeção direta dos 32.636 acórdãos coletados (divididos em ementa, relatório, fundamentação e dispositivo) e dos 11.068 artigos de lei citados. | • Aba acórdãos (busca por processo, relator, câmara, ano ou artigo) • Aba legislação citada (busca no texto real da lei). |
| Extração | Comparação de desempenho, custo e latência entre os extratores + painel de auditoria do Laya-ft-v1 e V·F·S. |
Cards comparativos, matriz de concordância, tabela de falsos positivos e telemetria da GPU RX 6700 XT. |
| Gráficos | Painel de figuras prontas para apresentação (de onde vêm as citações, sobrevivência de arestas, Laya-ft-v1, árvore V·F·S e benchmark de recomendação). | Todos os gráficos SVG são gerados dinamicamente a partir dos JSONs dos experimentos. |
8 Mapa de scripts e arquivos de dados
| Arquivo / Script | Papel na arquitetura |
|---|---|
scrapers/teor_lote.py |
Coletor resiliente do inteiro teor em PDF no portal e-SAJ do TJSP (com reconexão automática de sessão CAS). |
scrapers/secoes_v2.py |
Segmentador estrutural do acórdão em ementa, relatorio, fundamentacao e dispositivo. |
scrapers/dispositivos_v3.pyscrapers/precedentes.py |
Extratores canônicos de artigos de lei, súmulas, temas repetitivos e tratados internacionais, integrados ao catálogo de 294 diplomas. |
indexador.py |
Lê dados/teor.jsonl, aplica secoes_v2 + extratores e grava dados/passagens.jsonl (296.014 passagens) e dados/acervo.jsonl. |
indexar_denso.pyindexar_leis.py |
Vetorizam na GPU (com BAAI/bge-m3) todas as passagens (dados/denso.npy) e os 25.913 textos de artigos de lei (dados/denso_leis.npy). |
grafo_citacoes.pygrafo_completo.py |
Constroem os grafos direcionados de dependência ($P(B\mid A)$) para cada extrator (projeto, laya, debertinha, ner, etc.) e para cada fonte (teor, usado, vfs, ementa). |
rodar_gpu_noite.py |
Executa na GPU os experimentos com debertinha_xsmall_lenerbr (3.000 acórdãos), auditoria laya-ft-v1 e classificação retórica V·F·S (1.200 citações). |
busca_hibrida.pyservidor.py |
Motor de busca (TF-IDF + Híbrido BM25/BGE-M3/RRF/Reranker), cálculo de cosseno lei↔caso e servidor HTTP de todas as telas. |