Files
vpd-permission-poc/docs/design/731-sgmp-game-scope-resolver

SGMP DB 기반 게임 범위 Resolver (#731)

목표

복수 게임이 포함된 데이터 질문에서 애플리케이션 코드나 에이전트 지시문에 게임명, prefix, 테이블명을 넣지 않는다. DB가 제공하는 게임 범위 뷰를 먼저 조회하고, 조회 가능으로 판정된 게임에만 기존 Few-shot NL2SQL MCP를 호출한다.

범위와 원칙

  • 기존 oracle.select_ai.smilegate_fewshot_nl2sql은 예제 검색, SQL 생성, 읽기 전용 실행을 담당하는 worker로 유지한다.
  • game_scope_resolve MCP는 SQL을 생성하거나 실행하지 않는다.
  • 공통 백오피스는 환경변수로 지정된 DB view 이름과 MCP tool 이름만 안다.
  • 게임명, alias, GAME_ID, GAME_PREFIX, 대상 object는 DB view의 데이터로만 결정한다.
  • 지원 여부는 대상 날짜의 행 수가 아니라, 현재 승인된 조회 object가 존재하는지로 판정한다. 데이터가 0건인 날도 정상 조회 범위다.

DB 공통 계약

고객 DB는 환경변수 BACKOFFICE_GAME_SCOPE_VIEW로 지정된 view를 제공한다. view는 아래 별칭(column alias)을 반환한다.

Column 의미
GAME_KEY 내부 게임 식별자
PROFILE_NAME 승인 object list를 판정한 Select AI profile
DISPLAY_NAME 화면 표시용 정식 게임명
GAME_ALIAS 질문에서 찾을 게임명 또는 별칭
QUERY_ALLOWED_YN 승인된 조회 object 존재 여부 (Y/N)
REASON_CODE 미지원 또는 보류 사유 코드
ALIAS_PRIORITY 동일/중첩 alias 정렬 우선순위
SCOPE_VERSION object list 변경 시 함께 갱신되는 버전

Smilegate view는 전체 게임 마스터와 alias를 기준으로 하고, 현재 Select AI profile별 승인 object list와 실제 object 존재 여부를 조합해 QUERY_ALLOWED_YN을 계산한다. 따라서 등록 게임이지만 현재 조회 object가 없는 게임도 N으로 반환된다.

MCP와 ReAct 계약

  1. 포털 ReAct는 게임 데이터 질의 전에 game_scope_resolve(question)를 호출한다.
  2. resolver는 질문 문자열과 GAME_ALIAS를 정규화해 포함 관계를 찾고, 우선순위와 alias 길이로 중복을 제거한다. 동일 우선순위의 복수 게임은 AMBIGUOUS로 반환한다.
  3. QUERY_ALLOWED_YN=Y인 scope에는 서명·만료된 opaque scopeToken과 worker tool 이름을 반환한다.
  4. ReAct는 nextAction=CALL_WORKER인 항목만 Few-shot NL2SQL에 전달한다. UNSUPPORTEDAMBIGUOUS는 SQL 실행 없이 결과에 표시한다.
  5. Few-shot worker는 scope token을 검증하고, token에 담긴 DB scope로만 prompt를 보강한다.

추출 게임명별 판정 계약

  • ADB Chat이 반환한 game_mentions의 각 항목은 서로 독립적으로 판정한다. 벡터 검색 결과를 하나의 목록으로 합쳐 모든 후보를 지원 게임으로 취급하지 않는다.
  • 벡터 검색은 후보를 찾는 단계다. ADB OCI GenAI가 추출 명칭과 후보의 카탈로그 명칭, 별칭, GAME_ID, GAME_PREFIX를 비교해 후보 중 하나를 선택하거나 전체를 거절한다.
  • 애플리케이션은 모델이 반환한 gameKey가 실제 후보 목록에 있을 때만 supportedGames에 넣는다. 후보 목록에 없는 식별자는 거절한다.
  • 모델이 모든 후보를 거절하면 해당 원문 명칭을 unmatchedGames에 남긴다. 유사도 순위가 높다는 이유만으로 다른 게임에 대입하지 않는다.
  • 게임 판정에 정규식, 부분문자열 매칭, 유사도 임계값을 사용하지 않는다.
  • 동일 게임이 여러 명칭으로 검색되더라도 supportedGamesgameKey 기준으로 중복을 제거한다. matchedGamesunmatchedGames에는 mention별 판정 근거를 유지한다.
  • 일부만 지원되는 복수 게임 질문은 status=PARTIAL로 반환하고, 지원 게임의 worker 실행과 미매칭 게임 안내를 함께 수행한다.

검증

  • view가 지원 게임과 object list 미연결 게임을 각각 반환하는지 확인한다.
  • resolver MCP의 결과에 구체 게임/테이블 하드코딩이 없는지 확인한다.
  • STD-06에서 미지원 게임은 worker가 호출되지 않고, 지원 게임 결과에는 few-shot 예제, 생성 SQL, 실행 결과가 포함되는지 확인한다.
  • STD-06 판정은 미매칭 게임과 지원 게임을 독립적으로 평가한다. 미매칭 게임을 답변에 명시하고 지원 게임의 요청 일자와 AU 집계를 반환하면 PARTIAL 성공을 PASS로 판정하며, 미매칭 게임 때문에 지원 게임 결과를 폐기하거나 전체 결과 없음으로 만들지 않는다.
  • 기존 단일 게임 Few-shot NL2SQL 및 미게임명 거절 guardrail 회귀를 확인한다.

논리 조인 메타데이터

COMN_GAME_ALIAS_BAS는 하나의 게임에 여러 alias 행을 갖기 때문에 GAME_ID가 유일키가 아니다. 따라서 공통 transaction table의 GAME_ID에 물리 FK를 추가하지 않는다. 대신 78_sgmp_game_alias_logical_joins.sql이 fact table에 GAME_ALIAS_JOIN annotation을 추가한다. 이 annotation은 게임명 필터에서 EXISTS 또는 DISTINCT GAME_ID alias subquery를 사용하고, alias 원본을 직접 조인해 집계 행을 늘리지 않도록 설명한다. Prefix 전용 테이블은 가짜 FK 없이 기존 alias/prefix 소유 범위 annotation을 유지한다.

보류 항목

전체 게임 마스터에 미지원 게임이 없다면 DB만으로 그 이름을 게임으로 식별할 수 없다. 이 경우 고객 원천 게임 마스터를 view에 연결하는 작업이 선행되어야 하며, 모델 추측으로 보완하지 않는다.

운영 배포 계약

  • GameScopeProperties 클래스와 application.ymlbackoffice.game-scope 구역은 하나의 배포 단위다. Java 클래스만 반영하면 환경변수가 존재해도 기본값(enabled=false, viewName="")으로 바인딩되어 worker 호출이 차단된다.
  • 운영 배포 후 BACKOFFICE_GAME_SCOPE_ENABLED, BACKOFFICE_GAME_SCOPE_VIEW, BACKOFFICE_GAME_SCOPE_MAX_SCOPES가 실제 실행 JAR의 설정 메타데이터에 연결되는지 MCP game_scope_resolve 호출로 확인한다.
  • 검증은 범위 판정 성공만으로 끝내지 않고, 지원 scope를 전달한 Few-shot NL2SQL이 읽기 전용 SQL 생성과 실행까지 완료하는지 확인한다.