diff --git a/database/adb/112_sgmp_select_ai_oci_llama4scout_profile.sql b/database/adb/112_sgmp_select_ai_oci_llama4scout_profile.sql new file mode 100644 index 0000000..dd9954a --- /dev/null +++ b/database/adb/112_sgmp_select_ai_oci_llama4scout_profile.sql @@ -0,0 +1,81 @@ +-- Creates a non-operational comparison profile for Smilegate game-scope chat. +-- The active GPT profile remains unchanged. Provider credentials and profile +-- metadata are copied from it so the only comparison variable is the model. + +DECLARE + v_exists PLS_INTEGER; + v_credential_name VARCHAR2(128); + v_region VARCHAR2(128); + v_compartment_id VARCHAR2(4000); + v_attributes CLOB; + v_attribute_json JSON_OBJECT_T := JSON_OBJECT_T(); +BEGIN + SELECT COUNT(*) + INTO v_exists + FROM user_cloud_ai_profiles + WHERE profile_name = 'SGMP_POC_OCI_LLAMA4SCOUT'; + + IF v_exists > 0 THEN + DBMS_CLOUD_AI.DROP_PROFILE( + profile_name => 'SGMP_POC_OCI_LLAMA4SCOUT', + force => TRUE + ); + END IF; + + SELECT DBMS_LOB.SUBSTR(attribute_value, 128, 1) + INTO v_credential_name + FROM user_cloud_ai_profile_attributes + WHERE profile_name = 'SGMP_POC_OCI_GPT54MINI' + AND attribute_name = 'credential_name'; + + SELECT DBMS_LOB.SUBSTR(attribute_value, 128, 1) + INTO v_region + FROM user_cloud_ai_profile_attributes + WHERE profile_name = 'SGMP_POC_OCI_GPT54MINI' + AND attribute_name = 'region'; + + SELECT DBMS_LOB.SUBSTR(attribute_value, 4000, 1) + INTO v_compartment_id + FROM user_cloud_ai_profile_attributes + WHERE profile_name = 'SGMP_POC_OCI_GPT54MINI' + AND attribute_name = 'oci_compartment_id'; + + v_attribute_json.put('provider', 'oci'); + v_attribute_json.put('credential_name', v_credential_name); + v_attribute_json.put('model', 'meta.llama-4-scout-17b-16e-instruct'); + v_attribute_json.put('region', v_region); + v_attribute_json.put('oci_compartment_id', v_compartment_id); + v_attributes := v_attribute_json.to_clob; + + DBMS_CLOUD_AI.CREATE_PROFILE( + profile_name => 'SGMP_POC_OCI_LLAMA4SCOUT', + attributes => v_attributes, + description => 'Non-operational Smilegate game-scope latency comparison' + ); + + FOR source_attribute IN ( + SELECT attribute_name, attribute_value + FROM user_cloud_ai_profile_attributes + WHERE profile_name = 'SGMP_POC_OCI_GPT54MINI' + AND attribute_name NOT IN ( + 'credential_name', 'model', 'provider', 'provider_endpoint', + 'region', 'oci_compartment_id', 'oci_endpoint_id', + 'oci_apiformat', 'oci_runtimetype' + ) + ) LOOP + DBMS_CLOUD_AI.SET_ATTRIBUTE( + profile_name => 'SGMP_POC_OCI_LLAMA4SCOUT', + attribute_name => source_attribute.attribute_name, + attribute_value => source_attribute.attribute_value + ); + END LOOP; +END; +/ + +SELECT attribute_name, attribute_value + FROM user_cloud_ai_profile_attributes + WHERE profile_name = 'SGMP_POC_OCI_LLAMA4SCOUT' + AND attribute_name IN ( + 'provider', 'model', 'credential_name', 'region', 'oci_compartment_id' + ) + ORDER BY attribute_name; diff --git a/database/adb/113_sgmp_game_scope_chat_profile_benchmark.sql b/database/adb/113_sgmp_game_scope_chat_profile_benchmark.sql new file mode 100644 index 0000000..78a12d1 --- /dev/null +++ b/database/adb/113_sgmp_game_scope_chat_profile_benchmark.sql @@ -0,0 +1,60 @@ +-- Read-only latency and JSON-shape comparison for the game-mention extraction +-- stage. Korean input is reconstructed from UTF-8 base64 for SQLcl safety. + +set serveroutput on size unlimited + +DECLARE + v_question CLOB := utl_i18n.raw_to_char( + utl_encode.base64_decode(utl_raw.cast_to_raw( + '66Gc65Oc64KY7J247J20656RIOy5tOygnOuCmOydmCAyMDI264WEIDfsm5QgMTXsnbwgQVXrpbwg6rCB6rCBIOyVjOugpOykmC4=' + )), + 'AL32UTF8' + ); + v_prompt CLOB; + v_result CLOB; + v_json JSON_OBJECT_T; + v_started PLS_INTEGER; + v_elapsed_seconds NUMBER; + + PROCEDURE run_profile(p_profile_name IN VARCHAR2) IS + BEGIN + v_started := DBMS_UTILITY.GET_TIME; + v_result := DBMS_CLOUD_AI.GENERATE( + prompt => v_prompt, + profile_name => p_profile_name, + action => 'chat' + ); + v_elapsed_seconds := (DBMS_UTILITY.GET_TIME - v_started) / 100; + v_json := JSON_OBJECT_T.parse(v_result); + DBMS_OUTPUT.PUT_LINE( + p_profile_name + || '|elapsed_seconds=' || TO_CHAR(v_elapsed_seconds, 'FM9990D00') + || '|scope_hint=' || NVL(v_json.get_string('scope_hint'), 'NULL') + || '|mention_count=' || v_json.get_array('game_mentions').get_size + ); + EXCEPTION + WHEN OTHERS THEN + DBMS_OUTPUT.PUT_LINE( + p_profile_name || '|elapsed_seconds=' + || TO_CHAR(v_elapsed_seconds, 'FM9990D00') + || '|ERROR|' || SQLCODE || '|' || SUBSTR(SQLERRM, 1, 300) + ); + DBMS_OUTPUT.PUT_LINE( + p_profile_name || '|raw_response=' || DBMS_LOB.SUBSTR(v_result, 1000, 1) + ); + END; +BEGIN + v_prompt := 'Extract only game-name mentions from the user question. ' + || 'Metrics, acronyms, dates, filters, and database object or column names are not game names unless they are themselves an explicit game title. ' + || 'When a title-like noun directly qualifies a game data request such as user master, character, sales, AU, NRU, server, or game log, preserve that noun as a game-name mention even when it is not in a catalog. ' + || 'Do not discard an unknown title merely because it cannot be resolved. General scope words such as common, overall, all, total, or every are not game-name mentions unless they are part of an explicit title. ' + || 'Return exactly one JSON object with keys game_mentions (array of strings) ' + || 'and scope_hint (GLOBAL, SINGLE_GAME, MULTI_GAME, ALL_GAMES, UNKNOWN). ' + || 'Do not resolve names to IDs and do not generate SQL. ' + || 'Return raw JSON only: no prose, no Markdown, and no code fence. Question: ' + || v_question; + + run_profile('SGMP_POC_OCI_GPT54MINI'); + run_profile('SGMP_POC_OCI_LLAMA4SCOUT'); +END; +/ diff --git a/docs/design/708-smilegate-select-ai-oci-genai/README.md b/docs/design/708-smilegate-select-ai-oci-genai/README.md index 439f18e..75adf4a 100644 --- a/docs/design/708-smilegate-select-ai-oci-genai/README.md +++ b/docs/design/708-smilegate-select-ai-oci-genai/README.md @@ -46,3 +46,24 @@ Smilegate DATA & AI PoC는 Autonomous Database의 게임 데이터에서 Select - `DBMS_CLOUD_AI.GENERATE(..., 'showsql')`이 읽기 전용 `SELECT` 또는 `WITH` SQL을 생성한다. - 해당 SQL을 읽기 전용 트랜잭션에서 실행해 결과를 반환한다. - 운영 MCP 응답의 `profile`이 `SGMP_POC_OCI_GPT54MINI`이다. + +## Llama 4 Scout 범위 판정 성능 비교 + +게임 범위 판정은 Text2SQL 실행 전 OCI Chat을 사용한다. 이 단계의 응답시간을 +비교하기 위해 운영 프로파일을 교체하지 않고 별도 테스트 프로파일 +`SGMP_POC_OCI_LLAMA4SCOUT`을 만든다. + +| 구분 | 운영 | 비교 대상 | +| --- | --- | --- | +| 프로파일 | `SGMP_POC_OCI_GPT54MINI` | `SGMP_POC_OCI_LLAMA4SCOUT` | +| 모델 | `openai.gpt-5.4-mini` | `meta.llama-4-scout-17b-16e-instruct` | +| 인증·리전 | 기존 OCI credential·inference region 유지 | 동일 | +| object list·metadata | 운영 값 | 운영 값 복제 | +| 운영 트래픽 | 사용 | 사용하지 않음 | + +`sql/adb/112_sgmp_select_ai_oci_llama4scout_profile.sql`은 기존 OCI 프로파일의 +credential, region, compartment, object list와 metadata instructions를 복제하고 +모델만 교체한다. 같은 질문을 두 프로파일에 각각 Chat 호출해 경과시간과 반환 JSON +형식을 기록한다. 품질·지연시간 결과를 검토하기 전에는 +`sg_game_extract_mentions`와 `sg_game_match_candidate`의 운영 프로파일을 바꾸지 +않는다.