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_REGIONregion), ex.: sa-saopaulo-1.OS_NAMESPACEOS_BUCKETGENAI_REGIONOCI_REGION. Padrão us-chicago-1; troque se sua tenancy não alcançar essa região (ver Operação & observabilidade).AI_LOG_RETENTION_DAYSapex_cred, RAG_CRED, compartimento no remote server apex_genai)-- 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.';
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.
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 indisponibilidade Credencial 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 AI ACL 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.