Pular para o conteúdo

Problemas comuns

Esta unidade acrescenta uma peça que a Unidade 1 não tinha: a rede. Com ela vêm modos de falha novos.

Todos os erros abaixo foram provocados de propósito na máquina do curso, e as mensagens são as que o CNJ devolveu de fato.

HTTP 401 — chave rejeitada

HTTP 401: {"error":{"root_cause":[{"type":"security_exception",
"reason":"unable to authenticate with provided credentials and anonymous
access is not allowed for this request",
"additional_unsuccessful_credentials":"API key: Illegal base64 character 2d", ...

Causa. A chave está errada, truncada, ou você definiu DATAJUD_API_KEY com um valor inválido.

Repare no detalhe: Illegal base64 character 2d. O caractere 2d é o hífen — no teste, a chave falsa era chave-invalida-de-proposito. A mensagem diz até qual caractere estragou.

Solução. Limpe a variável de ambiente e deixe o padrão do cnj.py valer:

set DATAJUD_API_KEY=

Se ainda assim falhar, confira a chave na documentação oficial do CNJ. Ela é pública e muda muito raramente.

HTTP 404 — índice não existe

HTTP 404: {"error":{"root_cause":[{"type":"index_not_found_exception",
"reason":"no such index [api_publica_tjxx]", ...

Causa. A sigla do tribunal está errada. Cada tribunal é um índice separado, e não existe api_publica_tjxx.

Solução. Confira a sigla. O padrão é tjrj, tjsp, tjmg, trf2, tst. Para voltar ao TJRJ:

set DATAJUD_TRIBUNAL=tjrj
Nota

Aproveite para experimentar. Trocando a variável para tjsp, a mesma consulta responde normalmente:

URL: https://api-publica.datajud.cnj.jus.br/api_publica_tjsp/_search
OK: {'value': 10000, 'relation': 'gte'}

Nada no código do agente é específico do TJRJ. O que muda é uma sigla numa URL — e as Tools, o modelo e o ciclo continuam iguais.

HTTP 400 — consulta malformada

HTTP 400: {"error":{"root_cause":[{"type":"illegal_argument_exception",
"reason":"Fielddata is disabled on [grau] in [api_publica_tjrj]. ...
Please use a keyword field instead. ...

Causa. Quase sempre: agregação ou sort num campo de texto analisado.

Solução. Acrescente .keyword ao nome do campo. Ver Fazendo perguntas em Query DSL.

O 400 é o erro mais frequente enquanto você estiver montando consulta, e é também o mais fácil — a mensagem do Elasticsearch costuma dizer exatamente o que fazer.

"Não foi possível alcançar a API do CNJ"

Não foi possível alcançar a API do CNJ ([Errno 11001] getaddrinfo failed).
Verifique sua conexão e se a rede do Tribunal permite a saída.

Causa. O nome não resolveu, ou a conexão foi recusada. Numa máquina do Tribunal, o suspeito principal é a política de rede.

Diagnóstico, em ordem:

ping api-publica.datajud.cnj.jus.br

Se o nome não resolve, é DNS ou bloqueio de domínio.

curl -I https://api-publica.datajud.cnj.jus.br

Se o ping responde e o curl trava, é firewall na saída HTTPS.

Solução. Se estiver bloqueado, o pedido à TI é a liberação do domínio api-publica.datajud.cnj.jus.br (porta 443).

Vale como argumento no pedido: é um endereço público do CNJ, com dados públicos, sem credencial nominal e sem tráfego de entrada. Não é um pedido de acesso a base sigilosa.

Se houver proxy corporativo, o Python o respeita por variável de ambiente:

set HTTPS_PROXY=http://proxy.tjrj.jus.br:8080

Acentos saem como ?? no terminal

"nome": "Distribui??o"

Causa. O console do Windows não usa UTF-8 por padrão. O dado chegou certo; a tela é que não sabe desenhá-lo.

Solução. É a primeira linha executável de todos os exemplos:

import sys
sys.stdout.reconfigure(encoding="utf-8")

Se preferir resolver no terminal, antes de rodar:

chcp 65001

O agente demora muito

Cada passo do ciclo é uma geração completa do qwen2:7b na sua CPU. Três passos podem levar vários minutos numa máquina sem GPU — e é normal.

O que ajuda, em ordem de efeito:

Medida Efeito
Reduzir max_steps Corta o pior caso
Manter _source enxuto Menos texto no contexto a cada volta
Manter o cache do catálogo Evita repetir a agregação
Modelo menor (qwen2.5:3b) Bem mais rápido, e erra mais
Atenção

O que não ajuda é aumentar num_ctx. Janela maior não deixa o modelo mais rápido — deixa mais lento, e ainda permite que o histórico cresça mais antes de doer.

O agente pega os dados e não para

O log mostra a Tool devolvendo tudo certo num passo, e o agente continua trabalhando até bater no max_steps.

Causa. O CodeAgent só encerra quando o código gerado chama final_answer(...). Modelos pequenos frequentemente não chamam: reconhecer que a tarefa terminou é um julgamento, e é o que eles fazem pior.

Solução. Peça explicitamente, no fim do enunciado:

agente.run(
    "Traga os 3 processos mais recentes sobre violência doméstica. "
    "Use somente os dados devolvidos pelas Tools. "
    "Assim que tiver os processos, chame final_answer com eles."
)

Não é garantia — é orientação. A garantia é o max_steps, que já está lá.

Atenção

Não aumente o max_steps para "dar mais chance". Um agente que não converge em 6 passos raramente converge em 20, e cada passo extra é uma geração completa do modelo mais um contexto maior — mais lento que o anterior.

O agente processou tudo e devolveu lixo, sem erro nenhum

Sintoma: a execução termina no tempo normal, sem exceção, e a saída são nomes de campo soltos, caracteres avulsos ou uma lista vazia.

Causa. Quase sempre o tipo de retorno de uma Tool. Em Python quase tudo é iterável, e iterar a coisa errada não dá erro — dá outro resultado:

A Tool devolve O modelo escreve O que acontece
str (JSON serializado) for x in tool() percorre caracteres
dict (envelope) lista.extend(tool()) acrescenta as chaves
list de dicionários ambos funciona

Diagnóstico. Antes de suspeitar do modelo, teste a Tool sozinha no terminal:

r = buscar_processos("Violência Doméstica Contra a Mulher", 3)
print(type(r), len(r))
print(type(r[0]))

Se type(r) for str, o problema é seu, não do agente.

Solução. Devolva objetos Python, e devolva-os na forma que o chamador vai compor — normalmente uma lista de dicionários. Ver Alfred no CNJ.

O agente respondeu com processos que não existem

Aconteceu na Unidade 1 e pode acontecer aqui.

Teste antes de acreditar:

import sys
sys.path.insert(0, "../../unidade1/exemplos")
from validar_cnj import validar_cnj

validar_cnj("0029098-20.2026.8.19.0000")   # True

Um número inventado por um LLM quase sempre reprova no dígito verificador. Um número que veio da API sempre passa.

Se reprovou, o problema não é o número — é que houve um passo em que o modelo escreveu no lugar de consultar. Olhe o log do agente e localize onde:

Fixando o capítulo

Q1: A API respondeu HTTP 404: no such index [api_publica_tjxx]. O que está errado?

Q2: O agente devolveu três números de processo e todos reprovaram em validar_cnj. Qual a leitura correta?

Q3: A máquina está na rede do Tribunal e a chamada falha com getaddrinfo failed. Qual o primeiro passo?