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()