Files
ampmInsights/docs/04-passo-a-passo-banco.html
Antonio Sergio Rodrigues Figueiredo 1e9af90582 Torna a regiao do Generative AI configuravel (GENAI_REGION)
Region estava fixa em us-chicago-1 em varios pontos (ACL, testes 5.1/5.2/5.3,
FNC_26ai_rag, fnc_26ai_tech_rag, fnc_26ai_embed, PRC_26AI_TECH). Tenancies com
escopo regional restrito (ex. America Latina) podem nao alcancar essa regiao,
mesmo com credencial/ACL/compartimento corretos - o sintoma e ORA-20404
"Object not found" com uma URL bem formada.

Novo parametro GENAI_REGION em TB_26AI_TECH_PARAMS (default us-chicago-1,
editavel) substitui o valor fixo em todos os pontos de chamada. Seção 1.6
(ACL) continua com host fixo por rodar antes da tabela de config existir,
mas o comentario agora aponta para o parametro. docs/09 ganhou uma entrada
de checklist nova: ORA-20404 com URL correta pode ser modelo aposentado
para uso on-demand na regiao (verificavel via
`oci generative-ai model-collection list-models`), nao so credencial/ACL.

Seções 6 e 7 de docs/04-passo-a-passo-banco.html tambem foram
resincronizadas com o sql/01_ampminsights_db_setup.sql atual (estavam
desatualizadas desde a adição do TB_26AI_TECH_LOG).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-24 15:20:32 -03:00

1832 lines
99 KiB
HTML

<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>ampmInsights &middot; Passo a passo do banco de dados</title>
<meta name="description" content="Roteiro seção por seção do script 01_ampminsights_db_setup.sql.">
<link rel="stylesheet" href="assets/main.css">
</head>
<body>
<div class="layout">
<aside class="sidebar">
<div class="brand">
<span class="oracle">ORACLE</span>
<span class="name">ampmInsights</span>
</div>
<button class="menu-toggle" type="button">Menu &#9776;</button>
<div class="kicker">Documentação V1 &middot; AM/PM</div>
<ul class="nav-list">
<li><a class="" href="index.html"><span class="step-no">1</span>Visão geral</a></li>
<li><a class="" href="02-arquitetura.html"><span class="step-no">2</span>Arquitetura</a></li>
<li><a class="" href="03-pre-requisitos-credenciais.html"><span class="step-no">3</span>Pré-requisitos & credenciais</a></li>
<li><a class="active" href="04-passo-a-passo-banco.html"><span class="step-no">4</span>Passo a passo: banco de dados</a></li>
<li><a class="" href="05-passo-a-passo-apex.html"><span class="step-no">5</span>Passo a passo: aplicação APEX</a></li>
<li><a class="" href="06-validacao-testes.html"><span class="step-no">6</span>Validação & testes</a></li>
<li><a class="" href="07-seguranca-boas-praticas.html"><span class="step-no">7</span>Segurança & boas práticas</a></li>
<li><a class="" href="08-glossario-roadmap.html"><span class="step-no">8</span>Glossário & roadmap</a></li>
<li><a class="" href="09-operacao-observabilidade.html"><span class="step-no">9</span>Operação & observabilidade</a></li>
</ul>
<div class="sidebar-footer">
Vulnerability &amp; Audit AI Insights<br>
Oracle AI Database 26ai &middot; AI Vector Search<br>
Versão V1 &middot; ambiente reprodutível do cliente
</div>
</aside>
<main class="content">
<p class="page-kicker">Script 1 de 2</p>
<h1>Passo a passo: banco de dados</h1>
<p class="lede">Guia de execução de sql/01_ampminsights_db_setup.sql, seção por seção, na ordem em que deve ser rodado.</p>
<p>Este roteiro acompanha <code>sql/01_ampminsights_db_setup.sql</code> seção por seção. Cada bloco
abaixo é o código <strong>completo</strong> daquela seção — use o botão <strong>Copiar</strong> e
cole direto no SQL Worksheet do Database Actions. Rode um bloco de cada vez, na ordem apresentada,
e confira que não houve erro antes de seguir para o próximo.</p>
<div class="callout info">
<div class="callout-title">Você só preenche valores uma vez</div>
<p>A partir da Seção 2, todo OCID, região, namespace e nome de bucket é digitado <strong>uma única
vez</strong>, na tabela de configuração. Os blocos seguintes (credencial, modelo ONNX, SELECT AI)
leem esses valores automaticamente — você não vai precisar colar o mesmo OCID de novo em nenhum
outro lugar deste arquivo.</p>
</div>
<h2>Seção 1 &middot; Executar conectado como ADMIN do Autonomous Database</h2>
<p>Conecte como <strong>ADMIN</strong> do Autonomous Database (Database Actions &rarr; SQL,
logado como ADMIN). Este bloco cria o usuário/schema <code>AMPMINSIGHTS</code>, concede os
privilégios de AI Vector Search / DBMS_CLOUD / SELECT AI / credenciais / jobs, habilita ORDS e cria a
regra de rede (ACL) que autoriza o schema a chamar o OCI Generative AI.</p>
<div class="callout danger">
<div class="callout-title">Antes de copiar</div>
<p>Troque <code>&lt;SUBSTITUA_POR_UMA_SENHA_FORTE_SUA&gt;</code> por uma senha forte escolhida por
você (mínimo 12 caracteres, com maiúsculas, minúsculas, número e caractere especial) antes de colar
este bloco no Worksheet.</p>
</div>
<div class="code-block">
<div class="code-bar">
<span class="code-label">Seção 1 — copiar e colar</span>
<button class="copy-btn" type="button">Copiar</button>
</div>
<pre><code class="lang-sql">-- 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 &quot;&lt;SUBSTITUA_POR_UMA_SENHA_FORTE_SUA&gt;&quot;;
-- 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 =&gt; TRUE,
p_schema =&gt; &#x27;AMPMINSIGHTS&#x27;,
p_url_mapping_type =&gt; &#x27;BASE_PATH&#x27;,
p_url_mapping_pattern =&gt; &#x27;ampminsights&#x27;,
p_auto_rest_auth =&gt; TRUE
);
-- habilita o compartilhamento de dados usado por alguns recursos de AI/Vector
C##ADP$SERVICE.DBMS_SHARE.ENABLE_SCHEMA(
SCHEMA_NAME =&gt; &#x27;AMPMINSIGHTS&#x27;,
ENABLED =&gt; TRUE
);
COMMIT;
END;
/
-- 1.4) Quota de armazenamento no tablespace de dados
ALTER USER AMPMINSIGHTS QUOTA UNLIMITED ON &quot;DATA&quot;;
-- 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 =&gt; &#x27;inference.generativeai.us-chicago-1.oci.oraclecloud.com&#x27;,
lower_port =&gt; 443,
upper_port =&gt; 443,
ace =&gt; xs$ace_type(
privilege_list =&gt; xs$name_list(&#x27;connect&#x27;),
principal_name =&gt; &#x27;AMPMINSIGHTS&#x27;,
principal_type =&gt; xs_acl.ptype_db
)
);
DBMS_NETWORK_ACL_ADMIN.APPEND_HOST_ACE(
host =&gt; &#x27;inference.generativeai.us-chicago-1.oci.oraclecloud.com&#x27;,
ace =&gt; xs$ace_type(
privilege_list =&gt; xs$name_list(&#x27;resolve&#x27;),
principal_name =&gt; &#x27;AMPMINSIGHTS&#x27;,
principal_type =&gt; 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 = &#x27;AMPMINSIGHTS&#x27;;
--------------------------------------------------------------------------------
-- A partir daqui, conecte-se como o usuario AMPMINSIGHTS (nao mais como ADMIN)
--------------------------------------------------------------------------------</code></pre>
</div>
<h2>Seção 2 &middot; Tabela de configuracao (preencha os valores UMA UNICA VEZ aqui)</h2>
<p>Agora conecte como o usuário <strong>AMPMINSIGHTS</strong> que você acabou de criar (não mais
como ADMIN). Este bloco cria a <strong>tabela de configuração</strong> e insere, de uma vez, os 8
valores que os próximos blocos vão precisar. Veja em
<a href="03-pre-requisitos-credenciais.html">Pré-requisitos &amp; credenciais</a> onde obter cada um.</p>
<div class="callout danger">
<div class="callout-title">Antes de copiar</div>
<p>Substitua os 8 marcadores <code>&lt;SUBSTITUA_...&gt;</code> pelos valores reais do seu ambiente
antes de colar. Depois de rodar, confira com o <code>SELECT</code> no final do bloco que nenhuma
linha ainda mostra um marcador.</p>
</div>
<div class="code-block">
<div class="code-bar">
<span class="code-label">Seção 2 — copiar e colar</span>
<button class="copy-btn" type="button">Copiar</button>
</div>
<pre><code class="lang-sql">--
-- 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 &quot;TB_26AI_TECH_PARAMS&quot;
( &quot;PARAM_NAME&quot; VARCHAR2(100 CHAR) NOT NULL ENABLE,
&quot;PARAM_VALUE&quot; VARCHAR2(1000 CHAR) NOT NULL ENABLE,
&quot;DESCRIPTION&quot; VARCHAR2(4000),
CONSTRAINT &quot;TB_26AI_TECH_PARAMS_PK&quot; PRIMARY KEY (&quot;PARAM_NAME&quot;)
USING INDEX ENABLE
);
COMMENT ON TABLE &quot;TB_26AI_TECH_PARAMS&quot; IS &#x27;Tabela de configuracao central da aplicacao ampmInsights - preencher uma unica vez.&#x27;;
-- Preencha os 8 marcadores abaixo e rode o bloco UMA VEZ.
INSERT INTO TB_26AI_TECH_PARAMS (PARAM_NAME, PARAM_VALUE, DESCRIPTION) VALUES
(&#x27;EMBEDDING_CREDENTIAL&#x27;, &#x27;OCI_CRED&#x27;,
&#x27;Nome da credencial que sera criada na SECAO 3. Nao precisa alterar este valor.&#x27;);
INSERT INTO TB_26AI_TECH_PARAMS (PARAM_NAME, PARAM_VALUE, DESCRIPTION) VALUES
(&#x27;EMBEDDING_COMPARTMENT&#x27;, &#x27;&lt;SUBSTITUA_PELO_OCID_DO_COMPARTIMENTO_DO_BANCO&gt;&#x27;,
&#x27;OCID do compartimento OCI onde o Autonomous Database foi criado.&#x27;);
INSERT INTO TB_26AI_TECH_PARAMS (PARAM_NAME, PARAM_VALUE, DESCRIPTION) VALUES
(&#x27;OCI_TENANCY_OCID&#x27;, &#x27;&lt;SUBSTITUA_PELO_OCID_DO_TENANCY&gt;&#x27;,
&#x27;OCID do tenancy OCI (campo &quot;tenancy&quot; da API key).&#x27;);
INSERT INTO TB_26AI_TECH_PARAMS (PARAM_NAME, PARAM_VALUE, DESCRIPTION) VALUES
(&#x27;OCI_USER_OCID&#x27;, &#x27;&lt;SUBSTITUA_PELO_OCID_DO_USUARIO_OCI&gt;&#x27;,
&#x27;OCID do usuario OCI dono da API key (campo &quot;user&quot; da API key).&#x27;);
INSERT INTO TB_26AI_TECH_PARAMS (PARAM_NAME, PARAM_VALUE, DESCRIPTION) VALUES
(&#x27;OCI_FINGERPRINT&#x27;, &#x27;&lt;SUBSTITUA_PELA_FINGERPRINT_DA_API_KEY&gt;&#x27;,
&#x27;Fingerprint da API key (campo &quot;fingerprint&quot; da API key).&#x27;);
INSERT INTO TB_26AI_TECH_PARAMS (PARAM_NAME, PARAM_VALUE, DESCRIPTION) VALUES
(&#x27;OCI_REGION&#x27;, &#x27;&lt;SUBSTITUA_PELA_SUA_REGIAO&gt;&#x27;,
&#x27;Regiao OCI do seu tenancy, ex.: sa-saopaulo-1 (campo &quot;region&quot; da API key).&#x27;);
INSERT INTO TB_26AI_TECH_PARAMS (PARAM_NAME, PARAM_VALUE, DESCRIPTION) VALUES
(&#x27;OS_NAMESPACE&#x27;, &#x27;&lt;SUBSTITUA_PELO_SEU_NAMESPACE_DE_OBJECT_STORAGE&gt;&#x27;,
&#x27;Namespace do Object Storage do seu tenancy (Console OCI &gt; Storage &gt; Buckets &gt; &quot;Namespace&quot;).&#x27;);
INSERT INTO TB_26AI_TECH_PARAMS (PARAM_NAME, PARAM_VALUE, DESCRIPTION) VALUES
(&#x27;OS_BUCKET&#x27;, &#x27;&lt;SUBSTITUA_PELO_NOME_DO_BUCKET_QUE_VOCE_VAI_CRIAR&gt;&#x27;,
&#x27;Nome do bucket de Object Storage onde o modelo ONNX sera armazenado (ver SECAO 4).&#x27;);
INSERT INTO TB_26AI_TECH_PARAMS (PARAM_NAME, PARAM_VALUE, DESCRIPTION) VALUES
(&#x27;AI_LOG_RETENTION_DAYS&#x27;, &#x27;90&#x27;,
&#x27;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.&#x27;);
INSERT INTO TB_26AI_TECH_PARAMS (PARAM_NAME, PARAM_VALUE, DESCRIPTION) VALUES
(&#x27;GENAI_REGION&#x27;, &#x27;us-chicago-1&#x27;,
&#x27;Regiao do OCI Generative AI usada pelo RAG/insights/embeddings (SECAO 5+). Pode ser diferente da OCI_REGION (que e a regiao &quot;de casa&quot; 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 &quot;oci generative-ai model-collection list-models&quot; 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.&#x27;);
COMMIT;
-- Confira: nenhuma linha abaixo deve ainda mostrar um valor &quot;&lt;SUBSTITUA...&gt;&quot;
-- antes de voce seguir para a SECAO 3.
SELECT param_name, param_value, description FROM TB_26AI_TECH_PARAMS ORDER BY param_name;</code></pre>
</div>
<h2>Seção 3 &middot; Credencial de acesso a OCI (Generative AI + Object Storage)</h2>
<p>Cria a credencial <code>OCI_CRED</code>, usada pelo banco para chamar o OCI Generative AI e o
Object Storage. O bloco já lê tenancy/usuário/compartimento/fingerprint da tabela de configuração da
Seção 2 — o único valor que você ainda precisa colar aqui é o conteúdo da <strong>chave privada</strong>
(.pem), porque ela nunca é guardada em texto puro em nenhuma tabela.</p>
<div class="callout danger">
<div class="callout-title">Antes de copiar</div>
<p>Substitua o marcador da chave privada pelo conteúdo completo do seu arquivo <code>.pem</code>
(incluindo as linhas <code>BEGIN/END PRIVATE KEY</code>). Depois de confirmar que a credencial foi
criada (consulta no final do bloco), você pode apagar o arquivo <code>.pem</code> do seu computador
com segurança.</p>
</div>
<div class="code-block">
<div class="code-bar">
<span class="code-label">Seção 3 — copiar e colar</span>
<button class="copy-btn" type="button">Copiar</button>
</div>
<pre><code class="lang-sql">--
-- 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 &quot;API Signing Key&quot; 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 &gt; usuario &gt; User settings &gt; API keys &gt; Add API key &gt;
-- Generate API key pair &gt; Download private key &gt; 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 = &#x27;OCI_TENANCY_OCID&#x27;;
SELECT param_value INTO v_user FROM TB_26AI_TECH_PARAMS WHERE param_name = &#x27;OCI_USER_OCID&#x27;;
SELECT param_value INTO v_compartment FROM TB_26AI_TECH_PARAMS WHERE param_name = &#x27;EMBEDDING_COMPARTMENT&#x27;;
SELECT param_value INTO v_fingerprint FROM TB_26AI_TECH_PARAMS WHERE param_name = &#x27;OCI_FINGERPRINT&#x27;;
jo := JSON_OBJECT_T();
jo.put(&#x27;user_ocid&#x27;, v_user);
jo.put(&#x27;tenancy_ocid&#x27;, v_tenancy);
jo.put(&#x27;compartment_ocid&#x27;, 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(&#x27;private_key&#x27;,
&#x27;&lt;SUBSTITUA_PELO_CONTEUDO_COMPLETO_DA_CHAVE_PRIVADA_PEM_INCLUINDO_AS_LINHAS_BEGIN_E_END_E_AS_QUEBRAS_DE_LINHA_ORIGINAIS&gt;&#x27;);
jo.put(&#x27;fingerprint&#x27;, v_fingerprint);
DBMS_VECTOR_CHAIN.CREATE_CREDENTIAL(
credential_name =&gt; &#x27;OCI_CRED&#x27;,
params =&gt; 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 = &#x27;OCI_CRED&#x27;;</code></pre>
</div>
<h2>Seção 4 &middot; Modelo de embeddings ONNX</h2>
<p>Opcional — só necessária se você for usar embeddings de imagem/texto combinados (CLIP). O
fluxo padrão de texto do ampmInsights (embeddings de relatórios, RAG) não depende desta seção e pode
ser pulado.</p>
<p>O arquivo <code>CLIP_VIT_LARGE_PATCH14_TXT.onnx</code>, já convertido e testado no formato que o
Oracle AI Database espera, está incluído neste pacote em <code>modelo-onnx/</code>. O passo 4.1 é só
localizar esse arquivo; depois é criar seu bucket e subir o arquivo (passo 4.2, via Console OCI ou
OCI CLI), e o bloco de SQL (passo 4.3) monta a URL sozinho a partir da tabela de configuração e
carrega o modelo no banco.</p>
<div class="code-block">
<div class="code-bar">
<span class="code-label">Seção 4 — copiar e colar</span>
<button class="copy-btn" type="button">Copiar</button>
</div>
<pre><code class="lang-sql">--
-- 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á logo abaixo, em &quot;Como converter um modelo
-- ONNX&quot; — é 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 &gt; Storage &gt; Buckets &gt; Create Bucket
-- (ou via OCI CLI: oci os bucket create --name &lt;valor-de-OS_BUCKET&gt; --compartment-id &lt;OCID-do-compartimento&gt;)
-- Console OCI &gt; abra o bucket &gt; Upload &gt; selecione o CLIP_VIT_LARGE_PATCH14_TXT.onnx
-- (ou via OCI CLI: oci os object put -bn &lt;valor-de-OS_BUCKET&gt; --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 = &#x27;OCI_REGION&#x27;;
SELECT param_value INTO v_namespace FROM TB_26AI_TECH_PARAMS WHERE param_name = &#x27;OS_NAMESPACE&#x27;;
SELECT param_value INTO v_bucket FROM TB_26AI_TECH_PARAMS WHERE param_name = &#x27;OS_BUCKET&#x27;;
v_uri := &#x27;https://objectstorage.&#x27; || v_region || &#x27;.oraclecloud.com/n/&#x27; || v_namespace || &#x27;/b/&#x27; || v_bucket || &#x27;/o/CLIP_VIT_LARGE_PATCH14_TXT.onnx&#x27;;
DBMS_VECTOR.LOAD_ONNX_MODEL_CLOUD(
model_name =&gt; &#x27;CLIP_VIT_LARGE_PATCH14_TXT&#x27;,
credential =&gt; &#x27;OCI_CRED&#x27;,
uri =&gt; v_uri,
metadata =&gt; JSON(&#x27;{
&quot;function&quot;: &quot;embedding&quot;,
&quot;embeddingOutput&quot;: &quot;embedding&quot;,
&quot;input&quot;: {&quot;input&quot;: [&quot;DATA&quot;]}
}&#x27;)
);
END;
/
SELECT model_name, algorithm, mining_function
FROM user_mining_models
WHERE model_name = &#x27;CLIP_VIT_LARGE_PATCH14_TXT&#x27;;</code></pre>
</div>
<h2 id="converter-onnx">Como converter um modelo ONNX (opcional)</h2>
<p>O arquivo incluído neste pacote (<code>modelo-onnx/CLIP_VIT_LARGE_PATCH14_TXT.onnx</code>) já
está pronto para uso — você não precisa desta seção para concluir a Seção 4. Ela fica aqui como
referência para o caso de, no futuro, você querer carregar no banco um modelo ONNX diferente.</p>
<h3>Por que um export "cru" pode não funcionar</h3>
<p>Um export "cru", feito chamando <code>torch.onnx.export</code> (ou o exportador equivalente do
HuggingFace <code>optimum</code>) diretamente, sem nenhum tratamento adicional, normalmente produz um
tensor de entrada com <strong>dois eixos dinâmicos não vinculados</strong>: o tamanho do lote
(<code>batch_size</code>) <em>e</em> o comprimento da sequência de tokens (<code>sequence_length</code>).
O mecanismo de ONNX Runtime embutido no Oracle AI Database exige que, no máximo, um eixo do tensor de
entrada seja dinâmico — os demais precisam ter um tamanho fixo conhecido em tempo de carga do modelo.
Um arquivo com dois eixos livres é rejeitado pelo <code>DBMS_VECTOR.LOAD_ONNX_MODEL_CLOUD</code> com
o erro <code>ORA-54426</code>, mesmo que o arquivo abra normalmente em qualquer visualizador ONNX e
pareça válido.</p>
<h3>A ferramenta certa: OML4Py <code>ONNXPipeline</code></h3>
<p>A Oracle disponibiliza um pacote Python próprio, <strong>OML4Py</strong>, com uma classe utilitária
(<code>oml.utils.ONNXPipeline</code>) que já sabe converter uma lista de modelos populares do
HuggingFace (incluindo o <code>openai/clip-vit-large-patch14</code> usado nesta seção) no formato que o
banco espera. Para esse modelo especificamente, o pipeline usa um template chamado
<code>multimodal_clip</code> que faz duas coisas ao mesmo tempo:</p>
<ul>
<li>fixa o comprimento de sequência em 77 tokens (o limite do CLIP), eliminando o segundo eixo
dinâmico;</li>
<li>embute o tokenizer do CLIP <em>dentro do próprio grafo ONNX</em> (usando operadores customizados
da biblioteca <code>onnxruntime-extensions</code>, como o nó <code>CLIPTokenizer</code>), de forma que
o modelo final recebe <strong>texto puro (string)</strong> como entrada em vez de IDs de token já
tokenizados. Sobra só um eixo dinâmico — o tamanho do lote.</li>
</ul>
<p>Resultado prático: o <code>ONNXPipeline</code> não gera um, mas <strong>dois</strong> arquivos a
partir do mesmo modelo — um com sufixo <code>_txt</code> (a torre de texto, que é a que interessa pra
embeddings de relatórios/RAG) e um com sufixo <code>_img</code> (a torre de imagem). Use o <code>_txt</code>
no <code>LOAD_ONNX_MODEL_CLOUD</code> da Seção 4.3 acima.</p>
<div class="callout info">
<div class="callout-title">Não existe cliente OML4Py para macOS</div>
<p>O pacote OML4Py só tem build oficial para Linux. Em uma máquina macOS (como a usada neste
roteiro), a conversão precisa rodar dentro de um container Docker Linux
(<code>--platform=linux/amd64</code>). Os passos abaixo já contemplam isso.</p>
</div>
<h3>Passo a passo (via Docker)</h3>
<p>Pré-requisitos: Docker Desktop instalado, o wheel do cliente OML4Py baixado do site da Oracle
(variante Linux x86_64), pelo menos ~15 GB de espaço livre em disco e Docker Desktop configurado com
~10&ndash;12 GB de memória (Settings &gt; Resources &gt; Memory) — a conversão baixa o modelo completo
(~1,7 GB), instala <code>torch</code> e faz tracing + quantização, que usam bem mais RAM do que o
tamanho do modelo em disco.</p>
<div class="code-block">
<div class="code-bar">
<span class="code-label">1 — criar a pasta de trabalho e o requirements.txt</span>
<button class="copy-btn" type="button">Copiar</button>
</div>
<pre><code class="lang-bash">mkdir -p ~/oracle-onnx-convert/{tmp,hf-cache,pip-cache,out}
cd ~/oracle-onnx-convert
cat &gt; requirements.txt &lt;&lt;&#x27;EOF&#x27;
--extra-index-url https://download.pytorch.org/whl/cpu
pandas==2.2.3
setuptools==80.8.0
scipy==1.14.1
matplotlib==3.10.0
oracledb==3.3.0
scikit-learn==1.6.1
numpy==2.1.0
pyarrow==19.0.0
onnxruntime==1.20.0
onnxruntime-extensions==0.14.0
onnx==1.18.0
torch==2.9.0
transformers==4.56.1
sentencepiece==0.2.1
EOF
# copie o .whl do OML4Py (baixado do site da Oracle) para esta pasta, ex.:
# oml-2.1.1-cp313-cp313-linux_x86_64.whl</code></pre>
</div>
<div class="code-block">
<div class="code-bar">
<span class="code-label">2 — subir o container com os mounts corretos</span>
<button class="copy-btn" type="button">Copiar</button>
</div>
<pre><code class="lang-bash">cd ~/oracle-onnx-convert
docker run -d --platform=linux/amd64 --name onnx-convert \
-v "$PWD":/work \
-v "$PWD/tmp":/tmp \
-v "$PWD/hf-cache":/root/.cache/huggingface \
-v "$PWD/pip-cache":/root/.cache/pip \
-e TMPDIR=/tmp \
-w /work python:3.13-slim sleep infinity</code></pre>
</div>
<div class="callout warning">
<div class="callout-title">Por que montar /tmp e os caches</div>
<p>Em ambientes com "Enhanced Container Isolation" (comum em Docker Desktop com política
corporativa), o <code>/tmp</code> interno do container pode vir montado como somente-leitura, e a
etapa de quantização do <code>onnxruntime</code> precisa escrever arquivos temporários ali. Montar
<code>hf-cache</code> e <code>pip-cache</code> no host também evita baixar o modelo (~1,7&nbsp;GB)
de novo caso você precise recriar o container.</p>
</div>
<div class="code-block">
<div class="code-bar">
<span class="code-label">3 — instalar dependências dentro do container</span>
<button class="copy-btn" type="button">Copiar</button>
</div>
<pre><code class="lang-bash">docker exec onnx-convert bash -c "apt-get update -qq && apt-get install -y -qq build-essential"
docker exec onnx-convert bash -c "pip install --upgrade pip -q && pip install -r requirements.txt -q"
docker exec onnx-convert bash -c "pip install oml-*.whl -q"</code></pre>
</div>
<div class="code-block">
<div class="code-bar">
<span class="code-label">4 — rodar a conversão</span>
<button class="copy-btn" type="button">Copiar</button>
</div>
<pre><code class="lang-bash">docker exec onnx-convert python3 -c "
from oml.utils import ONNXPipeline
import os
pipeline = ONNXPipeline(model_name=&#x27;openai/clip-vit-large-patch14&#x27;)
os.makedirs(&#x27;/work/out&#x27;, exist_ok=True)
pipeline.export2file(&#x27;CLIP_VIT_LARGE_PATCH14&#x27;, output_dir=&#x27;/work/out&#x27;)
print(&#x27;EXPORT_DONE&#x27;)
"</code></pre>
</div>
<p>Ao final, <code>~/oracle-onnx-convert/out/</code> vai ter dois arquivos:
<code>CLIP_VIT_LARGE_PATCH14_txt.onnx</code> (o que interessa) e
<code>CLIP_VIT_LARGE_PATCH14_img.onnx</code>.</p>
<h3>Verificar o resultado antes de subir pro bucket</h3>
<p>Com o pacote <code>onnx</code> (<code>pip install onnx</code>, roda em qualquer SO, inclusive fora
do container) dá pra inspecionar o grafo gerado e confirmar que o eixo duplicado sumiu, sem precisar
de acesso ao banco:</p>
<div class="code-block">
<div class="code-bar">
<span class="code-label">verificação local</span>
<button class="copy-btn" type="button">Copiar</button>
</div>
<pre><code class="lang-python">import onnx
m = onnx.load(&#x27;CLIP_VIT_LARGE_PATCH14_txt.onnx&#x27;)
for inp in m.graph.input:
dims = [d.dim_param or d.dim_value for d in inp.type.tensor_type.shape.dim]
print(inp.name, dims)
# esperado: input [&#x27;batch_size&#x27;] -&gt; um so eixo dinamico, tipo string
# (elem_type 8 = STRING; o primeiro node do grafo deve ser um CLIPTokenizer)</code></pre>
</div>
<p>Se a saída mostrar <strong>dois</strong> eixos no input (ex.: <code>[&#x27;batch_size&#x27;,
&#x27;sequence_length&#x27;]</code>), o arquivo ainda é um export cru e vai reproduzir o ORA-54426 — volte ao
passo 4 do Docker. Com um só eixo confirmado, siga para a Seção 4.2/4.3 acima (upload no bucket e
<code>LOAD_ONNX_MODEL_CLOUD</code>). Se o modelo já estava carregado no banco com o nome
<code>CLIP_VIT_LARGE_PATCH14_TXT</code>, rode <code>DBMS_VECTOR.DROP_ONNX_MODEL</code> antes de
carregar a versão nova (o mesmo nome de modelo não pode ser recarregado por cima).</p>
<h2>Seção 5 &middot; Testes rapidos de sanidade (embedding, geracao de texto, SELECT AI)</h2>
<p>Três testes rápidos para confirmar que a credencial e a rede estão corretas antes de seguir
para as tabelas e o PL/SQL da aplicação: um teste de embedding, um teste de geração de texto e a
criação de um profile de SELECT AI (que já lê região e compartimento da tabela de configuração).</p>
<div class="code-block">
<div class="code-bar">
<span class="code-label">Seção 5 — copiar e colar</span>
<button class="copy-btn" type="button">Copiar</button>
</div>
<pre><code class="lang-sql">-- 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(&#x27;Teste simples para gerar um embedding.&#x27;),
JSON(&#x27;{
&quot;provider&quot;: &quot;ocigenai&quot;,
&quot;credential_name&quot;: &quot;OCI_CRED&quot;,
&quot;url&quot;: &quot;https://inference.generativeai.&#x27; || (SELECT param_value FROM TB_26AI_TECH_PARAMS WHERE param_name = &#x27;GENAI_REGION&#x27;) || &#x27;.oci.oraclecloud.com/20231130/actions/embedText&quot;,
&quot;model&quot;: &quot;cohere.embed-v4.0&quot;
}&#x27;)
)
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(&#x27;Responda somente com a palavra: sucesso&#x27;),
JSON(&#x27;{
&quot;provider&quot;: &quot;ocigenai&quot;,
&quot;credential_name&quot;: &quot;OCI_CRED&quot;,
&quot;url&quot;: &quot;https://inference.generativeai.&#x27; || (SELECT param_value FROM TB_26AI_TECH_PARAMS WHERE param_name = &#x27;GENAI_REGION&#x27;) || &#x27;.oci.oraclecloud.com/20231130/actions/chat&quot;,
&quot;model&quot;: &quot;meta.llama-4-maverick-17b-128e-instruct-fp8&quot;,
&quot;chatRequest&quot;: {
&quot;temperature&quot;: 0.1,
&quot;topK&quot;: 1,
&quot;maxTokens&quot;: 50
}
}&#x27;)
) 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 = &#x27;EMBEDDING_COMPARTMENT&#x27;;
SELECT param_value INTO v_genai_region FROM TB_26AI_TECH_PARAMS WHERE param_name = &#x27;GENAI_REGION&#x27;;
DBMS_CLOUD_AI.CREATE_PROFILE(
profile_name =&gt; &#x27;OCI_CRED2&#x27;,
attributes =&gt; &#x27;{
&quot;provider&quot;: &quot;oci&quot;,
&quot;credential_name&quot;: &quot;OCI_CRED&quot;,
&quot;region&quot;: &quot;&#x27; || v_genai_region || &#x27;&quot;,
&quot;model&quot;: &quot;meta.llama-4-maverick-17b-128e-instruct-fp8&quot;,
&quot;temperature&quot;: 0,
&quot;comments&quot;: true,
&quot;object_list&quot;: [
{&quot;owner&quot;: &quot;AMPMINSIGHTS&quot;, &quot;name&quot;: &quot;V_26AI_TECH&quot;},
{&quot;owner&quot;: &quot;AMPMINSIGHTS&quot;, &quot;name&quot;: &quot;TB_26AI_TECH_CMDB&quot;}
],
&quot;enforce_object_list&quot;: &quot;true&quot;
}&#x27;,
description =&gt; &#x27;Profile ampmInsights para uso no SELECT AI (OCI Generative AI - Llama 4 Maverick). Compartimento: &#x27; || v_compartment
);
END;
/
SELECT DBMS_CLOUD_AI.GENERATE(
prompt =&gt; &#x27;Responda apenas: CONECTADO&#x27;,
profile_name =&gt; &#x27;OCI_CRED2&#x27;,
action =&gt; &#x27;chat&#x27;
) AS resposta
FROM dual;</code></pre>
</div><div class="callout warning">
<div class="callout-title">O passo mais importante</div>
<p><code>TB_26AI_TECH_PARAMS</code> (criada na Seção 2) guarda o nome da credencial e o OCID do
compartimento. Todo o PL/SQL da aplicação — e o job de processamento em lote criado pelo botão da
interface — lê esses valores dali. Se algo falhar mais adiante, confira primeiro se essa tabela
está com os valores reais preenchidos.</p>
</div>
<h2>Seção 6 &middot; Tabelas, sequence, trigger e view da aplicacao</h2>
<p>Cria <code>TB_26AI_TECH_CHAT</code>, <code>TB_26AI_TECH_CMDB</code>, <code>TB_26AI_TECH_SYS</code>,
<code>TB_26AI_TECH_V2</code> (+ trigger/sequence de <code>ID_INSIGHT</code>), a tabela legada
<code>TB_26AI_TECH</code>, <code>TB_26AI_TECH_VECTOR</code> e a view <code>V_26AI_TECH</code>. Nomes
idênticos aos usados no export da aplicação APEX — não renomear estes objetos.</p>
<div class="code-block">
<div class="code-bar">
<span class="code-label">Seção 6 — copiar e colar</span>
<button class="copy-btn" type="button">Copiar</button>
</div>
<pre><code class="lang-sql">-- 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 &quot;TB_26AI_TECH_CHAT&quot;
( &quot;USER_NAME&quot; VARCHAR2(200) ANNOTATIONS(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Identificador, papel ou atributo de usuario/controle de acesso associado a interacoes de chat do dominio tecnico.&#x27;),
&quot;IS_OWN&quot; VARCHAR2(6) ANNOTATIONS(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Indicador booleano de is own no registro de interacoes de chat do dominio tecnico.&#x27;),
&quot;COMMENT_TEXT&quot; CLOB ANNOTATIONS(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Conteudo textual, documental ou binario associado a interacoes de chat do dominio tecnico; o nome da coluna indica o papel especifico no fluxo.&#x27;),
&quot;COMMENT_DATE&quot; DATE ANNOTATIONS(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Data, hora ou marco temporal associado ao registro de interacoes de chat do dominio tecnico.&#x27;),
&quot;SESSION_ID&quot; NUMBER ANNOTATIONS(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Identificador ou codigo de session no contexto de interacoes de chat do dominio tecnico.&#x27;)
)
ANNOTATIONS(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Armazena registros de interacoes de chat do dominio tecnico (&quot;fale com os dados&quot;); e classificada, pela nomenclatura e estrutura, como tabela operacional do dominio.&#x27;);
CREATE TABLE &quot;TB_26AI_TECH_CMDB&quot;
( &quot;ID&quot; 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(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Identificador unico do registro de itens de configuracao tecnica (CMDB); compoe a chave primaria da tabela. E coluna identity preenchida automaticamente pelo Oracle.&#x27;),
&quot;NOME&quot; VARCHAR2(255) ANNOTATIONS(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Nome ou titulo usado para identificar o registro de itens de configuracao tecnica (CMDB) em consultas e interfaces.&#x27;),
&quot;EMPRESA&quot; VARCHAR2(50) ANNOTATIONS(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Atributo EMPRESA do registro de itens de configuracao tecnica (CMDB).&#x27;),
&quot;CLASSE&quot; VARCHAR2(50) ANNOTATIONS(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Atributo de classificacao, versao, origem ou formato do registro de itens de configuracao tecnica (CMDB).&#x27;),
&quot;AMBIENTE&quot; VARCHAR2(50) ANNOTATIONS(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Atributo AMBIENTE do registro de itens de configuracao tecnica (CMDB).&#x27;),
&quot;STATUS_OPERACIONAL&quot; VARCHAR2(50) ANNOTATIONS(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Indicador de estado ou de controle do registro de itens de configuracao tecnica (CMDB).&#x27;),
&quot;DESCRIÇÃO&quot; VARCHAR2(32767) ANNOTATIONS(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Texto descritivo, detalhe ou observacao associado a itens de configuracao tecnica (CMDB).&#x27;),
&quot;SOX&quot; NUMBER ANNOTATIONS(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Atributo SOX do registro de itens de configuracao tecnica (CMDB).&#x27;),
&quot;COFRE&quot; NUMBER ANNOTATIONS(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Atributo COFRE do registro de itens de configuracao tecnica (CMDB).&#x27;),
&quot;ENDEREÇO_IP&quot; VARCHAR2(50) ANNOTATIONS(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Endereco IP registrado no contexto de itens de configuracao tecnica (CMDB).&#x27;),
&quot;SISTEMA_OPERACIONAL&quot; VARCHAR2(255) ANNOTATIONS(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Atributo SISTEMA_OPERACIONAL do registro de itens de configuracao tecnica (CMDB).&#x27;),
&quot;TIPO_DE_REDE&quot; VARCHAR2(50) ANNOTATIONS(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Atributo TIPO_DE_REDE do registro de itens de configuracao tecnica (CMDB).&#x27;),
&quot;É_VIRTUAL&quot; NUMBER ANNOTATIONS(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Atributo E_VIRTUAL do registro de itens de configuracao tecnica (CMDB).&#x27;),
&quot;CRITICIDADE&quot; VARCHAR2(50) ANNOTATIONS(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Atributo CRITICIDADE do registro de itens de configuracao tecnica (CMDB).&#x27;),
&quot;INSTÂNCIAS_BANCOS&quot; VARCHAR2(50) ANNOTATIONS(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Atributo INSTANCIAS_BANCOS do registro de itens de configuracao tecnica (CMDB).&#x27;),
&quot;APLICAÇÕES_RELACIONADAS&quot; VARCHAR2(32767) ANNOTATIONS(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Atributo APLICACOES_RELACIONADAS do registro de itens de configuracao tecnica (CMDB).&#x27;),
&quot;JANELAS_DE_MANUTENÇÃO&quot; VARCHAR2(255) ANNOTATIONS(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Atributo JANELAS_DE_MANUTENCAO do registro de itens de configuracao tecnica (CMDB).&#x27;),
&quot;ANALISTA_RESPONSAVEL&quot; VARCHAR2(255) ANNOTATIONS(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Atributo ANALISTA_RESPONSAVEL do registro de itens de configuracao tecnica (CMDB).&#x27;),
&quot;ANALISTAS_RESPONSÁVEIS&quot; VARCHAR2(255) ANNOTATIONS(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Atributo ANALISTAS_RESPONSAVEIS do registro de itens de configuracao tecnica (CMDB).&#x27;),
&quot;GERENCIADO_PELO_GRUPO&quot; VARCHAR2(255) ANNOTATIONS(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Atributo GERENCIADO_PELO_GRUPO do registro de itens de configuracao tecnica (CMDB).&#x27;),
&quot;GRUPOS_RESPONSÁVEIS&quot; VARCHAR2(32767) ANNOTATIONS(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Atributo GRUPOS_RESPONSAVEIS do registro de itens de configuracao tecnica (CMDB).&#x27;),
&quot;GRUPO_RESPONSÁVEL&quot; VARCHAR2(255) ANNOTATIONS(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Atributo GRUPO_RESPONSAVEL do registro de itens de configuracao tecnica (CMDB).&#x27;),
&quot;EDR&quot; NUMBER ANNOTATIONS(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Atributo EDR do registro de itens de configuracao tecnica (CMDB).&#x27;),
&quot;TENABLE&quot; NUMBER ANNOTATIONS(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Atributo TENABLE do registro de itens de configuracao tecnica (CMDB).&#x27;),
&quot;SIEM&quot; NUMBER ANNOTATIONS(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Atributo SIEM do registro de itens de configuracao tecnica (CMDB).&#x27;),
&quot;APPLIANCE&quot; NUMBER ANNOTATIONS(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Atributo APPLIANCE do registro de itens de configuracao tecnica (CMDB).&#x27;),
PRIMARY KEY (&quot;ID&quot;)
USING INDEX ENABLE
)
ANNOTATIONS(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Armazena registros de itens de configuracao tecnica (CMDB); e utilizada por VIEW V_26AI_TECH.&#x27;);
CREATE TABLE &quot;TB_26AI_TECH_SYS&quot;
( &quot;ID_1&quot; 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(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Identificador unico do registro de cadastro de sistemas tecnicos; compoe a chave primaria da tabela.&#x27;),
&quot;ID&quot; NUMBER ANNOTATIONS(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Identificador tecnico do registro de cadastro de sistemas tecnicos.&#x27;),
&quot;TIMESTAMP&quot; TIMESTAMP (9) WITH TIME ZONE ANNOTATIONS(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Data, hora ou marco temporal associado ao registro de cadastro de sistemas tecnicos.&#x27;),
&quot;HOST&quot; VARCHAR2(50) ANNOTATIONS(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Atributo HOST do registro de cadastro de sistemas tecnicos.&#x27;),
&quot;FACILITY&quot; VARCHAR2(50) ANNOTATIONS(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Atributo FACILITY do registro de cadastro de sistemas tecnicos.&#x27;),
&quot;SEVERITY&quot; VARCHAR2(50) ANNOTATIONS(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Atributo SEVERITY do registro de cadastro de sistemas tecnicos.&#x27;),
&quot;PROCESS&quot; VARCHAR2(50) ANNOTATIONS(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Atributo PROCESS do registro de cadastro de sistemas tecnicos.&#x27;),
&quot;PID&quot; NUMBER ANNOTATIONS(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Atributo PID do registro de cadastro de sistemas tecnicos.&#x27;),
&quot;ORACLE_INSTANCE&quot; VARCHAR2(50) ANNOTATIONS(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Atributo ORACLE_INSTANCE do registro de cadastro de sistemas tecnicos.&#x27;),
&quot;MESSAGE&quot; VARCHAR2(255) ANNOTATIONS(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Mensagem, diagnostico ou informacao de log associada ao processamento de cadastro de sistemas tecnicos.&#x27;),
&quot;RAW_SYSLOG&quot; VARCHAR2(255) ANNOTATIONS(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Mensagem, diagnostico ou informacao de log associada ao processamento de cadastro de sistemas tecnicos.&#x27;),
&quot;INSIGHT_REPORT&quot; CLOB ANNOTATIONS(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Conteudo textual gerado por IA associado a cadastro de sistemas tecnicos.&#x27;),
&quot;INSIGHT_JSON&quot; CLOB ANNOTATIONS(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Conteudo estruturado em JSON relacionado ao insight gerado por IA para cadastro de sistemas tecnicos.&#x27;),
PRIMARY KEY (&quot;ID_1&quot;)
USING INDEX ENABLE
)
ANNOTATIONS(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Armazena registros de cadastro de sistemas tecnicos (syslog); e utilizada por PROCEDURE PRC_26AI_TECH.&#x27;);
CREATE SEQUENCE &quot;SEQ_26AI_TECH&quot; MINVALUE 1 MAXVALUE 9999999999999999999999999999 INCREMENT BY 1 START WITH 1 CACHE 20 NOORDER NOCYCLE NOKEEP NOSCALE GLOBAL;
CREATE TABLE &quot;TB_26AI_TECH_V2&quot;
( &quot;ID_1&quot; 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(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Identificador unico do registro de dados tecnicos (versao 2); compoe a chave primaria da tabela.&#x27;),
&quot;AGE_IN_DAYS&quot; NUMBER ANNOTATIONS(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Idade em dias do achado, referenciada em VIEW V_26AI_TECH.&#x27;),
&quot;ASSET_DISPLAY_IPV4_ADDRESS&quot; VARCHAR2(255) ANNOTATIONS(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Endereco IPv4 do ativo, referenciado em VIEW V_26AI_TECH.&#x27;),
&quot;ASSET_ID&quot; VARCHAR2(255) ANNOTATIONS(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Identificador do ativo, referenciado em VIEW V_26AI_TECH.&#x27;),
&quot;ASSET_NAME&quot; VARCHAR2(100) ANNOTATIONS(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Nome do ativo, referenciado em VIEW V_26AI_TECH.&#x27;),
&quot;ASSET_TAGS&quot; VARCHAR2(32767) ANNOTATIONS(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Tags do ativo, referenciadas em VIEW V_26AI_TECH.&#x27;),
&quot;DEFINITION_EXPLOITABILITY_EASE&quot; VARCHAR2(50) ANNOTATIONS(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Facilidade de exploracao da vulnerabilidade, referenciada em VIEW V_26AI_TECH.&#x27;),
&quot;DEFINITION_FAMILY&quot; VARCHAR2(255) ANNOTATIONS(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Familia da definicao de vulnerabilidade, referenciada em VIEW V_26AI_TECH.&#x27;),
&quot;DEFINITION_ID&quot; NUMBER ANNOTATIONS(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Identificador da definicao de vulnerabilidade, referenciado em VIEW V_26AI_TECH.&#x27;),
&quot;DEFINITION_NAME&quot; VARCHAR2(255) ANNOTATIONS(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Nome da definicao de vulnerabilidade, referenciado em VIEW V_26AI_TECH.&#x27;),
&quot;DEFINITION_VPR_SCORE&quot; NUMBER ANNOTATIONS(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Score VPR (Vulnerability Priority Rating), referenciado em VIEW V_26AI_TECH.&#x27;),
&quot;FIRST_OBSERVED&quot; TIMESTAMP (9) WITH TIME ZONE ANNOTATIONS(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Data da primeira observacao, referenciada em VIEW V_26AI_TECH.&#x27;),
&quot;ID&quot; VARCHAR2(255) ANNOTATIONS(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Identificador tecnico do achado, referenciado em VIEW V_26AI_TECH.&#x27;),
&quot;LAST_SEEN&quot; TIMESTAMP (9) WITH TIME ZONE ANNOTATIONS(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Data da ultima observacao, referenciada em VIEW V_26AI_TECH.&#x27;),
&quot;OUTPUT&quot; VARCHAR2(32767) ANNOTATIONS(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Saida/detalhe tecnico do scanner, referenciada em VIEW V_26AI_TECH.&#x27;),
&quot;PROTOCOL&quot; VARCHAR2(50) ANNOTATIONS(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Protocolo relacionado ao achado, referenciado em VIEW V_26AI_TECH.&#x27;),
&quot;RESURFACED_DATE&quot; TIMESTAMP (9) WITH TIME ZONE ANNOTATIONS(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Data de ressurgimento do achado, referenciada em VIEW V_26AI_TECH.&#x27;),
&quot;SEVERITY&quot; VARCHAR2(50) ANNOTATIONS(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Severidade do achado, referenciada em VIEW V_26AI_TECH.&#x27;),
&quot;STATE&quot; VARCHAR2(50) ANNOTATIONS(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Estado do achado, referenciado em VIEW V_26AI_TECH.&#x27;),
&quot;INSIGHT_REPORT&quot; CLOB ANNOTATIONS(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Relatorio de insight gerado por IA, referenciado em VIEW V_26AI_TECH.&#x27;),
&quot;INSIGHT_JSON&quot; CLOB ANNOTATIONS(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Insight estruturado em JSON gerado por IA.&#x27;),
&quot;ID_INSIGHT&quot; NUMBER ANNOTATIONS(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Identificador sequencial do insight, gerado pelo trigger BIU_TB_26AI_TECH_V2, referenciado em VIEW V_26AI_TECH.&#x27;),
PRIMARY KEY (&quot;ID_1&quot;)
USING INDEX ENABLE
)
ANNOTATIONS(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Armazena os achados de vulnerabilidade (principal fonte de dados tecnicos); e utilizada por PROCEDURE PRC_26AI_TECH e VIEW V_26AI_TECH.&#x27;);
CREATE OR REPLACE EDITIONABLE TRIGGER &quot;BIU_TB_26AI_TECH_V2&quot;
BEFORE INSERT OR UPDATE
ON TB_26AI_TECH_V2
FOR EACH ROW
BEGIN
:new.ID_INSIGHT := SEQ_26AI_TECH.NEXTVAL;
END;
/
ALTER TRIGGER &quot;BIU_TB_26AI_TECH_V2&quot; ENABLE;
-- Tabela legada (mantida por compatibilidade: ainda e usada por uma pagina/
-- carga de dados mais antiga da aplicacao - &quot;DL_TECH_VULNERABILIDADES&quot;).
CREATE TABLE &quot;TB_26AI_TECH&quot;
( &quot;ID_1&quot; 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,
&quot;AGE_IN_DAYS&quot; NUMBER,
&quot;ASSET_DISPLAY_IPV4_ADDRESS&quot; VARCHAR2(255),
&quot;ASSET_ID&quot; VARCHAR2(255),
&quot;ASSET_NAME&quot; VARCHAR2(100),
&quot;EMPRESA&quot; VARCHAR2(50),
&quot;AMBIENTE&quot; VARCHAR2(50),
&quot;STATUS&quot; VARCHAR2(50),
&quot;DESCRIÇÃO&quot; VARCHAR2(32767),
&quot;ASSET_OPERATING_SYSTEM&quot; VARCHAR2(255),
&quot;DEFINITION_EXPLOITABILITY_EASE&quot; VARCHAR2(50),
&quot;DEFINITION_FAMILY&quot; VARCHAR2(255),
&quot;DEFINITION_ID&quot; NUMBER,
&quot;DEFINITION_NAME&quot; VARCHAR2(255),
&quot;DEFINITION_VPR_SCORE&quot; NUMBER,
&quot;FIRST_OBSERVED&quot; DATE,
&quot;ID&quot; VARCHAR2(255),
&quot;LAST_SEEN&quot; DATE,
&quot;OUTPUT&quot; VARCHAR2(32767),
&quot;PROTOCOL&quot; VARCHAR2(50),
&quot;RESURFACED_DATE&quot; DATE,
&quot;SEVERITY&quot; VARCHAR2(50),
&quot;STATE&quot; VARCHAR2(50),
&quot;INSIGHT_REPORT&quot; CLOB,
&quot;INSIGHT_JSON&quot; CLOB,
&quot;ID_INSIGHT&quot; NUMBER,
PRIMARY KEY (&quot;ID_1&quot;)
USING INDEX ENABLE
);
CREATE TABLE &quot;TB_26AI_TECH_VECTOR&quot;
( &quot;EMBED_ID&quot; NUMBER ANNOTATIONS(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Representacao vetorial (embedding) associada ao conteudo de embeddings de conhecimento tecnico, destinada a buscas por similaridade e fluxos de recuperacao aumentada (RAG).&#x27;),
&quot;EMBED_DATA&quot; CLOB ANNOTATIONS(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Trecho de texto (chunk) que originou o vetor, referenciado em FUNCTION FNC_26AI_TECH_RAG.&#x27;),
&quot;EMBED_VECTOR&quot; VECTOR ANNOTATIONS(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Vetor (embedding) do trecho, referenciado em FUNCTION FNC_26AI_TECH_RAG.&#x27;),
&quot;TITULO&quot; VARCHAR2(2000) ANNOTATIONS(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Titulo/identificacao do registro de embeddings de conhecimento tecnico.&#x27;),
&quot;ID&quot; VARCHAR2(200) ANNOTATIONS(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Referencia (rowid/id) do registro de origem do insight, referenciada em FUNCTION FNC_26AI_TECH_RAG.&#x27;),
&quot;SOURCE_TYPE&quot; VARCHAR2(3) ANNOTATIONS(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Origem do dado vetorizado: VUL (vulnerabilidades) ou SYS (syslog).&#x27;)
)
ANNOTATIONS(&quot;LLM_DESCRIPTION_PT_BR&quot; &#x27;Armazena os vetores (chunks) usados na busca semantica/RAG; e utilizada por FUNCTION FNC_26AI_TECH_RAG e PROCEDURE PRC_26AI_TECH.&#x27;);
-- 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 &quot;Company&quot; 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 &quot;V_26AI_TECH&quot; (&quot;CID&quot;, &quot;AGE_IN_DAYS&quot;, &quot;ASSET_DISPLAY_IPV4_ADDRESS&quot;, &quot;ASSET_ID&quot;, &quot;ASSET_NAME&quot;, &quot;ASSET_TAGS&quot;, &quot;DEFINITION_EXPLOITABILITY_EASE&quot;, &quot;DEFINITION_FAMILY&quot;, &quot;DEFINITION_ID&quot;, &quot;DEFINITION_NAME&quot;, &quot;DEFINITION_VPR_SCORE&quot;, &quot;FIRST_OBSERVED&quot;, &quot;ID&quot;, &quot;LAST_SEEN&quot;, &quot;OUTPUT&quot;, &quot;PROTOCOL&quot;, &quot;RESURFACED_DATE&quot;, &quot;SEVERITY&quot;, &quot;STATE&quot;, &quot;INSIGHT_REPORT&quot;, &quot;ID_INSIGHT&quot;, &quot;NOME&quot;, &quot;EMPRESA&quot;, &quot;CLASSE&quot;, &quot;AMBIENTE&quot;, &quot;STATUS_OPERACIONAL&quot;, &quot;DESCRICAO&quot;, &quot;SOX&quot;, &quot;COFRE&quot;, &quot;ENDERECO_IP&quot;, &quot;SISTEMA_OPERACIONAL&quot;, &quot;TIPO_DE_REDE&quot;, &quot;IS_VIRTUAL&quot;, &quot;CRITICIDADE&quot;, &quot;INSTANCIAS_BANCOS&quot;, &quot;APLICACOES_RELACIONADAS&quot;, &quot;JANELAS_DE_MANUTENCAO&quot;, &quot;ANALISTA_RESPONSAVEL&quot;, &quot;ANALISTAS_RESPONSAVEIS&quot;, &quot;GERENCIADO_PELO_GRUPO&quot;, &quot;GRUPOS_RESPONSAVEIS&quot;, &quot;GRUPO_RESPONSAVEL&quot;, &quot;EDR&quot;, &quot;TENABLE&quot;, &quot;SIEM&quot;, &quot;APPLIANCE&quot;) 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),&#x27;Ipiranga&#x27;,&#x27;Company&#x27;),&#x27;Ampm&#x27;,&#x27;Company&#x27;) NOME ,
replace(replace(initcap(c.EMPRESA),&#x27;Ipiranga&#x27;,&#x27;Company&#x27;),&#x27;Ampm&#x27;,&#x27;Company&#x27;) 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 &quot;TB_26AI_TECH_LOG&quot;
( &quot;LOG_ID&quot; NUMBER GENERATED ALWAYS AS IDENTITY MINVALUE 1 MAXVALUE 9999999999999999999999999999 INCREMENT BY 1 START WITH 1 CACHE 20 NOORDER NOCYCLE NOKEEP NOSCALE NOT NULL ENABLE,
&quot;LOG_TS&quot; TIMESTAMP(6) WITH TIME ZONE DEFAULT SYSTIMESTAMP NOT NULL ENABLE,
&quot;CALLING_OBJECT&quot; VARCHAR2(128),
&quot;OPERATION&quot; VARCHAR2(30),
&quot;SOURCE_TYPE&quot; VARCHAR2(10),
&quot;SOURCE_ID&quot; VARCHAR2(200),
&quot;PROVIDER&quot; VARCHAR2(30),
&quot;MODEL_NAME&quot; VARCHAR2(100),
&quot;APP_USER&quot; VARCHAR2(100),
&quot;STATUS&quot; VARCHAR2(10),
&quot;ERROR_CODE&quot; NUMBER,
&quot;ERROR_MESSAGE&quot; VARCHAR2(4000),
&quot;DURATION_MS&quot; NUMBER,
&quot;PROMPT_CHARS&quot; NUMBER,
&quot;RESPONSE_CHARS&quot; NUMBER,
CONSTRAINT &quot;TB_26AI_TECH_LOG_PK&quot; PRIMARY KEY (&quot;LOG_ID&quot;) USING INDEX ENABLE
);
CREATE INDEX &quot;TB_26AI_TECH_LOG_TS_IX&quot; ON &quot;TB_26AI_TECH_LOG&quot; (&quot;LOG_TS&quot;);
CREATE INDEX &quot;TB_26AI_TECH_LOG_ST_IX&quot; ON &quot;TB_26AI_TECH_LOG&quot; (&quot;STATUS&quot;,&quot;LOG_TS&quot;);
COMMENT ON TABLE &quot;TB_26AI_TECH_LOG&quot; IS &#x27;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.&#x27;;</code></pre>
</div>
<h2>Seção 7 &middot; PL/SQL de geracao de embeddings, RAG e insights (ampmInsights)</h2>
<p>Cria <code>PRC_26AI_TECH_LOG</code> (log de cada chamada de IA/embedding — ver
<a href="09-operacao-observabilidade.html">Operação &amp; observabilidade</a>) e as funções e a
procedure descritas em <a href="02-arquitetura.html">Arquitetura</a>: <code>fnc_26ai_embed</code>,
<code>fnc_26ai_tech_rag</code>, <code>FNC_26AI_TECH_MCP_V1</code>, <code>FNC_26ai_rag</code> e
<code>prc_26ai_tech</code>. É um bloco longo (a maior parte é o texto dos prompts de IA) — copie e
cole inteiro de uma vez.</p>
<div class="code-block">
<div class="code-bar">
<span class="code-label">Seção 7 — copiar e colar</span>
<button class="copy-btn" type="button">Copiar</button>
</div>
<pre><code class="lang-sql">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(&#x27;APP_USER&#x27;), SYS_CONTEXT(&#x27;USERENV&#x27;,&#x27;SESSION_USER&#x27;)),
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 &#x27;COHERE&#x27;,
p_credential IN VARCHAR2 DEFAULT &#x27;OCI_CRED&#x27;)
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) := &#x27;https://inference.generativeai.sa-saopaulo-1.oci.oraclecloud.com/20231130/actions/embedText&#x27;;
v_body JSON_OBJECT_T;
r DBMS_CLOUD_TYPES.RESP;
BEGIN
v_string := replace(replace(replace(p_string,chr(13),&#x27; &#x27;),chr(10),&#x27; &#x27;),&#x27;&quot;&#x27;,&#x27;&#x27;) ;
IF p_emb_type = &#x27;ONNX&#x27; 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 = &#x27;COHERE&#x27; 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(&#x27;{ &quot;provider&quot;: &quot;ocigenai&quot;,
&quot;credential_name&quot;: &quot;&#x27; || p_credential || &#x27;&quot;,
&quot;url&quot;: &quot;https://inference.generativeai.&#x27; || (SELECT param_value FROM TB_26AI_TECH_PARAMS WHERE param_name = &#x27;GENAI_REGION&#x27;) || &#x27;.oci.oraclecloud.com/20231130/actions/embedText&quot;,
&quot;model&quot;: &quot;cohere.embed-v4.0&quot;
}&#x27;)
)
) t
CROSS JOIN JSON_TABLE(
t.column_value,
&#x27;$[*]&#x27; COLUMNS (
embed_id NUMBER PATH &#x27;$.embed_id&#x27;,
text_chunk VARCHAR2(4000) PATH &#x27;$.embed_data&#x27;,
embed_vector CLOB PATH &#x27;$.embed_vector&#x27;
)
) AS et;
ELSIF p_emb_type = &#x27;vLLM&#x27; THEN
-- Endpoint self-hosted opcional (ex.: vLLM atras de um load
-- balancer proprio). Ajuste &quot;host&quot; e &quot;model&quot; 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 := &#x27;{
&quot;provider&quot;: &quot;openai&quot;,
&quot;url&quot;: &quot;https://&lt;SUBSTITUA_PELO_SEU_ENDPOINT_VLLM&gt;/embed/v1/embeddings&quot;,
&quot;host&quot;: &quot;local&quot;,
&quot;model&quot;: &quot;&lt;SUBSTITUA_PELO_MODELO_QUE_VOCE_HOSPEDA&gt;&quot;,
&quot;batch_size&quot;: 50}&#x27;;
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(&#x27;Erro: &#x27; || SQLCODE || &#x27; - &#x27; || SQLERRM);
PRC_26AI_TECH_LOG(
p_calling_object =&gt; &#x27;FNC_26AI_EMBED&#x27;,
p_operation =&gt; &#x27;EMBEDDING&#x27;,
p_status =&gt; &#x27;ERROR&#x27;,
p_provider =&gt; &#x27;vLLM&#x27;,
p_error_code =&gt; SQLCODE,
p_error_message =&gt; 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 =&gt; &#x27;FNC_26AI_EMBED&#x27;,
p_operation =&gt; &#x27;EMBEDDING&#x27;,
p_status =&gt; &#x27;ERROR&#x27;,
p_provider =&gt; p_emb_type,
p_error_code =&gt; SQLCODE,
p_error_message =&gt; SQLERRM
);
RAISE;
END;
/
CREATE OR REPLACE FUNCTION fnc_26ai_tech_rag(p_query VARCHAR2,
p_top_k IN NUMBER ,
p_credential in varchar2 default &#x27;OCI_CRED&#x27;,
p_app_user in varchar2 default V(&#x27;APP_USER&#x27;),
p_source_type varchar2 default &#x27;VUL&#x27; )
RETURN CLOB IS
/*
Projeto: ampmInsights
Objetivo: funcao de RAG (Retrieval-Augmented Generation) para &quot;fale com os
seus dados&quot; 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) := &#x27;LLAMA4&#x27;; -- [ 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 = &#x27;GENAI_REGION&#x27;;
-- embedding da pergunta do usuario
query_vec := to_vector( fnc_26ai_embed ( p_string =&gt; p_query, p_emb_type =&gt; &#x27;COHERE&#x27; ) ) ;
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 || &#x27;&quot;&#x27; || replace(replace(replace(replace(message_cursor.BODY,chr(10),null),chr(13),null),&#x27;&quot;&#x27;,&#x27;&#x27;),&#x27;&#x27;&#x27;&#x27;,&#x27;&#x27;) || &#x27;&quot;,&#x27; ;
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 = &#x27;LLAMA4&#x27; THEN
params_genai := &#x27;{
&quot;provider&quot; : &quot;ocigenai&quot;,
&quot;credential_name&quot; : &quot;&#x27; || p_credential || &#x27;&quot;,
&quot;url&quot; : &quot;https://inference.generativeai.&#x27; || v_genai_region || &#x27;.oci.oraclecloud.com/20231130/actions/chat&quot;,
&quot;model&quot;: &quot;meta.llama-4-maverick-17b-128e-instruct-fp8&quot;}&#x27;;
ELSIF v_llm = &#x27;OPENAI&#x27; THEN
params_genai := &#x27;{
&quot;provider&quot; : &quot;openai&quot;,
&quot;credential_name&quot; : &quot;CRED_OPENAI&quot;,
&quot;url&quot; : &quot;https://api.openai.com/v1/chat/completions&quot;,
&quot;model&quot; : &quot;gpt-4.1-mini&quot;,
&quot;temperature&quot;: 0.4
}&#x27;;
END IF;
v_pre_prompt := &#x27;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: &quot;Informacao nao fornecida&quot;.
- 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: &lt;achado&gt; [report_id | secao/campo | data]
- Evidencia 2: &lt;achado&gt; [report_id | secao/campo | data]
- Evidencia 3: &lt;achado&gt; [report_id | secao/campo | data]
## Diagnostico consolidado
- Causa/hipotese principal (Alta/Media/Baixa)
- Risco de curto prazo
- Risco de medio prazo
## Recomendacoes priorizadas
- P1: &lt;acao&gt; | Impacto: &lt;...&gt; | Esforco: &lt;Baixo/Medio/Alto&gt;
- P2: &lt;acao&gt; | Impacto: &lt;...&gt; | Esforco: &lt;Baixo/Medio/Alto&gt;
- P3: &lt;acao&gt; | Impacto: &lt;...&gt; | Esforco: &lt;Baixo/Medio/Alto&gt;
## Lacunas e proximos dados necessarios
- Informacao nao fornecida: &lt;campo/contexto ausente&gt;
- Dado adicional recomendado para aumentar confianca da resposta: &lt;...&gt;&#x27;;
v_pre_prompt2 := &#x27;{ &quot;role&quot;: &quot;user&quot;,&quot;content&quot;: &quot;Contexto:&quot;&#x27; || v_context || &#x27; &quot;Pergunta&quot;: &#x27; || p_query || &#x27;&quot;}&#x27; ;
output := dbms_vector_chain.utl_to_generate_text( replace(replace(replace(replace(v_pre_prompt || v_pre_prompt2,chr(10),null),chr(13),null),&#x27;&quot;&#x27;,&#x27;&#x27;),&#x27;&#x27;&#x27;&#x27;,&#x27;&#x27;) , 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 =&gt; &#x27;FNC_26AI_TECH_RAG&#x27;,
p_operation =&gt; &#x27;RAG&#x27;,
p_status =&gt; &#x27;ERROR&#x27;,
p_source_type =&gt; p_source_type,
p_provider =&gt; &#x27;ocigenai&#x27;,
p_error_code =&gt; SQLCODE,
p_error_message =&gt; 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, &#x27;OCI_CRED&#x27;, &#x27;MCPUSER&#x27;)
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 &#x27;OCI_CRED&#x27;,
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) := &#x27;meta.llama-4-maverick-17b-128e-instruct-fp8&#x27;;
resp DBMS_CLOUD_TYPES.RESP;
v_t0 PLS_INTEGER := DBMS_UTILITY.GET_TIME;
v_result CLOB;
BEGIN
SELECT &#x27;https://inference.generativeai.&#x27; || param_value || &#x27;.oci.oraclecloud.com&#x27;
INTO v_gen_ai_endpoint
FROM TB_26AI_TECH_PARAMS WHERE param_name = &#x27;GENAI_REGION&#x27;;
resp := dbms_cloud.send_request(
credential_name =&gt; p_oci_cred,
uri =&gt; v_gen_ai_endpoint || &#x27;/20231130/actions/chat&#x27;,
method =&gt; dbms_cloud.METHOD_POST,
body =&gt; utl_raw.cast_to_raw(json_object(
&#x27;compartmentId&#x27; value p_comp,
&#x27;servingMode&#x27; value
(json_object(
&#x27;modelId&#x27; value v_gen_ai_model,
&#x27;servingType&#x27; value &#x27;ON_DEMAND&#x27;
)),
&#x27;chatRequest&#x27; value
(json_object(
&#x27;apiFormat&#x27; value &#x27;GENERIC&#x27;,
&#x27;messages&#x27; value
(json_array(JSON_OBJECT(
&#x27;role&#x27; value &#x27;USER&#x27;,
&#x27;content&#x27; value
(json_array(JSON_OBJECT(
&#x27;type&#x27; value &#x27;TEXT&#x27;,
&#x27;text&#x27; value p_ai_prompt
)))
))),
&#x27;temperature&#x27; value 0.1,
&#x27;topK&#x27; value -1
))
))
);
v_result := json_value( dbms_cloud.get_response_text(resp) , &#x27;$.chatResponse.choices[0].message.content[0].text&#x27;) ;
PRC_26AI_TECH_LOG(
p_calling_object =&gt; &#x27;FNC_26AI_RAG&#x27;,
p_operation =&gt; &#x27;CHAT&#x27;,
p_status =&gt; &#x27;OK&#x27;,
p_provider =&gt; &#x27;ocigenai&#x27;,
p_model_name =&gt; v_gen_ai_model,
p_duration_ms =&gt; (DBMS_UTILITY.GET_TIME - v_t0) * 10,
p_prompt_chars =&gt; LENGTH(p_ai_prompt),
p_response_chars =&gt; LENGTH(v_result)
);
RETURN v_result;
EXCEPTION
WHEN OTHERS THEN
PRC_26AI_TECH_LOG(
p_calling_object =&gt; &#x27;FNC_26AI_RAG&#x27;,
p_operation =&gt; &#x27;CHAT&#x27;,
p_status =&gt; &#x27;ERROR&#x27;,
p_provider =&gt; &#x27;ocigenai&#x27;,
p_model_name =&gt; v_gen_ai_model,
p_error_code =&gt; SQLCODE,
p_error_message =&gt; SQLERRM,
p_duration_ms =&gt; (DBMS_UTILITY.GET_TIME - v_t0) * 10,
p_prompt_chars =&gt; LENGTH(p_ai_prompt)
);
RETURN &#x27;Nao foi possivel gerar um texto com base nas informacoes.&#x27;;
END;
/
CREATE OR REPLACE PROCEDURE prc_26ai_tech (p_rowid IN VARCHAR DEFAULT NULL,
p_oci_cred IN VARCHAR2 DEFAULT &#x27;OCI_CRED&#x27;,
p_comp IN VARCHAR2,
p_source_type VARCHAR2 DEFAULT &#x27;VUL&#x27; )
/*
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 &quot;Gerar Insights em Lote&quot; 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 = &#x27;EMBEDDING_COMPARTMENT&#x27;;
FOR r1 IN (SELECT rowid cid FROM TB_26AI_TECH_v2 WHERE insight_report IS NULL) LOOP
PRC_26AI_TECH (p_rowid =&gt; r1.cid,
p_oci_cred =&gt; &#x27;OCI_CRED&#x27;,
p_comp =&gt; v_comp,
p_source_type =&gt; &#x27;VUL&#x27;);
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 = &#x27;GENAI_REGION&#x27;;
IF p_source_type = &#x27;VUL&#x27; THEN -- vulnerabilidades
v_pre_prompt :=&#x27;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 &quot;Informacao nao fornecida&quot;.
- 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 &quot;quick wins&quot;
- 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&#x27;;
v_pre_prompt_json := &#x27;## 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 &quot;```json&quot; no comeco nem no final como &quot;```&quot;.
## Exemplo JSON:
Retorne um JSON valido (sem comentarios), espelhando o relatorio:
{
&quot;id&quot;: &quot;&quot;,
&quot;titulo&quot;: &quot;&quot;,
&quot;analise&quot;: {
&quot;resumo_tecnico&quot;: &quot;&quot;,
&quot;vetor_ataque&quot;: &quot;&quot;,
&quot;pre_condicoes&quot;: [],
&quot;impacto_cia&quot;: {
&quot;confidencialidade&quot;: &quot;&quot;,
&quot;integridade&quot;: &quot;&quot;,
&quot;disponibilidade&quot;: &quot;&quot;
}
},
&quot;diagnostico&quot;: {
&quot;causa_raiz&quot;: &quot;&quot;,
&quot;classificacao&quot;: {
&quot;cwe&quot;: &quot;&quot;,
&quot;owasp&quot;: &quot;&quot;
},
&quot;severidade&quot;: &quot;&quot;,
&quot;probabilidade_exploracao&quot;: &quot;&quot;,
&quot;impacto_negocio&quot;: &quot;&quot;,
&quot;prioridade_final&quot;: &quot;&quot;,
&quot;justificativa&quot;: &quot;&quot;
},
&quot;recomendacoes&quot;: [
{
&quot;acao&quot;: &quot;&quot;,
&quot;tipo&quot;: &quot;corretiva|preventiva|detectiva&quot;,
&quot;esforco&quot;: &quot;baixo|medio|alto&quot;,
&quot;dependencias&quot;: []
}
],
&quot;plano_acao&quot;: [
{
&quot;prazo&quot;: &quot;curto|medio|longo&quot;,
&quot;etapa&quot;: &quot;&quot;,
&quot;responsavel_sugerido&quot;: &quot;&quot;,
&quot;deadline_sugerido&quot;: &quot;&quot;,
&quot;resultado_esperado&quot;: &quot;&quot;,
&quot;criterio_aceite&quot;: &quot;&quot;
}
],
&quot;lacunas_informacao&quot;: []
}&#x27;;
SELECT json_object(
&#x27;AGE_IN_DAYS&#x27; VALUE AGE_IN_DAYS,
&#x27;ASSET_DISPLAY_IPV4_ADDRESS&#x27; VALUE ASSET_DISPLAY_IPV4_ADDRESS,
&#x27;ASSET_ID&#x27; VALUE ASSET_ID,
&#x27;ASSET_NAME&#x27; VALUE ASSET_NAME,
&#x27;ASSET_TAGS&#x27; VALUE ASSET_TAGS,
&#x27;DEFINITION_EXPLOITABILITY_EASE&#x27; VALUE DEFINITION_EXPLOITABILITY_EASE,
&#x27;DEFINITION_FAMILY&#x27; VALUE DEFINITION_FAMILY,
&#x27;DEFINITION_ID&#x27; VALUE DEFINITION_ID,
&#x27;DEFINITION_NAME&#x27; VALUE DEFINITION_NAME,
&#x27;DEFINITION_VPR_SCORE&#x27; VALUE DEFINITION_VPR_SCORE,
&#x27;FIRST_OBSERVED&#x27; VALUE FIRST_OBSERVED,
&#x27;ID&#x27; VALUE ID,
&#x27;LAST_SEEN&#x27; VALUE LAST_SEEN,
&#x27;OUTPUT&#x27; VALUE OUTPUT,
&#x27;PROTOCOL&#x27; VALUE PROTOCOL,
&#x27;RESURFACED_DATE&#x27; VALUE RESURFACED_DATE,
&#x27;SEVERITY&#x27; VALUE SEVERITY,
&#x27;STATE&#x27; VALUE STATE,
&#x27;INSIGHT_REPORT&#x27; VALUE INSIGHT_REPORT,
&#x27;ID_INSIGHT&#x27; VALUE ID_INSIGHT,
&#x27;NOME&#x27; VALUE NOME,
&#x27;EMPRESA&#x27; VALUE EMPRESA,
&#x27;CLASSE&#x27; VALUE CLASSE,
&#x27;AMBIENTE&#x27; VALUE AMBIENTE,
&#x27;STATUS_OPERACIONAL&#x27; VALUE STATUS_OPERACIONAL,
&#x27;DESCRICAO&#x27; VALUE DESCRICAO,
&#x27;SOX&#x27; VALUE SOX,
&#x27;COFRE&#x27; VALUE COFRE,
&#x27;ENDERECO_IP&#x27; VALUE ENDERECO_IP,
&#x27;SISTEMA_OPERACIONAL&#x27; VALUE SISTEMA_OPERACIONAL,
&#x27;TIPO_DE_REDE&#x27; VALUE TIPO_DE_REDE,
&#x27;IS_VIRTUAL&#x27; VALUE IS_VIRTUAL,
&#x27;CRITICIDADE&#x27; VALUE CRITICIDADE,
&#x27;INSTANCIAS_BANCOS&#x27; VALUE INSTANCIAS_BANCOS,
&#x27;APLICACOES_RELACIONADAS&#x27; VALUE APLICACOES_RELACIONADAS,
&#x27;JANELAS_DE_MANUTENCAO&#x27; VALUE JANELAS_DE_MANUTENCAO,
&#x27;ANALISTA_RESPONSAVEL&#x27; VALUE ANALISTA_RESPONSAVEL,
&#x27;ANALISTAS_RESPONSAVEIS&#x27; VALUE ANALISTAS_RESPONSAVEIS,
&#x27;GERENCIADO_PELO_GRUPO&#x27; VALUE GERENCIADO_PELO_GRUPO,
&#x27;GRUPOS_RESPONSAVEIS&#x27; VALUE GRUPOS_RESPONSAVEIS,
&#x27;GRUPO_RESPONSAVEL&#x27; VALUE GRUPO_RESPONSAVEL,
&#x27;EDR&#x27; VALUE EDR,
&#x27;TENABLE&#x27; VALUE TENABLE,
&#x27;SIEM&#x27; VALUE SIEM,
&#x27;APPLIANCE&#x27; 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 =&gt; v_pre_prompt || &#x27;. Dados: &#x27; || v_customer_data,
p_oci_cred =&gt; p_oci_cred,
p_comp =&gt; p_comp
);
v_json := replace( replace( FNC_26ai_rag( p_ai_prompt =&gt; &#x27;MODO JSON: &#x27; || v_pre_prompt || &#x27; &#x27; || v_pre_prompt_json || &#x27;. Dados: &#x27; || v_customer_data,
p_oci_cred =&gt; p_oci_cred,
p_comp =&gt; p_comp
) ,&#x27;```json&#x27;,&#x27;&#x27; ),&#x27;```&#x27;,&#x27;&#x27; );
UPDATE TB_26AI_TECH_v2
SET insight_report = v_response,
insight_json = v_json
WHERE rowid = p_rowid;
ELSIF p_source_type = &#x27;SYS&#x27; THEN -- SYSLOG
v_pre_prompt :=&#x27;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.&#x27;;
v_pre_prompt_json := &#x27;## 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 &quot;```json&quot; no comeco nem no final como &quot;```&quot;.
## Exemplo JSON:
Retorne um JSON valido (sem comentarios), espelhando o relatorio:
{
&quot;tipo_relatorio&quot;: &quot;decisao_operacional_syslog_oracle_linux&quot;,
&quot;versao_schema&quot;: &quot;1.0&quot;,
&quot;fonte_dados&quot;: {
&quot;arquivo_csv&quot;: &quot;syslog_oracle_linux_examples.csv&quot;,
&quot;mecanismo&quot;: &quot;RAG&quot;,
&quot;modelo_destino&quot;: &quot;Llama 4&quot;,
&quot;campos_csv&quot;: [
&quot;id&quot;,
&quot;timestamp&quot;,
&quot;host&quot;,
&quot;facility&quot;,
&quot;severity&quot;,
&quot;process&quot;,
&quot;pid&quot;,
&quot;oracle_instance&quot;,
&quot;message&quot;,
&quot;raw_syslog&quot;
]
},
&quot;classificacao_evento&quot;: {
&quot;nivel_risco&quot;: &quot;Baixo|Medio|Alto|Critico&quot;,
&quot;severidade_syslog&quot;: &quot;info|notice|warning|err|crit&quot;,
&quot;categoria&quot;: &quot;Banco de dados|Sistema operacional|Rede|Storage|Seguranca|Backup|Data Guard|RAC|Autenticacao&quot;,
&quot;impacto_potencial&quot;: &quot;Descrever impacto operacional provavel&quot;,
&quot;estado&quot;: &quot;Informativo|Em investigacao|Acao requerida|Escalado|Resolvido&quot;
},
&quot;resumo_executivo&quot;: {
&quot;descricao&quot;: &quot;Resumo em 2 a 4 frases do evento ou alarme analisado&quot;,
&quot;ativo_afetado&quot;: {
&quot;host&quot;: &quot;Nome do servidor afetado&quot;,
&quot;oracle_instance&quot;: &quot;Instancia Oracle afetada&quot;,
&quot;processo&quot;: &quot;Processo principal relacionado ao evento&quot;
},
&quot;risco_operacional&quot;: &quot;Descricao objetiva do risco&quot;,
&quot;recomendacao_curta&quot;: &quot;Acao recomendada em uma frase&quot;
},
&quot;evidencias_syslog&quot;: [
{
&quot;id&quot;: 0,
&quot;timestamp&quot;: &quot;YYYY-MM-DDTHH:MM:SS-03:00&quot;,
&quot;host&quot;: &quot;host_origem&quot;,
&quot;facility&quot;: &quot;facility_syslog&quot;,
&quot;severity&quot;: &quot;severity_syslog&quot;,
&quot;process&quot;: &quot;processo_origem&quot;,
&quot;pid&quot;: 0,
&quot;oracle_instance&quot;: &quot;instancia_oracle&quot;,
&quot;message&quot;: &quot;mensagem_normalizada&quot;,
&quot;raw_syslog&quot;: &quot;linha_syslog_original&quot;,
&quot;relevancia&quot;: &quot;Alta|Media|Baixa&quot;
}
],
&quot;interpretacao_operacional&quot;: {
&quot;fato_observado&quot;: &quot;O que foi observado diretamente no Syslog&quot;,
&quot;inferencia&quot;: &quot;Interpretacao operacional baseada nas evidencias&quot;,
&quot;possivel_causa&quot;: &quot;Hipotese provavel, sem declarar causa raiz definitiva sem evidencia&quot;,
&quot;sequencia_eventos&quot;: &quot;Evento isolado, sequencia de falha, recuperacao ou recorrencia&quot;,
&quot;recorrencia&quot;: &quot;Isolado|Recorrente|Sequencia de falha|Recuperacao|Indeterminado&quot;
},
&quot;acoes_recomendadas&quot;: {
&quot;imediatas&quot;: [
{
&quot;prioridade&quot;: 1,
&quot;acao&quot;: &quot;Acao imediata recomendada&quot;,
&quot;objetivo&quot;: &quot;Resultado esperado da acao&quot;,
&quot;responsavel_sugerido&quot;: &quot;Operacao N1|Operacao N2|DBA Oracle|Linux/Infraestrutura|Storage|Redes|Seguranca|Sustentacao de Aplicacao|Gestao de Crise&quot;
}
]
}&#x27;;
SELECT json_object(
&#x27;ID_1&#x27; VALUE a.&quot;ID_1&quot;,
&#x27;ID&#x27; VALUE a.&quot;ID&quot;,
&#x27;TIMESTAMP&#x27; VALUE a.&quot;TIMESTAMP&quot;,
&#x27;HOST&#x27; VALUE a.&quot;HOST&quot;,
&#x27;FACILITY&#x27; VALUE a.&quot;FACILITY&quot;,
&#x27;SEVERITY&#x27; VALUE a.&quot;SEVERITY&quot;,
&#x27;PROCESS&#x27; VALUE a.&quot;PROCESS&quot;,
&#x27;PID&#x27; VALUE a.&quot;PID&quot;,
&#x27;ORACLE_INSTANCE&#x27; VALUE a.&quot;ORACLE_INSTANCE&quot;,
&#x27;MESSAGE&#x27; VALUE a.&quot;MESSAGE&quot;,
&#x27;RAW_SYSLOG&#x27; VALUE a.&quot;RAW_SYSLOG&quot;
) AS my_json
INTO v_customer_data
FROM &quot;TB_26AI_TECH_SYS&quot; a
WHERE rowid = p_rowid;
v_response := FNC_26ai_rag( p_ai_prompt =&gt; v_pre_prompt || &#x27;. Dados: &#x27; || v_customer_data,
p_oci_cred =&gt; p_oci_cred,
p_comp =&gt; 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) &gt; 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(&#x27;{ &quot;provider&quot;: &quot;ocigenai&quot;,
&quot;credential_name&quot;: &quot;&#x27; || p_oci_cred || &#x27;&quot;,
&quot;url&quot;: &quot;https://inference.generativeai.&#x27; || v_genai_region || &#x27;.oci.oraclecloud.com/20231130/actions/embedText&quot;,
&quot;model&quot;: &quot;cohere.embed-v4.0&quot;
}&#x27;)
)
) t
CROSS JOIN JSON_TABLE(
t.column_value, &#x27;$[*]&#x27;
COLUMNS (
embed_id NUMBER PATH &#x27;$.embed_id&#x27;,
text_chunk VARCHAR2(4000) PATH &#x27;$.embed_data&#x27;,
embed_vector CLOB PATH &#x27;$.embed_vector&#x27;
)
) AS et;
PRC_26AI_TECH_LOG(
p_calling_object =&gt; &#x27;PRC_26AI_TECH&#x27;,
p_operation =&gt; &#x27;EMBEDDING&#x27;,
p_status =&gt; &#x27;OK&#x27;,
p_source_type =&gt; p_source_type,
p_source_id =&gt; p_rowid,
p_provider =&gt; &#x27;ocigenai&#x27;,
p_model_name =&gt; &#x27;cohere.embed-v4.0&#x27;,
p_prompt_chars =&gt; LENGTH(v_response)
);
END IF;
PRC_26AI_TECH_LOG(
p_calling_object =&gt; &#x27;PRC_26AI_TECH&#x27;,
p_operation =&gt; &#x27;INSIGHT_PIPELINE&#x27;,
p_status =&gt; &#x27;OK&#x27;,
p_source_type =&gt; p_source_type,
p_source_id =&gt; p_rowid
);
COMMIT;
EXCEPTION
WHEN OTHERS THEN
v_error := sqlerrm;
PRC_26AI_TECH_LOG(
p_calling_object =&gt; &#x27;PRC_26AI_TECH&#x27;,
p_operation =&gt; &#x27;INSIGHT_PIPELINE&#x27;,
p_status =&gt; &#x27;ERROR&#x27;,
p_source_type =&gt; p_source_type,
p_source_id =&gt; p_rowid,
p_error_code =&gt; SQLCODE,
p_error_message =&gt; 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 = &#x27;VUL&#x27; THEN
UPDATE TB_26AI_TECH_v2
SET insight_report = &#x27;Nao foi possivel gerar o insight para este registro no momento.&#x27;,
insight_json = null
WHERE rowid = p_rowid;
ELSIF p_source_type = &#x27;SYS&#x27; THEN
UPDATE TB_26AI_TECH_SYS
SET insight_report = &#x27;Nao foi possivel gerar o insight para este registro no momento.&#x27;,
insight_json = null
WHERE rowid = p_rowid;
END IF;
COMMIT;
END;
/</code></pre>
</div>
<h2>Seção 8 &middot; Instalar a aplicacao APEX (ampmInsights)</h2>
<p>Últimos passos, agora fora do SQL Worksheet: instalar a aplicação APEX. Detalhado em
<a href="05-passo-a-passo-apex.html">Passo a passo: aplicação APEX</a>.</p>
<div class="code-block">
<div class="code-bar">
<span class="code-label">Seção 8 — copiar e colar</span>
<button class="copy-btn" type="button">Copiar</button>
</div>
<pre><code class="lang-sql">-- 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 &gt; 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 &quot;parsing schema&quot; e AMPMINSIGHTS.
-- Confirmar &quot;Run and Build&quot;.
-- 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 &quot;Gerar Insights em Lote&quot; 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</code></pre>
</div>
<div class="callout success">
<div class="callout-title">Terminou o script 1?</div>
<p>Siga para <a href="05-passo-a-passo-apex.html">Passo a passo: aplicação APEX</a> para importar
<code>sql/02_ampminsights_apex_app.sql</code>.</p>
</div>
<div class="pillnav"><a class="prev" href="03-pre-requisitos-credenciais.html">&larr; Pré-requisitos & credenciais</a><a class="next" href="05-passo-a-passo-apex.html">Passo a passo: aplicação APEX &rarr;</a></div>
</main>
</div>
<script src="assets/main.js"></script>
</body>
</html>