# #708 Smilegate Select AI OCI GenAI 전환 ## 프로젝트 개요 Smilegate DATA & AI PoC는 Autonomous Database의 게임 데이터에서 Select AI Text2SQL을 생성하고, MCP와 백오피스를 통해 결과를 조회한다. 현재 운영 프로파일은 외부 OpenRouter 경유 Claude를 사용한다. ## 목표 `SGMP_POC_HAIKU45`가 가진 게임 데이터 object list와 메타데이터 활용 범위는 유지하면서, LLM 호출 경로만 OCI Generative AI `openai.gpt-5.4-mini`로 전환한다. ADB Resource Principal이 아닌 이 머신의 `~/.oci/config` DEFAULT API signing credential을 ADB credential으로 등록한다. ## 전환 설계 | 구분 | 기존 | 전환 후 | | --- | --- | --- | | 프로파일 | `SGMP_POC_HAIKU45` | `SGMP_POC_OCI_GPT54MINI` | | 제공자 | OpenAI 호환 외부 경로 | OCI Generative AI (`provider: oci`) | | 모델 | Claude Haiku 4.5 | `openai.gpt-5.4-mini` | | 인증 | 외부 API credential | DEFAULT API signing key 기반 `SGMP_POC_OCI_DEFAULT_CRED` | | OCI 리전 | 외부 서비스 | `us-chicago-1` (GPT-5.4 Mini OCI inference route) | | 게임 데이터 범위 | 기존 object list | 기존 profile attributes에서 복제 | | MCP 설정 | 기존 프로파일명 | `BACKOFFICE_SELECT_AI_PROFILE=SGMP_POC_OCI_GPT54MINI` | 신규 프로파일은 기존 프로파일의 metadata 관련 attributes를 복사하고, 외부 endpoint·credential·model은 OCI 값으로 새로 설정한다. 따라서 object list, comment, annotation, constraint 기반 Text2SQL 문맥은 유지된다. 기존 외부 프로파일은 삭제하지 않으며, 전환 실패 시 환경변수만 원래 값으로 되돌린다. ## 사전 조건 1. `~/.oci/config` DEFAULT의 user, tenancy, fingerprint, key_file이 유효한 OCI API signing key여야 한다. 2. DEFAULT API signing user가 Chicago 리전 root compartment에서 OCI Generative AI `openai.gpt-5.4-mini` 호출 권한을 가져야 한다. DEFAULT config의 signing region과 GPT inference route는 독립적이므로 profile attribute `region`은 `us-chicago-1`로 명시한다. 3. 스크립트는 `SGMP_POC` 프로파일 소유자로 실행한다. ## 구현 순서 1. `sql/adb/72_sgmp_select_ai_oci_genai_profile.sql`로 신규 OCI 프로파일을 만든다. 2. 새 프로파일로 한글 Text2SQL `SHOWSQL`과 생성 SQL의 읽기 전용 실행을 검증한다. 3. 운영 서버의 `BACKOFFICE_SELECT_AI_PROFILE`만 새 프로파일로 교체하고 백오피스를 재기동한다. 4. 운영 MCP의 `oracle.select_ai.smilegate_game_text2sql` 응답 profile과 집계 결과를 검증한다. ## 롤백 새 프로파일을 삭제하지 않는다. MCP에서 오류가 나거나 SQL 품질이 허용 기준을 충족하지 않으면 `/etc/smilegate/backoffice.env`의 `BACKOFFICE_SELECT_AI_PROFILE`을 `SGMP_POC_HAIKU45`로 되돌린 뒤 서비스를 재기동한다. ## 검증 기준 - 새 프로파일 provider=`oci`, model=`openai.gpt-5.4-mini`, credential=`SGMP_POC_OCI_DEFAULT_CRED`, region=`us-chicago-1` - 한글 질의는 SQLcl UTF-8 base64 복원식으로 전달한다. - `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`의 운영 프로파일을 바꾸지 않는다. 후보 모델 비교는 `sql/adb/114_sgmp_create_scope_chat_candidate_profiles.sql`과 `sql/adb/115_sgmp_scope_chat_candidate_benchmark.sql`으로 수행한다. 후보는 운영과 분리된 `SGMP_SCOPE_*` 프로파일로 생성한다. 각 모델은 `NONE`, `SINGLE`, `MULTI`, `ALL` 질문에서 다음을 기록한다. - 초 단위 Chat 응답시간 - 설명문·Markdown 없이 raw JSON만 반환했는지 - `scope_hint`와 `game_mentions` 수가 기대값과 일치하는지 - 생성 또는 Chat 호출 오류 ## 게임명 추출과 벡터 점수 판정 게임명과 조회 범위 추출은 짧은 JSON Chat 작업이므로 운영 프로파일 `SGMP_POC_OCI_COHERE_COMMAND` (`cohere.command-latest`)을 사용한다. 게임 카탈로그의 `ALIASES_JSON`에는 게임명, 영문명, 약칭, 게임 ID, prefix와 운영 등록 별칭을 JSON 배열로 저장한다. 이 JSON 배열 전체를 게임당 하나의 임베딩으로 생성한다. 추출된 각 게임명은 해당 게임 벡터의 cosine distance와 `SG_GAME_SCOPE_POLICY`에 저장된 최대값을 비교해 `MATCHED` 또는 `UNMATCHED`로 판정한다. 후보 동일성 확인을 위한 별도 LLM 호출은 사용하지 않는다. 정책값은 코드가 아니라 DB 설정 테이블에 저장한다. 게임 카탈로그·임베딩 모델이 변경되면 운영자가 그 기준값을 조정할 수 있다. `NONE`/`SINGLE`/`MULTI`/`ALL` 계약, Few-shot NL2SQL 전달 형식, Text2SQL 프로파일은 유지한다. ### 검증 기준 - 추출 결과는 JSON 파싱 가능하고 `game_mentions`, `scope_hint`만 반환한다. - `NONE`, `SINGLE`, `MULTI`, `ALL`에서 canonical `targets`, `dataEligibleTargets`, `unresolvedTargets`가 유지된다. - 동일성 판정을 위한 추가 OCI Chat 호출이 발생하지 않는다. ### 후보 프로파일 비교 결과 동일한 JSON 추출 프롬프트로 `NONE`, `SINGLE`, `MULTI`, `ALL`을 호출한 결과, `cohere.command-latest`, `cohere.command-plus-latest`, `cohere.command-a-vision`은 기본 4건에서 모두 범위와 게임명 수를 맞췄다. `google.gemini-2.5-flash-lite`는 JSON 파싱이 일관되지 않았고, Grok과 Llama Maverick은 게임 미지정 또는 전체 게임 질의에서 범위 오류가 있었다. 게임명 추출은 짧은 단일 JSON 요청이므로 `cohere.command-latest`를 선택했다. 이 측정값은 ADB 내부 Chat 호출 시간이며, Portal의 MCP·ReAct·답변 합성 시간을 포함한 전체 체감시간과는 별도로 관리한다.