refs #739: govern Smilegate few-shot references
This commit is contained in:
219
sql/adb/82_sgmp_qa_fewshot_reference_governance.sql
Normal file
219
sql/adb/82_sgmp_qa_fewshot_reference_governance.sql
Normal file
@@ -0,0 +1,219 @@
|
||||
-- Governed Few-shot examples for the Smilegate Select AI MCP.
|
||||
-- Existing rows are preserved for audit and only APPROVED rows are retrievable.
|
||||
|
||||
DECLARE
|
||||
PROCEDURE add_column(p_definition IN VARCHAR2) IS
|
||||
BEGIN
|
||||
EXECUTE IMMEDIATE 'ALTER TABLE sg_qa_vector_example ADD (' || p_definition || ')';
|
||||
EXCEPTION
|
||||
WHEN OTHERS THEN
|
||||
IF SQLCODE != -1430 THEN
|
||||
RAISE;
|
||||
END IF;
|
||||
END;
|
||||
BEGIN
|
||||
add_column('reference_status VARCHAR2(16) DEFAULT ''DRAFT'' NOT NULL');
|
||||
add_column('reference_kind VARCHAR2(32) DEFAULT ''SQL_TEMPLATE'' NOT NULL');
|
||||
add_column('target_type VARCHAR2(16) DEFAULT ''ANY'' NOT NULL');
|
||||
add_column('object_role VARCHAR2(64)');
|
||||
add_column('inspection_status VARCHAR2(16) DEFAULT ''PENDING'' NOT NULL');
|
||||
add_column('inspection_note CLOB');
|
||||
add_column('verified_at TIMESTAMP(6)');
|
||||
add_column('verified_by VARCHAR2(128)');
|
||||
END;
|
||||
/
|
||||
|
||||
UPDATE sg_qa_vector_example
|
||||
SET reference_status = 'RETIRED',
|
||||
reference_kind = 'SQL_TEMPLATE',
|
||||
target_type = 'SINGLE',
|
||||
inspection_status = 'RETIRED',
|
||||
inspection_note = 'Executed successfully but maps BUBBLYZ to the CZN physical user-master object. Conflicts with the approved game-target contract.',
|
||||
verified_at = SYSTIMESTAMP,
|
||||
verified_by = 'SGMP_POC_REVIEW'
|
||||
WHERE example_id = 2;
|
||||
|
||||
UPDATE sg_qa_vector_example
|
||||
SET reference_status = 'RETIRED',
|
||||
reference_kind = 'OBJECT_UNAVAILABLE',
|
||||
target_type = 'SINGLE',
|
||||
object_role = 'GAME_ALIAS_CATALOG',
|
||||
inspection_status = 'RETIRED',
|
||||
inspection_note = 'Executed successfully with no BUBBLYZ alias rows, but the game literal is not a reusable object-unavailable template. The current game query plan is the authoritative boundary source.',
|
||||
verified_at = SYSTIMESTAMP,
|
||||
verified_by = 'SGMP_POC_REVIEW'
|
||||
WHERE example_id = 3;
|
||||
|
||||
UPDATE sg_qa_vector_example
|
||||
SET reference_status = 'APPROVED',
|
||||
reference_kind = 'SQL_TEMPLATE',
|
||||
target_type = 'SINGLE',
|
||||
object_role = 'GAME_USER_MASTER',
|
||||
inspection_status = 'VERIFIED',
|
||||
inspection_note = 'Logical placeholder template. The resolved physical object must come only from the current game query plan.',
|
||||
verified_at = SYSTIMESTAMP,
|
||||
verified_by = 'SGMP_POC_REVIEW'
|
||||
WHERE example_id = 4;
|
||||
|
||||
UPDATE sg_qa_vector_example
|
||||
SET reference_status = 'APPROVED',
|
||||
reference_kind = 'NO_TARGET',
|
||||
target_type = 'NONE',
|
||||
inspection_status = 'VERIFIED',
|
||||
inspection_note = 'Executed successfully with no rows. Canonical boundary for an unscoped game-user-master request.',
|
||||
verified_at = SYSTIMESTAMP,
|
||||
verified_by = 'SGMP_POC_REVIEW'
|
||||
WHERE example_id = 5;
|
||||
|
||||
UPDATE sg_qa_vector_example
|
||||
SET reference_status = 'RETIRED',
|
||||
reference_kind = 'METADATA_POLICY',
|
||||
target_type = 'ANY',
|
||||
object_role = 'GAME_ALIAS_CATALOG',
|
||||
inspection_status = 'RETIRED',
|
||||
inspection_note = 'Not directly executable: requires an unbound GAME_TERM placeholder. Game resolution is now supplied by game_query_plan.',
|
||||
verified_at = SYSTIMESTAMP,
|
||||
verified_by = 'SGMP_POC_REVIEW'
|
||||
WHERE example_id = 6;
|
||||
|
||||
UPDATE sg_qa_vector_example
|
||||
SET reference_status = 'RETIRED',
|
||||
reference_kind = 'SQL_TEMPLATE',
|
||||
target_type = 'NONE',
|
||||
object_role = 'GAME_USER_MASTER',
|
||||
inspection_status = 'RETIRED',
|
||||
inspection_note = 'Executed successfully but chooses CZN_COMN_USER_MST for a game-unscoped question. Conflicts with the NONE target contract.',
|
||||
verified_at = SYSTIMESTAMP,
|
||||
verified_by = 'SGMP_POC_REVIEW'
|
||||
WHERE example_id IN (7, 8);
|
||||
|
||||
CREATE OR REPLACE FUNCTION sg_qa_vector_store(
|
||||
p_question IN CLOB,
|
||||
p_answer_sql IN CLOB,
|
||||
p_answer IN CLOB DEFAULT NULL
|
||||
) RETURN NUMBER
|
||||
AUTHID DEFINER
|
||||
IS
|
||||
PRAGMA AUTONOMOUS_TRANSACTION;
|
||||
v_input CLOB;
|
||||
v_embedding VECTOR;
|
||||
v_example_id NUMBER;
|
||||
BEGIN
|
||||
IF p_question IS NULL OR p_answer_sql IS NULL THEN
|
||||
RAISE_APPLICATION_ERROR(-20002, 'question and answer_sql are required.');
|
||||
END IF;
|
||||
|
||||
v_input := TO_CLOB('Question: ') || p_question
|
||||
|| TO_CLOB(CHR(10) || 'Answer SQL: ') || p_answer_sql
|
||||
|| CASE WHEN p_answer IS NULL THEN NULL ELSE TO_CLOB(CHR(10) || 'Answer: ') || p_answer END;
|
||||
v_embedding := DBMS_VECTOR.UTL_TO_EMBEDDING(
|
||||
v_input,
|
||||
JSON(sg_qa_vector_params('search_document'))
|
||||
);
|
||||
|
||||
INSERT INTO sg_qa_vector_example (
|
||||
question, answer_sql, answer_text, embedding_input, embedding, embedding_model,
|
||||
reference_status, reference_kind, target_type, inspection_status
|
||||
) VALUES (
|
||||
p_question, p_answer_sql, p_answer, v_input, v_embedding, 'cohere.embed-v4.0',
|
||||
'DRAFT', 'SQL_TEMPLATE', 'ANY', 'PENDING'
|
||||
) RETURNING example_id INTO v_example_id;
|
||||
|
||||
COMMIT;
|
||||
RETURN v_example_id;
|
||||
EXCEPTION
|
||||
WHEN OTHERS THEN
|
||||
ROLLBACK;
|
||||
RAISE;
|
||||
END;
|
||||
/
|
||||
|
||||
CREATE OR REPLACE FUNCTION sg_qa_vector_search(
|
||||
p_question IN CLOB,
|
||||
p_top_k IN PLS_INTEGER DEFAULT 3,
|
||||
p_target_type IN VARCHAR2 DEFAULT 'ANY'
|
||||
) RETURN SYS_REFCURSOR
|
||||
AUTHID DEFINER
|
||||
IS
|
||||
v_query_vector VECTOR;
|
||||
v_results SYS_REFCURSOR;
|
||||
v_target_type VARCHAR2(16) := UPPER(TRIM(NVL(p_target_type, 'ANY')));
|
||||
BEGIN
|
||||
IF p_question IS NULL THEN
|
||||
RAISE_APPLICATION_ERROR(-20003, 'question is required.');
|
||||
END IF;
|
||||
IF p_top_k IS NULL OR p_top_k < 1 OR p_top_k > 20 THEN
|
||||
RAISE_APPLICATION_ERROR(-20004, 'top_k must be between 1 and 20.');
|
||||
END IF;
|
||||
IF v_target_type NOT IN ('NONE', 'SINGLE', 'MULTI', 'ALL', 'ANY') THEN
|
||||
RAISE_APPLICATION_ERROR(-20005, 'target_type must be NONE, SINGLE, MULTI, ALL, or ANY.');
|
||||
END IF;
|
||||
|
||||
v_query_vector := DBMS_VECTOR.UTL_TO_EMBEDDING(
|
||||
p_question,
|
||||
JSON(sg_qa_vector_params('search_query'))
|
||||
);
|
||||
|
||||
OPEN v_results FOR
|
||||
SELECT example_id,
|
||||
question,
|
||||
answer_sql,
|
||||
answer_text,
|
||||
embedding_model,
|
||||
reference_kind,
|
||||
target_type,
|
||||
object_role,
|
||||
vector_distance(embedding, v_query_vector, COSINE) AS cosine_distance
|
||||
FROM sg_qa_vector_example
|
||||
WHERE reference_status = 'APPROVED'
|
||||
AND (target_type = 'ANY' OR v_target_type = 'ANY' OR target_type = v_target_type)
|
||||
ORDER BY vector_distance(embedding, v_query_vector, COSINE), example_id
|
||||
FETCH FIRST p_top_k ROWS ONLY;
|
||||
RETURN v_results;
|
||||
END;
|
||||
/
|
||||
|
||||
CREATE OR REPLACE FUNCTION sg_qa_vector_context(
|
||||
p_question IN CLOB,
|
||||
p_top_k IN PLS_INTEGER DEFAULT 3,
|
||||
p_target_type IN VARCHAR2 DEFAULT 'ANY'
|
||||
) RETURN CLOB
|
||||
AUTHID DEFINER
|
||||
IS
|
||||
v_results SYS_REFCURSOR;
|
||||
v_id NUMBER;
|
||||
v_q CLOB;
|
||||
v_sql CLOB;
|
||||
v_answer CLOB;
|
||||
v_model VARCHAR2(128);
|
||||
v_kind VARCHAR2(32);
|
||||
v_target VARCHAR2(16);
|
||||
v_role VARCHAR2(64);
|
||||
v_dist NUMBER;
|
||||
v_context CLOB := EMPTY_CLOB();
|
||||
BEGIN
|
||||
v_results := sg_qa_vector_search(p_question, p_top_k, p_target_type);
|
||||
LOOP
|
||||
FETCH v_results INTO v_id, v_q, v_sql, v_answer, v_model, v_kind, v_target, v_role, v_dist;
|
||||
EXIT WHEN v_results%NOTFOUND;
|
||||
v_context := v_context
|
||||
|| CASE WHEN DBMS_LOB.GETLENGTH(v_context) = 0 THEN NULL ELSE CHR(10) || CHR(10) END
|
||||
|| '[Example ' || v_id || ', kind=' || v_kind || ', target_type=' || v_target
|
||||
|| ', cosine_distance=' || TO_CHAR(v_dist, 'FM0D000000') || ']' || CHR(10)
|
||||
|| 'Question: ' || v_q || CHR(10)
|
||||
|| 'Answer SQL: ' || v_sql
|
||||
|| CASE WHEN v_answer IS NULL THEN NULL ELSE CHR(10) || 'Answer: ' || v_answer END;
|
||||
END LOOP;
|
||||
CLOSE v_results;
|
||||
RETURN v_context;
|
||||
END;
|
||||
/
|
||||
|
||||
COMMENT ON COLUMN sg_qa_vector_example.reference_status IS
|
||||
'Few-shot retrieval lifecycle: DRAFT, APPROVED, or RETIRED. Only APPROVED is retrievable.';
|
||||
COMMENT ON COLUMN sg_qa_vector_example.reference_kind IS
|
||||
'Few-shot semantic kind: SQL_TEMPLATE, NO_TARGET, OBJECT_UNAVAILABLE, or METADATA_POLICY.';
|
||||
COMMENT ON COLUMN sg_qa_vector_example.target_type IS
|
||||
'Applicable game query-plan target type: NONE, SINGLE, MULTI, ALL, or ANY.';
|
||||
COMMENT ON COLUMN sg_qa_vector_example.object_role IS
|
||||
'Logical object role; physical object names must be sourced from the current game query plan.';
|
||||
Reference in New Issue
Block a user