diff --git a/prc_26ai_nl2sql.sql b/prc_26ai_nl2sql.sql new file mode 100644 index 0000000..43da79b --- /dev/null +++ b/prc_26ai_nl2sql.sql @@ -0,0 +1,265 @@ +create or replace procedure prc_26AI_NL2SQL ( + p_app_user in varchar2, + p_prompt in clob, + p_profile in varchar2, + p_action in varchar2 default 'narrate', + p_limit_rows in number default 100, + p_force_runsql in varchar2 default 'N', + p_result out clob + ) +as +/* + + Criado por: fernando.leal@oracle.com + Data: Oct/2025 + Objetivo: demonstrar casos de uso do Oracle AI Database 26ai + + v1 - rotina para controle de regras ao SelectAI - leal + +begin + dbms_cloud_ai.create_profile( + profile_name => 'PROF_CENSO_V1', + attributes => + '{"provider": "oci", + "credential_name": "OCI_CRED", + "oci_compartment_id": "ocid1.compartment.oc1..xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "region": "us-chicago-1", + "model": "meta.llama-4-maverick-17b-128e-instruct-fp8", + "oci_apiformat": "GENERIC", + "object_list_mode": "automated", + "object_list": [ + {"owner": "AICHAT1", "name": "TB_26AI_CENSO"} + ], + "enforce_object_list": true, + "constraints":"true", + "comments": true, + "annotations": true, + "temperature": 0.1 + }' + ); +end; + + +*/ + v_response clob; + v_narrate clob; + v_pre_prompt_geral clob; + v_pre_prompt_contexto clob; + v_contexto clob; + + v_categoria varchar2(200); + v_profile varchar2(200); + + v_estimated_rows number; + -- + -- Limite de linhas que pode ser narrado + -- + v_limit_rows number := p_limit_rows; + -- + -- caso numero de linhas seja muito alto (definido por v_limit_rows), a acao narrate sera alterada para runwsql automaticamente + -- + v_force_runsql varchar2(1) := upper(p_force_runsql); + v_dt_start TIMESTAMP ; + v_runsql clob; +begin + + v_dt_start := current_timestamp; + + v_pre_prompt_geral := 'Sempre utilize alias para referencias nome da tabela. Nunca cite owner.'; + + -- + -- Ajustar e definir as categorias existentes. As categorias irao definir pre prompts mais especificos + -- + SELECT DBMS_CLOUD_AI.GENERATE(prompt => 'Com base na pergunta: "' || p_prompt || '", defina qual a melhor categoria para ela: "cidades","estados","população","censo","outros". + A resposta deve ser em JSON, e deve seguir este exemplo: { "categoria": "exemplo" }. APENAS ESTE JSON DEVE SER RETORNADO.', + profile_name => p_profile, + action => 'chat') response + INTO v_contexto; + + begin + SELECT jt.categoria + INTO v_categoria + FROM JSON_TABLE( + replace(replace(v_contexto,'```',''),'json',''), + '$[*]' COLUMNS ( + categoria VARCHAR2(50) PATH '$.categoria' + ) + ) jt; + exception + when others then + p_result := v_contexto; + end; + + dbms_output.put_line('v_categoria: ' || v_categoria); + + if v_categoria in ('cidades','estados','população','censo') then + + v_pre_prompt_contexto := 'Filtros para nome de estados sempre devem ser com 2 caracteres em MAISUCULO. Exemplo: Minas Gerais como MG, Amazonas como AM, Pará como PA'; + + -- pode haver definicao de varios profiles, sendo que cada um estara associado a uma categoria especifica. Neste exemplo, herda da propria chamada + v_profile := 'PROF_CENSO_V3'; + + else + + p_result := 'O prompt informado não faz referência aos dados que podem ser retornados. Contexto: ' || v_categoria; + + end if; + + dbms_output.put_line('v_profile: ' || v_profile); + + -- + -- deve ter havido uma categorizacao da questao com associacao a um profile do SelectAI + -- + if v_profile is not null then + + -- resposta do showsql para analise do comando + SELECT DBMS_CLOUD_AI.GENERATE(prompt => v_pre_prompt_geral || ' ' || v_pre_prompt_contexto || ' ' || p_prompt, + profile_name => v_profile, + action => 'showsql') response + INTO v_response; + + if upper(v_response) like 'SELECT%' or upper(v_response) like 'WITH%' then + + -- estimativa do numero de linahs retornadas + -- baseado em estatisticas das tabelas e indices + BEGIN + EXECUTE IMMEDIATE 'EXPLAIN PLAN SET STATEMENT_ID = ''plan_selectai'' FOR ' || v_response; + + SELECT MAX(cardinality) + INTO v_estimated_rows + FROM plan_table + WHERE id = 0 + AND STATEMENT_ID = 'plan_selectai'; + EXCEPTION + WHEN OTHERS THEN + v_estimated_rows := 0; + END; + + dbms_output.put_line('v_response: ' || v_response); + dbms_output.put_line('v_estimated_rows: ' || v_estimated_rows); + dbms_output.put_line('v_limit_rows: ' || v_limit_rows); + dbms_output.put_line('v_force_runsql: ' || v_force_runsql); + + -- validacoes + -- if instr(upper(v_response),'WHERE') = 0 and instr(upper(v_response),'GROUP') = 0 then + + --p_result := 'O prompt informado não tem nenhum tipo de filtro. Procure adicionar algum critério, como filtros por data, empresa, região, SKU, etc'; + + if v_estimated_rows > v_limit_rows then + + -- + -- colocar recurso pra trazer dados parcisi (ate X linhas ) + -- + + if lower(p_action) = 'narrate' and v_force_runsql = 'Y' then + + -- chamada principal do SelectAI + BEGIN + SELECT DBMS_CLOUD_AI.GENERATE(prompt => v_pre_prompt_geral || ' ' || v_pre_prompt_contexto || ' ' || p_prompt, + profile_name => v_profile, + action => 'runsql') response + INTO v_narrate; + EXCEPTION + WHEN NO_DATA_FOUND THEN + v_narrate := 'Desculpe, mas não há informações específicas sobre "' || p_prompt || '". Há regras de acesso definidas em seu perfil.'; + END; + + p_result := v_narrate; + + else + + p_result := 'Estimativa de linhas retornadas: ' || v_estimated_rows || '. Procure adicionar algum critério, como filtros por data, empresa, região, SKU, etc'; + + end if; + + else + + if p_action <> 'showsql' then + -- chamada principal do SelectAI + BEGIN + SELECT DBMS_CLOUD_AI.GENERATE(prompt => v_pre_prompt_geral || ' ' || v_pre_prompt_contexto || ' ' || p_prompt, + profile_name => v_profile, + action => p_action) response + INTO v_narrate; + + /* + Feedback is available only on Oracle AI Database 26ai. + You can use it alongside the existing Select AI actions: runsql, showsql, and explainsql. + Ensure that your AI profile is configured for NL2SQL generation and not RAG. + */ + if p_action <> 'runsql' then + SELECT DBMS_CLOUD_AI.GENERATE(prompt => v_pre_prompt_geral || ' ' || v_pre_prompt_contexto || ' ' || p_prompt, + profile_name => v_profile, + action => 'runsql') response + INTO v_runsql; + end if; + + EXCEPTION + WHEN NO_DATA_FOUND THEN + v_narrate := 'Desculpe, mas não há informações específicas sobre "' || p_prompt || '". Há regras de acesso definidas em seu perfil.'; + END; + + p_result := v_narrate; + + else + + p_result := v_response; -- sql ja gerado + + + end if; + + + end if; + + else + + p_result := 'Não foi possível gerar uma consulta para atender sua questão: ' || v_response; + + end if; -- select + + end if; -- v_profile + + + + if p_result is not null then + + -- + -- log + -- + insert into TB_26AI_CENSO_HISTORY(USERNAME, + DT, + PROMPT, + RESPONSE, + PROFILE, + NARRATE, + DT_START, + DT_END, + PROMPT_CHARS, + RESPONSE_CHARS + ) + values( lower( p_app_user ) , + sysdate , + p_prompt , + v_response , + v_profile, + --case + -- when lower(p_action) = 'narrate' then + p_result, + -- end, + v_dt_start, + current_timestamp, + DBMS_LOB.GETLENGTH(p_prompt), + case + when lower(p_action) = 'narrate' then + DBMS_LOB.GETLENGTH(v_response) + DBMS_LOB.GETLENGTH(p_result) + else + DBMS_LOB.GETLENGTH(p_result) + end + ) ; + commit; + end if; -- save do p_result + + dbms_output.put_line('p_result: ' || p_result); + +end; +/ \ No newline at end of file diff --git a/prc_26ai_rerank_vllm.sql b/prc_26ai_rerank_vllm.sql new file mode 100644 index 0000000..70a6a07 --- /dev/null +++ b/prc_26ai_rerank_vllm.sql @@ -0,0 +1,34 @@ +create or replace procedure prc_26AI_rerank_VLLM( p_text in varchar2, p_string_options in varchar2) +as + l_resp DBMS_CLOUD_TYPES.resp; + l_text CLOB; + l_body_clob CLOB; + l_body BLOB; + l_query VARCHAR2(500) := 'qual o melhor meio de transporte para ir ate o trabalho em SP'; -- := p_text; +BEGIN + -- montar o JSON do body corretamente + l_body_clob := '{' + || '"model": "Qwen/Qwen3-Reranker-8B",' + || '"topN": 1,' + || '"query": "' || l_query || '",' + || '"documents": ["foguete", "planeta", "carro"]' + || '}'; + + -- "documents": [ p_string_options ] + + l_body := UTL_I18N.STRING_TO_RAW(l_body_clob, 'AL32UTF8'); + + l_resp := DBMS_CLOUD.SEND_REQUEST( + credential_name => NULL, + uri => 'https://hub-gpus.DOMINIO.com.br/rerank/v1/rerank', + method => DBMS_CLOUD.METHOD_POST, + headers => JSON_OBJECT('Content-Type' VALUE 'application/json'), + body => l_body + ); + + l_text := DBMS_CLOUD.GET_RESPONSE_TEXT(l_resp); + + DBMS_OUTPUT.PUT_LINE('Status: ' || DBMS_CLOUD.GET_RESPONSE_STATUS_CODE(l_resp)); + DBMS_OUTPUT.PUT_LINE(SUBSTR(l_text, 1, 5000)); +END; +/ \ No newline at end of file diff --git a/prc_26ai_tech.sql b/prc_26ai_tech.sql new file mode 100644 index 0000000..dd6af6c --- /dev/null +++ b/prc_26ai_tech.sql @@ -0,0 +1,248 @@ +create or replace procedure prc_26ai_tech (p_rowid in varchar default null, + p_oci_cred IN VARCHAR2 default 'OCI_CRED', + p_comp in varchar2 ) +/* + + +Para testes de carga, ou associacao a jobs: + +declare +v_resp clob; +v_json clob; +begin +for r1 in (select rowid cid from TB_26AI_TECH where insight_report is null ) loop + PRC_26AI_TECH (p_rowid => r1.cid , + p_oci_cred => 'OCI_CRED', + p_comp => 'ocid1.compartment.oc1..aaaaaaaayv4jpgnurtdpxwfy3t2tak6akpyh6jgunlc6pdmilqv5f2s5nevq', + p_response => v_resp, + p_json => v_json ); +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; +begin + + v_pre_prompt :='Você é um analista sênior de dados e operações. +Sua tarefa é interpretar os dados, comparar os resultados e produzir um relatório executivo e técnico acionável. + +Objetivo: +Gerar insights em 4 blocos: +1) Análise +2) Diagnóstico +3) Recomendações +4) Plano de ação + +Regras de qualidade: +- Não invente dados ausentes. Quando faltar contexto, declare explicitamente “Informação não fornecida”. +- Seja específico, com linguagem executiva + técnica. +- Priorize risco real de negócio e explorabilidade. +- Sempre indicar severidade e prioridade. +- Sempre incluir ações de curto, médio e longo prazo. +- Quando possível, referenciar boas práticas (OWASP, NIST, CIS, CVE/CWE). + +Formato obrigatório da resposta: +## 1. Análise +- Resumo executivo (5 a 8 linhas) +- Principais métricas observadas +- Pontos fora do padrão (outliers/anomalias) + +## 2. Diagnóstico +- Causas prováveis por ordem de impacto (Alta/Média/Baixa) +- Evidências que sustentam cada causa (referenciando campos do JSON) +- Riscos de curto e médio prazo se nada for feito + +## 3. Recomendações +Para cada recomendação, informe: +- Ação recomendada +- Problema que resolve +- Impacto esperado +- Esforço estimado (Baixo/Médio/Alto) +- Prioridade (P1/P2/P3) + +## 4. Plano de ação (30-60-90 dias) +- 30 dias: ações imediatas e “quick wins” +- 60 dias: ajustes estruturais +- 90 dias: consolidação e otimização +Para cada etapa, incluir: +- Responsável sugerido (perfil/função) +- Dependências +- Métrica de sucesso (KPI) +- Critério de conclusão'; + + +v_pre_prompt_json := '## FORMATO DE SAÍDA JSON +Quando solicitado no modo JSON, responda EXCLUSIVAMENTE com o objeto JSON +válido conforme o schema abaixo, sem texto antes ou depois, sem markdown, +sem blocos de código. O JSON deve ser parseable diretamente. +Campos não avaliáveis por qualidade de imagem devem receber null. +Não inclua explicações, texto introdutório, saudações ou blocos de Markdown como "```json" no comeco nem no final como "```". + +## Exemplo JSON: +Retorne um JSON válido (sem comentários), espelhando o relatório: +{ + "id": "", + "titulo": "", + "analise": { + "resumo_tecnico": "", + "vetor_ataque": "", + "pre_condicoes": [], + "impacto_cia": { + "confidencialidade": "", + "integridade": "", + "disponibilidade": "" + } + }, + "diagnostico": { + "causa_raiz": "", + "classificacao": { + "cwe": "", + "owasp": "" + }, + "severidade": "", + "probabilidade_exploracao": "", + "impacto_negocio": "", + "prioridade_final": "", + "justificativa": "" + }, + "recomendacoes": [ + { + "acao": "", + "tipo": "corretiva|preventiva|detectiva", + "esforco": "baixo|medio|alto", + "dependencias": [] + } + ], + "plano_acao": [ + { + "prazo": "curto|medio|longo", + "etapa": "", + "responsavel_sugerido": "", + "deadline_sugerido": "", + "resultado_esperado": "", + "criterio_aceite": "" + } + ], + "lacunas_informacao": [] +}'; + + select json_object( + 'AGE_IN_DAYS' VALUE AGE_IN_DAYS, + 'ASSET_DISPLAY_IPV4_ADDRESS' VALUE ASSET_DISPLAY_IPV4_ADDRESS, + 'ASSET_ID' VALUE ASSET_ID, + 'ASSET_NAME' VALUE ASSET_NAME, + 'ASSET_TAGS' VALUE ASSET_TAGS, + 'DEFINITION_EXPLOITABILITY_EASE' VALUE DEFINITION_EXPLOITABILITY_EASE, + 'DEFINITION_FAMILY' VALUE DEFINITION_FAMILY, + 'DEFINITION_ID' VALUE DEFINITION_ID, + 'DEFINITION_NAME' VALUE DEFINITION_NAME, + 'DEFINITION_VPR_SCORE' VALUE DEFINITION_VPR_SCORE, + 'FIRST_OBSERVED' VALUE FIRST_OBSERVED, + 'ID' VALUE ID, + 'LAST_SEEN' VALUE LAST_SEEN, + 'OUTPUT' VALUE OUTPUT, + 'PROTOCOL' VALUE PROTOCOL, + 'RESURFACED_DATE' VALUE RESURFACED_DATE, + 'SEVERITY' VALUE SEVERITY, + 'STATE' VALUE STATE, + 'INSIGHT_REPORT' VALUE INSIGHT_REPORT, + 'ID_INSIGHT' VALUE ID_INSIGHT, + 'NOME' VALUE NOME, + 'EMPRESA' VALUE EMPRESA, + 'CLASSE' VALUE CLASSE, + 'AMBIENTE' VALUE AMBIENTE, + 'STATUS_OPERACIONAL' VALUE STATUS_OPERACIONAL, + 'DESCRICAO' VALUE DESCRICAO, + 'SOX' VALUE SOX, + 'COFRE' VALUE COFRE, + 'ENDERECO_IP' VALUE ENDERECO_IP, + 'SISTEMA_OPERACIONAL' VALUE SISTEMA_OPERACIONAL, + 'TIPO_DE_REDE' VALUE TIPO_DE_REDE, + 'IS_VIRTUAL' VALUE IS_VIRTUAL, + 'CRITICIDADE' VALUE CRITICIDADE, + 'INSTANCIAS_BANCOS' VALUE INSTANCIAS_BANCOS, + 'APLICACOES_RELACIONADAS' VALUE APLICACOES_RELACIONADAS, + 'JANELAS_DE_MANUTENCAO' VALUE JANELAS_DE_MANUTENCAO, + 'ANALISTA_RESPONSAVEL' VALUE ANALISTA_RESPONSAVEL, + 'ANALISTAS_RESPONSAVEIS' VALUE ANALISTAS_RESPONSAVEIS, + 'GERENCIADO_PELO_GRUPO' VALUE GERENCIADO_PELO_GRUPO, + 'GRUPOS_RESPONSAVEIS' VALUE GRUPOS_RESPONSAVEIS, + 'GRUPO_RESPONSAVEL' VALUE GRUPO_RESPONSAVEL, + 'EDR' VALUE EDR, + 'TENABLE' VALUE TENABLE, + 'SIEM' VALUE SIEM, + 'APPLIANCE' VALUE APPLIANCE + ) AS my_json + into v_customer_data + from v_26ai_tech a + where cid = p_rowid; + -- and insight_report is null ; + + v_response := FNC_26ai_rag( p_ai_prompt => v_pre_prompt || '. Dados: ' || v_customer_data, + p_oci_cred => p_oci_cred, + p_comp => p_comp + ); + + v_json := replace( replace( FNC_26ai_rag( p_ai_prompt => 'MODO JSON: ' || v_pre_prompt || ' ' || v_pre_prompt_json || '. Dados: ' || v_customer_data, + p_oci_cred => p_oci_cred, + p_comp => p_comp + ) ,'```json','' ),'```','' ); + + update TB_26AI_TECH_v2 + set insight_report = v_response, + insight_json = v_json + where rowid = p_rowid; + + + if length(v_response) > 0 then + + -- vetorizacao do relatorio gerado + insert into TB_26AI_TECH_VECTOR + SELECT et.embed_id, + v_response, + et.embed_vector, + null, + p_rowid + FROM dual + CROSS JOIN TABLE( + DBMS_VECTOR_CHAIN.UTL_TO_EMBEDDINGS( + -- DBMS_VECTOR_CHAIN.UTL_TO_CHUNKS( + -- dbms_vector_chain.utl_to_text( v_response ) , + ( v_response ) , + -- JSON('{"by":"words","max":"1000","split":"sentence","normalize":"all","overlap":"0"}') ), + json('{ "provider": "ocigenai", + "credential_name": "' || p_oci_cred || '", + "url": "https://inference.generativeai.us-chicago-1.oci.oraclecloud.com/20231130/actions/embedText", + "model": "cohere.embed-v4.0" + }') + ) + ) t + CROSS JOIN JSON_TABLE( + t.column_value, '$[*]' + COLUMNS ( + embed_id NUMBER PATH '$.embed_id', + text_chunk VARCHAR2(4000) PATH '$.embed_data', + embed_vector CLOB PATH '$.embed_vector' + ) + ) AS et; + + end if; + + commit; + +exception + when others then + v_error := sqlerrm; + update TB_26AI_TECH_v2 + set insight_report = v_error, + insight_json = null + where rowid = p_rowid; + commit; +end; +/ \ No newline at end of file diff --git a/prc_26ai_vulnerabilidade.sql b/prc_26ai_vulnerabilidade.sql new file mode 100644 index 0000000..ea23499 --- /dev/null +++ b/prc_26ai_vulnerabilidade.sql @@ -0,0 +1,187 @@ +create or replace procedure prc_26ai_vulnerabilidade (p_rowid in varchar default null, + p_oci_cred IN VARCHAR2 default 'OCI_CRED', + p_comp in varchar2, + p_response out clob, + p_json out clob ) +/* + + +Para testes de carga, ou associacao a jobs: + +declare +v_resp clob; +v_json clob; +begin +for r1 in (select rowid cid from TB_26AI_TECH_VULNERABILIDADE where insight_report is null ) loop + prc_26ai_vulnerabilidade (p_rowid => r1.cid , + p_oci_cred => 'OCI_CRED', + p_comp => 'ocid1.compartment.oc1..aaaaaaaayv4jpgnurtdpxwfy3t2tak6akpyh6jgunlc6pdmilqv5f2s5nevq', + p_response => v_resp, + p_json => v_json ); +end loop; +end; + +*/ +as + v_pre_prompt clob; + v_customer_data clob; + v_pre_prompt_json clob; +begin + + v_pre_prompt :='Você é um analista sênior de dados e operações. +Sua tarefa é interpretar os dados, comparar os resultados e produzir um relatório executivo e técnico acionável. + +Objetivo: +Gerar insights em 4 blocos: +1) Análise +2) Diagnóstico +3) Recomendações +4) Plano de ação + +Regras de qualidade: +- Não invente dados ausentes. Quando faltar contexto, declare explicitamente “Informação não fornecida”. +- Seja específico, com linguagem executiva + técnica. +- Priorize risco real de negócio e explorabilidade. +- Sempre indicar severidade e prioridade. +- Sempre incluir ações de curto, médio e longo prazo. +- Quando possível, referenciar boas práticas (OWASP, NIST, CIS, CVE/CWE). + +Formato obrigatório da resposta: +## 1. Análise +- Resumo executivo (5 a 8 linhas) +- Principais métricas observadas +- Pontos fora do padrão (outliers/anomalias) + +## 2. Diagnóstico +- Causas prováveis por ordem de impacto (Alta/Média/Baixa) +- Evidências que sustentam cada causa (referenciando campos do JSON) +- Riscos de curto e médio prazo se nada for feito + +## 3. Recomendações +Para cada recomendação, informe: +- Ação recomendada +- Problema que resolve +- Impacto esperado +- Esforço estimado (Baixo/Médio/Alto) +- Prioridade (P1/P2/P3) + +## 4. Plano de ação (30-60-90 dias) +- 30 dias: ações imediatas e “quick wins” +- 60 dias: ajustes estruturais +- 90 dias: consolidação e otimização +Para cada etapa, incluir: +- Responsável sugerido (perfil/função) +- Dependências +- Métrica de sucesso (KPI) +- Critério de conclusão'; + + +v_pre_prompt_json := '## FORMATO DE SAÍDA JSON +Quando solicitado no modo JSON, responda EXCLUSIVAMENTE com o objeto JSON +válido conforme o schema abaixo, sem texto antes ou depois, sem markdown, +sem blocos de código. O JSON deve ser parseable diretamente. +Campos não avaliáveis por qualidade de imagem devem receber null. +Não inclua explicações, texto introdutório, saudações ou blocos de Markdown como "```json" no comeco nem no final como "```". + +## Exemplo JSON: +Retorne um JSON válido (sem comentários), espelhando o relatório: +{ + "id": "", + "titulo": "", + "analise": { + "resumo_tecnico": "", + "vetor_ataque": "", + "pre_condicoes": [], + "impacto_cia": { + "confidencialidade": "", + "integridade": "", + "disponibilidade": "" + } + }, + "diagnostico": { + "causa_raiz": "", + "classificacao": { + "cwe": "", + "owasp": "" + }, + "severidade": "", + "probabilidade_exploracao": "", + "impacto_negocio": "", + "prioridade_final": "", + "justificativa": "" + }, + "recomendacoes": [ + { + "acao": "", + "tipo": "corretiva|preventiva|detectiva", + "esforco": "baixo|medio|alto", + "dependencias": [] + } + ], + "plano_acao": [ + { + "prazo": "curto|medio|longo", + "etapa": "", + "responsavel_sugerido": "", + "deadline_sugerido": "", + "resultado_esperado": "", + "criterio_aceite": "" + } + ], + "lacunas_informacao": [] +}'; + + select json_object(a.*) my_json + into v_customer_data + from TB_26AI_TECH_VULNERABILIDADE a + where rowid = p_rowid + and insight_report is null ; + + p_response := FNC_26ai_rag( p_ai_prompt => v_pre_prompt || '. Dados: ' || v_customer_data, + p_oci_cred => p_oci_cred, + p_comp => p_comp + ); + + p_json := replace( replace( FNC_26ai_rag( p_ai_prompt => 'MODO JSON: ' || v_pre_prompt || ' ' || v_pre_prompt_json || '. Dados: ' || v_customer_data, + p_oci_cred => p_oci_cred, + p_comp => p_comp + ) ,'```json','' ),'```','' ); + + update TB_26AI_TECH_VULNERABILIDADE + set insight_report = p_response, + insight_json = p_json + where rowid = p_rowid; + + -- vetorizacao do relatorio gerado + insert into TB_26AI_TECH_VULNERABILIDADE_VECTOR + SELECT et.embed_id, + et.text_chunk, + et.embed_vector, + null, + p_rowid + FROM TB_26AI_TECH_VULNERABILIDADE + CROSS JOIN TABLE( + DBMS_VECTOR_CHAIN.UTL_TO_EMBEDDINGS( + DBMS_VECTOR_CHAIN.UTL_TO_CHUNKS( + insight_report , + JSON('{"by":"words","max":"1000","split":"sentence","normalize":"all","overlap":"0"}') + ), + json('{ "provider": "ocigenai", + "credential_name": "' || p_oci_cred || '", + "url": "https://inference.generativeai.us-chicago-1.oci.oraclecloud.com/20231130/actions/embedText", + "model": "cohere.embed-v4.0" + }') + ) + ) t + CROSS JOIN JSON_TABLE( + t.column_value, '$[*]' + COLUMNS ( + embed_id NUMBER PATH '$.embed_id', + text_chunk VARCHAR2(4000) PATH '$.embed_data', + embed_vector CLOB PATH '$.embed_vector' + ) + ) AS et; + commit; + +end; +/ \ No newline at end of file diff --git a/tb_26ai_agro.sql b/tb_26ai_agro.sql new file mode 100644 index 0000000..0f1b4b3 --- /dev/null +++ b/tb_26ai_agro.sql @@ -0,0 +1,9 @@ + + CREATE TABLE "TB_26AI_AGRO" + ( "ID" NUMBER GENERATED ALWAYS AS IDENTITY MINVALUE 1 MAXVALUE 9999999999999999999999999999 INCREMENT BY 1 START WITH 1 CACHE 20 ORDER NOCYCLE NOKEEP NOSCALE NOT NULL ENABLE, + "FILE_NAME" VARCHAR2(200), + "FILE_MIMETYPE" VARCHAR2(200), + "FILE_CHARSET" VARCHAR2(200), + "FILE_BLOB" BLOB, + "UPDATED_DATE" DATE + ) ; \ No newline at end of file