5.9 KiB
Smilegate 게임 대상 계약 통합 설계
1. 배경
현재 game_query_plan은 게임을 찾지 못하면 STOP_NO_MATCH, 여러 게임이면
FAN_OUT을 반환한다. Portal의 ReAct 모델이 이 지시를 종료 조건으로 해석하거나
일부 게임만 다음 도구로 전달하면서 다음 문제가 발생했다.
- 게임명이 없는 전체 매출 질의가 SQL 생성 전에 중단된다.
- 여러 게임 중 일부만 매칭되면 매칭된 게임의 조회도 생략될 수 있다.
- 계획 결과를 전달해도 NL2SQL worker가 질문 전체를 다시 단일 게임 벡터검색하여 범위를 축소할 수 있다.
- 게임별 사용자 마스터 물리 객체를 모델이 추측해야 한다.
2. 목표
질문의 게임 대상을 NONE, SINGLE, MULTI, ALL 네 가지로 통일하고,
모든 유형에서 원 질문과 전체 계획 결과를 smilegate_fewshot_nl2sql에 한 번
전달한다. 계획 단계는 조회 중단이나 SQL 조립을 결정하지 않는다.
3. 계약
game_query_plan은 다음 필드를 반환한다.
| 필드 | 내용 |
|---|---|
targetType |
NONE, SINGLE, MULTI, ALL |
status |
NO_TARGET, SUPPORTED, PARTIAL, UNMATCHED |
targets |
언급 순서를 보존한 게임 대상 배열 |
nextAction |
항상 CALL_FEWSHOT |
executionMode |
UNSCOPED, SINGLE, COMBINED, ALL |
각 targets 항목은 다음 값을 가진다.
| 필드 | 내용 |
|---|---|
mention |
질문에서 추출한 게임명. NONE은 null |
status |
NONE, MATCHED, UNMATCHED, CATALOG |
gameKey, gameId |
DB 카탈로그가 반환한 게임 식별자 |
gamePrefix |
DB 카탈로그가 반환한 prefix |
gameName, aliases |
표시명과 별칭 |
userMasterObjectName |
현재 Select AI 승인 객체 중 해당 게임의 사용자 마스터 물리 객체. 없으면 null |
cosineDistance |
후보 검색 거리. 적용되지 않으면 null |
reasonCode, reason |
매칭 또는 미매칭 근거 |
유형별 처리 방식은 다음과 같다.
NONE: 게임 대상 항목 하나를 모든 게임 필드가null인 상태로 전달한다. 공통 거래·기준 객체 질의는 계속하되 prefix 전용 객체를 임의 선택하지 않는다.SINGLE: 질문에서 언급된 대상 한 건을 전달한다. 미매칭이면 게임 필드가null인 대상도 그대로 다음 도구에 전달한다.MULTI: 언급된 대상 모두를 전달한다. 매칭·미매칭을 함께 보존한다.ALL: 게임 카탈로그의 활성 게임을 모두 반환한다. 사용자 마스터 물리 객체가 없는 게임도null로 보존한다.
4. DB 설계
SG_GAME_CATALOG에 USER_MASTER_OBJECT_NAME을 추가한다.
- 값은
COMN_GAME_ALIAS_BAS/운영 게임 registry의GAME_PREFIX와 현재USER_CLOUD_AI_PROFILE_ATTRIBUTES.object_list,USER_OBJECTS를 조합해 계산한다. - 공통 정책이나 애플리케이션 코드에는 특정 게임명, prefix, 테이블명을 넣지 않는다.
- 운영 registry에만 존재하는 게임도 카탈로그에 동기화하고 임베딩을 생성한다.
- 게임별 물리 객체가 없으면 컬럼은
null이다.
SG_GAME_CATALOG_SEARCH는 물리 객체명을 후보 결과에 포함한다.
SG_GAME_QUERY_PLAN은 추출된 mention마다 후보 선택 결과를 targets로 만들며,
ALL은 벡터 선택 없이 전체 카탈로그를 사용한다.
5. MCP와 NL2SQL 설계
game_query_plan 도구 설명은 “항상 먼저 호출하고 결과를 원 질문과 함께 다음
도구에 전달”하도록 바꾼다. smilegate_fewshot_nl2sql의 입력은 다음과 같다.
prompt: 사용자가 입력한 원 질문queryPlan: 바로 앞game_query_plan의 전체 JSONscopeGameKey: 하위 호환용 선택 값. 새 흐름에서는 사용하지 않는다.
NL2SQL worker는 전달된 queryPlan을 권위 있는 게임 범위로 사용한다.
계획이 있으면 질문 전체를 다시 게임 카탈로그 벡터검색하지 않는다.
- 공통 객체에 게임 식별 컬럼이 있으면 질문 의미에 따라
IN과GROUP BY를 사용할 수 있다. - 대상별 물리 객체가 다르면 제공된 객체만 사용해
UNION ALL할 수 있다. - 물리 객체가
null인 대상을 임의 객체로 대체하지 않는다. NONE에서 생성 SQL이 prefix 전용 객체를 참조하면 실행 전에 차단한다.- 최종 SQL은 기존과 같이 단일
SELECT/WITH, read-only transaction, 최대 행수와 timeout 제한을 적용한다.
6. Portal ReAct 설계
Portal은 도구 호출 순서를 Java/Python 조건문으로 강제하지 않는다. 외부 환경변수의 system prompt와 MCP 도구 설명으로 다음 절차를 안내한다.
game_query_plan을 호출한다.targetType과 상관없이 원 질문, 전체queryPlan으로smilegate_fewshot_nl2sql을 한 번 호출한다.- SQL, 실행 결과, 매칭·미매칭 대상을 함께 설명한다.
7. 검증
운영 MCP에서 다음 네 질문군을 실제 호출한다.
| 유형 | 검증 내용 |
|---|---|
NONE |
게임명이 없는 전체 매출 질의가 공통 테이블로 실행되고 게임 필터가 임의 추가되지 않는다. |
SINGLE |
한 게임의 AU 질의가 해당 게임 식별자/물리 객체로 실행된다. |
MULTI |
지원·미지원 게임을 함께 질문해 지원 결과와 미지원 상태가 한 답변에 보존된다. |
ALL |
전체 게임 질의가 전체 카탈로그 대상을 받아 공통 객체 그룹 또는 게임별 객체 결합 SQL로 실행된다. |
추가 검증:
- Maven 테스트
- Portal Python 테스트
- MCP
tools/listschema/description 확인 - 생성 SQL에서
NONE의 prefix 전용 객체 차단 확인 - 운영 서비스 health와 Portal ReAct 실제 응답 확인
8. 변경 이력
- Redmine:
#739 - Backoffice branch:
smilegate - Portal branch:
main