Skip to content

통합 검색·근거 기반 답변 규약 (EXPLORE ANSWER CONVENTION) ​

항목내용
상태채택 (2026-09-25)
범위portal-foundation 을 소비하는 모든 포털의 통합 검색과 근거 기반 답변(대화형 매뉴얼 진입)
결정입력은 셸 통합 검색창(PortalShell 상단 검색)과 페이지 내 검색창(PortalExploreSearch) 두 표면만 쓴다. 대화 전용 패널을 새로 만들지 않는다. 검색 조합은 ExploreGateway, 답변 생성은 포털 서버(ModelGateway), 색인·검색·인용은 포털이 소유한다
대상AgentCenter(참조 구현) · ProcessCenter(선행 구현) · GuideCenter · DocumentLibrary · lunchapp
관련MANUAL_CONVENTION.md(매뉴얼 진입점) · ROUTING_CONVENTION.md(경로가 화면의 원천)

1. 왜 검색창인가 ​

"업무 중 물어보면 근거 문서로 답한다"를 위해 새 대화 UI를 만들지 않는다. 셸에는 이미 검색창이 있고, 검색 결과·답변·인용을 그릴 자리가 이미 있다.

이미 있는 자산위치대화형 진입에서의 역할
셸 상단 검색창PortalShell → PortalTopNav → PortalExploreDialog어느 화면에서든 Ctrl/⌘ K 로 열리는 대화 표면
페이지 내 검색창PortalExploreSearch(exploreSearch.tsx)화면 안에서 검색·답변을 그대로 쓰는 표면
결과·답변 타입PortalExploreResult · PortalExploreAnswer(citations)메뉴·업무 데이터·문서·답변을 한 모양으로 표시
답변 카드PortalExploreAnswerCard답변 본문 + 인용 링크 + 권한 범위 고지를 한 곳에서 렌더
게이트웨이 클라이언트createExploreGatewayClient(portal-operations)여러 포털 색인을 한 번에 조회
대안채택하지 않은 이유
전용 대화 패널(우측 드로어·플로팅 챗)진입점이 셋이 되어 "매뉴얼은 한 곳에서 찾는다"(MANUAL_CONVENTION.md §1)가 깨진다. 셸이 대화 상태·인용·권한 고지를 중복 소유한다
페이지마다 별도 채팅 컴포넌트포털·화면마다 답변 모양이 갈라진다. 인용·권한 고지를 매번 다시 만든다
검색과 답변을 한 요청으로검색은 즉시, 답변은 문서 독해 후 응답이다. 묶으면 첫 결과가 답변 생성만큼 느려진다(onAsk 를 분리한 이유)

2. 규칙 (필수) ​

  1. 입력은 두 표면만 — 셸 상단 검색(PortalShell) · 페이지 내 PortalExploreSearch. 새 대화 컴포넌트를 만들지 않는다.
  2. 결과·답변 모양은 하나 — PortalExploreResult(kind: menu·record·document)와 PortalExploreAnswer { answer, citations }. 답변 렌더는 PortalExploreAnswerCard 하나가 담당한다.
  3. 입력 변경과 제출을 구분한다 — onSearchChange(타이핑) / onSearchSubmit(Enter·검색 버튼). 조회·이동은 제출에서만 한다.
  4. 답변은 근거와 함께만 — citations 가 비면 답변을 렌더하지 않는다(결과만 표시). 서버도 인용 없는 답변을 만들지 않는다. 출처 없는 문장은 사용자가 검증할 수 없다.
  5. 권한 필터는 데이터 원천에서 — 결과를 모은 뒤 거르지 않는다. 게이트웨이 호출은 사용자 위임 토큰(audience=explore-gateway)으로 하고 브라우저에 서비스 토큰을 노출하지 않는다. 부분 실패(partial·unavailablePortals)는 숨기지 않는다.
  6. 포털은 어댑터를 제공한다 — POST /api/explore/search(서비스 토큰 인증 + x-explore-subject-id)와 ExploreGateway 카탈로그 등록. 게이트웨이는 색인을 소유하지 않는다.
  7. 답변 생성은 포털 서버가 ModelGateway 로 — 검색(retrieval)과 생성(completion)을 분리 호출하고 AI 기능 대장에 등록한다. 게이트웨이 스트리밍은 미지원이므로 1차는 비스트리밍이다.
  8. 매뉴얼 대화형 진입도 같은 계약 — 매뉴얼 화면·셸 어디서 열어도 같은 검색창·같은 답변 카드를 쓴다(MANUAL_CONVENTION.md §7).
  9. 실패는 대화창 안에서 말한다 — 연합 검색의 부분 실패는 exploreUnavailablePortals, 답변 실패는 exploreAnswerError 로 셸에 넘기고 대화창 안에 표시한다. 포털 화면 상단에 상시 배너를 두지 않는다: 사라지지 않는 경고는 배경이 되어 읽히지 않고, 레이아웃을 밀어낸다(2026-10 피드백). 답변 실패는 대기 표시도 멈춘다 — 영원한 "읽는 중"은 실패를 숨긴다.

3. 두 표면 계약 ​

표면컴포넌트조회답변실패 표시
셸 상단PortalShell → PortalTopNav → PortalExploreDialogexploreResults(미지정 시 현재 포털 메뉴를 바로가기 결과로 채운다)onExploreAsk · exploreAnswer · exploreAnswerLoadingexploreUnavailablePortals · exploreAnswerError(대화창 안)
페이지 내PortalExploreSearchonSearch(query) => Promise<PortalExploreSearchResponse>onAsk · answer · answerLoading검색창이 partial·unavailablePortals 를 스스로 표시

공통 props: locale(ko·en) · onSubmit(셸은 onSearchSubmit) · onSelect · answer.citations.

4. 포털 구현 순서 ​

  1. 어댑터 — 포털 데이터에서 결과를 만들어 POST /api/explore/search 로 노출한다(권한은 그 포털이 판단).
  2. 카탈로그 — ExploreGateway 에 포털을 등록한다(주소·색인 범위). 미등록이면 게이트웨이가 그 포털을 건너뛴다(unavailablePortals).
  3. 배선 — 셸에는 exploreResults·onExploreSelect·onExploreAsk·exploreAnswer 를, 화면에는 PortalExploreSearch 를 붙인다.
  4. 답변 — 포털 서버가 검색 결과 상위 문서를 ModelGateway 로 요약하고 citations 를 채운다. 인용이 없으면 답변 대신 결과만 돌려준다.

5. 상태 ​

항목상태
셸 검색창 제출 구분(onSearchSubmit) · 답변 슬롯(onExploreAsk·exploreAnswer) · 공용 답변 카드구현 완료(portal-foundation 0.6.158)
페이지 내 검색창 답변 슬롯(onAsk·answer)구현 완료(0.6.158)
관리자 셸(PortalAdminShell)의 같은 슬롯구현 완료(0.6.158 — PortalShellProps 상속으로 그대로 전달되므로 관리자 셸도 같은 검색창·같은 답변 카드를 쓴다)
AgentCenter 어댑터·카탈로그구현 완료(2026-09-25 · D-070 — POST /api/explore/v1/search 어댑터, 셸 explore.search)
AgentCenter 근거 기반 답변구현 완료(2026-09-25 · D-071·D-072 — 포털 서버가 ModelGateway /v1/chat/completions 로 요약, 근거 0건이면 모델을 부르지 않음, AI_ENABLED 구성 시에만 슬롯 활성)
ProcessCenter 게이트웨이 어댑터선행 구현
부분 실패·답변 실패의 대화창 내 표시(exploreUnavailablePortals·exploreAnswerError)구현 완료(0.6.185 — 포털 화면 상단의 상시 배너를 걷어내고 대화창 안에서 표시)

6. 검증 ​

  • 셸: 제출/입력 구분, 답변 카드·질문 콜백 전달 — packages/ui-react/src/explore/portalShellExplore.contract.test.tsx.
  • 대화창: 제출 분리·답변 인용·로딩 비활성 — packages/ui-react/src/explore/PortalExploreDialog.browser.test.tsx.
  • 페이지 검색창: 질문 전달·답변 인용·로딩 — packages/ui-react/src/exploreSearch.contract.test.tsx.
  • 포털: 어댑터 응답이 PortalExploreSearchResponse 계약(results·partial·unavailablePortals·requestId)을 만족하는지 테스트로 고정한다.
  • 부분 실패·답변 실패: 셸 전달 — packages/ui-react/src/explore/portalShellExplore.contract.test.tsx, 대화창 표시(부분 실패 줄·대기 정지) — packages/ui-react/src/explore/PortalExploreDialog.browser.test.tsx.

7. 소비 포털 체크리스트 ​

  1. 검색창을 새로 만들지 않고 셸/PortalExploreSearch 를 썼는가.
  2. 조회는 onSubmit 에서만 하는가(타이핑마다 게이트웨이를 때리지 않는가).
  3. 답변에 citations 를 채웠는가(없으면 답변을 렌더하지 않는다).
  4. 브라우저에 서비스 토큰을 노출하지 않고 위임 토큰을 쓰는가.
  5. 부분 실패를 대화창 안에서 알리는가(exploreUnavailablePortals·exploreAnswerError) — 포털 화면 상단에 상시 배너를 두지 않았는가.