125 lines
5.1 KiB
SQL
125 lines
5.1 KiB
SQL
create or replace FUNCTION fnc_26ai_rag_aiagent(p_query VARCHAR2,
|
|
p_top_k IN NUMBER ,
|
|
p_prompt_length out number,
|
|
p_credential in varchar2 default 'OCI_CRED',
|
|
p_app_user in varchar2 default V('APP_USER') )
|
|
RETURN CLOB IS
|
|
/*
|
|
|
|
Criado por: fernando.leal@oracle.com
|
|
Data: Oct/2025
|
|
Objetivo: demonstrar casos de uso do Oracle AI Database 26ai
|
|
|
|
v1 - funcao de RAG para estudo explorar "fale com seus dados" (quando nao ter AgentAI disponivel para exibicao) - leal
|
|
|
|
*/
|
|
v_context CLOB;
|
|
v_pre_prompt clob;
|
|
v_prompt clob;
|
|
v_pre_prompt2 clob;
|
|
params_genai CLOB;
|
|
output CLOB;
|
|
query_vec VECTOR;
|
|
-- https://docs.oracle.com/en/database/oracle/oracle-database/23/arpls/dbms_vector_chain1.html#GUID-017C9002-194C-48E5-B59B-EF5C60BC8405
|
|
v_llm varchar2(20) := 'LLAMA4'; -- [ LLAMA4 | OPENAI ]
|
|
|
|
BEGIN
|
|
|
|
|
|
-- embedding do prompt para dedicated
|
|
query_vec := to_vector( fnc_26ai_embed ( p_string => p_query, p_emb_type => 'COHERE' ) );
|
|
|
|
|
|
for message_cursor in (
|
|
select lv.ID as DOCID,
|
|
lv.EMBED_DATA as BODY,
|
|
vector_distance(lv.EMBED_VECTOR, query_vec, cosine ) AS SCORE,
|
|
lv.FILE_NAME
|
|
from TB_26AI_AIAGENT_VECTOR lv
|
|
where lower(p_query) <> 'oi'
|
|
and lower(p_query) <> 'ola'
|
|
and lower(p_query) <> 'olá'
|
|
and lower(p_query) <> 'bom dia'
|
|
and lower(p_query) <> 'boa tarde'
|
|
and lower(p_query) <> 'teste'
|
|
-- and vector_distance(lv.EMBED_VECTOR, query_vec, cosine ) >= 8/10
|
|
and ( upper(USER_NAME) like 'ADMIN%' or upper(USER_NAME) = upper(p_app_user) )
|
|
order by SCORE
|
|
FETCH EXACT FIRST p_top_k ROWS ONLY
|
|
) loop
|
|
|
|
|
|
v_context := v_context || '"' || replace(replace(replace(replace(message_cursor.BODY || ' - Citations: ' || message_cursor.file_name ,
|
|
chr(10),null),chr(13),null),'"',''),'''','') || '",' ;
|
|
|
|
end loop;
|
|
|
|
|
|
--
|
|
-- pre requisito sao as credenciais definidas com nome OCI_CRED criadas a partir de dbms_vector.create_credential
|
|
--
|
|
-- para montar request body abaixo: https://docs.oracle.com/en-us/iaas/api/#/en/generative-ai-inference/20231130/datatypes/GenerateTextDetails
|
|
--
|
|
if v_llm = 'LLAMA4' then
|
|
|
|
params_genai := '{
|
|
"provider" : "ocigenai",
|
|
"credential_name" : "' || p_credential || '",
|
|
"url" : "https://inference.generativeai.us-chicago-1.oci.oraclecloud.com/20231130/actions/chat",
|
|
"model": "meta.llama-4-maverick-17b-128e-instruct-fp8"}';
|
|
|
|
elsif v_llm = 'OPENAI' then
|
|
|
|
params_genai := '{
|
|
"provider" : "openai",
|
|
"credential_name" : "CRED_OPENAI",
|
|
"url" : "https://api.openai.com/v1/chat/completions",
|
|
"model" : "gpt-4.1-mini",
|
|
"temperature": 0.4
|
|
}';
|
|
|
|
end if;
|
|
|
|
-- augmented prompt atraves do vetor criado no banco
|
|
v_pre_prompt := '"messages": [
|
|
{
|
|
"role": "system",
|
|
"content": "Objetivo
|
|
Resgate informações dos documentos de modo a trazer explicações claras e objetivas.
|
|
Escopo
|
|
• Responda apenas sobre informações contidas em documentos.
|
|
• Se a pergunta não estiver nesse escopo, retorne com recusa educada.
|
|
• Se o prompt tiver um"oi", "olá", "bom dia", ou qualquer tipo de saudação, retorne apenas "Como posso lhe ajudar?"
|
|
• Sempre cite a origem da resposta, descrita em "Citations" (nome do arquivo PDF, DOC ou imagem PNG, JPG, etc)
|
|
Formato da resposta
|
|
• A saída deve ser obrigatoriamente em listas e tópicos, nunca em parágrafos corridos.
|
|
• Estrutura fixa da resposta:
|
|
• Título curto com o insight principal.
|
|
• Resumo em 3 bullets (curtos, diretos).
|
|
• Principais insights: lista não ordenada (•) para destaques gerais.
|
|
• Rankings ou comparações: lista ordenada (1, 2, 3).
|
|
• É proibido escrever respostas fora desse formato.
|
|
• Use negrito para informações críticas e itálico para sinais preliminares ou hipóteses.
|
|
• Nunca resposnda com um JSON na resposta. Respostas são para usuários finais, devem ser respostas claras confoirme "Formato da resposta"
|
|
Guardrails
|
|
• Nunca exponha PII.
|
|
• Se não houver evidências suficientes, declare claramente essa limitação no mesmo formato de lista.
|
|
Linguagem
|
|
• Sempre em português claro, executivo e direto.
|
|
• Evite jargões técnicos.
|
|
• Valores monetários em BRL.",';
|
|
|
|
|
|
v_pre_prompt2 := '{ "role": "user","content": "Contexto:"' || v_context || ' "Pergunta": ' || p_query || '"}' ; -- sem ]'
|
|
|
|
v_prompt := v_pre_prompt || v_pre_prompt2 || ']';
|
|
|
|
-- para LLama, a contabilizacao é por caracteres
|
|
p_prompt_length := fnc_26ai_char_count(v_prompt);
|
|
|
|
output := dbms_vector_chain.utl_to_generate_text( replace(replace(replace(replace(v_prompt,chr(10),null),chr(13),null),'"',''),'''','') , json(params_genai));
|
|
|
|
RETURN output;
|
|
|
|
END;
|
|
/ |