From 97eba38d29c18562886d72a706f91f5da14b838c Mon Sep 17 00:00:00 2001 From: flealdba Date: Fri, 8 May 2026 13:15:51 +0000 Subject: [PATCH] Upload files to "/" --- fnc_26ai_agro.sql | 145 ++++++++++++++++++++++++++++++++++ fnc_26ai_censo_vpd.sql | 60 ++++++++++++++ fnc_26ai_char_count.sql | 25 ++++++ fnc_26ai_default_password.sql | 42 ++++++++++ 4 files changed, 272 insertions(+) create mode 100644 fnc_26ai_agro.sql create mode 100644 fnc_26ai_censo_vpd.sql create mode 100644 fnc_26ai_char_count.sql create mode 100644 fnc_26ai_default_password.sql diff --git a/fnc_26ai_agro.sql b/fnc_26ai_agro.sql new file mode 100644 index 0000000..2fa5b10 --- /dev/null +++ b/fnc_26ai_agro.sql @@ -0,0 +1,145 @@ +create or replace function fnc_26ai_agro( p_image_id in number, + p_tipo_cultura in varchar2 default 'Soja', + p_comp_id in varchar2, + p_credential in varchar2 default 'OCI_CRED') +return clob +as +/* + + Criado por: fernando.leal@oracle.com + Data: Oct/2025 + Objetivo: demonstrar casos de uso do Oracle AI Database 26ai + + v1 - similaridade e rag para AGRO - leal + v2 - prompt nao cita mais origem do dado como documento Embrapa - leal + +-- PDF + + BEGIN + DBMS_CLOUD.GET_OBJECT( + credential_name => 'OCI_CRED', + object_uri => 'https://objectstorage.sa-saopaulo-1.oraclecloud.com/p/d8iuDNoKn5EC_JZWO4JukFHL_WatZHxMY_NUnCzvE56WtliIIcCQlwLpH6EIGx-z/n/idajmumkp9ca/b/bucket-database26ai/o/Doc-256-2023OL-1.pdf', + directory_name => 'DATA_PUMP_DIR'); + END; + +-- Embedding: + +INSERT INTO "TB_26AI_AGRO_VECTOR" +select embed_id, + text_chunk, + embed_vector, + 'Soja', + 'Doc-256-2023OL-1.pdf' + from dual dt + CROSS JOIN TABLE( + dbms_vector_chain.utl_to_embeddings( + dbms_vector_chain.utl_to_chunks( + -- PDF Embrapa - Doencas no cultivo da Soja + dbms_vector_chain.utl_to_text( to_blob(bfilename('DATA_PUMP_DIR', 'Doc-256-2023OL-1.pdf')) ), + -- dicas para chunking: https://docs.oracle.com/en/database/oracle/oracle-database/23/vecse/explore-chunking-techniques-and-examples.html + json('{"by":"words","max":"220","split":"sentence","normalize":"all", "overlap":50}') + ), + json('{ + "provider": "ocigenai", + "credential_name": "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; + + -- Citros + +INSERT INTO "TB_26AI_AGRO_VECTOR" +select embed_id, + text_chunk, + embed_vector , 'Citros', 'agro_citrus_embrapa02.pdf' +FROM dual dt +CROSS JOIN TABLE( + dbms_vector_chain.utl_to_embeddings( + dbms_vector_chain.utl_to_chunks( + dbms_vector_chain.utl_to_text( + to_blob(bfilename('DATA_PUMP_DIR', 'agro_citrus_embrapa02.pdf')) + ), + json('{"by":"words","max":"120","split":"sentence","normalize":"all", "overlap":20}') + ), + json('{ + "provider": "ocigenai", + "credential_name": "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 + +*/ + messages CLOB; + v_vector clob; + p_prompt clob; + p_prompt2 clob; +begin + + SELECT json_value( fnc_26ai_embed_image_cohere(file_name, file_blob, p_credential, p_comp_id) , '$.embeddings[*].vector()') + INTO v_vector + from TB_26AI_AGRO + where id = p_image_id; + + for message_cursor in ( + + SELECT embed_data, doc_origem + FROM TB_26AI_AGRO_VECTOR + WHERE TIPO_CULTURA = p_tipo_cultura + ORDER BY VECTOR_DISTANCE(EMBED_VECTOR, v_vector , COSINE ) + FETCH EXACT FIRST 60 ROWS ONLY + + ) loop + + messages := messages || '"' || replace(replace(replace(replace(message_cursor.embed_data || '- Fonte:' || message_cursor.doc_origem ,chr(10),null),chr(13),null),'"',''),'''','') || '",' ; + + END LOOP; + + p_prompt := 'Você é um especialista em fitopatologia treinado para analisar sinais e sintomas de doenças e pragas em plantas. +##Seu objetivo é: +Ao receber uma imagem e os textos recuperados pelo RAG, identificar: +Sintomas visíveis na imagem, descrevendo: +cor +formato das lesões +padrão/distribuição +textura +presença de manchas, necrose, deformações, podridão etc. +##A provável doença ou praga, citando: +nome da doença +agente causal (fungo, bactéria, vírus, inseto, nematoide, parasita etc.) +nome científico quando disponível nos trechos recuperados. +##Explicação mostrando quais informações recuperadas justificam a conclusão. +##Regras rígidas: +Nunca invente sintomas, doenças ou causas. +Só responda se houver correspondência clara entre a imagem e as informações dos trechos. +Se o RAG não permitir identificar com segurança, responda “informação insuficiente nos trechos recuperados para diagnóstico.” +##Nas explicações, cite sempre o trecho recuperado que embasou a conclusão.'; + + -- cuidado com temperatura usando "." ou "," + --execute immediate('alter session set nls_numeric_characters=''.,'' '); + + -- sem re-rank (opcao de uso para refinar resultado) + p_prompt2 := p_prompt || '. Estes dados referem-se à cultura de ' || p_tipo_cultura || ': ' || messages || '. Cite o documento de origem dos dados em destaque.'; + + return fnc_26ai_rag_agro(p_prompt2 , p_credential , p_image_id, p_comp_id ); + +end; +/ \ No newline at end of file diff --git a/fnc_26ai_censo_vpd.sql b/fnc_26ai_censo_vpd.sql new file mode 100644 index 0000000..0bddc01 --- /dev/null +++ b/fnc_26ai_censo_vpd.sql @@ -0,0 +1,60 @@ +create or replace FUNCTION fnc_26ai_censo_vpd ( + schema_name IN VARCHAR2, + object_name IN VARCHAR2 +) RETURN VARCHAR2 +AS +/* + + Criado por: fernando.leal@oracle.com + Data: Oct/2025 + Objetivo: demonstrar casos de uso do Oracle AI Database 26ai + + v1 - funcao de VPD para demonstracao de dados Censo - leal + + Pre req: + +-- como ADMIN +grant CREATE ANY CONTEXT to aichat1 + +-- como AICHAT1 +CREATE CONTEXT CTX_26AI_RLS USING pkg_26AI_CENSO_RLS; + +CREATE OR REPLACE PACKAGE pkg_26AI_CENSO_RLS AS + PROCEDURE set_user(p_user IN VARCHAR2); +END; + +CREATE OR REPLACE PACKAGE BODY pkg_26AI_CENSO_RLS AS + + PROCEDURE set_user(p_user IN VARCHAR2) IS + BEGIN + DBMS_SESSION.SET_CONTEXT( + namespace => 'CTX_26AI_RLS', + attribute => 'SESSION_USER', + value => p_user + ); + END; + +END ; + +-- teste +BEGIN + pkg_26AI_CENSO_RLS.set_user('ADMIN'); +END; + +SELECT SYS_CONTEXT('CTX_26AI_RLS','SESSION_USER') ; + + +*/ + l_predicate VARCHAR2(4000); +BEGIN + + pkg_26AI_CENSO_RLS.set_user( trim(lower(V('APP_USER'))) ); + + -- Build a predicate that filters by allowed operation codes for current user + l_predicate := ' UF IN (SELECT UF FROM TB_26AI_CENSO_VPD WHERE trim(lower(username)) = ''' || SYS_CONTEXT('CTX_26AI_RLS','SESSION_USER') || ''')'; + + --insert into tb_test values( l_predicate ); + + RETURN l_predicate; +END; +/ \ No newline at end of file diff --git a/fnc_26ai_char_count.sql b/fnc_26ai_char_count.sql new file mode 100644 index 0000000..1108b56 --- /dev/null +++ b/fnc_26ai_char_count.sql @@ -0,0 +1,25 @@ +create or replace FUNCTION fnc_26ai_char_count (p_text CLOB) + RETURN NUMBER +IS +/* + + Criado por: fernando.leal@oracle.com + Data: Oct/2025 + Objetivo: demonstrar casos de uso do Oracle AI Database 26ai + + v1 - contador de palavras para estudo de custo de modelo LLAMA - leal + +*/ + v_len NUMBER; + v_len_sem NUMBER; +BEGIN + -- Tamanho original + v_len := NVL(DBMS_LOB.GETLENGTH(p_text), 0); + + IF v_len = 0 THEN + RETURN 0; + END IF; + + RETURN v_len; +END; +/ \ No newline at end of file diff --git a/fnc_26ai_default_password.sql b/fnc_26ai_default_password.sql new file mode 100644 index 0000000..82484a8 --- /dev/null +++ b/fnc_26ai_default_password.sql @@ -0,0 +1,42 @@ +create or replace FUNCTION fnc_26ai_default_password RETURN VARCHAR2 IS + v_letras VARCHAR2(52) := 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'; + v_numeros VARCHAR2(10) := '0123456789'; + v_especiais VARCHAR2(20) := '@#$'; + v_senha VARCHAR2(50); + v_final VARCHAR2(50); + + -- Função interna para embaralhar caracteres + FUNCTION shuffle(p_str VARCHAR2) RETURN VARCHAR2 IS + v_tmp VARCHAR2(200); + v_idx PLS_INTEGER; + v_src VARCHAR2(200) := p_str; + BEGIN + WHILE LENGTH(v_src) > 0 LOOP + v_idx := DBMS_RANDOM.VALUE(1, LENGTH(v_src)+1); + v_tmp := v_tmp || SUBSTR(v_src, v_idx, 1); + v_src := SUBSTR(v_src, 1, v_idx-1) || SUBSTR(v_src, v_idx+1); + END LOOP; + RETURN v_tmp; + END; +BEGIN + DBMS_RANDOM.INITIALIZE(TRUNC(DBMS_RANDOM.VALUE * 100000)); + + -- 4 letras + FOR i IN 1..4 LOOP + v_senha := v_senha || SUBSTR(v_letras, TRUNC(DBMS_RANDOM.VALUE(1, LENGTH(v_letras)+1)), 1); + END LOOP; + + -- 2 números + FOR i IN 1..2 LOOP + v_senha := v_senha || SUBSTR(v_numeros, TRUNC(DBMS_RANDOM.VALUE(1, LENGTH(v_numeros)+1)), 1); + END LOOP; + + -- 1 especial + v_senha := v_senha || SUBSTR(v_especiais, TRUNC(DBMS_RANDOM.VALUE(1, LENGTH(v_especiais)+1)), 1); + + -- Embaralhar tudo + v_final := shuffle(v_senha); + + RETURN v_final; +END; +/ \ No newline at end of file