-- 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