add selectai
This commit is contained in:
36
lab/init.sql
36
lab/init.sql
@@ -19,23 +19,25 @@ END blob_to_clob;
|
||||
/
|
||||
|
||||
|
||||
set serveroutput on
|
||||
set define off
|
||||
|
||||
CREATE OR REPLACE PROCEDURE CONVERT_MDFILES_TO_JSON AS
|
||||
l_md_content CLOB;
|
||||
l_prompt CLOB;
|
||||
l_final_json CLOB;
|
||||
-- CHR(10) agrega saltos de linea al prompt.
|
||||
-- CHR(10) agrega saltos de linea al prompt enviado al modelo.
|
||||
BEGIN
|
||||
SELECT md_clob INTO l_md_content
|
||||
FROM markdown_files WHERE STATUS = 'INGESTED'
|
||||
AND ROWNUM = 1
|
||||
FOR UPDATE;
|
||||
|
||||
-- =====================================================================
|
||||
-- Llamada unica: metadatos de la promocion y lista de comercios
|
||||
-- Llamada unica: genera todo el JSON estructurado desde el markdown.
|
||||
-- =====================================================================
|
||||
l_prompt :=
|
||||
'Abaixo está um documento em markdown de uma promoção do ueno bank (Paraguai), em espanhol.' || CHR(10) ||
|
||||
'Extraia os metadados da promoção e TODOS os comércios em formato JSON estruturado.' || CHR(10) || CHR(10) ||
|
||||
'Extraia todos os dados relevantes da promoção em formato JSON estruturado.' || CHR(10) || CHR(10) ||
|
||||
'Retorne APENAS o objeto JSON abaixo (sem markdown fences, sem texto antes ou depois):' || CHR(10) ||
|
||||
'{' || CHR(10) ||
|
||||
' "promocao": {' || CHR(10) ||
|
||||
@@ -51,7 +53,7 @@ BEGIN
|
||||
' "ecommerce_permitido": true' || CHR(10) ||
|
||||
' },' || CHR(10) ||
|
||||
' "beneficios_por_nivel": [' || CHR(10) ||
|
||||
' {"nivel": "nivel 1", "percentual_reintegro": 0, "monto_compra_minimo_gs": 0, "reintegro_maximo_gs": 0}' || CHR(10) ||
|
||||
' {"nivel": "nivel N", "percentual_reintegro": 0, "monto_compra_minimo_gs": 0, "reintegro_maximo_gs": 0}' || CHR(10) ||
|
||||
' ],' || CHR(10) ||
|
||||
' "cuotas": {' || CHR(10) ||
|
||||
' "maximo_sin_intereses": 0,' || CHR(10) ||
|
||||
@@ -69,17 +71,16 @@ BEGIN
|
||||
'}' || CHR(10) || CHR(10) ||
|
||||
'REGRAS:' || CHR(10) ||
|
||||
'- Datas no formato ISO YYYY-MM-DD.' || CHR(10) ||
|
||||
'- Campos booleanos devem usar true ou false.' || CHR(10) ||
|
||||
'- Campos numericos devem usar numbers, sem aspas.' || CHR(10) ||
|
||||
'- Campos booleanos devem usar true ou false sem aspas.' || CHR(10) ||
|
||||
'- Campos numéricos devem usar números, sem aspas.' || CHR(10) ||
|
||||
'- Valores monetários em guaranies como integers (remover "Gs.", pontos e espaços).' || CHR(10) ||
|
||||
'- Se um campo não aparecer no documento, use null.' || CHR(10) ||
|
||||
'- exclusoes: liste apenas os principais pontos de exclusão em frases curtas.' || CHR(10) || CHR(10) ||
|
||||
'REGRAS PARA comercios:' || CHR(10) ||
|
||||
'- Extraia TODOS os comércios que aparecem literalmente no documento.' || CHR(10) ||
|
||||
'- category: seção em negrito mais próxima (**Belleza...**, **Grupo Zavidoro...**, etc).' || CHR(10) ||
|
||||
'- payment_processor: "upay" ou "bancard" conforme aparece ao lado do nome.' || CHR(10) ||
|
||||
'- Preserve os nomes exatamente como aparecem.' || CHR(10) ||
|
||||
'- Não invente comércios, categorias ou processadores de pagamento.' || CHR(10) || CHR(10) ||
|
||||
'- exclusoes: liste apenas os principais pontos de exclusão em frases curtas.' || CHR(10) ||
|
||||
'- comercios: extraia TODOS os comércios que aparecem literalmente no documento.' || CHR(10) ||
|
||||
'- comercios.category: seção em negrito mais próxima (**Belleza...**, **Grupo Zavidoro...**, etc).' || CHR(10) ||
|
||||
'- comercios.payment_processor: "upay" ou "bancard" conforme aparece ao lado do nome.' || CHR(10) ||
|
||||
'- Preserve os nomes dos comércios exatamente como aparecem.' || CHR(10) ||
|
||||
'- Não invente comércios nem complete nomes ausentes.' || CHR(10) || CHR(10) ||
|
||||
'DOCUMENTO:' || CHR(10) || l_md_content;
|
||||
|
||||
l_final_json := DBMS_CLOUD_AI.GENERATE(
|
||||
@@ -87,15 +88,12 @@ BEGIN
|
||||
profile_name => 'PROFILE_GPT-5.5',
|
||||
action => 'chat');
|
||||
|
||||
|
||||
DBMS_OUTPUT.PUT_LINE('Resposta bruta do LLM: ' || LENGTH(l_final_json) || ' chars');
|
||||
|
||||
IF l_final_json IS NOT JSON THEN
|
||||
RAISE_APPLICATION_ERROR(-20210,
|
||||
'LLM retornou JSON inválido. Últimos 200 chars: ' || SUBSTR(l_final_json, -200));
|
||||
'Modelo retornou JSON inválido. Últimos 200 chars: ' || SUBSTR(l_final_json, -200));
|
||||
END IF;
|
||||
|
||||
-- Guarda el JSON estructurado generado por el modelo.
|
||||
-- Graba el JSON completo generado por el modelo.
|
||||
INSERT INTO parsed_markdown_files (data) VALUES (l_final_json);
|
||||
|
||||
UPDATE markdown_files SET STATUS = 'LOADED';
|
||||
|
||||
@@ -35,38 +35,55 @@ FROM parsed_markdown_files;
|
||||
|
||||
-- merchants
|
||||
SELECT docs.category,
|
||||
docs.name
|
||||
docs.name,
|
||||
docs.payment_processor
|
||||
FROM parsed_markdown_files,
|
||||
JSON_TABLE(data, '$.comercios[*]'
|
||||
COLUMNS (
|
||||
name VARCHAR2(4000) PATH '$.name',
|
||||
category VARCHAR2(4000) PATH '$.category'
|
||||
category VARCHAR2(4000) PATH '$.category',
|
||||
payment_processor VARCHAR2(20) PATH '$.payment_processor'
|
||||
)) docs
|
||||
ORDER BY category, name;
|
||||
|
||||
|
||||
-- beneficios por nivel
|
||||
SELECT docs.nivel,
|
||||
docs.percentual_reintegro,
|
||||
docs.monto_compra_minimo_gs,
|
||||
docs.reintegro_maximo_gs
|
||||
FROM parsed_markdown_files,
|
||||
JSON_TABLE(data, '$.beneficios_por_nivel[*]'
|
||||
COLUMNS (
|
||||
nivel VARCHAR2(100) PATH '$.nivel',
|
||||
nivel VARCHAR2(20) PATH '$.nivel',
|
||||
percentual_reintegro NUMBER PATH '$.percentual_reintegro',
|
||||
monto_compra_minimo_gs NUMBER PATH '$.monto_compra_minimo_gs',
|
||||
reintegro_maximo_gs NUMBER PATH '$.reintegro_maximo_gs'
|
||||
)) docs
|
||||
ORDER BY 1;
|
||||
|
||||
-- Tabela de benefícios
|
||||
SELECT nivel, percentual_reintegro || '%' AS pct,
|
||||
TO_CHAR(monto_compra_minimo_gs, '999G999G999') AS monto_min,
|
||||
TO_CHAR(reintegro_maximo_gs, '999G999G999') AS reint_max
|
||||
FROM parsed_markdown_files t,
|
||||
JSON_TABLE(t.data, '$.beneficios_por_nivel[*]'
|
||||
COLUMNS (
|
||||
nivel VARCHAR2(20) PATH '$.nivel',
|
||||
percentual_reintegro NUMBER PATH '$.percentual_reintegro',
|
||||
monto_compra_minimo_gs NUMBER PATH '$.monto_compra_minimo_gs',
|
||||
reintegro_maximo_gs NUMBER PATH '$.reintegro_maximo_gs'
|
||||
))
|
||||
ORDER BY nivel DESC;
|
||||
|
||||
-- Comércios por categoria
|
||||
SELECT category, COUNT(*) AS qtd
|
||||
SELECT category, payment_processor, COUNT(*) AS qtd
|
||||
FROM parsed_markdown_files t,
|
||||
JSON_TABLE(t.data, '$.comercios[*]'
|
||||
COLUMNS (
|
||||
category VARCHAR2(200) PATH '$.category'
|
||||
category VARCHAR2(200) PATH '$.category',
|
||||
payment_processor VARCHAR2(20) PATH '$.payment_processor'
|
||||
))
|
||||
GROUP BY category
|
||||
GROUP BY category, payment_processor
|
||||
ORDER BY qtd DESC;
|
||||
|
||||
|
||||
@@ -75,37 +92,9 @@ SELECT
|
||||
docs.data.promocao.titulo.string() as titulo,
|
||||
docs.data.promocao.vigencia.data_inicio || ' a ' || docs.data.promocao.vigencia.data_fim as vigencia,
|
||||
docs.data.medios_pago.rede as rede,
|
||||
docs.data.medios_pago.qr_permitido as qr_permitido
|
||||
docs.data.medios_pago.qr_permitido as qr_permitido,
|
||||
docs.data.cuotas.maximo_sin_intereses as max_sin_intereses,
|
||||
docs.data.acreditacao_reintegro.prazo_dias_habiles as prazo_dias_habiles
|
||||
FROM parsed_markdown_files docs;
|
||||
|
||||
|
||||
|
||||
/* --------------------------------
|
||||
|
||||
DUALITY VIEW
|
||||
|
||||
-------------------------------- */
|
||||
-- convert
|
||||
DECLARE
|
||||
schema_sql clob;
|
||||
BEGIN
|
||||
schema_sql := dbms_json_duality.infer_and_generate_schema(
|
||||
json('{"tableNames" : [ "PARSED_MARKDOWN_FILES" ],
|
||||
"viewNames" : [ "T" ],
|
||||
"useFlexFields" : false,
|
||||
"updatability" : true,
|
||||
"sourceSchema" : "APP_USER"}')
|
||||
);
|
||||
|
||||
execute immediate schema_sql;
|
||||
|
||||
dbms_json_duality.import(table_name => 'PARSED_MARKDOWN_FILES', view_name => 'T');
|
||||
|
||||
execute immediate 'rename T TO V_PARSED_MARKDOWN_FILES';
|
||||
END;
|
||||
/
|
||||
|
||||
|
||||
SELECT * FROM T_ROOT;
|
||||
SELECT * FROM T_BENEFICIOS_POR_NIVEL;
|
||||
SELECT * FROM T_COMERCIOS;
|
||||
|
||||
46
lab/json/02_create_duality_view.sql
Normal file
46
lab/json/02_create_duality_view.sql
Normal file
@@ -0,0 +1,46 @@
|
||||
|
||||
set serveroutput on
|
||||
set long 999999
|
||||
set linesize 200
|
||||
set pagesize 5000
|
||||
|
||||
/* --------------------------------
|
||||
|
||||
DUALITY VIEW
|
||||
|
||||
-------------------------------- */
|
||||
-- convert
|
||||
DECLARE
|
||||
schema_sql clob;
|
||||
BEGIN
|
||||
schema_sql := dbms_json_duality.infer_and_generate_schema(
|
||||
json('{"tableNames" : [ "PARSED_MARKDOWN_FILES" ],
|
||||
"viewNames" : [ "T" ],
|
||||
"useFlexFields" : false,
|
||||
"updatability" : true,
|
||||
"sourceSchema" : "APP_USER"}')
|
||||
);
|
||||
|
||||
execute immediate schema_sql;
|
||||
|
||||
dbms_json_duality.import(table_name => 'PARSED_MARKDOWN_FILES', view_name => 'T');
|
||||
|
||||
execute immediate 'rename T TO V_PARSED_MARKDOWN_FILES';
|
||||
END;
|
||||
/
|
||||
|
||||
|
||||
SELECT * FROM T_ROOT;
|
||||
SELECT * FROM T_COMERCIOS;
|
||||
SELECT * FROM T_BENEFICIOS_POR_NIVEL;
|
||||
SELECT * FROM T_ACREDITACAO_REINTEGRO;
|
||||
SELECT * FROM T_CUOTAS;
|
||||
SELECT * FROM T_MEDIOS_PAGO;
|
||||
SELECT * FROM T_PROMOCAO;
|
||||
SELECT * FROM T_VIGENCIA;
|
||||
|
||||
|
||||
-- duality view collection
|
||||
SELECT json_serialize(data returning clob pretty) AS json_data
|
||||
FROM v_parsed_markdown_files;
|
||||
|
||||
43
lab/selectai/01_profiles.sql
Normal file
43
lab/selectai/01_profiles.sql
Normal file
@@ -0,0 +1,43 @@
|
||||
|
||||
EXEC DBMS_CLOUD_AI.DROP_PROFILE('PROFILE_LLAMA_4_17B');
|
||||
|
||||
BEGIN
|
||||
DBMS_CLOUD_AI.CREATE_PROFILE(
|
||||
profile_name => 'PROFILE_LLAMA_4_17B',
|
||||
attributes => JSON_OBJECT(
|
||||
'provider' VALUE 'oci',
|
||||
'credential_name' VALUE 'OCI$RESOURCE_PRINCIPAL',
|
||||
'model' VALUE 'meta.llama-4-maverick-17b-128e-instruct-fp8',
|
||||
'region' VALUE 'us-chicago-1',
|
||||
'oci_compartment_id' VALUE 'ocid1.compartment.oc1..aaaaaaaa33ogmhasyvcqzuvkrfzo5mavh3q2le7mgwmy74yzpyqi7byxgrlq',
|
||||
'temperature' VALUE 0,
|
||||
'max_tokens' VALUE 4096
|
||||
));
|
||||
END;
|
||||
/
|
||||
|
||||
|
||||
EXEC DBMS_CLOUD_AI.DROP_PROFILE('PROFILE_GPT-5.5');
|
||||
|
||||
BEGIN
|
||||
DBMS_CLOUD_AI.CREATE_PROFILE(
|
||||
profile_name => 'PROFILE_GPT-5.5',
|
||||
attributes => JSON_OBJECT(
|
||||
'provider' VALUE 'oci',
|
||||
'credential_name' VALUE 'OCI$RESOURCE_PRINCIPAL',
|
||||
'model' VALUE 'openai.gpt-5.5',
|
||||
'region' VALUE 'us-chicago-1',
|
||||
'oci_compartment_id' VALUE 'ocid1.compartment.oc1..aaaaaaaa33ogmhasyvcqzuvkrfzo5mavh3q2le7mgwmy74yzpyqi7byxgrlq',
|
||||
'temperature' VALUE 1,
|
||||
'max_tokens' VALUE 8192
|
||||
));
|
||||
END;
|
||||
/
|
||||
|
||||
set define off
|
||||
var response CLOB
|
||||
exec :response := DBMS_CLOUD_AI.GENERATE(prompt => 'Hola', profile_name => 'PROFILE_GPT-5.5', action => 'chat');
|
||||
print :response
|
||||
|
||||
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
EXEC DBMS_CLOUD_AI.DROP_PROFILE('PROFILE_GPT-5.5');
|
||||
|
||||
BEGIN
|
||||
DBMS_CLOUD_AI.CREATE_PROFILE(
|
||||
profile_name => 'PROFILE_GPT-5.5',
|
||||
attributes => JSON_OBJECT(
|
||||
'provider' VALUE 'oci',
|
||||
'credential_name' VALUE 'OCI$RESOURCE_PRINCIPAL',
|
||||
'model' VALUE 'openai.gpt-5.5',
|
||||
'region' VALUE 'us-chicago-1',
|
||||
'oci_compartment_id' VALUE 'ocid1.compartment.oc1..aaaaaaaa33ogmhasyvcqzuvkrfzo5mavh3q2le7mgwmy74yzpyqi7byxgrlq',
|
||||
'temperature' VALUE 1,
|
||||
'max_tokens' VALUE 8192
|
||||
));
|
||||
END;
|
||||
/
|
||||
|
||||
set define off
|
||||
var response CLOB
|
||||
exec :response := DBMS_CLOUD_AI.GENERATE(prompt => 'Olá', profile_name => 'PROFILE_GPT-5.5', action => 'chat');
|
||||
print :response
|
||||
|
||||
297
lab/selectai/02_annotations.sql
Normal file
297
lab/selectai/02_annotations.sql
Normal file
@@ -0,0 +1,297 @@
|
||||
set define off
|
||||
|
||||
-- ============================================================================
|
||||
-- Lab: Annotations para SELECT AI
|
||||
-- ============================================================================
|
||||
-- Este script documenta tablas relacionales generadas desde una JSON COLLECTION
|
||||
-- TABLE y la JSON Relational Duality View que recompone el documento.
|
||||
--
|
||||
-- SELECT AI usa nombres, relaciones y metadatos para generar SQL. Las
|
||||
-- annotations ayudan a explicar el significado de tablas y columnas con
|
||||
-- lenguaje de negocio, sinonimos y pistas de uso.
|
||||
--
|
||||
-- Nota: para ejecutar el lab mas de una vez, cambie ADD por REPLACE en las
|
||||
-- annotations que ya existan.
|
||||
-- ============================================================================
|
||||
|
||||
-- ============================================================================
|
||||
-- T_ROOT: tabla raiz del documento JSON
|
||||
-- ============================================================================
|
||||
|
||||
ALTER TABLE t_root ANNOTATIONS (
|
||||
ADD display_name 'Documento de promocion',
|
||||
ADD business_description 'Tabla raiz de cada promocion extraida desde markdown. Une promocion, medios de pago, cuotas, reintegro, exclusiones y listas hijas.',
|
||||
ADD select_ai_hint 'Use esta tabla como punto de partida cuando la pregunta sea sobre una promocion completa o sobre condiciones generales.',
|
||||
ADD example_questions 'Que promociones existen? Cuales son las exclusiones? Que banco emite la promocion?'
|
||||
);
|
||||
|
||||
ALTER TABLE t_root MODIFY "_id" ANNOTATIONS (
|
||||
ADD display_name 'Identificador del documento',
|
||||
ADD business_description 'Clave tecnica RAW que identifica un documento JSON de promocion.',
|
||||
ADD select_ai_hint 'No mostrar al usuario final salvo que pida identificadores tecnicos.'
|
||||
);
|
||||
|
||||
ALTER TABLE t_root MODIFY exclusoes ANNOTATIONS (
|
||||
ADD display_name 'Exclusiones de la promocion',
|
||||
ADD business_description 'Lista JSON con reglas, restricciones y condiciones que excluyen compras o situaciones del beneficio.',
|
||||
ADD synonyms 'restricciones, condiciones, limitaciones, no aplica, fuera de promocion',
|
||||
ADD select_ai_hint 'Cuando el usuario pregunte que no aplica o que esta excluido, consulte este campo JSON.'
|
||||
);
|
||||
|
||||
ALTER TABLE t_root MODIFY titulo_t_promocao ANNOTATIONS (
|
||||
ADD display_name 'Titulo de la promocion',
|
||||
ADD business_description 'Referencia al titulo principal de la promocion.',
|
||||
ADD relationship_hint 'Clave foranea hacia T_PROMOCAO.TITULO.'
|
||||
);
|
||||
|
||||
ALTER TABLE t_root MODIFY emissor_t_medios_pago ANNOTATIONS (
|
||||
ADD display_name 'Emisor del medio de pago',
|
||||
ADD business_description 'Banco o entidad emisora usada para enlazar los medios de pago aceptados.',
|
||||
ADD relationship_hint 'Clave foranea hacia T_MEDIOS_PAGO.EMISSOR.'
|
||||
);
|
||||
|
||||
ALTER TABLE t_root MODIFY maximo_sin_intereses_t_cuotas ANNOTATIONS (
|
||||
ADD display_name 'Maximo de cuotas sin intereses',
|
||||
ADD business_description 'Valor usado para enlazar las condiciones de cuotas sin intereses.',
|
||||
ADD unit 'cuotas',
|
||||
ADD relationship_hint 'Clave foranea hacia T_CUOTAS.MAXIMO_SIN_INTERESES.'
|
||||
);
|
||||
|
||||
ALTER TABLE t_root MODIFY prazo_dias_habiles_t_acreditacao_reintegro ANNOTATIONS (
|
||||
ADD display_name 'Plazo de acreditacion del reintegro',
|
||||
ADD business_description 'Cantidad de dias habiles usada para enlazar la regla de acreditacion del reintegro.',
|
||||
ADD unit 'dias habiles',
|
||||
ADD relationship_hint 'Clave foranea hacia T_ACREDITACAO_REINTEGRO.PRAZO_DIAS_HABILES.'
|
||||
);
|
||||
|
||||
-- ============================================================================
|
||||
-- T_PROMOCAO y T_VIGENCIA: datos principales de la promocion
|
||||
-- ============================================================================
|
||||
|
||||
ALTER TABLE t_promocao ANNOTATIONS (
|
||||
ADD display_name 'Promocion',
|
||||
ADD business_description 'Datos principales de la oferta bancaria, incluyendo titulo y vigencia.',
|
||||
ADD select_ai_hint 'Use esta tabla para responder preguntas sobre el nombre de la promocion y sus fechas.'
|
||||
);
|
||||
|
||||
ALTER TABLE t_promocao MODIFY titulo ANNOTATIONS (
|
||||
ADD display_name 'Titulo',
|
||||
ADD business_description 'Nombre oficial de la promocion segun el documento markdown.',
|
||||
ADD synonyms 'nombre de promocion, campana, oferta'
|
||||
);
|
||||
|
||||
ALTER TABLE t_promocao MODIFY data_inicio_t_vigencia ANNOTATIONS (
|
||||
ADD display_name 'Fecha de inicio',
|
||||
ADD business_description 'Fecha inicial de vigencia enlazada con T_VIGENCIA.',
|
||||
ADD relationship_hint 'Parte de la clave compuesta hacia T_VIGENCIA.'
|
||||
);
|
||||
|
||||
ALTER TABLE t_promocao MODIFY data_fim_t_vigencia ANNOTATIONS (
|
||||
ADD display_name 'Fecha de fin',
|
||||
ADD business_description 'Fecha final de vigencia enlazada con T_VIGENCIA.',
|
||||
ADD relationship_hint 'Parte de la clave compuesta hacia T_VIGENCIA.'
|
||||
);
|
||||
|
||||
ALTER TABLE t_vigencia ANNOTATIONS (
|
||||
ADD display_name 'Vigencia',
|
||||
ADD business_description 'Rango de fechas en que la promocion esta activa.',
|
||||
ADD example_questions 'La promocion sigue vigente? Cuando termina la promocion?'
|
||||
);
|
||||
|
||||
ALTER TABLE t_vigencia MODIFY data_inicio ANNOTATIONS (
|
||||
ADD display_name 'Inicio de vigencia',
|
||||
ADD business_description 'Primer dia en que la promocion puede ser aplicada.',
|
||||
ADD unit 'fecha'
|
||||
);
|
||||
|
||||
ALTER TABLE t_vigencia MODIFY data_fim ANNOTATIONS (
|
||||
ADD display_name 'Fin de vigencia',
|
||||
ADD business_description 'Ultimo dia en que la promocion puede ser aplicada.',
|
||||
ADD unit 'fecha'
|
||||
);
|
||||
|
||||
-- ============================================================================
|
||||
-- T_MEDIOS_PAGO: tarjetas, QR, ecommerce y billeteras
|
||||
-- ============================================================================
|
||||
|
||||
ALTER TABLE t_medios_pago ANNOTATIONS (
|
||||
ADD display_name 'Medios de pago',
|
||||
ADD business_description 'Condiciones de pago aceptadas por la promocion, como tarjetas, red, QR, ecommerce y billeteras electronicas.',
|
||||
ADD select_ai_hint 'Use esta tabla para preguntas sobre como pagar para recibir el beneficio.'
|
||||
);
|
||||
|
||||
ALTER TABLE t_medios_pago MODIFY emissor ANNOTATIONS (
|
||||
ADD display_name 'Emisor',
|
||||
ADD business_description 'Entidad emisora aceptada para participar de la promocion.',
|
||||
ADD synonyms 'banco, entidad, issuer'
|
||||
);
|
||||
|
||||
ALTER TABLE t_medios_pago MODIFY rede ANNOTATIONS (
|
||||
ADD display_name 'Red de tarjeta',
|
||||
ADD business_description 'Red o marca de tarjeta aceptada por la promocion.',
|
||||
ADD synonyms 'marca, red, network'
|
||||
);
|
||||
|
||||
ALTER TABLE t_medios_pago MODIFY qr_permitido ANNOTATIONS (
|
||||
ADD display_name 'QR permitido',
|
||||
ADD business_description 'Indica si el pago por QR participa de la promocion.',
|
||||
ADD select_ai_hint 'Campo booleano: true significa que QR esta permitido.'
|
||||
);
|
||||
|
||||
ALTER TABLE t_medios_pago MODIFY ecommerce_permitido ANNOTATIONS (
|
||||
ADD display_name 'Ecommerce permitido',
|
||||
ADD business_description 'Indica si compras online o ecommerce participan de la promocion.',
|
||||
ADD select_ai_hint 'Campo booleano: true significa que ecommerce esta permitido.'
|
||||
);
|
||||
|
||||
ALTER TABLE t_medios_pago MODIFY tarjetas_aceitas ANNOTATIONS (
|
||||
ADD display_name 'Tarjetas aceptadas',
|
||||
ADD business_description 'Array JSON con las tarjetas o productos de tarjeta que califican.',
|
||||
ADD synonyms 'tarjetas validas, tarjetas admitidas, tarjetas participantes',
|
||||
ADD select_ai_hint 'Use funciones JSON cuando necesite filtrar por una tarjeta especifica.'
|
||||
);
|
||||
|
||||
ALTER TABLE t_medios_pago MODIFY billeteras_electronicas ANNOTATIONS (
|
||||
ADD display_name 'Billeteras electronicas',
|
||||
ADD business_description 'Array JSON con billeteras digitales aceptadas por la promocion.',
|
||||
ADD synonyms 'wallets, billeteras, monederos digitales',
|
||||
ADD select_ai_hint 'Use funciones JSON cuando el usuario pregunte por una billetera especifica.'
|
||||
);
|
||||
|
||||
-- ============================================================================
|
||||
-- T_CUOTAS: informacion de financiamiento
|
||||
-- ============================================================================
|
||||
|
||||
ALTER TABLE t_cuotas ANNOTATIONS (
|
||||
ADD display_name 'Cuotas',
|
||||
ADD business_description 'Reglas de financiamiento sin intereses para la promocion.',
|
||||
ADD example_questions 'Cuantas cuotas sin intereses permite la promocion? El cliente debe pedir las cuotas?'
|
||||
);
|
||||
|
||||
ALTER TABLE t_cuotas MODIFY maximo_sin_intereses ANNOTATIONS (
|
||||
ADD display_name 'Maximo sin intereses',
|
||||
ADD business_description 'Cantidad maxima de cuotas sin intereses permitidas.',
|
||||
ADD unit 'cuotas'
|
||||
);
|
||||
|
||||
ALTER TABLE t_cuotas MODIFY requer_solicitacao_cliente ANNOTATIONS (
|
||||
ADD display_name 'Requiere solicitud del cliente',
|
||||
ADD business_description 'Indica si el cliente debe solicitar expresamente el pago en cuotas.',
|
||||
ADD select_ai_hint 'Campo booleano: true significa que el cliente debe solicitarlo.'
|
||||
);
|
||||
|
||||
-- ============================================================================
|
||||
-- T_ACREDITACAO_REINTEGRO: como se acredita el beneficio
|
||||
-- ============================================================================
|
||||
|
||||
ALTER TABLE t_acreditacao_reintegro ANNOTATIONS (
|
||||
ADD display_name 'Acreditacion del reintegro',
|
||||
ADD business_description 'Reglas de acreditacion del reintegro: plazo, porcentaje acreditado y tipo de cuenta.',
|
||||
ADD select_ai_hint 'Use esta tabla para preguntas sobre cuando y donde se acredita el reintegro.'
|
||||
);
|
||||
|
||||
ALTER TABLE t_acreditacao_reintegro MODIFY prazo_dias_habiles ANNOTATIONS (
|
||||
ADD display_name 'Plazo en dias habiles',
|
||||
ADD business_description 'Cantidad de dias habiles hasta acreditar el reintegro.',
|
||||
ADD unit 'dias habiles',
|
||||
ADD synonyms 'plazo, demora, tiempo de acreditacion'
|
||||
);
|
||||
|
||||
ALTER TABLE t_acreditacao_reintegro MODIFY percentual_creditado ANNOTATIONS (
|
||||
ADD display_name 'Porcentaje acreditado',
|
||||
ADD business_description 'Porcentaje del reintegro que sera acreditado al cliente.',
|
||||
ADD unit 'porcentaje'
|
||||
);
|
||||
|
||||
ALTER TABLE t_acreditacao_reintegro MODIFY tipo_conta ANNOTATIONS (
|
||||
ADD display_name 'Tipo de cuenta',
|
||||
ADD business_description 'Cuenta o producto donde se acredita el reintegro.',
|
||||
ADD synonyms 'cuenta destino, producto, cuenta de acreditacion'
|
||||
);
|
||||
|
||||
-- ============================================================================
|
||||
-- T_COMERCIOS: comercios participantes
|
||||
-- ============================================================================
|
||||
|
||||
ALTER TABLE t_comercios ANNOTATIONS (
|
||||
ADD display_name 'Comercios participantes',
|
||||
ADD business_description 'Lista de comercios que participan de la promocion, con categoria y procesador de pago.',
|
||||
ADD select_ai_hint 'Use esta tabla para preguntas sobre donde comprar, rubros participantes o procesadores de pago.'
|
||||
);
|
||||
|
||||
ALTER TABLE t_comercios MODIFY name ANNOTATIONS (
|
||||
ADD display_name 'Nombre del comercio',
|
||||
ADD business_description 'Nombre del comercio tal como aparece en el documento original.',
|
||||
ADD synonyms 'tienda, local, merchant, comercio'
|
||||
);
|
||||
|
||||
ALTER TABLE t_comercios MODIFY category ANNOTATIONS (
|
||||
ADD display_name 'Categoria del comercio',
|
||||
ADD business_description 'Rubro o seccion del markdown donde aparece el comercio.',
|
||||
ADD synonyms 'rubro, segmento, categoria, grupo'
|
||||
);
|
||||
|
||||
ALTER TABLE t_comercios MODIFY payment_processor ANNOTATIONS (
|
||||
ADD display_name 'Procesador de pago',
|
||||
ADD business_description 'Procesador asociado al comercio, por ejemplo upay o bancard.',
|
||||
ADD synonyms 'procesadora, adquirente, payment processor'
|
||||
);
|
||||
|
||||
ALTER TABLE t_comercios MODIFY "_id_t_root" ANNOTATIONS (
|
||||
ADD display_name 'Documento de origen',
|
||||
ADD business_description 'Clave tecnica que enlaza el comercio con el documento raiz de la promocion.',
|
||||
ADD relationship_hint 'Clave foranea hacia T_ROOT."_id".'
|
||||
);
|
||||
|
||||
-- ============================================================================
|
||||
-- T_BENEFICIOS_POR_NIVEL: reglas de reintegro por nivel
|
||||
-- ============================================================================
|
||||
|
||||
ALTER TABLE t_beneficios_por_nivel ANNOTATIONS (
|
||||
ADD display_name 'Beneficios por nivel',
|
||||
ADD business_description 'Lista de niveles de cliente y sus reglas de reintegro, compra minima y tope maximo.',
|
||||
ADD select_ai_hint 'Use esta tabla para comparar beneficios entre niveles.'
|
||||
);
|
||||
|
||||
ALTER TABLE t_beneficios_por_nivel MODIFY nivel ANNOTATIONS (
|
||||
ADD display_name 'Nivel del cliente',
|
||||
ADD business_description 'Nivel o segmento del cliente dentro de la promocion.',
|
||||
ADD synonyms 'segmento, nivel, categoria de cliente'
|
||||
);
|
||||
|
||||
ALTER TABLE t_beneficios_por_nivel MODIFY percentual_reintegro ANNOTATIONS (
|
||||
ADD display_name 'Porcentaje de reintegro',
|
||||
ADD business_description 'Porcentaje de reintegro ofrecido para el nivel.',
|
||||
ADD unit 'porcentaje'
|
||||
);
|
||||
|
||||
ALTER TABLE t_beneficios_por_nivel MODIFY monto_compra_minimo_gs ANNOTATIONS (
|
||||
ADD display_name 'Compra minima',
|
||||
ADD business_description 'Monto minimo de compra requerido para aplicar el beneficio.',
|
||||
ADD unit 'guaranies'
|
||||
);
|
||||
|
||||
ALTER TABLE t_beneficios_por_nivel MODIFY reintegro_maximo_gs ANNOTATIONS (
|
||||
ADD display_name 'Tope maximo de reintegro',
|
||||
ADD business_description 'Monto maximo de reintegro que puede recibir el cliente en guaranies.',
|
||||
ADD unit 'guaranies',
|
||||
ADD synonyms 'tope, limite, maximo de devolucion'
|
||||
);
|
||||
|
||||
ALTER TABLE t_beneficios_por_nivel MODIFY "_id_t_root" ANNOTATIONS (
|
||||
ADD display_name 'Documento de origen',
|
||||
ADD business_description 'Clave tecnica que enlaza el beneficio por nivel con el documento raiz de la promocion.',
|
||||
ADD relationship_hint 'Clave foranea hacia T_ROOT."_id".'
|
||||
);
|
||||
|
||||
-- ============================================================================
|
||||
-- V_PARSED_MARKDOWN_FILES: vista JSON Relational Duality
|
||||
-- ============================================================================
|
||||
|
||||
ALTER VIEW v_parsed_markdown_files ANNOTATIONS (
|
||||
ADD display_name 'Documento JSON de promocion',
|
||||
ADD business_description 'JSON Relational Duality View que presenta las tablas normalizadas como un unico documento JSON consultable y actualizable.',
|
||||
ADD select_ai_hint 'Use esta vista cuando el usuario pregunte por el documento completo o quiera ver la estructura JSON de la promocion.',
|
||||
ADD example_questions 'Muestre el JSON completo de la promocion. Que comercios aparecen dentro del documento? Que condiciones tiene la promocion?'
|
||||
);
|
||||
|
||||
123
lab/selectai/03_select.sql
Normal file
123
lab/selectai/03_select.sql
Normal file
@@ -0,0 +1,123 @@
|
||||
set serveroutput on
|
||||
set long 9999999
|
||||
set pagesize 1000
|
||||
set linesize 200
|
||||
-- ============================================================================
|
||||
-- Profile especializado para el lab de SELECT AI con annotations
|
||||
-- ============================================================================
|
||||
-- Este profile limita el contexto de SELECT AI a las tres tablas del ejercicio.
|
||||
-- La opcion annotations=true envia las annotations de tablas y columnas al modelo.
|
||||
-- enforce_object_list=true evita que el modelo use otras tablas accesibles.
|
||||
|
||||
BEGIN
|
||||
DBMS_CLOUD_AI.DROP_PROFILE(
|
||||
profile_name => 'PROFILE_GPT_5_5_SELECTAI',
|
||||
force => TRUE
|
||||
);
|
||||
END;
|
||||
/
|
||||
|
||||
BEGIN
|
||||
DBMS_CLOUD_AI.CREATE_PROFILE(
|
||||
profile_name => 'PROFILE_GPT_5_5_SELECTAI',
|
||||
attributes => JSON_OBJECT(
|
||||
'provider' VALUE 'oci',
|
||||
'credential_name' VALUE 'OCI$RESOURCE_PRINCIPAL',
|
||||
'model' VALUE 'openai.gpt-5.5',
|
||||
'region' VALUE 'us-chicago-1',
|
||||
'oci_compartment_id' VALUE 'ocid1.compartment.oc1..aaaaaaaa33ogmhasyvcqzuvkrfzo5mavh3q2le7mgwmy74yzpyqi7byxgrlq',
|
||||
'temperature' VALUE 1,
|
||||
'max_tokens' VALUE 8192,
|
||||
'annotations' VALUE 'true',
|
||||
'object_list_mode' VALUE 'all',
|
||||
'enforce_object_list' VALUE 'true',
|
||||
'object_list' VALUE JSON_ARRAY(
|
||||
JSON_OBJECT('owner' VALUE USER, 'name' VALUE 'T_ROOT'),
|
||||
JSON_OBJECT('owner' VALUE USER, 'name' VALUE 'T_COMERCIOS'),
|
||||
JSON_OBJECT('owner' VALUE USER, 'name' VALUE 'T_BENEFICIOS_POR_NIVEL')
|
||||
)
|
||||
),
|
||||
description => 'Profile para SELECT AI usando annotations y solamente T_ROOT, T_COMERCIOS y T_BENEFICIOS_POR_NIVEL.'
|
||||
);
|
||||
END;
|
||||
/
|
||||
|
||||
-- ============================================================================
|
||||
-- Lab: Consultas SELECT AI usando annotations
|
||||
-- ============================================================================
|
||||
-- Este script contiene ejemplos didacticos de SELECT AI.
|
||||
--
|
||||
-- La accion SHOWSQL muestra el SQL que el modelo genera. Esto ayuda a ver como
|
||||
-- las annotations de display_name, business_description, synonyms y
|
||||
-- relationship_hint guian la seleccion de tablas, columnas y joins.
|
||||
|
||||
|
||||
-- SELECT AI modes:
|
||||
-- showsql: cuando quieres obtener el SQL generado, revisarlo, auditarlo, registrarlo en logs o ejecutarlo después con control propio.
|
||||
-- runsql: cuando aceptas que la base de datos genere y ejecute la consulta directamente.
|
||||
-- narrate: cuando quieres una respuesta en lenguaje natural basada en el resultado.
|
||||
-- explainsql: cuando quieres explicar el SQL generado.
|
||||
-- chat: conversación general con el modelo, no necesariamente sobre SQL.
|
||||
|
||||
-- ============================================================================
|
||||
|
||||
EXEC DBMS_CLOUD_AI.SET_PROFILE('PROFILE_GPT_5_5_SELECTAI');
|
||||
|
||||
-- ============================================================================
|
||||
-- Ejemplo 1: sinonimos de comercios y categorias
|
||||
-- ============================================================================
|
||||
-- Las annotations indican que T_COMERCIOS representa "Comercios participantes"
|
||||
-- y que NAME tambien puede ser entendido como tienda, local, merchant o comercio.
|
||||
-- El prompt usa lenguaje de negocio, no nombres tecnicos de columnas.
|
||||
|
||||
-- select ai
|
||||
SELECT AI runsql Muestra los locales participantes por rubro, indicando el comercio, la categoria y la procesadora de pago.;
|
||||
|
||||
|
||||
SELECT JSON_SERIALIZE(
|
||||
DBMS_CLOUD_AI.GENERATE(
|
||||
prompt => 'Muestra los locales participantes por rubro, indicando el comercio, la categoria y la procesadora de pago.',
|
||||
profile_name => 'PROFILE_GPT_5_5_SELECTAI',
|
||||
action => 'runsql'
|
||||
) returning CLOB pretty);
|
||||
|
||||
|
||||
|
||||
-- dbms_cloud_ai
|
||||
DECLARE
|
||||
l_response CLOB;
|
||||
BEGIN
|
||||
l_response := DBMS_CLOUD_AI.GENERATE(
|
||||
prompt => 'Muestra los locales participantes por rubro, indicando el comercio, la categoria y la procesadora de pago.',
|
||||
profile_name => 'PROFILE_GPT_5_5_SELECTAI',
|
||||
action => 'showsql'
|
||||
);
|
||||
|
||||
DBMS_OUTPUT.PUT_LINE(DBMS_LOB.SUBSTR(l_response, 4000, 1));
|
||||
END;
|
||||
/
|
||||
|
||||
-- ============================================================================
|
||||
-- Ejemplo 2: beneficio por segmento, compra minima y tope
|
||||
-- ============================================================================
|
||||
-- Las annotations explican que "nivel" tambien puede significar segmento o
|
||||
-- categoria de cliente, y que "tope" es el reintegro maximo en guaranies.
|
||||
-- El prompt usa esos sinonimos para mostrar como SELECT AI entiende el negocio.
|
||||
|
||||
SELECT AI runsql
|
||||
Para cada segmento de cliente, lista el porcentaje de reintegro,
|
||||
la compra minima requerida y el tope maximo de devolucion en guaranies.
|
||||
;
|
||||
|
||||
-- ============================================================================
|
||||
-- Ejemplo 3: pregunta de negocio cruzando comercios y niveles
|
||||
-- ============================================================================
|
||||
-- Este ejemplo combina tres tablas. Las relationship_hint de T_ROOT, T_COMERCIOS
|
||||
-- y T_BENEFICIOS_POR_NIVEL ayudan al modelo a entender que ambas listas hijas
|
||||
-- pertenecen al mismo documento de promocion.
|
||||
|
||||
SELECT AI runsql
|
||||
Combine los comercios participantes con los beneficios por nivel de cliente del mismo documento.
|
||||
Muestra rubro, comercio, procesadora, nivel del cliente, porcentaje de reintegro, compra minima
|
||||
y limite maximo de devolucion.
|
||||
;
|
||||
@@ -27,7 +27,7 @@ DECLARE
|
||||
l_clob CLOB;
|
||||
l_blob BLOB;
|
||||
l_uri VARCHAR2(1000) := 'https://objectstorage.us-chicago-1.oraclecloud.com/n/idi1o0a010nx/b/md-processed/o/';
|
||||
l_filename VARCHAR2(500) := 'Banco Atlas - Beneficios Estaciones de Servicio.md';
|
||||
l_filename VARCHAR2(500) := 'Promocion-Reintegro-30-de-reintegro-en-comercios-adheridos-12-cuotas-sin-interese-_-DIC-2025v1.md';
|
||||
BEGIN
|
||||
l_clob := blob_to_clob(DBMS_CLOUD.GET_OBJECT(credential_name => 'OCI$RESOURCE_PRINCIPAL', object_uri => l_uri || l_filename));
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ update markdown_files
|
||||
|
||||
commit;
|
||||
|
||||
select md_clob, embedding from markdown_files;
|
||||
select substr(md_clob, 50, 60) as md_preview, embedding from markdown_files;
|
||||
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ select
|
||||
VECTOR_DISTANCE(embedding,
|
||||
VECTOR_EMBEDDING(
|
||||
MULTILINGUAL_E5_BASE
|
||||
USING 'estaciones de servicio' as DATA)
|
||||
USING 'tarjeta de crédito' as DATA)
|
||||
) as distance
|
||||
from markdown_files;
|
||||
|
||||
@@ -68,7 +68,6 @@ FROM markdown_files m,
|
||||
)
|
||||
) et;
|
||||
|
||||
commit;
|
||||
|
||||
-- ver los chunks generados
|
||||
select doc_id, file_name, chunk_id, chunk_text
|
||||
@@ -83,7 +82,7 @@ select
|
||||
chunk_id,
|
||||
VECTOR_DISTANCE(embedding,
|
||||
VECTOR_EMBEDDING(MULTILINGUAL_E5_BASE
|
||||
USING 'estaciones de servicio' as DATA
|
||||
USING 'tarjeta de crédito' as DATA
|
||||
)
|
||||
) as distance,
|
||||
chunk_text
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
set long 999999
|
||||
set pages 1000
|
||||
set lines 200
|
||||
set pagesize 1000
|
||||
set linesize 200
|
||||
|
||||
/* --------------------------------
|
||||
|
||||
@@ -9,8 +9,6 @@ HNSW INDEX
|
||||
-------------------------------- */
|
||||
|
||||
-- crear indice HNSW para busquedas vectoriales aproximadas
|
||||
DROP INDEX IF EXISTS markdown_chunks_hnsw_idx;
|
||||
|
||||
CREATE VECTOR INDEX markdown_chunks_hnsw_idx
|
||||
ON markdown_chunks (embedding)
|
||||
ORGANIZATION INMEMORY NEIGHBOR GRAPH
|
||||
@@ -22,6 +20,7 @@ PARAMETERS (
|
||||
EFCONSTRUCTION 200
|
||||
);
|
||||
|
||||
DROP INDEX IF EXISTS markdown_chunks_hnsw_idx;
|
||||
|
||||
/* --------------------------------
|
||||
|
||||
@@ -30,8 +29,6 @@ IVF INDEX
|
||||
-------------------------------- */
|
||||
|
||||
-- crear indice IVF con DOC_ID incluido para filtros por documento
|
||||
DROP INDEX IF EXISTS markdown_chunks_ivf_idx;
|
||||
|
||||
CREATE VECTOR INDEX markdown_chunks_ivf_idx
|
||||
ON markdown_chunks (embedding)
|
||||
INCLUDE (doc_id)
|
||||
@@ -44,7 +41,7 @@ PARAMETERS (
|
||||
MIN_VECTORS_PER_PARTITION 1
|
||||
);
|
||||
|
||||
|
||||
DROP INDEX IF EXISTS markdown_chunks_ivf_idx;
|
||||
/* --------------------------------
|
||||
|
||||
TEXT INDEX + VECTOR SEARCH
|
||||
@@ -63,24 +60,22 @@ select
|
||||
SCORE(1) as text_score,
|
||||
VECTOR_DISTANCE(embedding,
|
||||
VECTOR_EMBEDDING(MULTILINGUAL_E5_BASE
|
||||
USING 'estaciones de servicio' as DATA
|
||||
USING 'Sucursales adheridas' as DATA
|
||||
)
|
||||
) as vector_distance,
|
||||
chunk_text
|
||||
from markdown_chunks
|
||||
where contains(chunk_text, 'Beneficio
|
||||
AND FUZZY(Benefcio)
|
||||
AND ABOUT(estaciones)
|
||||
AND (Visa accum Mastercard)
|
||||
AND (Clásica OR Oro)
|
||||
AND (crédito NOT débito)
|
||||
AND NEAR((POS, Infonet), 5)
|
||||
AND NEAR((App, Premmia, Petrobras), 1)
|
||||
AND (consumo AND personal)', 1) > 0
|
||||
where contains(chunk_text, '(Mastercard ACCUM NEAR((Dúo,Clásica),1))', 1) > 0
|
||||
order by vector_distance
|
||||
fetch first 3 rows only;
|
||||
|
||||
|
||||
-- Promoción
|
||||
-- FUZZY(Promción)
|
||||
-- ABOUT(Promoción)
|
||||
-- NEAR((tarjetas, físicas, billeteras, electrónicas), 5)
|
||||
-- Black OR Albirroja
|
||||
-- BENDITA ACCUM STYLE
|
||||
-- (Mastercard ACCUM NEAR((Dúo,Clásica),1))
|
||||
|
||||
/* --------------------------------
|
||||
|
||||
@@ -105,12 +100,13 @@ SELECT JSON_SERIALIZE(
|
||||
JSON('{
|
||||
"hybrid_index_name" : "markdown_chunks_hybrid_idx",
|
||||
"search_fusion" : "UNION",
|
||||
"search_scorer" : "rsf",
|
||||
"vector" : {
|
||||
"search_text" : "beneficios en estaciones de servicio",
|
||||
"search_text" : "Vigencia",
|
||||
"search_mode" : "CHUNK"
|
||||
},
|
||||
"text" : {
|
||||
"contains" : "estaciones AND Petrobras"
|
||||
"contains" : "Shopping NEAR San NEAR Lorenzo"
|
||||
},
|
||||
"return" : {
|
||||
"values" : [
|
||||
@@ -135,8 +131,8 @@ FROM
|
||||
'hybrid_index_name' VALUE 'markdown_chunks_hybrid_idx',
|
||||
'search_fusion' VALUE 'INTERSECT',
|
||||
'search_scorer' VALUE 'rsf',
|
||||
'vector' VALUE json_object('search_text' VALUE 'beneficios en estaciones de servicio'),
|
||||
'text' VALUE json_object('contains' VALUE 'estaciones AND Petrobras'),
|
||||
'vector' VALUE json_object('search_text' VALUE 'COMERCIOS ADHERIDOS'),
|
||||
'text' VALUE json_object('contains' VALUE 'BENDITA ACCUM STYLE'),
|
||||
'return' VALUE json_object(
|
||||
'values' VALUE json_array('rowid', 'score', 'vector_score', 'vector_rank', 'text_score', 'text_rank', 'chunk_text'),
|
||||
'topN' VALUE 3
|
||||
|
||||
Reference in New Issue
Block a user