From 1e9af90582fe915f7f51393b0c18105cbf91f63f Mon Sep 17 00:00:00 2001 From: Antonio Sergio Rodrigues Figueiredo Date: Fri, 24 Jul 2026 15:20:32 -0300 Subject: [PATCH] Torna a regiao do Generative AI configuravel (GENAI_REGION) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- docs/03-pre-requisitos-credenciais.html | 2 + docs/04-passo-a-passo-banco.html | 254 +++++++++++++++++++++--- docs/09-operacao-observabilidade.html | 3 +- sql/01_ampminsights_db_setup.sql | 69 ++++--- 4 files changed, 272 insertions(+), 56 deletions(-) diff --git a/docs/03-pre-requisitos-credenciais.html b/docs/03-pre-requisitos-credenciais.html index d85db57..acf7687 100644 --- a/docs/03-pre-requisitos-credenciais.html +++ b/docs/03-pre-requisitos-credenciais.html @@ -98,6 +98,8 @@ Allow group ampminsights-app to read objects in compartment <nome-do-comparti OCI_REGIONPasso 4 acima (campo region), ex.: sa-saopaulo-1. OS_NAMESPACEPasso 6 acima. Só necessário se for usar o modelo ONNX (Seção 4 do script 1). OS_BUCKETNome que você escolher para o bucket que vai criar na Seção 4 do script 1. +GENAI_REGIONRegião do OCI Generative AI (Seção 5+) — pode ser diferente de OCI_REGION. Padrão us-chicago-1; troque se sua tenancy não alcançar essa região (ver Operação & observabilidade). +AI_LOG_RETENTION_DAYSPreenchido automaticamente (90 dias) — dias de retenção do log de chamadas de IA/embeddings. Chave privada (.pem)Passo 7 acima — colada direto na Seção 3 do script 1, nunca na tabela de configuração. Credenciais do export APEX (apex_cred, RAG_CRED, compartimento no remote server apex_genai)Mesmos valores de tenancy/compartimento acima — preenchidos na importação do app (ver Passo a passo: aplicação APEX). diff --git a/docs/04-passo-a-passo-banco.html b/docs/04-passo-a-passo-banco.html index a44c6a1..ec83104 100644 --- a/docs/04-passo-a-passo-banco.html +++ b/docs/04-passo-a-passo-banco.html @@ -112,9 +112,15 @@ 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). Se voce for --- usar outra regiao de Generative AI, ajuste o host abaixo (e repita --- este bloco para cada host adicional que for necessario). +-- Generative AI usado neste script (regiao us-chicago-1 por padrao - o +-- mesmo valor que vai para o parametro GENAI_REGION da SECAO 2, que +-- ainda nao existe neste ponto do script, por isso o host aqui e +-- digitado direto). Nem toda tenancy alcanca us-chicago-1 (ex.: algumas +-- tenancies com escopo regional restrito, como America Latina, podem +-- so alcancar sa-saopaulo-1) - se for o seu caso, troque o host abaixo +-- pela regiao que a sua tenancy alcanca, E use o mesmo valor no +-- parametro GENAI_REGION da SECAO 2 (repita este bloco para cada host +-- adicional que for necessario). BEGIN DBMS_NETWORK_ACL_ADMIN.APPEND_HOST_ACE( host => 'inference.generativeai.us-chicago-1.oci.oraclecloud.com', @@ -217,6 +223,14 @@ INSERT INTO TB_26AI_TECH_PARAMS (PARAM_NAME, PARAM_VALUE, DESCRIPTION) VALUES ('OS_BUCKET', '<SUBSTITUA_PELO_NOME_DO_BUCKET_QUE_VOCE_VAI_CRIAR>', 'Nome do bucket de Object Storage onde o modelo ONNX sera armazenado (ver SECAO 4).'); +INSERT INTO TB_26AI_TECH_PARAMS (PARAM_NAME, PARAM_VALUE, DESCRIPTION) VALUES + ('AI_LOG_RETENTION_DAYS', '90', + 'Dias de retencao do log de chamadas de IA/embeddings (TB_26AI_TECH_LOG) - ver docs/09-operacao-observabilidade.html para a query de purga.'); + +INSERT INTO TB_26AI_TECH_PARAMS (PARAM_NAME, PARAM_VALUE, DESCRIPTION) VALUES + ('GENAI_REGION', 'us-chicago-1', + 'Regiao do OCI Generative AI usada pelo RAG/insights/embeddings (SECAO 5+). Pode ser diferente da OCI_REGION (que e a regiao "de casa" do seu tenancy/bucket) - o Generative AI so roda em regioes especificas. Se a sua tenancy nao alcancar us-chicago-1 (comum em tenancies com escopo regional restrito, ex. America Latina), troque para uma regiao que a sua tenancy alcance (ex. sa-saopaulo-1) E repita a ACL da SECAO 1.6 para o novo host - confirme antes com "oci generative-ai model-collection list-models" ou o Console OCI que o modelo usado (meta.llama-4-maverick-17b-128e-instruct-fp8) ainda esta ativo para uso on-demand na regiao escolhida, ja que a disponibilidade de modelos varia por regiao e muda com o tempo.'); + COMMIT; -- Confira: nenhuma linha abaixo deve ainda mostrar um valor "<SUBSTITUA...>" @@ -532,14 +546,15 @@ criação de um profile de SELECT AI (que já lê região e compartimento da tab
-- 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)
+-- 5.1) Teste de embedding (Cohere, via OCI Generative AI). A URL usa a
+--      regiao configurada em GENAI_REGION (SECAO 2), nao um valor fixo.
 SELECT VECTOR_SERIALIZE(
     DBMS_VECTOR_CHAIN.UTL_TO_EMBEDDING(
         TO_CLOB('Teste simples para gerar um embedding.'),
         JSON('{
             "provider": "ocigenai",
             "credential_name": "OCI_CRED",
-            "url": "https://inference.generativeai.us-chicago-1.oci.oraclecloud.com/20231130/actions/embedText",
+            "url": "https://inference.generativeai.' || (SELECT param_value FROM TB_26AI_TECH_PARAMS WHERE param_name = 'GENAI_REGION') || '.oci.oraclecloud.com/20231130/actions/embedText",
             "model": "cohere.embed-v4.0"
         }')
     )
@@ -547,13 +562,14 @@ SELECT VECTOR_SERIALIZE(
 ) AS embedding
 FROM dual;
 
--- 5.2) Teste de geracao de texto (Llama 4, via OCI Generative AI)
+-- 5.2) Teste de geracao de texto (Llama 4, via OCI Generative AI). Mesma
+--      logica: a URL usa a regiao configurada em GENAI_REGION (SECAO 2).
 SELECT DBMS_VECTOR_CHAIN.UTL_TO_GENERATE_TEXT(
     TO_CLOB('Responda somente com a palavra: sucesso'),
     JSON('{
         "provider": "ocigenai",
         "credential_name": "OCI_CRED",
-        "url": "https://inference.generativeai.us-chicago-1.oci.oraclecloud.com/20231130/actions/chat",
+        "url": "https://inference.generativeai.' || (SELECT param_value FROM TB_26AI_TECH_PARAMS WHERE param_name = 'GENAI_REGION') || '.oci.oraclecloud.com/20231130/actions/chat",
         "model": "meta.llama-4-maverick-17b-128e-instruct-fp8",
         "chatRequest": {
             "temperature": 0.1,
@@ -565,27 +581,28 @@ SELECT DBMS_VECTOR_CHAIN.UTL_TO_GENERATE_TEXT(
 FROM dual;
 
 -- 5.3) Teste de SELECT AI (perguntas em linguagem natural sobre as views/
---      tabelas do schema). O bloco abaixo le EMBEDDING_COMPARTMENT 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.
+--      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 (us-chicago-1) e fixa de
---      proposito, igual nos testes 5.1/5.2 e na ACL da SECAO 1.6 - nao
---      precisa (nem deve) ser trocada pelo valor de OCI_REGION da tabela de
---      configuracao, ja que o servico so esta disponivel em algumas regioes
---      especificas da OCI.
+--      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_compartment   TB_26AI_TECH_PARAMS.PARAM_VALUE%TYPE;
+  v_genai_region  TB_26AI_TECH_PARAMS.PARAM_VALUE%TYPE;
 BEGIN
-  SELECT param_value INTO v_compartment FROM TB_26AI_TECH_PARAMS WHERE param_name = 'EMBEDDING_COMPARTMENT';
+  SELECT param_value INTO v_compartment  FROM TB_26AI_TECH_PARAMS WHERE param_name = 'EMBEDDING_COMPARTMENT';
+  SELECT param_value INTO v_genai_region FROM TB_26AI_TECH_PARAMS WHERE param_name = 'GENAI_REGION';
 
   DBMS_CLOUD_AI.CREATE_PROFILE(
     profile_name => 'OCI_CRED2',
     attributes   => '{
       "provider": "oci",
       "credential_name": "OCI_CRED",
-      "region": "us-chicago-1",
+      "region": "' || v_genai_region || '",
       "model": "meta.llama-4-maverick-17b-128e-instruct-fp8",
       "temperature": 0,
       "comments": true,
@@ -835,19 +852,89 @@ LEFT OUTER JOIN
                      GROUP BY nome
                      HAVING count(1) = 1 )
       ) c
-ON  ( upper(v.ASSET_NAME) = upper(c.nome) AND c.AMBIENTE IS NOT NULL );
+ON ( upper(v.ASSET_NAME) = upper(c.nome) AND c.AMBIENTE IS NOT NULL ); + +-- Log de chamadas de IA/embeddings (sucesso e erro) - nao guarda prompt/ +-- resposta completos, so metadados de uso. Ver docs/09-operacao-observabilidade.html. +CREATE TABLE "TB_26AI_TECH_LOG" + ( "LOG_ID" NUMBER GENERATED ALWAYS AS IDENTITY MINVALUE 1 MAXVALUE 9999999999999999999999999999 INCREMENT BY 1 START WITH 1 CACHE 20 NOORDER NOCYCLE NOKEEP NOSCALE NOT NULL ENABLE, + "LOG_TS" TIMESTAMP(6) WITH TIME ZONE DEFAULT SYSTIMESTAMP NOT NULL ENABLE, + "CALLING_OBJECT" VARCHAR2(128), + "OPERATION" VARCHAR2(30), + "SOURCE_TYPE" VARCHAR2(10), + "SOURCE_ID" VARCHAR2(200), + "PROVIDER" VARCHAR2(30), + "MODEL_NAME" VARCHAR2(100), + "APP_USER" VARCHAR2(100), + "STATUS" VARCHAR2(10), + "ERROR_CODE" NUMBER, + "ERROR_MESSAGE" VARCHAR2(4000), + "DURATION_MS" NUMBER, + "PROMPT_CHARS" NUMBER, + "RESPONSE_CHARS" NUMBER, + CONSTRAINT "TB_26AI_TECH_LOG_PK" PRIMARY KEY ("LOG_ID") USING INDEX ENABLE + ); + +CREATE INDEX "TB_26AI_TECH_LOG_TS_IX" ON "TB_26AI_TECH_LOG" ("LOG_TS"); +CREATE INDEX "TB_26AI_TECH_LOG_ST_IX" ON "TB_26AI_TECH_LOG" ("STATUS","LOG_TS"); + +COMMENT ON TABLE "TB_26AI_TECH_LOG" IS 'Log de cada chamada a Generative AI/embeddings feita pelo ampmInsights (sucesso ou erro) - nao guarda prompt/resposta completos, so metadados de uso (modelo, duracao, tamanho, status, erro). Usada para troubleshooting e monitoramento de consumo - ver docs/09-operacao-observabilidade.html.';

Seção 7 · PL/SQL de geracao de embeddings, RAG e insights (ampmInsights)

-

Cria as funções e a procedure descritas em Arquitetura: -fnc_26ai_embed, fnc_26ai_tech_rag, FNC_26AI_TECH_MCP_V1, -FNC_26ai_rag e prc_26ai_tech. É um bloco longo (a maior parte é o texto dos -prompts de IA) — copie e cole inteiro de uma vez.

+

Cria PRC_26AI_TECH_LOG (log de cada chamada de IA/embedding — ver +Operação & observabilidade) e as funções e a +procedure descritas em Arquitetura: fnc_26ai_embed, +fnc_26ai_tech_rag, FNC_26AI_TECH_MCP_V1, FNC_26ai_rag e +prc_26ai_tech. É um bloco longo (a maior parte é o texto dos prompts de IA) — copie e +cole inteiro de uma vez.

Seção 7 — copiar e colar
-
CREATE OR REPLACE FUNCTION fnc_26ai_embed( p_string      IN VARCHAR2,
+  
CREATE OR REPLACE PROCEDURE PRC_26AI_TECH_LOG (
+  p_calling_object  IN VARCHAR2,
+  p_operation       IN VARCHAR2,
+  p_status          IN VARCHAR2,
+  p_source_type     IN VARCHAR2 DEFAULT NULL,
+  p_source_id       IN VARCHAR2 DEFAULT NULL,
+  p_provider        IN VARCHAR2 DEFAULT NULL,
+  p_model_name      IN VARCHAR2 DEFAULT NULL,
+  p_error_code      IN NUMBER   DEFAULT NULL,
+  p_error_message   IN VARCHAR2 DEFAULT NULL,
+  p_duration_ms     IN NUMBER   DEFAULT NULL,
+  p_prompt_chars    IN NUMBER   DEFAULT NULL,
+  p_response_chars  IN NUMBER   DEFAULT NULL
+) AS
+  PRAGMA AUTONOMOUS_TRANSACTION;
+/*
+  Projeto: ampmInsights
+  Objetivo: registrar em TB_26AI_TECH_LOG cada chamada a Generative AI/
+            embeddings (sucesso ou erro), para troubleshooting e
+            monitoramento de consumo (ver docs/09-operacao-observabilidade.html).
+  Autonomous transaction: pode ser chamada de dentro de functions invocadas
+  em contexto SQL sem interferir na transacao do chamador; nunca propaga erro
+  (uma falha ao logar nao pode derrubar a chamada real de IA).
+*/
+BEGIN
+  INSERT INTO TB_26AI_TECH_LOG (
+    calling_object, operation, source_type, source_id, provider, model_name,
+    app_user, status, error_code, error_message, duration_ms, prompt_chars,
+    response_chars
+  ) VALUES (
+    p_calling_object, p_operation, p_source_type, p_source_id, p_provider,
+    p_model_name, NVL(V('APP_USER'), SYS_CONTEXT('USERENV','SESSION_USER')),
+    p_status, p_error_code, SUBSTR(p_error_message, 1, 4000), p_duration_ms,
+    p_prompt_chars, p_response_chars
+  );
+  COMMIT;
+EXCEPTION
+  WHEN OTHERS THEN
+    NULL; -- logging nunca pode quebrar a chamada real
+END;
+/
+
+CREATE OR REPLACE FUNCTION fnc_26ai_embed( p_string      IN VARCHAR2,
                                             p_emb_type    IN VARCHAR2 DEFAULT 'COHERE',
                                             p_credential  IN VARCHAR2 DEFAULT 'OCI_CRED')
 RETURN CLOB
@@ -891,7 +978,7 @@ BEGIN
                         dbms_vector_chain.utl_to_text( v_string ),
 					     json('{    "provider": "ocigenai",
                                 "credential_name": "' || p_credential || '",
-                                "url": "https://inference.generativeai.us-chicago-1.oci.oraclecloud.com/20231130/actions/embedText",
+                                "url": "https://inference.generativeai.' || (SELECT param_value FROM TB_26AI_TECH_PARAMS WHERE param_name = 'GENAI_REGION') || '.oci.oraclecloud.com/20231130/actions/embedText",
                                 "model": "cohere.embed-v4.0"
                             }')
                 )
@@ -929,12 +1016,34 @@ BEGIN
 				EXCEPTION
 					WHEN OTHERS THEN
 					   DBMS_OUTPUT.PUT_LINE('Erro: ' || SQLCODE || ' - ' || SQLERRM);
+					   PRC_26AI_TECH_LOG(
+					     p_calling_object => 'FNC_26AI_EMBED',
+					     p_operation      => 'EMBEDDING',
+					     p_status         => 'ERROR',
+					     p_provider       => 'vLLM',
+					     p_error_code     => SQLCODE,
+					     p_error_message  => SQLERRM
+					   );
 				END;
 
     END IF;
 
 	RETURN v_embedding;
 
+EXCEPTION
+  WHEN OTHERS THEN
+    -- Cobre os ramos ONNX/COHERE (o vLLM ja trata e loga o proprio erro
+    -- acima e nao propaga). Loga e repropaga sem mudar o comportamento
+    -- existente.
+    PRC_26AI_TECH_LOG(
+      p_calling_object => 'FNC_26AI_EMBED',
+      p_operation      => 'EMBEDDING',
+      p_status         => 'ERROR',
+      p_provider       => p_emb_type,
+      p_error_code     => SQLCODE,
+      p_error_message  => SQLERRM
+    );
+    RAISE;
 END;
 /
 
@@ -959,9 +1068,12 @@ RETURN CLOB IS
    output        CLOB;
    query_vec     VECTOR;
    v_llm         VARCHAR2(20) := 'LLAMA4'; -- [ LLAMA4 | OPENAI ]
+   v_genai_region TB_26AI_TECH_PARAMS.PARAM_VALUE%TYPE;
 
 BEGIN
 
+  SELECT param_value INTO v_genai_region FROM TB_26AI_TECH_PARAMS WHERE param_name = 'GENAI_REGION';
+
   -- embedding da pergunta do usuario
   query_vec := to_vector( fnc_26ai_embed ( p_string => p_query, p_emb_type => 'COHERE' ) ) ;
 
@@ -987,7 +1099,7 @@ BEGIN
     params_genai := '{
 		"provider" : "ocigenai",
      	"credential_name" : "' || p_credential || '",
-		"url" : "https://inference.generativeai.us-chicago-1.oci.oraclecloud.com/20231130/actions/chat",
+		"url" : "https://inference.generativeai.' || v_genai_region || '.oci.oraclecloud.com/20231130/actions/chat",
 		"model": "meta.llama-4-maverick-17b-128e-instruct-fp8"}';
 
   ELSIF v_llm = 'OPENAI' THEN
@@ -1055,6 +1167,20 @@ Formato obrigatorio de saida:
 
    RETURN output;
 
+EXCEPTION
+  WHEN OTHERS THEN
+    -- Nao havia handler antes; loga e repropaga (comportamento de
+    -- propagar o erro ao chamador continua o mesmo).
+    PRC_26AI_TECH_LOG(
+      p_calling_object => 'FNC_26AI_TECH_RAG',
+      p_operation      => 'RAG',
+      p_status         => 'ERROR',
+      p_source_type    => p_source_type,
+      p_provider       => 'ocigenai',
+      p_error_code     => SQLCODE,
+      p_error_message  => SQLERRM
+    );
+    RAISE;
 END;
 /
 
@@ -1087,10 +1213,16 @@ RETURN CLOB AS
   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) := 'https://inference.generativeai.us-chicago-1.oci.oraclecloud.com';
+      v_gen_ai_endpoint VARCHAR2(500);
       v_gen_ai_model    VARCHAR2(500) := 'meta.llama-4-maverick-17b-128e-instruct-fp8';
       resp DBMS_CLOUD_TYPES.RESP;
+      v_t0     PLS_INTEGER := DBMS_UTILITY.GET_TIME;
+      v_result CLOB;
 BEGIN
+    SELECT 'https://inference.generativeai.' || param_value || '.oci.oraclecloud.com'
+      INTO v_gen_ai_endpoint
+      FROM TB_26AI_TECH_PARAMS WHERE param_name = 'GENAI_REGION';
+
     resp := dbms_cloud.send_request(
         credential_name => p_oci_cred,
         uri => v_gen_ai_endpoint || '/20231130/actions/chat',
@@ -1119,10 +1251,34 @@ BEGIN
                         ))
         ))
     );
-    RETURN json_value( dbms_cloud.get_response_text(resp) , '$.chatResponse.choices[0].message.content[0].text') ;
+    v_result := json_value( dbms_cloud.get_response_text(resp) , '$.chatResponse.choices[0].message.content[0].text') ;
+
+    PRC_26AI_TECH_LOG(
+      p_calling_object => 'FNC_26AI_RAG',
+      p_operation      => 'CHAT',
+      p_status         => 'OK',
+      p_provider       => 'ocigenai',
+      p_model_name     => v_gen_ai_model,
+      p_duration_ms    => (DBMS_UTILITY.GET_TIME - v_t0) * 10,
+      p_prompt_chars   => LENGTH(p_ai_prompt),
+      p_response_chars => LENGTH(v_result)
+    );
+
+    RETURN v_result;
 
 EXCEPTION
  WHEN OTHERS THEN
+     PRC_26AI_TECH_LOG(
+       p_calling_object => 'FNC_26AI_RAG',
+       p_operation      => 'CHAT',
+       p_status         => 'ERROR',
+       p_provider       => 'ocigenai',
+       p_model_name     => v_gen_ai_model,
+       p_error_code     => SQLCODE,
+       p_error_message  => SQLERRM,
+       p_duration_ms    => (DBMS_UTILITY.GET_TIME - v_t0) * 10,
+       p_prompt_chars   => LENGTH(p_ai_prompt)
+     );
      RETURN 'Nao foi possivel gerar um texto com base nas informacoes.';
 END;
 /
@@ -1167,8 +1323,11 @@ AS
   v_response        CLOB;
   v_json            CLOB;
   v_error           CLOB;
+  v_genai_region    TB_26AI_TECH_PARAMS.PARAM_VALUE%TYPE;
 BEGIN
 
+  SELECT param_value INTO v_genai_region FROM TB_26AI_TECH_PARAMS WHERE param_name = 'GENAI_REGION';
+
 IF p_source_type = 'VUL' THEN -- vulnerabilidades
 
     v_pre_prompt :='Voce e um analista senior de dados e operacoes.
@@ -1565,7 +1724,7 @@ Retorne um JSON valido (sem comentarios), espelhando o relatorio:
                            (  v_response ) ,
                         json('{ "provider": "ocigenai",
                                 "credential_name": "' || p_oci_cred || '",
-                                "url": "https://inference.generativeai.us-chicago-1.oci.oraclecloud.com/20231130/actions/embedText",
+                                "url": "https://inference.generativeai.' || v_genai_region || '.oci.oraclecloud.com/20231130/actions/embedText",
                                 "model": "cohere.embed-v4.0"
                             }')
                     )
@@ -1579,21 +1738,52 @@ Retorne um JSON valido (sem comentarios), espelhando o relatorio:
                     )
                 ) AS et;
 
+       PRC_26AI_TECH_LOG(
+         p_calling_object => 'PRC_26AI_TECH',
+         p_operation      => 'EMBEDDING',
+         p_status         => 'OK',
+         p_source_type    => p_source_type,
+         p_source_id      => p_rowid,
+         p_provider       => 'ocigenai',
+         p_model_name     => 'cohere.embed-v4.0',
+         p_prompt_chars   => LENGTH(v_response)
+       );
+
     END IF;
 
+    PRC_26AI_TECH_LOG(
+      p_calling_object => 'PRC_26AI_TECH',
+      p_operation      => 'INSIGHT_PIPELINE',
+      p_status         => 'OK',
+      p_source_type    => p_source_type,
+      p_source_id      => p_rowid
+    );
+
     COMMIT;
 
 EXCEPTION
   WHEN OTHERS THEN
     v_error := sqlerrm;
+    PRC_26AI_TECH_LOG(
+      p_calling_object => 'PRC_26AI_TECH',
+      p_operation      => 'INSIGHT_PIPELINE',
+      p_status         => 'ERROR',
+      p_source_type    => p_source_type,
+      p_source_id      => p_rowid,
+      p_error_code     => SQLCODE,
+      p_error_message  => v_error
+    );
+    -- Antes, o erro tecnico (sqlerrm) era gravado direto em insight_report e
+    -- ficava visivel pro usuario de negocio no modal. Agora o erro completo
+    -- vai so pro log (TB_26AI_TECH_LOG); o usuario ve uma mensagem amigavel.
     IF p_source_type = 'VUL' THEN
         UPDATE TB_26AI_TECH_v2
-           SET insight_report = v_error,
+           SET insight_report = 'Nao foi possivel gerar o insight para este registro no momento.',
                insight_json =  null
            WHERE rowid = p_rowid;
     ELSIF p_source_type = 'SYS' THEN
         UPDATE TB_26AI_TECH_SYS
-           SET insight_report = v_error,
+           SET insight_report = 'Nao foi possivel gerar o insight para este registro no momento.',
                insight_json =  null
            WHERE rowid = p_rowid;
     END IF;
diff --git a/docs/09-operacao-observabilidade.html b/docs/09-operacao-observabilidade.html
index 4600c63..285f708 100644
--- a/docs/09-operacao-observabilidade.html
+++ b/docs/09-operacao-observabilidade.html
@@ -50,7 +50,8 @@ rapidamente qualquer problema, e o checklist abaixo para os casos mais comuns.ORA-00942 em qualquer objeto TB_26AI_TECH_*Conectado como ADMIN em vez de AMPMINSIGHTS.Rode SELECT USER FROM DUAL; — tem que voltar AMPMINSIGHTS. Reconecte e repita a seção que falhou.
 "AI Insight"/chat sempre retorna um texto genérico de indisponibilidadeCredencial OCI_CRED ausente ou quebrada.SELECT credential_name FROM user_credentials WHERE credential_name = 'OCI_CRED'; — se não retornar linha, refaça a Seção 3 conectado como AMPMINSIGHTS. Depois, confira o motivo exato na consulta de "Erros recentes" abaixo.
 Erro de rede/timeout ao chamar o Generative AIACL de rede (Seção 1.6) não cobre o host correto.SELECT host, privilege FROM dba_host_aces WHERE principal = 'AMPMINSIGHTS'; — deve listar inference.generativeai.us-chicago-1.oci.oraclecloud.com com RESOLVE e CONNECT.
-ORA-20404 ("Object not found", domínio oci.my$cloud_domain)Perfil de SELECT AI usando a região "de casa" do tenancy em vez da região do Generative AI.A região do Generative AI já vem fixa (us-chicago-1) na Seção 5.3 do Passo a passo: banco de dados — não troque pelo valor de OCI_REGION.
+ORA-20404 ("Object not found", domínio oci.my$cloud_domain)Perfil de SELECT AI usando a região "de casa" do tenancy (OCI_REGION) em vez da região do Generative AI.Use o valor de GENAI_REGION (Seção 2), não OCI_REGION — ver Seção 5.3 do Passo a passo: banco de dados.
+ORA-20404 com URL bem formada (região correta no domínio)A tenancy não alcança a região configurada em GENAI_REGION, ou o modelo não está mais disponível para uso on-demand nessa região (a disponibilidade de modelos varia por região e muda com o tempo).Rode oci generative-ai model-collection list-models --compartment-id <seu-compartimento> --region <regiao-candidata> --capability CHAT --all (ou o Console OCI) e confirme que o modelo usado está ACTIVE e sem time-on-demand-retired preenchido nessa região; ajuste GENAI_REGION (e a ACL da Seção 1.6 para o novo host) para uma região que sua tenancy alcance e que ainda sirva o modelo on-demand.
 
 
diff --git a/sql/01_ampminsights_db_setup.sql b/sql/01_ampminsights_db_setup.sql index cda76e5..311f0dc 100644 --- a/sql/01_ampminsights_db_setup.sql +++ b/sql/01_ampminsights_db_setup.sql @@ -103,9 +103,15 @@ 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). Se voce for --- usar outra regiao de Generative AI, ajuste o host abaixo (e repita --- este bloco para cada host adicional que for necessario). +-- Generative AI usado neste script (regiao us-chicago-1 por padrao - o +-- mesmo valor que vai para o parametro GENAI_REGION da SECAO 2, que +-- ainda nao existe neste ponto do script, por isso o host aqui e +-- digitado direto). Nem toda tenancy alcanca us-chicago-1 (ex.: algumas +-- tenancies com escopo regional restrito, como America Latina, podem +-- so alcancar sa-saopaulo-1) - se for o seu caso, troque o host abaixo +-- pela regiao que a sua tenancy alcanca, E use o mesmo valor no +-- parametro GENAI_REGION da SECAO 2 (repita este bloco para cada host +-- adicional que for necessario). BEGIN DBMS_NETWORK_ACL_ADMIN.APPEND_HOST_ACE( host => 'inference.generativeai.us-chicago-1.oci.oraclecloud.com', @@ -201,6 +207,10 @@ INSERT INTO TB_26AI_TECH_PARAMS (PARAM_NAME, PARAM_VALUE, DESCRIPTION) VALUES ('AI_LOG_RETENTION_DAYS', '90', 'Dias de retencao do log de chamadas de IA/embeddings (TB_26AI_TECH_LOG) - ver docs/09-operacao-observabilidade.html para a query de purga.'); +INSERT INTO TB_26AI_TECH_PARAMS (PARAM_NAME, PARAM_VALUE, DESCRIPTION) VALUES + ('GENAI_REGION', 'us-chicago-1', + 'Regiao do OCI Generative AI usada pelo RAG/insights/embeddings (SECAO 5+). Pode ser diferente da OCI_REGION (que e a regiao "de casa" do seu tenancy/bucket) - o Generative AI so roda em regioes especificas. Se a sua tenancy nao alcancar us-chicago-1 (comum em tenancies com escopo regional restrito, ex. America Latina), troque para uma regiao que a sua tenancy alcance (ex. sa-saopaulo-1) E repita a ACL da SECAO 1.6 para o novo host - confirme antes com "oci generative-ai model-collection list-models" ou o Console OCI que o modelo usado (meta.llama-4-maverick-17b-128e-instruct-fp8) ainda esta ativo para uso on-demand na regiao escolhida, ja que a disponibilidade de modelos varia por regiao e muda com o tempo.'); + COMMIT; -- Confira: nenhuma linha abaixo deve ainda mostrar um valor "" @@ -340,14 +350,15 @@ WHERE model_name = 'CLIP_VIT_LARGE_PATCH14_TXT'; -- 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) +-- 5.1) Teste de embedding (Cohere, via OCI Generative AI). A URL usa a +-- regiao configurada em GENAI_REGION (SECAO 2), nao um valor fixo. SELECT VECTOR_SERIALIZE( DBMS_VECTOR_CHAIN.UTL_TO_EMBEDDING( TO_CLOB('Teste simples para gerar um embedding.'), JSON('{ "provider": "ocigenai", "credential_name": "OCI_CRED", - "url": "https://inference.generativeai.us-chicago-1.oci.oraclecloud.com/20231130/actions/embedText", + "url": "https://inference.generativeai.' || (SELECT param_value FROM TB_26AI_TECH_PARAMS WHERE param_name = 'GENAI_REGION') || '.oci.oraclecloud.com/20231130/actions/embedText", "model": "cohere.embed-v4.0" }') ) @@ -355,13 +366,14 @@ SELECT VECTOR_SERIALIZE( ) AS embedding FROM dual; --- 5.2) Teste de geracao de texto (Llama 4, via OCI Generative AI) +-- 5.2) Teste de geracao de texto (Llama 4, via OCI Generative AI). Mesma +-- logica: a URL usa a regiao configurada em GENAI_REGION (SECAO 2). SELECT DBMS_VECTOR_CHAIN.UTL_TO_GENERATE_TEXT( TO_CLOB('Responda somente com a palavra: sucesso'), JSON('{ "provider": "ocigenai", "credential_name": "OCI_CRED", - "url": "https://inference.generativeai.us-chicago-1.oci.oraclecloud.com/20231130/actions/chat", + "url": "https://inference.generativeai.' || (SELECT param_value FROM TB_26AI_TECH_PARAMS WHERE param_name = 'GENAI_REGION') || '.oci.oraclecloud.com/20231130/actions/chat", "model": "meta.llama-4-maverick-17b-128e-instruct-fp8", "chatRequest": { "temperature": 0.1, @@ -373,27 +385,28 @@ SELECT DBMS_VECTOR_CHAIN.UTL_TO_GENERATE_TEXT( FROM dual; -- 5.3) Teste de SELECT AI (perguntas em linguagem natural sobre as views/ --- tabelas do schema). O bloco abaixo le EMBEDDING_COMPARTMENT 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. +-- 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 (us-chicago-1) e fixa de --- proposito, igual nos testes 5.1/5.2 e na ACL da SECAO 1.6 - nao --- precisa (nem deve) ser trocada pelo valor de OCI_REGION da tabela de --- configuracao, ja que o servico so esta disponivel em algumas regioes --- especificas da OCI. +-- 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_compartment TB_26AI_TECH_PARAMS.PARAM_VALUE%TYPE; + v_genai_region TB_26AI_TECH_PARAMS.PARAM_VALUE%TYPE; BEGIN - SELECT param_value INTO v_compartment FROM TB_26AI_TECH_PARAMS WHERE param_name = 'EMBEDDING_COMPARTMENT'; + SELECT param_value INTO v_compartment FROM TB_26AI_TECH_PARAMS WHERE param_name = 'EMBEDDING_COMPARTMENT'; + SELECT param_value INTO v_genai_region FROM TB_26AI_TECH_PARAMS WHERE param_name = 'GENAI_REGION'; DBMS_CLOUD_AI.CREATE_PROFILE( profile_name => 'OCI_CRED2', attributes => '{ "provider": "oci", "credential_name": "OCI_CRED", - "region": "us-chicago-1", + "region": "' || v_genai_region || '", "model": "meta.llama-4-maverick-17b-128e-instruct-fp8", "temperature": 0, "comments": true, @@ -752,7 +765,7 @@ BEGIN dbms_vector_chain.utl_to_text( v_string ), json('{ "provider": "ocigenai", "credential_name": "' || p_credential || '", - "url": "https://inference.generativeai.us-chicago-1.oci.oraclecloud.com/20231130/actions/embedText", + "url": "https://inference.generativeai.' || (SELECT param_value FROM TB_26AI_TECH_PARAMS WHERE param_name = 'GENAI_REGION') || '.oci.oraclecloud.com/20231130/actions/embedText", "model": "cohere.embed-v4.0" }') ) @@ -842,9 +855,12 @@ RETURN CLOB IS output CLOB; query_vec VECTOR; v_llm VARCHAR2(20) := 'LLAMA4'; -- [ LLAMA4 | OPENAI ] + v_genai_region TB_26AI_TECH_PARAMS.PARAM_VALUE%TYPE; BEGIN + SELECT param_value INTO v_genai_region FROM TB_26AI_TECH_PARAMS WHERE param_name = 'GENAI_REGION'; + -- embedding da pergunta do usuario query_vec := to_vector( fnc_26ai_embed ( p_string => p_query, p_emb_type => 'COHERE' ) ) ; @@ -870,7 +886,7 @@ BEGIN params_genai := '{ "provider" : "ocigenai", "credential_name" : "' || p_credential || '", - "url" : "https://inference.generativeai.us-chicago-1.oci.oraclecloud.com/20231130/actions/chat", + "url" : "https://inference.generativeai.' || v_genai_region || '.oci.oraclecloud.com/20231130/actions/chat", "model": "meta.llama-4-maverick-17b-128e-instruct-fp8"}'; ELSIF v_llm = 'OPENAI' THEN @@ -984,12 +1000,16 @@ RETURN CLOB AS 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) := 'https://inference.generativeai.us-chicago-1.oci.oraclecloud.com'; + v_gen_ai_endpoint VARCHAR2(500); v_gen_ai_model VARCHAR2(500) := 'meta.llama-4-maverick-17b-128e-instruct-fp8'; resp DBMS_CLOUD_TYPES.RESP; v_t0 PLS_INTEGER := DBMS_UTILITY.GET_TIME; v_result CLOB; BEGIN + SELECT 'https://inference.generativeai.' || param_value || '.oci.oraclecloud.com' + INTO v_gen_ai_endpoint + FROM TB_26AI_TECH_PARAMS WHERE param_name = 'GENAI_REGION'; + resp := dbms_cloud.send_request( credential_name => p_oci_cred, uri => v_gen_ai_endpoint || '/20231130/actions/chat', @@ -1090,8 +1110,11 @@ AS v_response CLOB; v_json CLOB; v_error CLOB; + v_genai_region TB_26AI_TECH_PARAMS.PARAM_VALUE%TYPE; BEGIN + SELECT param_value INTO v_genai_region FROM TB_26AI_TECH_PARAMS WHERE param_name = 'GENAI_REGION'; + IF p_source_type = 'VUL' THEN -- vulnerabilidades v_pre_prompt :='Voce e um analista senior de dados e operacoes. @@ -1488,7 +1511,7 @@ Retorne um JSON valido (sem comentarios), espelhando o relatorio: ( v_response ) , json('{ "provider": "ocigenai", "credential_name": "' || p_oci_cred || '", - "url": "https://inference.generativeai.us-chicago-1.oci.oraclecloud.com/20231130/actions/embedText", + "url": "https://inference.generativeai.' || v_genai_region || '.oci.oraclecloud.com/20231130/actions/embedText", "model": "cohere.embed-v4.0" }') )