-------------------------------------------------------------------------------- -- ampmInsights - Oracle AI Database 26ai | Vulnerability & Audit Insights -- Script 1/2 - Provisionamento do banco de dados -- -- O que este script faz: -- 1) Cria o schema da aplicacao (AMPMINSIGHTS) e concede os privilegios -- necessarios (incluindo AI Vector Search / DBMS_VECTOR_CHAIN, DBMS_CLOUD -- e DBMS_CLOUD_AI) em um Autonomous Database 26ai. -- 2) Cria UMA UNICA tabela de configuracao com todos os OCIDs/identificadores -- OCI que voce vai precisar (SECAO 2). Voce preenche esses valores UMA -- VEZ; todos os passos seguintes leem essa tabela automaticamente, em vez -- de pedir para voce colar o mesmo OCID de novo em varios lugares. -- 3) Cria a credencial usada pelo banco para chamar o OCI Generative AI e o -- OCI Object Storage. -- 4) Carrega um modelo de embeddings (ONNX) ja convertido, a partir do -- Object Storage. -- 5) Roda testes rapidos de sanidade (embedding, geracao de texto, SELECT AI). -- 6) Cria as tabelas, a view, a sequence, o trigger e o PL/SQL (funcoes e -- procedure) que geram os insights de IA e os vetores (chunks) usados na -- busca semantica ("fale com os dados"). -- -- Por que este script existe (V1): -- Esta e uma versao adaptada do ambiente de demonstracao construido para a -- AM/PM, para que a propria AM/PM (ou o parceiro V8 Solution) possa -- reproduzir o ambiente em seu proprio tenancy OCI. Nenhuma credencial, -- chave, senha ou OCID reais foram mantidos neste arquivo: todo valor que -- precisa ser preenchido por voce aparece como um marcador no formato -- . -- -- Como copiar e colar no Database Actions (SQL): -- Cada bloco abaixo esta pronto para ser copiado inteiro (com o botao -- "Copiar" da versao HTML desta documentacao, em docs/04-passo-a-passo-banco.html) -- e colado direto no SQL Worksheet do Database Actions. Rode um bloco de -- cada vez, na ordem apresentada, e confirme que nao houve erro antes de -- seguir para o proximo. -- -- Antes de rodar, leia (na pasta docs/, ao lado desta pasta sql/): -- 03-pre-requisitos-credenciais.html -> como obter cada OCID/valor -- 04-passo-a-passo-banco.html -> este script, explicado passo a passo, -- com cada bloco pronto para copiar -- -- Como usar este script: -- - SECAO 1 : conecte como ADMIN do Autonomous Database (ex.: via Database -- Actions / SQL Worksheet, ou SQL Developer/SQLcl). -- - SECAO 2+ : conecte como o novo usuario AMPMINSIGHTS criado na SECAO 1. -- - So depois de terminar este arquivo, instale o export do APEX -- (02_ampminsights_apex_app.sql) - veja docs/05-passo-a-passo-apex.html. -- -- Convencao usada neste arquivo: -- = valor obrigatorio que voce precisa colocar antes de -- rodar o bloco. O script NAO vai funcionar com o -- marcador no lugar do valor real. -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- SECAO 1 - Executar conectado como ADMIN do Autonomous Database -------------------------------------------------------------------------------- -- 1.1) Criar o schema/usuario da aplicacao. -- Troque a senha abaixo por uma senha forte escolhida por voce ANTES de -- rodar este comando (minimo 12 caracteres, com maiusculas, minusculas, -- numero e caractere especial - regra padrao do Oracle Database). CREATE USER AMPMINSIGHTS IDENTIFIED BY ""; -- 1.2) Papeis basicos GRANT CONNECT TO AMPMINSIGHTS; GRANT RESOURCE TO AMPMINSIGHTS; ALTER USER AMPMINSIGHTS DEFAULT ROLE CONNECT, RESOURCE; -- 1.3) Habilitar REST (ORDS) para o schema e habilitar Data Sharing BEGIN ORDS_ADMIN.ENABLE_SCHEMA( p_enabled => TRUE, p_schema => 'AMPMINSIGHTS', p_url_mapping_type => 'BASE_PATH', p_url_mapping_pattern => 'ampminsights', p_auto_rest_auth => TRUE ); -- habilita o compartilhamento de dados usado por alguns recursos de AI/Vector C##ADP$SERVICE.DBMS_SHARE.ENABLE_SCHEMA( SCHEMA_NAME => 'AMPMINSIGHTS', ENABLED => TRUE ); COMMIT; END; / -- 1.4) Quota de armazenamento no tablespace de dados ALTER USER AMPMINSIGHTS QUOTA UNLIMITED ON "DATA"; -- 1.5) Privilegios usados pela aplicacao (AI Vector Search, DBMS_CLOUD, -- SELECT AI, mineracao/embeddings, credenciais e jobs agendados) GRANT EXECUTE ON dbms_vector_chain TO AMPMINSIGHTS; GRANT EXECUTE ON dbms_cloud TO AMPMINSIGHTS; GRANT EXECUTE ON dbms_cloud_ai TO AMPMINSIGHTS; GRANT CONNECT TO AMPMINSIGHTS; GRANT RESOURCE TO AMPMINSIGHTS; GRANT CREATE MINING MODEL TO AMPMINSIGHTS; GRANT CREATE CREDENTIAL TO AMPMINSIGHTS; GRANT CREATE JOB TO AMPMINSIGHTS; -- 1.6) Regras de rede (ACL) para o schema poder chamar o endpoint do OCI -- Generative AI usado neste script (regiao us-chicago-1 por padrao - o -- mesmo valor que vai para o parametro GENAI_REGION da SECAO 2, que -- ainda nao existe neste ponto do script, por isso o host aqui e -- digitado direto). Nem toda tenancy alcanca us-chicago-1 (ex.: algumas -- tenancies com escopo regional restrito, como America Latina, podem -- so alcancar sa-saopaulo-1) - se for o seu caso, troque o host abaixo -- pela regiao que a sua tenancy alcanca, E use o mesmo valor no -- parametro GENAI_REGION da SECAO 2 (repita este bloco para cada host -- adicional que for necessario). BEGIN DBMS_NETWORK_ACL_ADMIN.APPEND_HOST_ACE( host => 'inference.generativeai.us-chicago-1.oci.oraclecloud.com', lower_port => 443, upper_port => 443, ace => xs$ace_type( privilege_list => xs$name_list('connect'), principal_name => 'AMPMINSIGHTS', principal_type => xs_acl.ptype_db ) ); DBMS_NETWORK_ACL_ADMIN.APPEND_HOST_ACE( host => 'inference.generativeai.us-chicago-1.oci.oraclecloud.com', ace => xs$ace_type( privilege_list => xs$name_list('resolve'), principal_name => 'AMPMINSIGHTS', principal_type => xs_acl.ptype_db ) ); END; / -- 1.7) Conferir as regras de rede criadas SELECT host, lower_port, upper_port, principal, privilege FROM dba_host_aces WHERE principal = 'AMPMINSIGHTS'; -------------------------------------------------------------------------------- -- A partir daqui, conecte-se como o usuario AMPMINSIGHTS (nao mais como ADMIN) -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- SECAO 2 - Tabela de configuracao (preencha os valores UMA UNICA VEZ aqui) -------------------------------------------------------------------------------- -- -- Esta e a UNICA seção onde voce vai colar OCIDs, regiao, namespace e bucket. -- Todos os blocos seguintes (credencial OCI, modelo ONNX, SELECT AI, e o job -- de geracao de insights criado pela propria aplicacao APEX) leem os valores -- DAQUI automaticamente - voce nao precisa colar o mesmo OCID de novo em -- nenhum outro lugar deste arquivo nem do aplicativo APEX. -- -- Onde obter cada valor: ver docs/03-pre-requisitos-credenciais.html. -- CREATE TABLE "TB_26AI_TECH_PARAMS" ( "PARAM_NAME" VARCHAR2(100 CHAR) NOT NULL ENABLE, "PARAM_VALUE" VARCHAR2(1000 CHAR) NOT NULL ENABLE, "DESCRIPTION" VARCHAR2(4000), CONSTRAINT "TB_26AI_TECH_PARAMS_PK" PRIMARY KEY ("PARAM_NAME") USING INDEX ENABLE ); COMMENT ON TABLE "TB_26AI_TECH_PARAMS" IS 'Tabela de configuracao central da aplicacao ampmInsights - preencher uma unica vez.'; -- Preencha os 8 marcadores abaixo e rode o bloco UMA VEZ. INSERT INTO TB_26AI_TECH_PARAMS (PARAM_NAME, PARAM_VALUE, DESCRIPTION) VALUES ('EMBEDDING_CREDENTIAL', 'OCI_CRED', 'Nome da credencial que sera criada na SECAO 3. Nao precisa alterar este valor.'); INSERT INTO TB_26AI_TECH_PARAMS (PARAM_NAME, PARAM_VALUE, DESCRIPTION) VALUES ('EMBEDDING_COMPARTMENT', '', 'OCID do compartimento OCI onde o Autonomous Database foi criado.'); INSERT INTO TB_26AI_TECH_PARAMS (PARAM_NAME, PARAM_VALUE, DESCRIPTION) VALUES ('OCI_TENANCY_OCID', '', 'OCID do tenancy OCI (campo "tenancy" da API key).'); INSERT INTO TB_26AI_TECH_PARAMS (PARAM_NAME, PARAM_VALUE, DESCRIPTION) VALUES ('OCI_USER_OCID', '', 'OCID do usuario OCI dono da API key (campo "user" da API key).'); INSERT INTO TB_26AI_TECH_PARAMS (PARAM_NAME, PARAM_VALUE, DESCRIPTION) VALUES ('OCI_FINGERPRINT', '', 'Fingerprint da API key (campo "fingerprint" da API key).'); INSERT INTO TB_26AI_TECH_PARAMS (PARAM_NAME, PARAM_VALUE, DESCRIPTION) VALUES ('OCI_REGION', '', 'Regiao OCI do seu tenancy, ex.: sa-saopaulo-1 (campo "region" da API key).'); INSERT INTO TB_26AI_TECH_PARAMS (PARAM_NAME, PARAM_VALUE, DESCRIPTION) VALUES ('OS_NAMESPACE', '', 'Namespace do Object Storage do seu tenancy (Console OCI > Storage > Buckets > "Namespace").'); INSERT INTO TB_26AI_TECH_PARAMS (PARAM_NAME, PARAM_VALUE, DESCRIPTION) VALUES ('OS_BUCKET', '', 'Nome do bucket de Object Storage onde o modelo ONNX sera armazenado (ver SECAO 4).'); INSERT INTO TB_26AI_TECH_PARAMS (PARAM_NAME, PARAM_VALUE, DESCRIPTION) VALUES ('AI_LOG_RETENTION_DAYS', '90', 'Dias de retencao do log de chamadas de IA/embeddings (TB_26AI_TECH_LOG) - ver docs/09-operacao-observabilidade.html para a query de purga.'); INSERT INTO TB_26AI_TECH_PARAMS (PARAM_NAME, PARAM_VALUE, DESCRIPTION) VALUES ('GENAI_REGION', 'us-chicago-1', 'Regiao do OCI Generative AI usada pelo RAG/insights/embeddings (SECAO 5+). Pode ser diferente da OCI_REGION (que e a regiao "de casa" do seu tenancy/bucket) - o Generative AI so roda em regioes especificas. Se a sua tenancy nao alcancar us-chicago-1 (comum em tenancies com escopo regional restrito, ex. America Latina), troque para uma regiao que a sua tenancy alcance (ex. sa-saopaulo-1) E repita a ACL da SECAO 1.6 para o novo host - confirme antes com "oci generative-ai model-collection list-models" ou o Console OCI que o modelo usado (meta.llama-4-maverick-17b-128e-instruct-fp8) ainda esta ativo para uso on-demand na regiao escolhida, ja que a disponibilidade de modelos varia por regiao e muda com o tempo.'); COMMIT; -- Confira: nenhuma linha abaixo deve ainda mostrar um valor "" -- antes de voce seguir para a SECAO 3. SELECT param_name, param_value, description FROM TB_26AI_TECH_PARAMS ORDER BY param_name; -------------------------------------------------------------------------------- -- SECAO 3 - Credencial de acesso a OCI (Generative AI + Object Storage) -------------------------------------------------------------------------------- -- -- Esta credencial (OCI_CRED) e o que permite o banco chamar o OCI Generative -- AI (para gerar embeddings e texto/insights) e o OCI Object Storage (para -- carregar o modelo ONNX). Ela usa autenticacao "API Signing Key" da OCI. -- O bloco abaixo LE tenancy/usuario/compartimento/fingerprint automaticamente -- da tabela de configuracao da SECAO 2 - voce so precisa colar a CHAVE -- PRIVADA aqui (ela nao e guardada em nenhuma tabela; o proprio banco a -- guarda de forma criptografada dentro da credencial). -- -- PRE-REQUISITO (feito uma unica vez, no Console OCI, fora do banco): -- Ver o passo a passo completo em docs/03-pre-requisitos-credenciais.html. -- Resumo: Console OCI > usuario > User settings > API keys > Add API key > -- Generate API key pair > Download private key > Add. Os 4 valores exibidos -- (user, fingerprint, tenancy, region) vao para a SECAO 2 acima; a chave -- privada baixada (.pem) vai direto no bloco abaixo. -- -- IMPORTANTE (seguranca): -- - A chave privada .pem equivale a uma senha: nao envie por e-mail/chat, -- nao suba para repositorio de codigo, restrinja a politica IAM ao -- minimo necessario e rotacione periodicamente. -- - Depois de rodar este bloco, o arquivo .pem local pode ser removido -- com seguranca - o banco guarda a chave de forma criptografada e ela -- nao aparece em nenhuma consulta. -- DECLARE v_tenancy TB_26AI_TECH_PARAMS.PARAM_VALUE%TYPE; v_user TB_26AI_TECH_PARAMS.PARAM_VALUE%TYPE; v_compartment TB_26AI_TECH_PARAMS.PARAM_VALUE%TYPE; v_fingerprint TB_26AI_TECH_PARAMS.PARAM_VALUE%TYPE; jo JSON_OBJECT_T; BEGIN SELECT param_value INTO v_tenancy FROM TB_26AI_TECH_PARAMS WHERE param_name = 'OCI_TENANCY_OCID'; SELECT param_value INTO v_user FROM TB_26AI_TECH_PARAMS WHERE param_name = 'OCI_USER_OCID'; SELECT param_value INTO v_compartment FROM TB_26AI_TECH_PARAMS WHERE param_name = 'EMBEDDING_COMPARTMENT'; SELECT param_value INTO v_fingerprint FROM TB_26AI_TECH_PARAMS WHERE param_name = 'OCI_FINGERPRINT'; jo := JSON_OBJECT_T(); jo.put('user_ocid', v_user); jo.put('tenancy_ocid', v_tenancy); jo.put('compartment_ocid', v_compartment); -- Cole aqui o conteudo COMPLETO do arquivo .pem baixado (incluindo as -- linhas -----BEGIN PRIVATE KEY----- e -----END PRIVATE KEY-----, com as -- quebras de linha originais). Este e o UNICO lugar de todo o pacote onde -- a chave privada e digitada. jo.put('private_key', ''); jo.put('fingerprint', v_fingerprint); DBMS_VECTOR_CHAIN.CREATE_CREDENTIAL( credential_name => 'OCI_CRED', params => JSON(jo.to_string)); END; / -- Conferir que a credencial foi criada (nao mostra a chave privada) SELECT credential_name, username, comments FROM user_credentials WHERE credential_name = 'OCI_CRED'; -------------------------------------------------------------------------------- -- SECAO 4 - Modelo de embeddings ONNX -------------------------------------------------------------------------------- -- -- Esta secao carrega um modelo de embeddings do tipo imagem/texto (ONNX) para -- casos de uso que combinem imagem e texto. O fluxo principal de texto do -- ampmInsights (embeddings de relatorios, RAG, etc.) usa o modelo hospedado no -- OCI Generative AI (cohere.embed-v4.0, chamado via DBMS_VECTOR_CHAIN na -- SECAO 5) e NAO depende desta secao. Pule a SECAO 4 se voce so precisa do -- fluxo de texto (a maioria dos casos). -- -- 4.1) O arquivo CLIP_VIT_LARGE_PATCH14_TXT.onnx já convertido e testado no -- formato que o Oracle AI Database espera está incluído neste pacote, -- na pasta modelo-onnx/. Basta usá-lo diretamente no passo 4.2 abaixo. -- (Se no futuro você quiser converter um modelo HuggingFace diferente, -- o passo a passo está em docs/04-passo-a-passo-banco.html, seção -- "Como converter um modelo ONNX" — é opcional, não é necessário para -- usar o arquivo já incluído aqui.) -- -- 4.2) Crie um bucket no SEU Object Storage (o nome deve ser o mesmo que voce -- colocou em OS_BUCKET na SECAO 2) e faca upload do arquivo: -- Console OCI > Storage > Buckets > Create Bucket -- (ou via OCI CLI: oci os bucket create --name --compartment-id ) -- Console OCI > abra o bucket > Upload > selecione o CLIP_VIT_LARGE_PATCH14_TXT.onnx -- (ou via OCI CLI: oci os object put -bn --file CLIP_VIT_LARGE_PATCH14_TXT.onnx) -- -- 4.3) Carregue o modelo no banco. O bloco abaixo monta a URI sozinho, usando -- OS_REGION/OS_NAMESPACE/OS_BUCKET da tabela de configuracao (SECAO 2) - -- voce nao precisa editar nenhuma URL na mao. -- DECLARE v_region TB_26AI_TECH_PARAMS.PARAM_VALUE%TYPE; v_namespace TB_26AI_TECH_PARAMS.PARAM_VALUE%TYPE; v_bucket TB_26AI_TECH_PARAMS.PARAM_VALUE%TYPE; v_uri VARCHAR2(1000); BEGIN SELECT param_value INTO v_region FROM TB_26AI_TECH_PARAMS WHERE param_name = 'OCI_REGION'; SELECT param_value INTO v_namespace FROM TB_26AI_TECH_PARAMS WHERE param_name = 'OS_NAMESPACE'; SELECT param_value INTO v_bucket FROM TB_26AI_TECH_PARAMS WHERE param_name = 'OS_BUCKET'; v_uri := 'https://objectstorage.' || v_region || '.oraclecloud.com/n/' || v_namespace || '/b/' || v_bucket || '/o/CLIP_VIT_LARGE_PATCH14_TXT.onnx'; DBMS_VECTOR.LOAD_ONNX_MODEL_CLOUD( model_name => 'CLIP_VIT_LARGE_PATCH14_TXT', credential => 'OCI_CRED', uri => v_uri, metadata => JSON('{ "function": "embedding", "embeddingOutput": "embedding", "input": {"input": ["DATA"]} }') ); END; / SELECT model_name, algorithm, mining_function FROM user_mining_models WHERE model_name = 'CLIP_VIT_LARGE_PATCH14_TXT'; -------------------------------------------------------------------------------- -- SECAO 5 - Testes rapidos de sanidade (embedding, geracao de texto, SELECT AI) -------------------------------------------------------------------------------- -- Rode os 3 blocos abaixo para confirmar que a credencial e a rede estao OK -- antes de seguir para as tabelas e o PL/SQL da aplicacao. -- 5.1) Teste de embedding (Cohere, via OCI Generative AI). A URL usa a -- regiao configurada em GENAI_REGION (SECAO 2), nao um valor fixo. SELECT VECTOR_SERIALIZE( DBMS_VECTOR_CHAIN.UTL_TO_EMBEDDING( TO_CLOB('Teste simples para gerar um embedding.'), JSON('{ "provider": "ocigenai", "credential_name": "OCI_CRED", "url": "https://inference.generativeai.' || (SELECT param_value FROM TB_26AI_TECH_PARAMS WHERE param_name = 'GENAI_REGION') || '.oci.oraclecloud.com/20231130/actions/embedText", "model": "cohere.embed-v4.0" }') ) RETURNING CLOB ) AS embedding FROM dual; -- 5.2) Teste de geracao de texto (Llama 4, via OCI Generative AI). Mesma -- logica: a URL usa a regiao configurada em GENAI_REGION (SECAO 2). SELECT DBMS_VECTOR_CHAIN.UTL_TO_GENERATE_TEXT( TO_CLOB('Responda somente com a palavra: sucesso'), JSON('{ "provider": "ocigenai", "credential_name": "OCI_CRED", "url": "https://inference.generativeai.' || (SELECT param_value FROM TB_26AI_TECH_PARAMS WHERE param_name = 'GENAI_REGION') || '.oci.oraclecloud.com/20231130/actions/chat", "model": "meta.llama-4-maverick-17b-128e-instruct-fp8", "chatRequest": { "temperature": 0.1, "topK": 1, "maxTokens": 50 } }') ) AS resposta FROM dual; -- 5.3) Teste de SELECT AI (perguntas em linguagem natural sobre as views/ -- tabelas do schema). O bloco abaixo le EMBEDDING_COMPARTMENT e -- GENAI_REGION da tabela de configuracao (SECAO 2). As tabelas/view -- referenciadas abaixo sao criadas na SECAO 6 - rode este bloco depois -- de criar V_26AI_TECH e TB_26AI_TECH_CMDB. -- -- A regiao do OCI Generative AI abaixo vem do parametro GENAI_REGION - -- nao precisa (nem deve) ser trocada pelo valor de OCI_REGION da tabela -- de configuracao (sao coisas diferentes de proposito), ja que o -- servico so esta disponivel em algumas regioes especificas da OCI. DECLARE v_compartment TB_26AI_TECH_PARAMS.PARAM_VALUE%TYPE; v_genai_region TB_26AI_TECH_PARAMS.PARAM_VALUE%TYPE; BEGIN SELECT param_value INTO v_compartment FROM TB_26AI_TECH_PARAMS WHERE param_name = 'EMBEDDING_COMPARTMENT'; SELECT param_value INTO v_genai_region FROM TB_26AI_TECH_PARAMS WHERE param_name = 'GENAI_REGION'; DBMS_CLOUD_AI.CREATE_PROFILE( profile_name => 'OCI_CRED2', attributes => '{ "provider": "oci", "credential_name": "OCI_CRED", "region": "' || v_genai_region || '", "model": "meta.llama-4-maverick-17b-128e-instruct-fp8", "temperature": 0, "comments": true, "object_list": [ {"owner": "AMPMINSIGHTS", "name": "V_26AI_TECH"}, {"owner": "AMPMINSIGHTS", "name": "TB_26AI_TECH_CMDB"} ], "enforce_object_list": "true" }', description => 'Profile ampmInsights para uso no SELECT AI (OCI Generative AI - Llama 4 Maverick). Compartimento: ' || v_compartment ); END; / SELECT DBMS_CLOUD_AI.GENERATE( prompt => 'Responda apenas: CONECTADO', profile_name => 'OCI_CRED2', action => 'chat' ) AS resposta FROM dual; -------------------------------------------------------------------------------- -- SECAO 6 - Tabelas, sequence, trigger e view da aplicacao -------------------------------------------------------------------------------- -- Os nomes de tabelas, view, sequence e trigger abaixo sao os MESMOS nomes -- referenciados internamente pelo export da aplicacao APEX -- (02_ampminsights_apex_app.sql). Nao renomeie estes objetos: a aplicacao -- tem centenas de referencias diretas a estes nomes exatos. CREATE TABLE "TB_26AI_TECH_CHAT" ( "USER_NAME" VARCHAR2(200) ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Identificador, papel ou atributo de usuario/controle de acesso associado a interacoes de chat do dominio tecnico.'), "IS_OWN" VARCHAR2(6) ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Indicador booleano de is own no registro de interacoes de chat do dominio tecnico.'), "COMMENT_TEXT" CLOB ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Conteudo textual, documental ou binario associado a interacoes de chat do dominio tecnico; o nome da coluna indica o papel especifico no fluxo.'), "COMMENT_DATE" DATE ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Data, hora ou marco temporal associado ao registro de interacoes de chat do dominio tecnico.'), "SESSION_ID" NUMBER ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Identificador ou codigo de session no contexto de interacoes de chat do dominio tecnico.') ) ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Armazena registros de interacoes de chat do dominio tecnico ("fale com os dados"); e classificada, pela nomenclatura e estrutura, como tabela operacional do dominio.'); CREATE TABLE "TB_26AI_TECH_CMDB" ( "ID" NUMBER GENERATED BY DEFAULT ON NULL AS IDENTITY MINVALUE 1 MAXVALUE 9999999999999999999999999999 INCREMENT BY 1 START WITH 1 CACHE 20 NOORDER NOCYCLE NOKEEP NOSCALE NOT NULL ENABLE ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Identificador unico do registro de itens de configuracao tecnica (CMDB); compoe a chave primaria da tabela. E coluna identity preenchida automaticamente pelo Oracle.'), "NOME" VARCHAR2(255) ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Nome ou titulo usado para identificar o registro de itens de configuracao tecnica (CMDB) em consultas e interfaces.'), "EMPRESA" VARCHAR2(50) ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Atributo EMPRESA do registro de itens de configuracao tecnica (CMDB).'), "CLASSE" VARCHAR2(50) ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Atributo de classificacao, versao, origem ou formato do registro de itens de configuracao tecnica (CMDB).'), "AMBIENTE" VARCHAR2(50) ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Atributo AMBIENTE do registro de itens de configuracao tecnica (CMDB).'), "STATUS_OPERACIONAL" VARCHAR2(50) ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Indicador de estado ou de controle do registro de itens de configuracao tecnica (CMDB).'), "DESCRIÇÃO" VARCHAR2(32767) ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Texto descritivo, detalhe ou observacao associado a itens de configuracao tecnica (CMDB).'), "SOX" NUMBER ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Atributo SOX do registro de itens de configuracao tecnica (CMDB).'), "COFRE" NUMBER ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Atributo COFRE do registro de itens de configuracao tecnica (CMDB).'), "ENDEREÇO_IP" VARCHAR2(50) ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Endereco IP registrado no contexto de itens de configuracao tecnica (CMDB).'), "SISTEMA_OPERACIONAL" VARCHAR2(255) ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Atributo SISTEMA_OPERACIONAL do registro de itens de configuracao tecnica (CMDB).'), "TIPO_DE_REDE" VARCHAR2(50) ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Atributo TIPO_DE_REDE do registro de itens de configuracao tecnica (CMDB).'), "É_VIRTUAL" NUMBER ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Atributo E_VIRTUAL do registro de itens de configuracao tecnica (CMDB).'), "CRITICIDADE" VARCHAR2(50) ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Atributo CRITICIDADE do registro de itens de configuracao tecnica (CMDB).'), "INSTÂNCIAS_BANCOS" VARCHAR2(50) ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Atributo INSTANCIAS_BANCOS do registro de itens de configuracao tecnica (CMDB).'), "APLICAÇÕES_RELACIONADAS" VARCHAR2(32767) ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Atributo APLICACOES_RELACIONADAS do registro de itens de configuracao tecnica (CMDB).'), "JANELAS_DE_MANUTENÇÃO" VARCHAR2(255) ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Atributo JANELAS_DE_MANUTENCAO do registro de itens de configuracao tecnica (CMDB).'), "ANALISTA_RESPONSAVEL" VARCHAR2(255) ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Atributo ANALISTA_RESPONSAVEL do registro de itens de configuracao tecnica (CMDB).'), "ANALISTAS_RESPONSÁVEIS" VARCHAR2(255) ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Atributo ANALISTAS_RESPONSAVEIS do registro de itens de configuracao tecnica (CMDB).'), "GERENCIADO_PELO_GRUPO" VARCHAR2(255) ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Atributo GERENCIADO_PELO_GRUPO do registro de itens de configuracao tecnica (CMDB).'), "GRUPOS_RESPONSÁVEIS" VARCHAR2(32767) ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Atributo GRUPOS_RESPONSAVEIS do registro de itens de configuracao tecnica (CMDB).'), "GRUPO_RESPONSÁVEL" VARCHAR2(255) ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Atributo GRUPO_RESPONSAVEL do registro de itens de configuracao tecnica (CMDB).'), "EDR" NUMBER ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Atributo EDR do registro de itens de configuracao tecnica (CMDB).'), "TENABLE" NUMBER ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Atributo TENABLE do registro de itens de configuracao tecnica (CMDB).'), "SIEM" NUMBER ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Atributo SIEM do registro de itens de configuracao tecnica (CMDB).'), "APPLIANCE" NUMBER ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Atributo APPLIANCE do registro de itens de configuracao tecnica (CMDB).'), PRIMARY KEY ("ID") USING INDEX ENABLE ) ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Armazena registros de itens de configuracao tecnica (CMDB); e utilizada por VIEW V_26AI_TECH.'); CREATE TABLE "TB_26AI_TECH_SYS" ( "ID_1" NUMBER GENERATED BY DEFAULT ON NULL AS IDENTITY MINVALUE 1 MAXVALUE 9999999999999999999999999999 INCREMENT BY 1 START WITH 1 CACHE 20 NOORDER NOCYCLE NOKEEP NOSCALE NOT NULL ENABLE ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Identificador unico do registro de cadastro de sistemas tecnicos; compoe a chave primaria da tabela.'), "ID" NUMBER ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Identificador tecnico do registro de cadastro de sistemas tecnicos.'), "TIMESTAMP" TIMESTAMP (9) WITH TIME ZONE ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Data, hora ou marco temporal associado ao registro de cadastro de sistemas tecnicos.'), "HOST" VARCHAR2(50) ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Atributo HOST do registro de cadastro de sistemas tecnicos.'), "FACILITY" VARCHAR2(50) ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Atributo FACILITY do registro de cadastro de sistemas tecnicos.'), "SEVERITY" VARCHAR2(50) ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Atributo SEVERITY do registro de cadastro de sistemas tecnicos.'), "PROCESS" VARCHAR2(50) ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Atributo PROCESS do registro de cadastro de sistemas tecnicos.'), "PID" NUMBER ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Atributo PID do registro de cadastro de sistemas tecnicos.'), "ORACLE_INSTANCE" VARCHAR2(50) ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Atributo ORACLE_INSTANCE do registro de cadastro de sistemas tecnicos.'), "MESSAGE" VARCHAR2(255) ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Mensagem, diagnostico ou informacao de log associada ao processamento de cadastro de sistemas tecnicos.'), "RAW_SYSLOG" VARCHAR2(255) ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Mensagem, diagnostico ou informacao de log associada ao processamento de cadastro de sistemas tecnicos.'), "INSIGHT_REPORT" CLOB ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Conteudo textual gerado por IA associado a cadastro de sistemas tecnicos.'), "INSIGHT_JSON" CLOB ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Conteudo estruturado em JSON relacionado ao insight gerado por IA para cadastro de sistemas tecnicos.'), PRIMARY KEY ("ID_1") USING INDEX ENABLE ) ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Armazena registros de cadastro de sistemas tecnicos (syslog); e utilizada por PROCEDURE PRC_26AI_TECH.'); CREATE SEQUENCE "SEQ_26AI_TECH" MINVALUE 1 MAXVALUE 9999999999999999999999999999 INCREMENT BY 1 START WITH 1 CACHE 20 NOORDER NOCYCLE NOKEEP NOSCALE GLOBAL; CREATE TABLE "TB_26AI_TECH_V2" ( "ID_1" NUMBER GENERATED BY DEFAULT ON NULL AS IDENTITY MINVALUE 1 MAXVALUE 9999999999999999999999999999 INCREMENT BY 1 START WITH 1 CACHE 20 NOORDER NOCYCLE NOKEEP NOSCALE NOT NULL ENABLE ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Identificador unico do registro de dados tecnicos (versao 2); compoe a chave primaria da tabela.'), "AGE_IN_DAYS" NUMBER ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Idade em dias do achado, referenciada em VIEW V_26AI_TECH.'), "ASSET_DISPLAY_IPV4_ADDRESS" VARCHAR2(255) ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Endereco IPv4 do ativo, referenciado em VIEW V_26AI_TECH.'), "ASSET_ID" VARCHAR2(255) ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Identificador do ativo, referenciado em VIEW V_26AI_TECH.'), "ASSET_NAME" VARCHAR2(100) ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Nome do ativo, referenciado em VIEW V_26AI_TECH.'), "ASSET_TAGS" VARCHAR2(32767) ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Tags do ativo, referenciadas em VIEW V_26AI_TECH.'), "DEFINITION_EXPLOITABILITY_EASE" VARCHAR2(50) ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Facilidade de exploracao da vulnerabilidade, referenciada em VIEW V_26AI_TECH.'), "DEFINITION_FAMILY" VARCHAR2(255) ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Familia da definicao de vulnerabilidade, referenciada em VIEW V_26AI_TECH.'), "DEFINITION_ID" NUMBER ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Identificador da definicao de vulnerabilidade, referenciado em VIEW V_26AI_TECH.'), "DEFINITION_NAME" VARCHAR2(255) ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Nome da definicao de vulnerabilidade, referenciado em VIEW V_26AI_TECH.'), "DEFINITION_VPR_SCORE" NUMBER ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Score VPR (Vulnerability Priority Rating), referenciado em VIEW V_26AI_TECH.'), "FIRST_OBSERVED" TIMESTAMP (9) WITH TIME ZONE ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Data da primeira observacao, referenciada em VIEW V_26AI_TECH.'), "ID" VARCHAR2(255) ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Identificador tecnico do achado, referenciado em VIEW V_26AI_TECH.'), "LAST_SEEN" TIMESTAMP (9) WITH TIME ZONE ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Data da ultima observacao, referenciada em VIEW V_26AI_TECH.'), "OUTPUT" VARCHAR2(32767) ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Saida/detalhe tecnico do scanner, referenciada em VIEW V_26AI_TECH.'), "PROTOCOL" VARCHAR2(50) ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Protocolo relacionado ao achado, referenciado em VIEW V_26AI_TECH.'), "RESURFACED_DATE" TIMESTAMP (9) WITH TIME ZONE ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Data de ressurgimento do achado, referenciada em VIEW V_26AI_TECH.'), "SEVERITY" VARCHAR2(50) ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Severidade do achado, referenciada em VIEW V_26AI_TECH.'), "STATE" VARCHAR2(50) ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Estado do achado, referenciado em VIEW V_26AI_TECH.'), "INSIGHT_REPORT" CLOB ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Relatorio de insight gerado por IA, referenciado em VIEW V_26AI_TECH.'), "INSIGHT_JSON" CLOB ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Insight estruturado em JSON gerado por IA.'), "ID_INSIGHT" NUMBER ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Identificador sequencial do insight, gerado pelo trigger BIU_TB_26AI_TECH_V2, referenciado em VIEW V_26AI_TECH.'), PRIMARY KEY ("ID_1") USING INDEX ENABLE ) ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Armazena os achados de vulnerabilidade (principal fonte de dados tecnicos); e utilizada por PROCEDURE PRC_26AI_TECH e VIEW V_26AI_TECH.'); CREATE OR REPLACE EDITIONABLE TRIGGER "BIU_TB_26AI_TECH_V2" BEFORE INSERT OR UPDATE ON TB_26AI_TECH_V2 FOR EACH ROW BEGIN :new.ID_INSIGHT := SEQ_26AI_TECH.NEXTVAL; END; / ALTER TRIGGER "BIU_TB_26AI_TECH_V2" ENABLE; -- Tabela legada (mantida por compatibilidade: ainda e usada por uma pagina/ -- carga de dados mais antiga da aplicacao - "DL_TECH_VULNERABILIDADES"). CREATE TABLE "TB_26AI_TECH" ( "ID_1" NUMBER GENERATED BY DEFAULT ON NULL AS IDENTITY MINVALUE 1 MAXVALUE 9999999999999999999999999999 INCREMENT BY 1 START WITH 1 CACHE 20 NOORDER NOCYCLE NOKEEP NOSCALE NOT NULL ENABLE, "AGE_IN_DAYS" NUMBER, "ASSET_DISPLAY_IPV4_ADDRESS" VARCHAR2(255), "ASSET_ID" VARCHAR2(255), "ASSET_NAME" VARCHAR2(100), "EMPRESA" VARCHAR2(50), "AMBIENTE" VARCHAR2(50), "STATUS" VARCHAR2(50), "DESCRIÇÃO" VARCHAR2(32767), "ASSET_OPERATING_SYSTEM" VARCHAR2(255), "DEFINITION_EXPLOITABILITY_EASE" VARCHAR2(50), "DEFINITION_FAMILY" VARCHAR2(255), "DEFINITION_ID" NUMBER, "DEFINITION_NAME" VARCHAR2(255), "DEFINITION_VPR_SCORE" NUMBER, "FIRST_OBSERVED" DATE, "ID" VARCHAR2(255), "LAST_SEEN" DATE, "OUTPUT" VARCHAR2(32767), "PROTOCOL" VARCHAR2(50), "RESURFACED_DATE" DATE, "SEVERITY" VARCHAR2(50), "STATE" VARCHAR2(50), "INSIGHT_REPORT" CLOB, "INSIGHT_JSON" CLOB, "ID_INSIGHT" NUMBER, PRIMARY KEY ("ID_1") USING INDEX ENABLE ); CREATE TABLE "TB_26AI_TECH_VECTOR" ( "EMBED_ID" NUMBER ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Representacao vetorial (embedding) associada ao conteudo de embeddings de conhecimento tecnico, destinada a buscas por similaridade e fluxos de recuperacao aumentada (RAG).'), "EMBED_DATA" CLOB ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Trecho de texto (chunk) que originou o vetor, referenciado em FUNCTION FNC_26AI_TECH_RAG.'), "EMBED_VECTOR" VECTOR ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Vetor (embedding) do trecho, referenciado em FUNCTION FNC_26AI_TECH_RAG.'), "TITULO" VARCHAR2(2000) ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Titulo/identificacao do registro de embeddings de conhecimento tecnico.'), "ID" VARCHAR2(200) ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Referencia (rowid/id) do registro de origem do insight, referenciada em FUNCTION FNC_26AI_TECH_RAG.'), "SOURCE_TYPE" VARCHAR2(3) ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Origem do dado vetorizado: VUL (vulnerabilidades) ou SYS (syslog).') ) ANNOTATIONS("LLM_DESCRIPTION_PT_BR" 'Armazena os vetores (chunks) usados na busca semantica/RAG; e utilizada por FUNCTION FNC_26AI_TECH_RAG e PROCEDURE PRC_26AI_TECH.'); -- View consolidada usada pela aplicacao e pelo SELECT AI. -- Observacao: as duas chamadas REPLACE() abaixo (colunas NOME/EMPRESA) -- fazem parte da logica de negocio original do ambiente de origem e -- generalizam nomes de marca especificos para "Company" em determinados -- cenarios de apresentacao. Como este e o proprio ambiente da AM/PM, avalie -- com o time de negocio se esse tratamento ainda faz sentido aqui ou se pode -- ser removido (ver docs/07-seguranca-boas-praticas.html). CREATE OR REPLACE FORCE EDITIONABLE VIEW "V_26AI_TECH" ("CID", "AGE_IN_DAYS", "ASSET_DISPLAY_IPV4_ADDRESS", "ASSET_ID", "ASSET_NAME", "ASSET_TAGS", "DEFINITION_EXPLOITABILITY_EASE", "DEFINITION_FAMILY", "DEFINITION_ID", "DEFINITION_NAME", "DEFINITION_VPR_SCORE", "FIRST_OBSERVED", "ID", "LAST_SEEN", "OUTPUT", "PROTOCOL", "RESURFACED_DATE", "SEVERITY", "STATE", "INSIGHT_REPORT", "ID_INSIGHT", "NOME", "EMPRESA", "CLASSE", "AMBIENTE", "STATUS_OPERACIONAL", "DESCRICAO", "SOX", "COFRE", "ENDERECO_IP", "SISTEMA_OPERACIONAL", "TIPO_DE_REDE", "IS_VIRTUAL", "CRITICIDADE", "INSTANCIAS_BANCOS", "APLICACOES_RELACIONADAS", "JANELAS_DE_MANUTENCAO", "ANALISTA_RESPONSAVEL", "ANALISTAS_RESPONSAVEIS", "GERENCIADO_PELO_GRUPO", "GRUPOS_RESPONSAVEIS", "GRUPO_RESPONSAVEL", "EDR", "TENABLE", "SIEM", "APPLIANCE") AS SELECT v.rowid cid, v.AGE_IN_DAYS , v.ASSET_DISPLAY_IPV4_ADDRESS , v.ASSET_ID , v.ASSET_NAME , v.ASSET_TAGS , v.DEFINITION_EXPLOITABILITY_EASE , v.DEFINITION_FAMILY , v.DEFINITION_ID , v.DEFINITION_NAME , v.DEFINITION_VPR_SCORE , v.FIRST_OBSERVED , v.ID , v.LAST_SEEN , v.OUTPUT , v.PROTOCOL , v.RESURFACED_DATE , v.SEVERITY , v.STATE , v.INSIGHT_REPORT , v.ID_INSIGHT , replace(replace(initcap(c.NOME),'Ipiranga','Company'),'Ampm','Company') NOME , replace(replace(initcap(c.EMPRESA),'Ipiranga','Company'),'Ampm','Company') EMPRESA , c.CLASSE , c.AMBIENTE , c.STATUS_OPERACIONAL , c.DESCRIÇÃO DESCRICAO , c.SOX , c.COFRE , c.ENDEREÇO_IP ENDERECO_IP , c.SISTEMA_OPERACIONAL , c.TIPO_DE_REDE , c.É_VIRTUAL IS_VIRTUAL , c.CRITICIDADE , c.INSTÂNCIAS_BANCOS INSTANCIAS_BANCOS , c.APLICAÇÕES_RELACIONADAS APLICACOES_RELACIONADAS , c.JANELAS_DE_MANUTENÇÃO JANELAS_DE_MANUTENCAO , c.ANALISTA_RESPONSAVEL , c.ANALISTAS_RESPONSÁVEIS ANALISTAS_RESPONSAVEIS , c.GERENCIADO_PELO_GRUPO , c.GRUPOS_RESPONSÁVEIS GRUPOS_RESPONSAVEIS , c.GRUPO_RESPONSÁVEL GRUPO_RESPONSAVEL , c.EDR, c.TENABLE , c.SIEM , c.APPLIANCE FROM TB_26AI_TECH_v2 v LEFT OUTER JOIN (SELECT * FROM TB_26AI_TECH_CMDB WHERE nome IN (SELECT nome FROM TB_26AI_TECH_CMDB GROUP BY nome HAVING count(1) = 1 ) ) c ON ( upper(v.ASSET_NAME) = upper(c.nome) AND c.AMBIENTE IS NOT NULL ); -- Log de chamadas de IA/embeddings (sucesso e erro) - nao guarda prompt/ -- resposta completos, so metadados de uso. Ver docs/09-operacao-observabilidade.html. CREATE TABLE "TB_26AI_TECH_LOG" ( "LOG_ID" NUMBER GENERATED ALWAYS AS IDENTITY MINVALUE 1 MAXVALUE 9999999999999999999999999999 INCREMENT BY 1 START WITH 1 CACHE 20 NOORDER NOCYCLE NOKEEP NOSCALE NOT NULL ENABLE, "LOG_TS" TIMESTAMP(6) WITH TIME ZONE DEFAULT SYSTIMESTAMP NOT NULL ENABLE, "CALLING_OBJECT" VARCHAR2(128), "OPERATION" VARCHAR2(30), "SOURCE_TYPE" VARCHAR2(10), "SOURCE_ID" VARCHAR2(200), "PROVIDER" VARCHAR2(30), "MODEL_NAME" VARCHAR2(100), "APP_USER" VARCHAR2(100), "STATUS" VARCHAR2(10), "ERROR_CODE" NUMBER, "ERROR_MESSAGE" VARCHAR2(4000), "DURATION_MS" NUMBER, "PROMPT_CHARS" NUMBER, "RESPONSE_CHARS" NUMBER, CONSTRAINT "TB_26AI_TECH_LOG_PK" PRIMARY KEY ("LOG_ID") USING INDEX ENABLE ); CREATE INDEX "TB_26AI_TECH_LOG_TS_IX" ON "TB_26AI_TECH_LOG" ("LOG_TS"); CREATE INDEX "TB_26AI_TECH_LOG_ST_IX" ON "TB_26AI_TECH_LOG" ("STATUS","LOG_TS"); COMMENT ON TABLE "TB_26AI_TECH_LOG" IS 'Log de cada chamada a Generative AI/embeddings feita pelo ampmInsights (sucesso ou erro) - nao guarda prompt/resposta completos, so metadados de uso (modelo, duracao, tamanho, status, erro). Usada para troubleshooting e monitoramento de consumo - ver docs/09-operacao-observabilidade.html.'; -------------------------------------------------------------------------------- -- SECAO 7 - PL/SQL de geracao de embeddings, RAG e insights (ampmInsights) -------------------------------------------------------------------------------- CREATE OR REPLACE PROCEDURE PRC_26AI_TECH_LOG ( p_calling_object IN VARCHAR2, p_operation IN VARCHAR2, p_status IN VARCHAR2, p_source_type IN VARCHAR2 DEFAULT NULL, p_source_id IN VARCHAR2 DEFAULT NULL, p_provider IN VARCHAR2 DEFAULT NULL, p_model_name IN VARCHAR2 DEFAULT NULL, p_error_code IN NUMBER DEFAULT NULL, p_error_message IN VARCHAR2 DEFAULT NULL, p_duration_ms IN NUMBER DEFAULT NULL, p_prompt_chars IN NUMBER DEFAULT NULL, p_response_chars IN NUMBER DEFAULT NULL ) AS PRAGMA AUTONOMOUS_TRANSACTION; /* Projeto: ampmInsights Objetivo: registrar em TB_26AI_TECH_LOG cada chamada a Generative AI/ embeddings (sucesso ou erro), para troubleshooting e monitoramento de consumo (ver docs/09-operacao-observabilidade.html). Autonomous transaction: pode ser chamada de dentro de functions invocadas em contexto SQL sem interferir na transacao do chamador; nunca propaga erro (uma falha ao logar nao pode derrubar a chamada real de IA). */ BEGIN INSERT INTO TB_26AI_TECH_LOG ( calling_object, operation, source_type, source_id, provider, model_name, app_user, status, error_code, error_message, duration_ms, prompt_chars, response_chars ) VALUES ( p_calling_object, p_operation, p_source_type, p_source_id, p_provider, p_model_name, NVL(V('APP_USER'), SYS_CONTEXT('USERENV','SESSION_USER')), p_status, p_error_code, SUBSTR(p_error_message, 1, 4000), p_duration_ms, p_prompt_chars, p_response_chars ); COMMIT; EXCEPTION WHEN OTHERS THEN NULL; -- logging nunca pode quebrar a chamada real END; / CREATE OR REPLACE FUNCTION fnc_26ai_embed( p_string IN VARCHAR2, p_emb_type IN VARCHAR2 DEFAULT 'COHERE', p_credential IN VARCHAR2 DEFAULT 'OCI_CRED') RETURN CLOB AS /* Projeto: ampmInsights Objetivo: gerar o embedding (vetor) de um texto, usando o provider indicado em p_emb_type: ONNX (modelo local carregado na SECAO 4), COHERE (OCI Generative AI - usado por padrao) ou vLLM (endpoint self-hosted, opcional). */ v_embedding CLOB; v_string CLOB; v_url VARCHAR2(700) := 'https://inference.generativeai.sa-saopaulo-1.oci.oraclecloud.com/20231130/actions/embedText'; v_body JSON_OBJECT_T; r DBMS_CLOUD_TYPES.RESP; BEGIN v_string := replace(replace(replace(p_string,chr(13),' '),chr(10),' '),'"','') ; IF p_emb_type = 'ONNX' THEN /* Pre-requisito: modelo ONNX carregado na SECAO 4 deste script (opcional). */ SELECT VECTOR_EMBEDDING( CLIP_VIT_LARGE_PATCH14_TXT USING v_string AS data ) AS embedding INTO v_embedding; ELSIF p_emb_type = 'COHERE' THEN /* CUIDADO: dbms_vector_chain.utl_to_text(v_string) usa internamente o Oracle Text Filter (processo externo ctxfilt) para converter documentos (PDF, DOCX etc.) em texto puro. O erro DRG-11225 (third-party filter timed out) indica que esse processo demorou mais que o timeout configurado. */ SELECT embed_vector INTO v_embedding FROM dual CROSS JOIN TABLE( dbms_vector_chain.utl_to_embeddings( dbms_vector_chain.utl_to_text( v_string ), json('{ "provider": "ocigenai", "credential_name": "' || p_credential || '", "url": "https://inference.generativeai.' || (SELECT param_value FROM TB_26AI_TECH_PARAMS WHERE param_name = 'GENAI_REGION') || '.oci.oraclecloud.com/20231130/actions/embedText", "model": "cohere.embed-v4.0" }') ) ) t CROSS JOIN JSON_TABLE( t.column_value, '$[*]' COLUMNS ( embed_id NUMBER PATH '$.embed_id', text_chunk VARCHAR2(4000) PATH '$.embed_data', embed_vector CLOB PATH '$.embed_vector' ) ) AS et; ELSIF p_emb_type = 'vLLM' THEN -- Endpoint self-hosted opcional (ex.: vLLM atras de um load -- balancer proprio). Ajuste "host" e "model" para o seu -- ambiente antes de usar esta opcao; nao e necessaria para o -- fluxo padrao (COHERE via OCI Generative AI). DECLARE params clob; v_embedding2 vector; BEGIN params := '{ "provider": "openai", "url": "https:///embed/v1/embeddings", "host": "local", "model": "", "batch_size": 50}'; v_embedding2 := dbms_vector_chain.utl_to_embedding( v_string , json(params)) ; v_embedding := TO_CLOB(TO_CHAR( v_embedding2 ) ) ; EXCEPTION WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE('Erro: ' || SQLCODE || ' - ' || SQLERRM); PRC_26AI_TECH_LOG( p_calling_object => 'FNC_26AI_EMBED', p_operation => 'EMBEDDING', p_status => 'ERROR', p_provider => 'vLLM', p_error_code => SQLCODE, p_error_message => SQLERRM ); END; END IF; RETURN v_embedding; EXCEPTION WHEN OTHERS THEN -- Cobre os ramos ONNX/COHERE (o vLLM ja trata e loga o proprio erro -- acima e nao propaga). Loga e repropaga sem mudar o comportamento -- existente. PRC_26AI_TECH_LOG( p_calling_object => 'FNC_26AI_EMBED', p_operation => 'EMBEDDING', p_status => 'ERROR', p_provider => p_emb_type, p_error_code => SQLCODE, p_error_message => SQLERRM ); RAISE; END; / CREATE OR REPLACE FUNCTION fnc_26ai_tech_rag(p_query VARCHAR2, p_top_k IN NUMBER , p_credential in varchar2 default 'OCI_CRED', p_app_user in varchar2 default V('APP_USER'), p_source_type varchar2 default 'VUL' ) RETURN CLOB IS /* Projeto: ampmInsights Objetivo: funcao de RAG (Retrieval-Augmented Generation) para "fale com os seus dados" no dominio tecnico (vulnerabilidades e syslog). */ v_context CLOB; v_pre_prompt CLOB; v_prompt CLOB; v_pre_prompt2 CLOB; params_genai CLOB; output CLOB; query_vec VECTOR; v_llm VARCHAR2(20) := 'LLAMA4'; -- [ LLAMA4 | OPENAI ] v_genai_region TB_26AI_TECH_PARAMS.PARAM_VALUE%TYPE; BEGIN SELECT param_value INTO v_genai_region FROM TB_26AI_TECH_PARAMS WHERE param_name = 'GENAI_REGION'; -- embedding da pergunta do usuario query_vec := to_vector( fnc_26ai_embed ( p_string => p_query, p_emb_type => 'COHERE' ) ) ; FOR message_cursor IN ( SELECT lv.ID AS DOCID, lv.EMBED_DATA AS BODY, vector_distance( lv.EMBED_VECTOR, query_vec, cosine ) AS SCORE FROM TB_26AI_TECH_VECTOR lv WHERE source_type = p_source_type ORDER BY SCORE FETCH EXACT FIRST p_top_k ROWS ONLY ) LOOP v_context := v_context || '"' || replace(replace(replace(replace(message_cursor.BODY,chr(10),null),chr(13),null),'"',''),'''','') || '",' ; END LOOP; -- Pre-requisito: credencial OCI_CRED criada na SECAO 3. -- Referencia do corpo da chamada: -- https://docs.oracle.com/en-us/iaas/api/#/en/generative-ai-inference/20231130/datatypes/GenerateTextDetails IF v_llm = 'LLAMA4' THEN params_genai := '{ "provider" : "ocigenai", "credential_name" : "' || p_credential || '", "url" : "https://inference.generativeai.' || v_genai_region || '.oci.oraclecloud.com/20231130/actions/chat", "model": "meta.llama-4-maverick-17b-128e-instruct-fp8"}'; ELSIF v_llm = 'OPENAI' THEN params_genai := '{ "provider" : "openai", "credential_name" : "CRED_OPENAI", "url" : "https://api.openai.com/v1/chat/completions", "model" : "gpt-4.1-mini", "temperature": 0.4 }'; END IF; v_pre_prompt := 'Voce e um Analista Senior de Inteligencia Operacional especializado em analisar relatorios tecnicos e executivos previamente gerados. Contexto de trabalho: - Voce recebera: 1) A pergunta do usuario 2) Um conjunto de trechos recuperados da base vetorizada de relatorios (com metadados como report_id, data, area, severidade, prioridade, fonte). - Sua tarefa e encontrar evidencias relevantes nesses relatorios e responder com precisao, sem inventar informacoes. Regras obrigatorias: - Use SOMENTE informacoes presentes nos trechos recuperados. - Se faltar dado para responder algo, escreva explicitamente: "Informacao nao fornecida". - Sempre cite as evidencias no formato: [report_id | secao/campo | data]. - Quando houver conflito entre relatorios, sinalize divergencia e indique qual evidencia e mais confiavel (recencia, completude, consistencia). - Priorize risco de negocio, severidade e urgencia. - Nao repita conteudo desnecessario; seja objetivo e acionavel. Metodo de resposta: 1) Entenda a intencao da pergunta (comparar, diagnosticar, priorizar, tendencia, causa, acao). 2) Selecione os trechos mais relevantes por aderencia semantica a pergunta. 3) Consolide achados em linguagem executiva + tecnica. 4) Gere recomendacoes praticas com prioridade e esforco. 5) Indique lacunas de dados que limitam a conclusao. Formato obrigatorio de saida: ## Resposta objetiva - Responda em formato markdown, e use fontes com mesmo tamanho, porem com titulos em NEGRITO. - Resposta direta a pergunta em 3 a 6 linhas. ## Evidencias encontradas - Evidencia 1: [report_id | secao/campo | data] - Evidencia 2: [report_id | secao/campo | data] - Evidencia 3: [report_id | secao/campo | data] ## Diagnostico consolidado - Causa/hipotese principal (Alta/Media/Baixa) - Risco de curto prazo - Risco de medio prazo ## Recomendacoes priorizadas - P1: | Impacto: <...> | Esforco: - P2: | Impacto: <...> | Esforco: - P3: | Impacto: <...> | Esforco: ## Lacunas e proximos dados necessarios - Informacao nao fornecida: - Dado adicional recomendado para aumentar confianca da resposta: <...>'; v_pre_prompt2 := '{ "role": "user","content": "Contexto:"' || v_context || ' "Pergunta": ' || p_query || '"}' ; output := dbms_vector_chain.utl_to_generate_text( replace(replace(replace(replace(v_pre_prompt || v_pre_prompt2,chr(10),null),chr(13),null),'"',''),'''','') , json(params_genai)); RETURN output; EXCEPTION WHEN OTHERS THEN -- Nao havia handler antes; loga e repropaga (comportamento de -- propagar o erro ao chamador continua o mesmo). PRC_26AI_TECH_LOG( p_calling_object => 'FNC_26AI_TECH_RAG', p_operation => 'RAG', p_status => 'ERROR', p_source_type => p_source_type, p_provider => 'ocigenai', p_error_code => SQLCODE, p_error_message => SQLERRM ); RAISE; END; / -- Funcao auxiliar usada por integracoes do tipo MCP (Model Context Protocol), -- caso a AM/PM/V8 Solution queira expor o RAG do ampmInsights como uma -- ferramenta (tool) de um agente externo. CREATE OR REPLACE FUNCTION FNC_26AI_TECH_MCP_V1 ( p_query IN VARCHAR2 ) RETURN CLOB AS V_TXT CLOB; V_SQL CLOB; BEGIN SELECT fnc_26ai_tech_rag(p_query, 60, 'OCI_CRED', 'MCPUSER') INTO V_TXT; RETURN V_TXT; END; / CREATE OR REPLACE FUNCTION FNC_26ai_rag (p_ai_prompt IN CLOB, p_oci_cred IN VARCHAR2 DEFAULT 'OCI_CRED', p_comp IN VARCHAR2 ) RETURN CLOB AS /* Projeto: ampmInsights Objetivo: funcao global de chamada ao LLM (Llama 4, via OCI Generative AI) usada pelo RAG e pela geracao de insights. */ v_gen_ai_endpoint VARCHAR2(500); v_gen_ai_model VARCHAR2(500) := 'meta.llama-4-maverick-17b-128e-instruct-fp8'; resp DBMS_CLOUD_TYPES.RESP; v_t0 PLS_INTEGER := DBMS_UTILITY.GET_TIME; v_result CLOB; BEGIN SELECT 'https://inference.generativeai.' || param_value || '.oci.oraclecloud.com' INTO v_gen_ai_endpoint FROM TB_26AI_TECH_PARAMS WHERE param_name = 'GENAI_REGION'; resp := dbms_cloud.send_request( credential_name => p_oci_cred, uri => v_gen_ai_endpoint || '/20231130/actions/chat', method => dbms_cloud.METHOD_POST, body => utl_raw.cast_to_raw(json_object( 'compartmentId' value p_comp, 'servingMode' value (json_object( 'modelId' value v_gen_ai_model, 'servingType' value 'ON_DEMAND' )), 'chatRequest' value (json_object( 'apiFormat' value 'GENERIC', 'messages' value (json_array(JSON_OBJECT( 'role' value 'USER', 'content' value (json_array(JSON_OBJECT( 'type' value 'TEXT', 'text' value p_ai_prompt ))) ))), 'temperature' value 0.1, 'topK' value -1 )) )) ); v_result := json_value( dbms_cloud.get_response_text(resp) , '$.chatResponse.choices[0].message.content[0].text') ; PRC_26AI_TECH_LOG( p_calling_object => 'FNC_26AI_RAG', p_operation => 'CHAT', p_status => 'OK', p_provider => 'ocigenai', p_model_name => v_gen_ai_model, p_duration_ms => (DBMS_UTILITY.GET_TIME - v_t0) * 10, p_prompt_chars => LENGTH(p_ai_prompt), p_response_chars => LENGTH(v_result) ); RETURN v_result; EXCEPTION WHEN OTHERS THEN PRC_26AI_TECH_LOG( p_calling_object => 'FNC_26AI_RAG', p_operation => 'CHAT', p_status => 'ERROR', p_provider => 'ocigenai', p_model_name => v_gen_ai_model, p_error_code => SQLCODE, p_error_message => SQLERRM, p_duration_ms => (DBMS_UTILITY.GET_TIME - v_t0) * 10, p_prompt_chars => LENGTH(p_ai_prompt) ); RETURN 'Nao foi possivel gerar um texto com base nas informacoes.'; END; / CREATE OR REPLACE PROCEDURE prc_26ai_tech (p_rowid IN VARCHAR DEFAULT NULL, p_oci_cred IN VARCHAR2 DEFAULT 'OCI_CRED', p_comp IN VARCHAR2, p_source_type VARCHAR2 DEFAULT 'VUL' ) /* Projeto: ampmInsights Gera o insight de IA (analise + diagnostico + recomendacoes + plano de acao) para um registro de TB_26AI_TECH_V2 (vulnerabilidades) ou TB_26AI_TECH_SYS (syslog), grava o resultado e cria o vetor (chunk) correspondente em TB_26AI_TECH_VECTOR. Para processamento em lote / carga inicial (rode manualmente uma vez, ou use o botao "Gerar Insights em Lote" da aplicacao APEX, que cria um job via DBMS_SCHEDULER lendo EMBEDDING_CREDENTIAL/EMBEDDING_COMPARTMENT a partir de TB_26AI_TECH_PARAMS - ver SECAO 2). O bloco abaixo tambem le o compartimento direto da tabela de configuracao, entao nao ha nenhum OCID para colar aqui: DECLARE v_resp CLOB; v_comp TB_26AI_TECH_PARAMS.PARAM_VALUE%TYPE; BEGIN SELECT param_value INTO v_comp FROM TB_26AI_TECH_PARAMS WHERE param_name = 'EMBEDDING_COMPARTMENT'; FOR r1 IN (SELECT rowid cid FROM TB_26AI_TECH_v2 WHERE insight_report IS NULL) LOOP PRC_26AI_TECH (p_rowid => r1.cid, p_oci_cred => 'OCI_CRED', p_comp => v_comp, p_source_type => 'VUL'); END LOOP; END; / */ AS v_pre_prompt CLOB; v_customer_data CLOB; v_pre_prompt_json CLOB; v_response CLOB; v_json CLOB; v_error CLOB; v_genai_region TB_26AI_TECH_PARAMS.PARAM_VALUE%TYPE; BEGIN SELECT param_value INTO v_genai_region FROM TB_26AI_TECH_PARAMS WHERE param_name = 'GENAI_REGION'; IF p_source_type = 'VUL' THEN -- vulnerabilidades v_pre_prompt :='Voce e um analista senior de dados e operacoes. Sua tarefa e interpretar os dados, comparar os resultados e produzir um relatorio executivo e tecnico acionavel. Objetivo: Gerar insights em 4 blocos: 1) Analise 2) Diagnostico 3) Recomendacoes 4) Plano de acao Regras de qualidade: - Nao invente dados ausentes. Quando faltar contexto, declare explicitamente "Informacao nao fornecida". - Seja especifico, com linguagem executiva + tecnica. - Priorize risco real de negocio e explorabilidade. - Sempre indicar severidade e prioridade. - Sempre incluir acoes de curto, medio e longo prazo. - Quando possivel, referenciar boas praticas (OWASP, NIST, CIS, CVE/CWE). Formato obrigatorio da resposta: ## 1. Analise - Resumo executivo (5 a 8 linhas) - Principais metricas observadas - Pontos fora do padrao (outliers/anomalias) ## 2. Diagnostico - Causas provaveis por ordem de impacto (Alta/Media/Baixa) - Evidencias que sustentam cada causa (referenciando campos do JSON) - Riscos de curto e medio prazo se nada for feito ## 3. Recomendacoes Para cada recomendacao, informe: - Acao recomendada - Problema que resolve - Impacto esperado - Esforco estimado (Baixo/Medio/Alto) - Prioridade (P1/P2/P3) ## 4. Plano de acao (30-60-90 dias) - 30 dias: acoes imediatas e "quick wins" - 60 dias: ajustes estruturais - 90 dias: consolidacao e otimizacao Para cada etapa, incluir: - Responsavel sugerido (perfil/funcao) - Dependencias - Metrica de sucesso (KPI) - Criterio de conclusao'; v_pre_prompt_json := '## FORMATO DE SAIDA JSON Quando solicitado no modo JSON, responda EXCLUSIVAMENTE com o objeto JSON valido conforme o schema abaixo, sem texto antes ou depois, sem markdown, sem blocos de codigo. O JSON deve ser parseable diretamente. Campos nao avaliaveis por qualidade de imagem devem receber null. Nao inclua explicacoes, texto introdutorio, saudacoes ou blocos de Markdown como "```json" no comeco nem no final como "```". ## Exemplo JSON: Retorne um JSON valido (sem comentarios), espelhando o relatorio: { "id": "", "titulo": "", "analise": { "resumo_tecnico": "", "vetor_ataque": "", "pre_condicoes": [], "impacto_cia": { "confidencialidade": "", "integridade": "", "disponibilidade": "" } }, "diagnostico": { "causa_raiz": "", "classificacao": { "cwe": "", "owasp": "" }, "severidade": "", "probabilidade_exploracao": "", "impacto_negocio": "", "prioridade_final": "", "justificativa": "" }, "recomendacoes": [ { "acao": "", "tipo": "corretiva|preventiva|detectiva", "esforco": "baixo|medio|alto", "dependencias": [] } ], "plano_acao": [ { "prazo": "curto|medio|longo", "etapa": "", "responsavel_sugerido": "", "deadline_sugerido": "", "resultado_esperado": "", "criterio_aceite": "" } ], "lacunas_informacao": [] }'; SELECT json_object( 'AGE_IN_DAYS' VALUE AGE_IN_DAYS, 'ASSET_DISPLAY_IPV4_ADDRESS' VALUE ASSET_DISPLAY_IPV4_ADDRESS, 'ASSET_ID' VALUE ASSET_ID, 'ASSET_NAME' VALUE ASSET_NAME, 'ASSET_TAGS' VALUE ASSET_TAGS, 'DEFINITION_EXPLOITABILITY_EASE' VALUE DEFINITION_EXPLOITABILITY_EASE, 'DEFINITION_FAMILY' VALUE DEFINITION_FAMILY, 'DEFINITION_ID' VALUE DEFINITION_ID, 'DEFINITION_NAME' VALUE DEFINITION_NAME, 'DEFINITION_VPR_SCORE' VALUE DEFINITION_VPR_SCORE, 'FIRST_OBSERVED' VALUE FIRST_OBSERVED, 'ID' VALUE ID, 'LAST_SEEN' VALUE LAST_SEEN, 'OUTPUT' VALUE OUTPUT, 'PROTOCOL' VALUE PROTOCOL, 'RESURFACED_DATE' VALUE RESURFACED_DATE, 'SEVERITY' VALUE SEVERITY, 'STATE' VALUE STATE, 'INSIGHT_REPORT' VALUE INSIGHT_REPORT, 'ID_INSIGHT' VALUE ID_INSIGHT, 'NOME' VALUE NOME, 'EMPRESA' VALUE EMPRESA, 'CLASSE' VALUE CLASSE, 'AMBIENTE' VALUE AMBIENTE, 'STATUS_OPERACIONAL' VALUE STATUS_OPERACIONAL, 'DESCRICAO' VALUE DESCRICAO, 'SOX' VALUE SOX, 'COFRE' VALUE COFRE, 'ENDERECO_IP' VALUE ENDERECO_IP, 'SISTEMA_OPERACIONAL' VALUE SISTEMA_OPERACIONAL, 'TIPO_DE_REDE' VALUE TIPO_DE_REDE, 'IS_VIRTUAL' VALUE IS_VIRTUAL, 'CRITICIDADE' VALUE CRITICIDADE, 'INSTANCIAS_BANCOS' VALUE INSTANCIAS_BANCOS, 'APLICACOES_RELACIONADAS' VALUE APLICACOES_RELACIONADAS, 'JANELAS_DE_MANUTENCAO' VALUE JANELAS_DE_MANUTENCAO, 'ANALISTA_RESPONSAVEL' VALUE ANALISTA_RESPONSAVEL, 'ANALISTAS_RESPONSAVEIS' VALUE ANALISTAS_RESPONSAVEIS, 'GERENCIADO_PELO_GRUPO' VALUE GERENCIADO_PELO_GRUPO, 'GRUPOS_RESPONSAVEIS' VALUE GRUPOS_RESPONSAVEIS, 'GRUPO_RESPONSAVEL' VALUE GRUPO_RESPONSAVEL, 'EDR' VALUE EDR, 'TENABLE' VALUE TENABLE, 'SIEM' VALUE SIEM, 'APPLIANCE' VALUE APPLIANCE ) AS my_json INTO v_customer_data FROM v_26ai_tech a WHERE cid = p_rowid; v_response := FNC_26ai_rag( p_ai_prompt => v_pre_prompt || '. Dados: ' || v_customer_data, p_oci_cred => p_oci_cred, p_comp => p_comp ); v_json := replace( replace( FNC_26ai_rag( p_ai_prompt => 'MODO JSON: ' || v_pre_prompt || ' ' || v_pre_prompt_json || '. Dados: ' || v_customer_data, p_oci_cred => p_oci_cred, p_comp => p_comp ) ,'```json','' ),'```','' ); UPDATE TB_26AI_TECH_v2 SET insight_report = v_response, insight_json = v_json WHERE rowid = p_rowid; ELSIF p_source_type = 'SYS' THEN -- SYSLOG v_pre_prompt :='Voce e um Assistente de Decisao Operacional especializado em interpretacao de eventos Syslog gerados por servidores Linux que executam bancos de dados Oracle. Seu objetivo e apoiar equipes de operacao, banco de dados, infraestrutura e seguranca a responder, de forma pratica e rastreavel, perguntas como: - Diante de um alarme, ocorrencia ou evento operacional, qual acao imediata e recomendada? - Existe historico parecido nos dados recuperados? - Qual procedimento operacional se aplica? - Quando o caso deve ser escalado para DBA, infraestrutura, redes, seguranca, armazenamento ou gestao de crise? - Qual evidencia do Syslog sustenta a recomendacao? Esquema dos dados: - `id`: identificador sequencial do evento no CSV. - `timestamp`: data e hora do evento em formato ISO com fuso horario. - `host`: servidor que gerou o evento. - `facility`: origem Syslog, como `daemon`, `local0`, `kern`, `authpriv` ou `cron`. - `severity`: severidade Syslog, como `info`, `notice`, `warning`, `err` ou `crit`. - `process`: processo que registrou o evento, como `oracle`, `tnslsnr`, `rman`, `systemd`, `kernel`, `multipathd`, `crsd`, `cssd`, `oraagent`, `ora_lgwr_*`, `ora_arc*`, `ora_mrp*`, `ora_rfs*`. - `pid`: identificador do processo. - `oracle_instance`: instancia Oracle relacionada, como `PROD`, `STBY` ou `RAC1`. - `message`: mensagem operacional normalizada. - `raw_syslog`: linha Syslog original ou aproximada. Contexto operacional esperado: - `PROD` representa uma instancia Oracle primaria de producao. - `STBY` representa uma instancia standby/Data Guard. - `RAC1` representa um ambiente Oracle RAC/Clusterware. - Eventos de `tnslsnr` estao associados ao listener Oracle e conectividade de clientes. - Eventos de `rman` indicam operacoes de backup e recuperacao. - Eventos `ora_arc*` indicam arquivamento de redo logs. - Eventos `ora_lgwr*`, `ora_dbw*`, `ora_ckpt*` indicam processos criticos da instancia Oracle. - Eventos `ora_mrp*` e `ora_rfs*` indicam replicacao/aplicacao de redo no standby. - Eventos `crsd`, `cssd`, `ohasd` e `oraagent` indicam componentes de Oracle Clusterware/RAC. - Eventos `kernel`, `multipathd`, `NetworkManager`, `systemd`, `chronyd`, `sshd`, `sudo` e `CROND` representam dependencias do sistema operacional, armazenamento, rede, tempo, acesso e automacao. Regras de interpretacao: 1. Use prioritariamente os trechos recuperados pelo RAG. Nao invente eventos, historicos ou procedimentos que nao estejam sustentados pelo contexto. 2. Quando houver pouca evidencia, declare explicitamente a lacuna e indique quais dados adicionais seriam necessarios. 3. Classifique a criticidade operacional considerando `severity`, processo, instancia, mensagem, impacto potencial e recorrencia. 4. Diferencie eventos informativos de eventos que exigem acao. 5. Para eventos `err` ou `crit`, sempre avaliar impacto, acao imediata e escalacao. 6. Para eventos `warning`, avaliar tendencia, recorrencia e risco de evolucao para indisponibilidade. 7. Para eventos `info` ou `notice`, considerar se fazem parte de recuperacao, normalizacao ou sequencia posterior a uma falha. 8. Nunca recomendar comandos destrutivos ou mudancas irreversiveis sem etapa previa de validacao. 9. Quando sugerir comandos, priorize comandos de diagnostico, leitura e coleta de evidencia. 10. Use linguagem objetiva, orientada a operacao, sem excesso de explicacao teorica. Padroes relevantes para decisao: - `ORA-00600`: erro interno Oracle. Tratar como criticidade alta ou critica. Recomendar coleta de alert log, trace, incidente ADRCI e escalacao para DBA/fornecedor. - `ORA-00257`: erro de archiver/FRA cheia. Tratar como risco direto de bloqueio de conexoes e indisponibilidade. Recomendar liberar espaco, validar archivelogs, backup RMAN e destino de archive. - `RMAN-03009`: falha de backup. Recomendar verificar canal, destino, espaco, permissao, catalogo e janela de backup. - `ORA-01034`: instancia Oracle indisponivel. Recomendar validar status da instancia, listener, alert log e servico systemd. - `TNS-12535`: timeout de listener/conectividade. Recomendar validar rede, firewall, listener, carga e origem do cliente. - `ORA-00060`: deadlock. Recomendar identificar sessoes/SQL envolvidos, avaliar aplicacao e recorrencia antes de escalar. - `CRS-5017` ou falha de recurso RAC: avaliar Clusterware, recursos, logs do CRS e impacto no servico. - Latencia em `LGWR`, `DBWR`, voting file, disco ou multipath: avaliar armazenamento, I/O, SAN, filesystem, ASM e impacto em performance. - Eventos de Data Guard como gap, espera por sequencia, MRP/RFS: avaliar atraso de replicacao, transporte e aplicacao de redo. - Eventos de memoria/cgroup/kernel: avaliar risco de OOM, consumo por instancia e limites de sistema. - Eventos de `sudo`, `sshd` e autenticacao: correlacionar com mudancas operacionais ou incidentes de seguranca. Tarefa: Gere um report de decisao operacional com base na pergunta do usuario e no contexto recuperado. Formato obrigatorio da resposta: 1. Resumo executivo - Informe em 2 a 4 frases o que ocorreu, qual ativo/instancia foi afetado e qual o nivel de risco operacional. 2. Evidencias encontradas no Syslog - Liste os eventos mais relevantes. - Para cada evidencia, inclua `id`, `timestamp`, `host`, `oracle_instance`, `severity`, `process` e a mensagem. - Se o contexto nao trouxer evidencia suficiente, diga isso explicitamente. 3. Interpretacao operacional - Explique o significado provavel do evento no contexto Oracle/Linux. - Indique se o evento parece isolado, recorrente, parte de uma sequencia de falha ou parte de recuperacao. 4. Acao recomendada - Liste a acao imediata recomendada. - Priorize contencao, diagnostico e reducao de impacto. - Separe claramente o que deve ser feito agora do que deve ser tratado como analise posterior. 5. Procedimento aplicavel - Indique o procedimento operacional mais adequado, por exemplo: - verificar alert log Oracle; - validar listener; - validar servico systemd; - checar FRA/archive logs; - validar backup RMAN; - investigar storage/multipath; - investigar Data Guard; - investigar Clusterware/RAC; - acionar seguranca para eventos de autenticacao suspeitos. 6. Confianca da recomendacao - Informe `Alta`, `Media` ou `Baixa`. - Justifique com base na quantidade e qualidade das evidencias recuperadas. Regras finais: - Responda em portugues do Brasil. - Seja objetivo e operacional. - Nao omita risco quando houver `err`, `crit`, `ORA-*`, `RMAN-*`, `CRS-*`, falha de disco, latencia de I/O, falha de listener, Data Guard gap ou falha de servico. - Nao declare causa raiz definitiva sem evidencia suficiente. - Sempre diferencie fato observado, inferencia e recomendacao.'; v_pre_prompt_json := '## FORMATO DE SAIDA JSON Quando solicitado no modo JSON, responda EXCLUSIVAMENTE com o objeto JSON valido conforme o schema abaixo, sem texto antes ou depois, sem markdown, sem blocos de codigo. O JSON deve ser parseable diretamente. Campos nao avaliaveis por qualidade de imagem devem receber null. Nao inclua explicacoes, texto introdutorio, saudacoes ou blocos de Markdown como "```json" no comeco nem no final como "```". ## Exemplo JSON: Retorne um JSON valido (sem comentarios), espelhando o relatorio: { "tipo_relatorio": "decisao_operacional_syslog_oracle_linux", "versao_schema": "1.0", "fonte_dados": { "arquivo_csv": "syslog_oracle_linux_examples.csv", "mecanismo": "RAG", "modelo_destino": "Llama 4", "campos_csv": [ "id", "timestamp", "host", "facility", "severity", "process", "pid", "oracle_instance", "message", "raw_syslog" ] }, "classificacao_evento": { "nivel_risco": "Baixo|Medio|Alto|Critico", "severidade_syslog": "info|notice|warning|err|crit", "categoria": "Banco de dados|Sistema operacional|Rede|Storage|Seguranca|Backup|Data Guard|RAC|Autenticacao", "impacto_potencial": "Descrever impacto operacional provavel", "estado": "Informativo|Em investigacao|Acao requerida|Escalado|Resolvido" }, "resumo_executivo": { "descricao": "Resumo em 2 a 4 frases do evento ou alarme analisado", "ativo_afetado": { "host": "Nome do servidor afetado", "oracle_instance": "Instancia Oracle afetada", "processo": "Processo principal relacionado ao evento" }, "risco_operacional": "Descricao objetiva do risco", "recomendacao_curta": "Acao recomendada em uma frase" }, "evidencias_syslog": [ { "id": 0, "timestamp": "YYYY-MM-DDTHH:MM:SS-03:00", "host": "host_origem", "facility": "facility_syslog", "severity": "severity_syslog", "process": "processo_origem", "pid": 0, "oracle_instance": "instancia_oracle", "message": "mensagem_normalizada", "raw_syslog": "linha_syslog_original", "relevancia": "Alta|Media|Baixa" } ], "interpretacao_operacional": { "fato_observado": "O que foi observado diretamente no Syslog", "inferencia": "Interpretacao operacional baseada nas evidencias", "possivel_causa": "Hipotese provavel, sem declarar causa raiz definitiva sem evidencia", "sequencia_eventos": "Evento isolado, sequencia de falha, recuperacao ou recorrencia", "recorrencia": "Isolado|Recorrente|Sequencia de falha|Recuperacao|Indeterminado" }, "acoes_recomendadas": { "imediatas": [ { "prioridade": 1, "acao": "Acao imediata recomendada", "objetivo": "Resultado esperado da acao", "responsavel_sugerido": "Operacao N1|Operacao N2|DBA Oracle|Linux/Infraestrutura|Storage|Redes|Seguranca|Sustentacao de Aplicacao|Gestao de Crise" } ] }'; SELECT json_object( 'ID_1' VALUE a."ID_1", 'ID' VALUE a."ID", 'TIMESTAMP' VALUE a."TIMESTAMP", 'HOST' VALUE a."HOST", 'FACILITY' VALUE a."FACILITY", 'SEVERITY' VALUE a."SEVERITY", 'PROCESS' VALUE a."PROCESS", 'PID' VALUE a."PID", 'ORACLE_INSTANCE' VALUE a."ORACLE_INSTANCE", 'MESSAGE' VALUE a."MESSAGE", 'RAW_SYSLOG' VALUE a."RAW_SYSLOG" ) AS my_json INTO v_customer_data FROM "TB_26AI_TECH_SYS" a WHERE rowid = p_rowid; v_response := FNC_26ai_rag( p_ai_prompt => v_pre_prompt || '. Dados: ' || v_customer_data, p_oci_cred => p_oci_cred, p_comp => p_comp ); UPDATE TB_26AI_TECH_SYS SET insight_report = v_response, insight_json = v_json WHERE rowid = p_rowid; END IF; IF length(v_response) > 0 THEN -- vetorizacao do relatorio gerado INSERT INTO TB_26AI_TECH_VECTOR SELECT et.embed_id, v_response, et.embed_vector, null, p_rowid, p_source_type FROM dual CROSS JOIN TABLE( DBMS_VECTOR_CHAIN.UTL_TO_EMBEDDINGS( ( v_response ) , json('{ "provider": "ocigenai", "credential_name": "' || p_oci_cred || '", "url": "https://inference.generativeai.' || v_genai_region || '.oci.oraclecloud.com/20231130/actions/embedText", "model": "cohere.embed-v4.0" }') ) ) t CROSS JOIN JSON_TABLE( t.column_value, '$[*]' COLUMNS ( embed_id NUMBER PATH '$.embed_id', text_chunk VARCHAR2(4000) PATH '$.embed_data', embed_vector CLOB PATH '$.embed_vector' ) ) AS et; PRC_26AI_TECH_LOG( p_calling_object => 'PRC_26AI_TECH', p_operation => 'EMBEDDING', p_status => 'OK', p_source_type => p_source_type, p_source_id => p_rowid, p_provider => 'ocigenai', p_model_name => 'cohere.embed-v4.0', p_prompt_chars => LENGTH(v_response) ); END IF; PRC_26AI_TECH_LOG( p_calling_object => 'PRC_26AI_TECH', p_operation => 'INSIGHT_PIPELINE', p_status => 'OK', p_source_type => p_source_type, p_source_id => p_rowid ); COMMIT; EXCEPTION WHEN OTHERS THEN v_error := sqlerrm; PRC_26AI_TECH_LOG( p_calling_object => 'PRC_26AI_TECH', p_operation => 'INSIGHT_PIPELINE', p_status => 'ERROR', p_source_type => p_source_type, p_source_id => p_rowid, p_error_code => SQLCODE, p_error_message => v_error ); -- Antes, o erro tecnico (sqlerrm) era gravado direto em insight_report e -- ficava visivel pro usuario de negocio no modal. Agora o erro completo -- vai so pro log (TB_26AI_TECH_LOG); o usuario ve uma mensagem amigavel. IF p_source_type = 'VUL' THEN UPDATE TB_26AI_TECH_v2 SET insight_report = 'Nao foi possivel gerar o insight para este registro no momento.', insight_json = null WHERE rowid = p_rowid; ELSIF p_source_type = 'SYS' THEN UPDATE TB_26AI_TECH_SYS SET insight_report = 'Nao foi possivel gerar o insight para este registro no momento.', insight_json = null WHERE rowid = p_rowid; END IF; COMMIT; END; / -------------------------------------------------------------------------------- -- SECAO 8 - Instalar a aplicacao APEX (ampmInsights) -------------------------------------------------------------------------------- -- etapa 1) Criar um workspace APEX (ou reutilizar um existente). -- etapa 2) Acessar o workspace usando o usuario de banco AMPMINSIGHTS criado -- na SECAO 1 (App Builder > associar o schema AMPMINSIGHTS ao -- workspace, se ainda nao estiver associado). -- etapa 3) Fazer upload do arquivo 02_ampminsights_apex_app.sql (instalacao -- da aplicacao). Confirmar que o "parsing schema" e AMPMINSIGHTS. -- Confirmar "Run and Build". -- etapa 4) Executar a aplicacao (logar com um usuario criado dentro da -- propria aplicacao, ou com o esquema de autenticacao configurado). -- etapa 5) Carregar os dados de CMDB (ativos/servidores). -- etapa 6) Carregar os dados de vulnerabilidades. -- etapa 7) Iniciar o processo de geracao de relatorios (insights) e -- vetorizacao (botao "Gerar Insights em Lote" na aplicacao, que cria -- um job via DBMS_SCHEDULER usando os parametros da SECAO 2). -- -- Veja o passo a passo detalhado, com telas e checklist, em: -- docs/05-passo-a-passo-apex.html -------------------------------------------------------------------------------- -- ANEXO - Limitacoes conhecidas / roadmap (herdadas do ambiente original) -------------------------------------------------------------------------------- -- 1) Os vetores (TB_26AI_TECH_VECTOR) nao sao removidos automaticamente em um -- eventual reprocessamento de um insight ja existente - avaliar rotina de -- limpeza/DELETE antes de reprocessar em massa. -- 2) A carga de dados (Data Load) atual faz "append": reexecutar uma carga -- pode gerar linhas duplicadas se o usuario nao tiver certeza de que os -- dados ja carregados nao estao duplicados (isso pode afetar contagens -- e indicadores). Considere um processo de MERGE/UPSERT como evolucao. -------------------------------------------------------------------------------- -- ANEXO - Objetos do ambiente de origem NAO incluidos neste script -------------------------------------------------------------------------------- -- O schema original continha ainda os objetos abaixo, confirmados (via -- inspecao do export da aplicacao) como NAO referenciados por -- 02_ampminsights_apex_app.sql. Foram deixados de fora desta linha de base -- limpa (V1) para nao carregar objetos orfaos no ambiente do cliente: -- DEMO_TECHNOLOGY -- DR$IDX_CONTENT_TECHNOLOGIES$N / $I / $B / $C / $K / $Q / $U (indice -- Oracle Text orfao, sem tabela base associada no export analisado) -- Caso alguma dessas pecas seja necessaria no seu caso de uso, recrie-a -- manualmente antes de prosseguir. --------------------------------------------------------------------------------