Files
vpd-permission-poc/database/adb/140_sgmp_hybrid_fewshot_reranking.sql

96 lines
3.9 KiB
MySQL

-- Hybrid retrieval remains database-driven: dense vector similarity handles
-- paraphrases, while lexical similarity distinguishes decisive request terms.
MERGE INTO sg_game_scope_policy t
USING (
SELECT 'QA_VECTOR_LEXICAL_WEIGHT' AS policy_key, 0.350000 AS number_value,
'Weight of normalized lexical question similarity in runtime Few-shot reranking.' AS description
FROM dual
UNION ALL
SELECT 'QA_VECTOR_HYBRID_SCORE_MARGIN', 0.050000,
'Maximum hybrid-score difference from the best runtime Few-shot candidate.'
FROM dual
) s
ON (t.policy_key = s.policy_key)
WHEN MATCHED THEN UPDATE SET
t.number_value = s.number_value,
t.description = s.description,
t.active_yn = 'Y',
t.updated_at = SYSTIMESTAMP
WHEN NOT MATCHED THEN INSERT (
policy_key, number_value, text_value, description, active_yn
) VALUES (
s.policy_key, s.number_value, NULL, s.description, 'Y'
)
/
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')));
v_max_cosine_distance NUMBER;
v_lexical_weight NUMBER;
v_hybrid_margin NUMBER;
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, 'invalid target type.');
END IF;
SELECT number_value INTO v_max_cosine_distance FROM sg_game_scope_policy
WHERE policy_key = 'QA_VECTOR_MAX_COSINE_DISTANCE' AND active_yn = 'Y';
SELECT number_value INTO v_lexical_weight FROM sg_game_scope_policy
WHERE policy_key = 'QA_VECTOR_LEXICAL_WEIGHT' AND active_yn = 'Y';
SELECT number_value INTO v_hybrid_margin FROM sg_game_scope_policy
WHERE policy_key = 'QA_VECTOR_HYBRID_SCORE_MARGIN' AND active_yn = 'Y';
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, source_case_id, source_type,
cosine_distance
FROM (
SELECT s.*,
MAX(s.hybrid_score) OVER () AS best_hybrid_score
FROM (
SELECT c.*,
((1 - v_lexical_weight) * (1 - c.cosine_distance)
+ v_lexical_weight * c.lexical_similarity) AS hybrid_score
FROM (
SELECT example_id, question, answer_sql, answer_text, embedding_model,
reference_kind, target_type, object_role, source_case_id, source_type,
VECTOR_DISTANCE(embedding, v_query_vector, COSINE) AS cosine_distance,
UTL_MATCH.JARO_WINKLER_SIMILARITY(
DBMS_LOB.SUBSTR(question, 4000, 1),
DBMS_LOB.SUBSTR(p_question, 4000, 1)
) / 100 AS lexical_similarity
FROM sg_qa_vector_example
WHERE reference_status = 'APPROVED'
AND inspection_status = 'VERIFIED'
AND answer_sql IS NOT NULL
AND (source_type = 'POLICY_TEMPLATE'
OR NOT REGEXP_LIKE(answer_sql, '<[A-Z][A-Z0-9_]*>', 'i'))
AND (target_type = 'ANY' OR v_target_type = 'ANY' OR target_type = v_target_type)
) c
WHERE c.cosine_distance <= v_max_cosine_distance
) s
)
WHERE hybrid_score >= best_hybrid_score - v_hybrid_margin
ORDER BY hybrid_score DESC, cosine_distance, example_id
FETCH FIRST p_top_k ROWS ONLY;
RETURN v_results;
END;
/
COMMIT