ReverbLabs · Kit abertodados públicos oficiais
Relatório de risco criminal

Um relatório com a sua marca, gerado na sua LLM

Um prompt e uma skill que qualquer pessoa usa para gerar um relatório de criminalidade por endereço, com fonte oficial em cada número. Personalize a marca, copie e rode no assistente que você já usa.

1. Personalize
Preencha empresa, foco e tom. O prompt se monta sozinho.
2. Instale
Cole como instrução de projeto, GPT, Gem ou skill.
3. Peça
Informe o endereço. A LLM busca a fonte oficial e monta o documento.

01 Escolha o caminho

As regras são as mesmas. Muda quem faz as contas: a LLM, um script, ou um sistema próprio.

CaminhoPara quemQuem calculaConfiabilidade
Prompt — qualquer LLM com buscaPesquisa pontual, teste rápidoA LLM (código quando houver)confira cada número
Skill com scripts — Claude / Claude CodeUso recorrente numa empresaScript Python determinísticoreprodutível
Plataforma própria — base + APIVender relatório em escalaPipeline com auditoriaauditável

Leia antes de vender: no caminho do prompt a LLM pode ler planilha errado. Para cliente pagante, use a skill ou a plataforma e confira cada número na fonte.

02 Personalize

Tudo roda nesta página. Nada é enviado a lugar nenhum — o prompt é montado no seu navegador.

✓ Roubo a transeunte✓ Roubo de veículo✓ Furto de veículo✓ Roubo a comércioRoubo de cargaFurto de cabosResidência✓ CVLI
Seu prompt (pronto para colar)
Você gera RELATÓRIOS DE RISCO CRIMINAL por endereço, usando EXCLUSIVAMENTE dados públicos oficiais brasileiros.
Marca: (empresa). Assinatura da análise: (quem assina). Público: (para quem). Tom: Técnico e sóbrio.

FONTES PERMITIDAS (nenhuma outra): ISP-RJ (dadosabertos.rj.gov.br), SSP-SP, SSP-BA (dados.ba.gov.br), SSP-RS, Sinesp/MJ, SIM-DataSUS, IBGE (CNEFE/população). Use o nível mais fino que a fonte publica para a UF do endereço; sem dado por bairro, caia para município (Sinesp) e DIGA isso em "Nível de detalhe".

NATUREZAS EM FOCO (salvo pedido em contrário): Roubo a transeunte, Roubo de veículo, Furto de veículo, Roubo a comércio, CVLI. JANELA: últimos 12 meses.

REGRAS INEGOCIÁVEIS:
1. Nenhum número sem URL da fonte + data de acesso.
2. Proibido estimar, interpolar, arredondar "pra fechar" ou completar dado ausente. Faltou → "não disponível".
3. Menos de 5 ocorrências numa célula → "menos de 5", SEM taxa.
4. Taxa/100 mil só com população ≥ 5.000 da mesma área/nível; mostre a fórmula (ocorrências / população × 100000).
5. Variação só com base anterior ≥ 20 ocorrências; senão "base pequena, sem variação".
6. NÃO crie "nota de risco" única somando crimes diferentes.
7. NADA sobre pessoas (nomes, vítimas, suspeitos). O relatório é sobre TERRITÓRIO (LGPD).
8. Dados oficiais e análise da empresa em seções SEPARADAS.

SE TIVER FERRAMENTA DE CÓDIGO/DADOS: baixe a planilha oficial, normalize e faça as contas em código. Sem ferramenta: use só os totais já publicados, sem recalcular. Se o usuário anexar um CSV oficial, use-o como fonte (cite-o).

ESTRUTURA (sempre, nesta ordem):
- Cabeçalho: Empresa — Diagnóstico de risco criminal · Local · Naturezas · Janela
- Resumo (3–5 linhas, no tom definido)
- Indicadores por natureza (tabela: natureza, nível, contagem, taxa/100k, variação, fonte)
- Nível de detalhe · Metodologia · Limitações · Fontes (com URL + data de acesso)
- Rodapé: (contato)

Peça o endereço se não vier na mensagem.
marca.json (para a skill)
{
  "empresa": "",
  "assinatura": "",
  "contato": "",
  "para_quem": "",
  "tom": "Técnico e sóbrio",
  "janela_meses": 12,
  "naturezas": [
    "Roubo a transeunte",
    "Roubo de veículo",
    "Furto de veículo",
    "Roubo a comércio",
    "CVLI"
  ],
  "secao_propria": null
}

03 Instale na sua LLM

Claude
Crie um projeto → cole o prompt nas instruções → ative busca na web. Para scripts, use a skill (seção 05).
ChatGPT
Crie um GPT ou projeto → cole o prompt → habilite navegação na web e análise de dados.
Gemini
Crie um Gem → cole o prompt nas instruções → confira a pesquisa com Google na conta.
Claude Code / agente
Salve o prompt como CLAUDE.md → coloque a pasta da skill no projeto → garanta acesso a domínios .gov.br.

04 Peça o relatório

Gere o relatório para:
Rua Exemplo, 100 – Bairro Exemplo – Rio de Janeiro/RJ – CEP 00000-000
Rótulo do local: CD Zona Norte
Cliente final: Indústria Exemplo
PedidoO que acontece
“Compare estes 3 endereços”Relatório de carteira com tabela comparativa
“Só roubo de carga, últimos 36 meses”Sobrescreve naturezas e janela só nesse pedido
“Anexei o CSV do ISP, use este arquivo”Usa o anexo como fonte citada, sem buscar
“Exporte em CSV”Tabela com todos os números + coluna de fonte

05 Skill com scripts

A LLM baixa a fonte e normaliza um CSV; o script faz as contas e as salvaguardas; a LLM redige a partir do JSON.

relatorio-risco-criminal/
├── SKILL.md         instruções e regras
├── marca.json       gerado na seção 02
└── scripts/
    └── calcular.py  taxas, variação e salvaguardas
SKILL.md
# Relatório de risco criminal — skill

A LLM ENCONTRA e BAIXA a fonte oficial e monta um CSV normalizado; o script scripts/calcular.py faz as
contas e aplica as salvaguardas; a LLM só redige a partir do JSON devolvido.

## Passos
1. Leia marca.json (empresa, assinatura, naturezas, janela, tom, seção própria).
2. Peça o endereço. Resolva UF / município / bairro.
3. Escolha a fonte oficial da UF (lista abaixo). Baixe a planilha/CSV mais recente.
4. Normalize para o CSV de entrada: area,nivel,natureza,periodo,valor,populacao,fonte_url,fonte_data
   (periodo = AAAA-MM; nivel = bairro|area_policial|municipio). População: IBGE.
5. Rode: python scripts/calcular.py dados.csv --meses <N>
6. Redija SÓ a partir do JSON (indicadores, avisos, fontes). Nunca invente número fora do JSON.

## Regras (iguais ao prompt)
Número sem URL+data = proibido. Nada de estimar/interpolar. "menos de 5" para célula pequena.
Sem nota única somando crimes. Nada sobre pessoas (LGPD). Dado oficial separado da análise da empresa.
Seções Nível de detalhe / Metodologia / Limitações / Fontes sempre presentes.

## Fontes oficiais permitidas
ISP-RJ · SSP-SP · SSP-BA · SSP-RS · Sinesp/MJ · SIM-DataSUS · IBGE (CNEFE/população).
Nível mais fino que a fonte publicar; sem dado por bairro → município, declarado.
scripts/calcular.py
#!/usr/bin/env python3
"""Calcula indicadores a partir de um CSV normalizado.

Entrada (CSV, uma linha por area x natureza x mes):
  area,nivel,natureza,periodo,valor,populacao,fonte_url,fonte_data
  periodo = AAAA-MM ; nivel = bairro|area_policial|municipio

Saida: JSON em stdout com indicadores por area e natureza.
Uso: python calcular.py dados.csv --meses 12
"""
import csv, json, sys, argparse
from collections import defaultdict

MIN_CELULA = 5        # abaixo disso: "menos de 5", sem taxa
MIN_POP = 5000        # abaixo disso: nao calcula taxa
MIN_BASE_VAR = 20     # base anterior menor: nao calcula variacao

def main():
    ap = argparse.ArgumentParser()
    ap.add_argument("csv"); ap.add_argument("--meses", type=int, default=12)
    a = ap.parse_args()
    rows = list(csv.DictReader(open(a.csv, encoding="utf-8")))
    if not rows: sys.exit("CSV vazio")
    obrig = {"area","nivel","natureza","periodo","valor","populacao","fonte_url","fonte_data"}
    falta = obrig - set(rows[0])
    if falta: sys.exit(f"Colunas ausentes: {sorted(falta)}")

    periodos = sorted({r["periodo"] for r in rows})
    atual = set(periodos[-a.meses:])
    anterior = set(periodos[-2*a.meses:-a.meses]) if len(periodos) >= 2*a.meses else set()

    g = defaultdict(lambda: {"atual":0,"anterior":0,"pop":None,"nivel":None,"fontes":set()})
    for r in rows:
        k = (r["area"], r["natureza"]); d = g[k]
        v = int(r["valor"])
        if r["periodo"] in atual: d["atual"] += v
        elif r["periodo"] in anterior: d["anterior"] += v
        if r["populacao"]: d["pop"] = int(r["populacao"])
        d["nivel"] = r["nivel"]; d["fontes"].add((r["fonte_url"], r["fonte_data"]))

    out = []
    for (area, nat), d in sorted(g.items()):
        item = {"area": area, "natureza": nat, "nivel": d["nivel"],
                "janela": f"{min(atual)} a {max(atual)}",
                "fontes": [{"url": u, "data": t} for u, t in sorted(d["fontes"])],
                "avisos": []}
        if d["atual"] < MIN_CELULA:
            item["contagem"] = "menos de 5"; item["taxa_100k"] = None
            item["avisos"].append("celula pequena: sem taxa")
        else:
            item["contagem"] = d["atual"]
            if d["pop"] and d["pop"] >= MIN_POP:
                item["taxa_100k"] = round(d["atual"] / d["pop"] * 1e5, 1)
                item["formula"] = f"{d['atual']} / {d['pop']} x 100000"
            else:
                item["taxa_100k"] = None
                item["avisos"].append("populacao ausente ou menor que 5.000")
        if anterior and d["anterior"] >= MIN_BASE_VAR and isinstance(item["contagem"], int):
            item["variacao_pct"] = round((d["atual"] - d["anterior"]) / d["anterior"] * 100, 1)
        else:
            item["variacao_pct"] = None
            if anterior: item["avisos"].append("base anterior pequena: sem variacao")
        out.append(item)
    json.dump({"indicadores": out}, sys.stdout, ensure_ascii=False, indent=2)

if __name__ == "__main__":
    main()

06 Fontes oficiais

O prompt restringe a busca a estas origens. O relatório nunca afirma precisão maior que a granularidade da fonte.

FonteCoberturaGranularidadeOnde
Instituto de Segurança Pública (ISP)RJBairro e área de delegacia (CISP)dadosabertos.rj.gov.br
Secretaria da Segurança Pública (SSP-SP)SPBoletins por categoria, mensalssp.sp.gov.br
Secretaria da Segurança Pública (SSP-BA)BAMicrodados de mortes violentas com bairrodados.ba.gov.br
Secretaria da Segurança Pública (SSP-RS)RSMunicípio, mensalssp.rs.gov.br
Sinesp (Ministério da Justiça)BrasilMunicípio, algumas tipologiasgov.br/mj
SIM/DataSUS (Ministério da Saúde)BrasilÓbitos por agressão, municípiodatasus.saude.gov.br
IBGE: CNEFE e populaçãoBrasilEndereço com coordenada; populaçãoibge.gov.br

07 Limites e regras

RegraPor quê
Nenhum número sem URL e data de acessoQualquer pessoa precisa conseguir conferir
Proibido estimar, interpolar ou completar dado ausenteNúmero inventado com a sua marca é responsabilidade sua
Menos de 5 ocorrências: mostrar “menos de 5”, sem taxaTaxa sobre contagem pequena é ruído
Sem “nota de risco” única somando crimes diferentesRoubo e homicídio não se somam; o índice esconderia isso
Nível de detalhe, Metodologia, Limitações e Fontes sempre presentesSubnotificação e cobertura parcial precisam estar à vista
Análise da empresa separada dos dados oficiaisO dado é do Estado; a opinião é de quem assina
Nada sobre pessoas: nomes, vítimas, suspeitosLGPD e ética; o relatório é sobre território

08 Adapte à sua empresa