File size: 12,676 Bytes
473972a | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 | #!/usr/bin/env python3
"""
scripts/build_chunks.py
Constroi chunks de texto da NT-01/2025 para o sistema RAG do Agente CBMGO
Suporta: extracao de PDF, chunks sinteticos e base de conhecimento embutida
"""
import json
import re
import argparse
from pathlib import Path
# =============================================================================
# BASE DE CONHECIMENTO NT-01/2025 EMBUTIDA
# =============================================================================
NT01_CONHECIMENTO = [
{
"id": "nt01_objetivo",
"section": "Art. 1 - Objetivo e Aplicacao",
"text": "A NT-01/2025 estabelece criterios para classificacao das edificacoes quanto a ocupacao, altura, area construida e caracteristicas construtivas para aplicacao das medidas de seguranca contra incendio pelo CBMGO. Aplica-se a edificacoes novas, ampliacao, reforma ou mudanca de uso no Estado de Goias conforme Lei Estadual 15.802/2006."
},
{
"id": "nt01_grupo_A",
"section": "Tabela 1 - Divisao A: Residencial",
"text": "GRUPO A-1 Residencial unifamiliar: casa, sobrado, chale. GRUPO A-2 Residencial multifamiliar: apartamento, flat, kitnet, condominio. Caracteristica: uso exclusivamente residencial permanente. Risco: baixo. Exigencias minimas: extintores, saidas de emergencia, sinalizacao."
},
{
"id": "nt01_grupo_B",
"section": "Tabela 1 - Divisao B: Hospedagem",
"text": "GRUPO B-1 Hospedagem transitoria: hotel, motel, pousada, hostel. GRUPO B-2 Hospedagem longa permanencia: apart-hotel, residencial senior. Caracteristica: populacao flutuante e dificuldade de evacuacao noturna. Exigencias: extintores, hidrantes (acima 750m2), iluminacao emergencia, alarme."
},
{
"id": "nt01_grupo_C",
"section": "Tabela 1 - Divisao C: Comercial",
"text": "GRUPO C-1 Comercio pequeno porte (ate 750m2): loja, farmacia, padaria, sapataria. GRUPO C-2 Comercio medio/grande porte (acima 750m2): supermercado, shopping center, hipermercado. Risco: medio. Exigencias: extintores, hidrantes obrigatorios C-2, rotas evacuacao, brigada acima 750m2."
},
{
"id": "nt01_grupo_D",
"section": "Tabela 1 - Divisao D: Reuniao de Publico",
"text": "GRUPO D-1 Esporte e lazer: ginasio, estadio, arena. GRUPO D-2 Cultura e religiao: teatro, cinema, igreja, museu. GRUPO D-3 Ensino: escola, universidade, creche. Caracteristica: alta densidade de ocupacao. Risco: medio a alto. Exigencias rigorosas para evacuacao rapida."
},
{
"id": "nt01_grupo_E",
"section": "Tabela 1 - Divisao E: Saude",
"text": "GRUPO E-1 Saude e assistencia: hospital, clinica, UBS, casa de repouso, abrigo. Caracteristica: pacientes com mobilidade reduzida necessitam evacuacao assistida. Risco especial. Exigencias: sprinklers, alarme, brigada treinada, area de refugio, sistema de hidrantes."
},
{
"id": "nt01_grupo_F",
"section": "Tabela 1 - Divisao F: Servicos",
"text": "GRUPO F-1 Servico profissional: escritorio, banco, consultorio, salon. GRUPO F-2 Transporte: aeroporto, rodoviaria, terminal. Risco: baixo a medio. Extintores obrigatorios, iluminacao emergencia acima de 200m2, sinalizacao conforme NBR 13434."
},
{
"id": "nt01_grupo_G",
"section": "Tabela 1 - Divisao G: Automotivo",
"text": "GRUPO G-1 Servicos automotivos: garagem, estacionamento coberto, posto de combustivel, oficina. Caracteristica: presenca de combustiveis inflamaveis. Risco: medio a alto. Exigencias: extintores especificos, ventilacao, detector de gas, distancias de seguranca."
},
{
"id": "nt01_grupo_H",
"section": "Tabela 1 - Divisao H: Industrial",
"text": "GRUPO H-1 Industrial baixo risco (ate 500 MJ/m2): alimenticio, textil. GRUPO H-2 Industrial medio risco (500-1000 MJ/m2): metalurgica, moveleira. GRUPO H-3 Industrial alto risco (acima 1000 MJ/m2): quimica, petroquimica. Brigada obrigatoria, sprinklers H-2 e H-3."
},
{
"id": "nt01_grupo_I",
"section": "Tabela 1 - Divisao I: Deposito",
"text": "GRUPO I-1 Deposito baixo risco: arquivo, papel, cereais. GRUPO I-2 Deposito medio risco: madeira, borracha. GRUPO I-3 Deposito alto risco: liquidos inflamaveis, produtos quimicos. Carga de incendio elevada. Sprinklers obrigatorios I-2 acima 750m2, I-3 sempre."
},
{
"id": "nt01_extintores",
"section": "Extintores de Incendio - NT-01/2025 e NBR 12693",
"text": "Extintores obrigatorios em todas edificacoes. Calculo por risco: BAIXO (A,B,F) = 1 extintor a cada 500m2; MEDIO (C,D,G) = 1 extintor a cada 250m2; ALTO (H,I,J) = 1 extintor a cada 150m2. Minimo: 2 extintores por pavimento. Tipo ABC (po quimico) para uso geral. Manutencao anual obrigatoria. Sinalizar conforme NBR 13434."
},
{
"id": "nt01_hidrantes",
"section": "Sistema de Hidrantes - NT-01/2025 e NBR 13714",
"text": "Hidrantes obrigatorios: area acima 750m2 ou altura acima 12m (aprox 4 pavimentos). Pressao minima: 10 m.c.a. Vazao minima: 300 L/min. Mangueira DN 65mm (externa), DN 40mm (interna). Distancia maxima entre hidrantes: 30m. Reservatorio tecnico de incendio (RTI) obrigatorio. Manutencao semestral."
},
{
"id": "nt01_spda",
"section": "SPDA - Sistema de Protecao contra Descargas Atmosfericas - NBR 5419",
"text": "SPDA obrigatorio: altura acima 15m ou area acima 1000m2 ou densidade de raios elevada. Projeto por engenheiro eletricista. Tipos: Franklin (captores), Gaiola Faraday, ESE (nao reconhecido NBR). Aterramento conforme NBR 5419. Manutencao anual."
},
{
"id": "nt01_saidas",
"section": "Saidas de Emergencia - NBR 9077",
"text": "Largura minima: 1,10m para ate 60 pessoas + 0,55m por 60 pessoas. Portas abertura no sentido do escape. Escadas: enclausuradas acima de 2 pavimentos (H>9m). Distancia maxima percorrida: 30m risco baixo / 20m risco alto. Rampas: inclinacao maxima 1:8 (12,5%). Portas corta-fogo: nas escadas enclausuradas."
},
{
"id": "nt01_iluminacao",
"section": "Iluminacao de Emergencia - NBR 10898",
"text": "Iluminacao emergencia obrigatoria: edificacoes acima 200m2 ou acima 1 pavimento. Autonomia minima: 1 hora. Nivel de iluminamento: 30 lux nas rotas de saida, 15 lux demais areas. Blocos autonomos com bateria selada. Teste mensal e semestral obrigatorios. Instalar em: corredores, escadas, saidas."
},
{
"id": "nt01_sinalizacao",
"section": "Sinalizacao de Seguranca - NBR 13434",
"text": "Sinalizacao obrigatoria em todas edificacoes. Categorias: saida de emergencia (verde), equipamentos de combate (vermelho), riscos especificos (amarelo), orientacao/salvamento (verde). Fotoluminescencia em rotas de evacuacao. Altura de fixacao: 1,80m a 2,10m do piso. Manutencao trimestral."
},
{
"id": "nt01_brigada",
"section": "Brigada de Incendio - NBR 14276",
"text": "Brigada obrigatoria: area acima 750m2 ou lotacao acima 100 pessoas. Composicao: brigadistas treinados em prevencao, primeiros socorros e evacuacao. Reciclagem anual. Numero de brigadistas: 5% da populacao (minimo 2 por pavimento). Lider de brigada: supervisor certificado. Simulacros anuais."
},
{
"id": "nt01_sprinklers",
"section": "Sprinklers - Sistema Automatico de Supressao - NBR 10897",
"text": "Sprinklers obrigatorios: residencial acima 30m altura, comercial acima 12m, industrial H-2 e H-3 acima 750m2, deposito I-2 acima 750m2, deposito I-3 sempre. Temperatura de acionamento: 57-79 graus C (padrao). Densidade de descarga conforme risco. Reservatorio dedicado obrigatorio."
},
{
"id": "nt01_alarme",
"section": "Sistema de Deteccao e Alarme - NBR 17240 e NBR 9441",
"text": "Alarme obrigatorio: hospitais, hoteis acima 750m2, escritorios acima 1500m2, industrias H-3, depositos I-3. Detectores de fumaca (ionicos ou fotoeletricos). Central de alarme incendio (CAIG). Acionadores manuais em rotas de saida. Aviso sonoro minimo 65 dB. Manutencao trimestral."
},
{
"id": "nt01_ppci",
"section": "PPCI - Plano de Prevencao contra Incendio e Panico",
"text": "PPCI obrigatorio para todas edificacoes antes de ocupar. Elaborado por Engenheiro (CREA) ou Arquiteto (CAU) com ART/RRT. Conteudo: memorial descritivo, calculos, plantas (baixa, cortes, fachadas), especificacoes tecnicas. Aprovacao pelo CBMGO antes inicio obras. Renovacao: 3 anos (baixo risco) ou 1 ano (alto risco). Taxas: DARM - CBMGO."
},
{
"id": "nt01_altura",
"section": "Altura da Edificacao - Definicao NT-01/2025",
"text": "Altura medida do nivel do passeio publico ate o piso do ultimo pavimento habitavel. Excluem-se: tico, cobertura, pavimento tecnico, casa de maquinas. Para edificacoes em terreno inclinado: considera-se o ponto de acesso do veiculo do Corpo de Bombeiros. Altura influencia: tipo de escada, sistemas obrigatorios."
},
{
"id": "nt01_carga_incendio",
"section": "Carga de Incendio Especifica",
"text": "Carga de incendio especifica (MJ/m2) determinada pelo uso: Residencial/Escritorio = 500 MJ/m2; Comercio = 750 MJ/m2; Industrial baixo = 500 MJ/m2; Industrial medio = 1000 MJ/m2; Industrial alto = 2000 MJ/m2; Deposito = variavel conforme material. Influencia na determinacao do tipo de estrutura resistente ao fogo."
},
]
def extrair_texto_pdf(pdf_path):
"""Extrai texto de PDF da NT-01/2025"""
try:
import pypdf
texto = ""
with open(pdf_path, "rb") as f:
reader = pypdf.PdfReader(f)
for page in reader.pages:
texto += page.extract_text() + "\n"
return texto
except ImportError:
print("[WARN] pypdf nao instalado. Use: pip install pypdf")
return None
except Exception as e:
print(f"[ERRO] Erro ao ler PDF: {e}")
return None
def chunkar_texto(texto, chunk_size=500, overlap=50):
"""Divide texto em chunks com sobreposicao"""
palavras = texto.split()
chunks = []
i = 0
while i < len(palavras):
chunk_palavras = palavras[i:i + chunk_size]
chunk_texto = " ".join(chunk_palavras)
chunks.append({
"id": f"pdf_chunk_{len(chunks):04d}",
"section": f"Chunk {len(chunks)+1} (PDF)",
"text": chunk_texto
})
i += chunk_size - overlap
return chunks
def gerar_chunks_sinteticos():
"""Gera chunks sinteticos baseados na base de conhecimento embutida"""
chunks = []
for item in NT01_CONHECIMENTO:
chunks.append({
"id": item["id"],
"source": "NT-01/2025 CBMGO",
"section": item["section"],
"text": item["text"],
"tokens_estimados": len(item["text"].split())
})
return chunks
def salvar_chunks(chunks, output_path):
"""Salva chunks em formato JSONL"""
with open(output_path, "w", encoding="utf-8") as f:
for chunk in chunks:
f.write(json.dumps(chunk, ensure_ascii=False) + "\n")
print(f"Chunks salvos: {output_path} ({len(chunks)} chunks)")
return output_path
def main():
parser = argparse.ArgumentParser(description="Construtor de chunks NT-01/2025 para RAG")
parser.add_argument("--pdf", type=str, help="Caminho para o PDF da NT-01/2025 (opcional)")
parser.add_argument("--synthetic", action="store_true", help="Usar base de conhecimento sintetica")
parser.add_argument("--output", type=str, default="data", help="Diretorio de saida")
parser.add_argument("--chunk-size", type=int, default=500, help="Tamanho do chunk em palavras")
args = parser.parse_args()
Path(args.output).mkdir(parents=True, exist_ok=True)
output_file = Path(args.output) / "chunks.jsonl"
if args.pdf:
print(f"Extraindo texto do PDF: {args.pdf}")
texto = extrair_texto_pdf(args.pdf)
if texto:
chunks = chunkar_texto(texto, chunk_size=args.chunk_size)
print(f"Extraidos {len(chunks)} chunks do PDF")
else:
print("Falha na extracao do PDF. Usando base sintetica.")
chunks = gerar_chunks_sinteticos()
else:
print("Usando base de conhecimento embutida NT-01/2025")
chunks = gerar_chunks_sinteticos()
salvar_chunks(chunks, output_file)
print(f"\nTotal: {len(chunks)} chunks salvos em {output_file}")
print("Execute scripts/build_embeddings.py para construir o indice FAISS")
if __name__ == "__main__":
main()
|