create or replace FUNCTION fnc_26ai_rag_telecom(p_query VARCHAR2, p_top_k IN NUMBER, p_new_session in number, p_credential in varchar2 default 'OCI_CRED' ) 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 TELECOM - leal begin dbms_cloud_ai.create_profile( profile_name => 'PROF_TELECOM_V1', attributes => '{"provider": "oci", "credential_name": "OCI_CRED", "oci_compartment_id": "ocid1.compartment.oc1..aaaaaaaakvd4bq4b3n7yn3gjjqzfhsl62dec44tjvi2iwa3sugw5frgfpzea", "region": "us-chicago-1", "model": "meta.llama-4-maverick-17b-128e-instruct-fp8", "oci_apiformat": "GENERIC", "object_list": [ {"owner": "AICHAT1", "name": "V_26AI_REMARK"}, {"owner": "AICHAT1", "name": "V_26AI_MASTER"}, {"owner": "AICHAT1", "name": "V_26AI_CLIENTE_FIXA_MOVEL_CONSOLIDADO"} ], "comments": true, "temperature": 0.1 }' ); end; / */ v_response_vector CLOB; v_pre_prompt clob; v_prompt clob; params_genai CLOB; output CLOB; query_vec VECTOR; v_has number; v_assistant clob; v_i number :=0 ; v_response_selectai clob; v_pre_prompt2 clob; v_select_ai_preprompt varchar2(4000) := ' . Não adicione nenhum filtro de data a menos que seja solicitado.'; v_select_ai_profile varchar2(20) := 'PROF_TELECOM_V1'; BEGIN -- embedding do prompt para dedicated query_vec := to_vector( fnc_26ai_embed ( p_string => p_query ,p_emb_type=>'COHERE') ); -- neste tenancy nao temos o DEDICATED - leal 17-10-25 for message_cursor in ( select lv.id as DOCID, lv.EMBED_DATA as BODY, vector_distance(lv.embed_vector, query_vec, cosine ) AS SCORE, null txt_aug from TB_26AI_TELECOM_VECTOR_DATA lv order by SCORE FETCH EXACT FIRST p_top_k ROWS ONLY ) loop v_i := message_cursor.SCORE; v_response_vector := v_response_vector || '"' || replace(replace(replace(replace(message_cursor.BODY || ': ' || message_cursor.txt_aug,chr(10),null),chr(13),null),'"',''),'''','') || '",' ; END LOOP; begin SELECT DBMS_CLOUD_AI.GENERATE(prompt => p_query || v_select_ai_preprompt , profile_name => v_select_ai_profile, action => 'runsql') response into v_response_selectai; if v_response_selectai like 'Sorry%' or v_response_selectai like 'No data found%' then v_response_selectai := '--' ; end if; exception when others then v_response_selectai := '-' ; end; -- -- 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 -- 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"}'; -- augmented prompt atraves do vetor criado no banco v_pre_prompt := '"messages": [ { "role": "system", "content": "Objetivo Transformar perguntas em análises qualitativas ou quantitativas e acionáveis para os executivos, cobrindo todos os motivos de contato. Instruções Escopo • Responda apenas sobre chamadas e motivos de contato no call center. • Se a pergunta não estiver nesse escopo, retorne com recusa educada. Processo • Classifique os resultados em temas: Técnico; Contas; Retenção; Vendas; Comercial/Atendimento. • Extraia sinais relevantes: qualidade de serviço, motivos dominantes de contato, intenções de cancelamento, menções a concorrentes, objeções de preço, falhas de processo, elogios, risco qualitativo de churn. • Analise sentimento (positivo, negativo, neutro) e emoções (raiva, frustração, ansiedade, alívio). • Avalie pitch de vendas quando aplicável. • Sintetize sempre em linguagem executiva. • Nunca invente números; se usar contagens, declare a amostra. • Nunca traga informações como "Não há dados suficientes para montar um gráfico" Formato da resposta (não use Markdown) • 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 executivo: exatamente 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. Guardrails • Nunca exponha PII. • Não reporte métricas individuais de agentes. • Se não houver evidências suficientes, declare claramente essa limitação no mesmo formato de lista. • Nunca cite "Não há necessidade de gráfico, pois os dados podem ser facilmente compreendidos na lista ordenada acima." Linguagem • Sempre em português claro, executivo e direto. • Evite jargões técnicos. • Estruture como briefing para diretoria. • Valores monetários em BRL.",'; v_pre_prompt2 := '{ "role": "user","content": "Contexto Chamadas:"' || v_response_vector || ' "Contexto BI": ' || v_response_selectai || ' "Pergunta": ' || p_query || '"}' ; -- sem ]' v_prompt := v_pre_prompt || v_pre_prompt2 || ']'; begin output := dbms_vector_chain.utl_to_generate_text( replace(replace(replace(replace(v_prompt,chr(10),null),chr(13),null),'"',''),'''','') , json(params_genai)); exception when others then begin v_prompt := v_pre_prompt || v_pre_prompt2 ; output := dbms_vector_chain.utl_to_generate_text( replace(replace(replace(replace(v_prompt,chr(10),null),chr(13),null),'"',''),'''','') , json(params_genai)); exception when others then v_prompt := v_pre_prompt; output := dbms_vector_chain.utl_to_generate_text( replace(replace(replace(replace(v_prompt,chr(10),null),chr(13),null),'"',''),'''','') , json(params_genai)); end ; end; --output := FNC_AI_LLAMA( replace(replace(replace(replace(messages,chr(10),null),chr(13),null),'"',''),'''','') ,'OCI_CRED'); RETURN output; END; /