지식그래프 설계 · 2/10
문서 중심 그래프를 만든 뒤에도 검색 결과는 기존 벡터 검색과 크게 다르지 않았습니다. 질문과 가까운 원문을 찾고 주변 트리플을 한 번 조회하는 것만으로는, 문서 여러 곳에 흩어진 관계나 질문에 직접 쓰이지 않은 연결을 충분히 활용하기 어려웠습니다. 그래프를 만든 이유는 비슷한 문장을 하나 더 찾기 위해서가 아니라, 벡터 검색이 놓치는 관계와 경로를 따라가기 위해서였습니다.
“배송비 기준은 무엇인가”처럼 한 문장에서 답을 찾는 질문은 한 번의 조회로 충분합니다. 그러나 “이 정책의 예외 승인 주체와 그 근거 문서를 알려 달라”는 질문은 정책을 찾고, 예외 관계를 따라가고, 승인 주체를 확인한 뒤 관련 원문까지 읽어야 합니다.
질문 유형마다 전용 쿼리를 추가하면 조합이 늘어날수록 분기와 프롬프트 규칙도 함께 커집니다. 4월에는 모델이 생각·행동·관측을 반복하는 ReAct 구조를 도입해 그래프, 원문, 정형 질의 도구 가운데 다음 행동을 고르게 했습니다. 멀티턴 자체가 목적이 아니라, 답을 만들기 전에 필요한 관계를 스스로 찾아갈 수 있는지 확인하기 위한 선택이었습니다.
검색을 답변 생성이 아니라 도구 선택 문제로 봤습니다
멀티턴 검색의 한 턴은 세 부분으로 구성됩니다.
Thought: 지금 부족한 정보가 무엇인가
Action: 허용된 도구 가운데 무엇을 호출할 것인가
Result: 도구가 반환한 구조화된 근거
도구는 역할이 겹치지 않게 나눴습니다.
- 클래스와 인스턴스의 트리플을 찾는 그래프 검색
- 정방향과 역방향 이웃을 따라가는 관계 탐색
sourceChunk로 원문을 가져오는 청크 조회- 원문 안에서 키워드를 찾는 보조 검색
- 표 데이터의 집계와 조인을 처리하는 읽기 전용 SQL
모델은 직접 저장소에 접근하지 않습니다. 허용된 도구와 인자 스키마 안에서만 움직입니다. SQL도 SELECT와 WITH만 허용하고 실행 전에 스키마를 제공합니다. 이렇게 해야 멀티턴의 유연성을 얻으면서도 실행 범위를 통제할 수 있습니다.
최대 턴 수에 도달하면 지금까지 모은 근거로 답을 합성합니다. 답을 못 찾았다는 이유로 루프가 끝없이 이어지지 않도록 종료 조건을 실행 계약에 포함했습니다.
모든 턴을 그대로 넣지 않았습니다
멀티턴은 검색 범위를 넓히지만 컨텍스트가 빠르게 커집니다. 한 턴에서 가져온 청크와 관계를 다음 턴에 모두 다시 넣으면, 모델은 새 근거보다 이전 출력의 반복을 더 많이 읽게 됩니다.
최근 세 턴은 남기고 이전 턴은 호출한 도구 중심으로 요약했습니다. 하지만 도구 결과도 500자로 잘렸고, 최대 턴에 도달한 뒤 강제로 합성할 때는 최근 메시지만 사용했습니다. 응답 데이터에 출처 목록은 남았지만 전체 근거가 합성 컨텍스트에 보존된 것은 아니었습니다.
이 절단은 컨텍스트를 줄였지만 표와 긴 원문의 뒷부분을 잃는 원인이 됐습니다. 모델이 이미 시도한 도구를 기억하는 일과 최종 합성에 필요한 근거를 온전히 보존하는 일은 다른 문제였습니다. 이후 평가에서 멀티턴 구조를 다시 보게 된 핵심 한계이기도 했습니다.
탐색 경로를 응답 데이터로 만들었습니다
멀티턴의 내부 로그만으로는 사용자가 답이 어디서 왔는지 알기 어렵습니다. 각 도구 호출에서 방문한 노드와 엣지를 별도로 모아 응답에 포함했습니다. 이 데이터는 디버깅 정보가 아니라 검색 결과의 한 부분입니다.
프론트엔드는 이 경로를 3D 그래프에서 강조했습니다. 대규모 그래프의 물리 계산은 Web Worker로 분리하고, 노드 수에 따라 틱 전송 주기와 링크 거리를 조절했습니다.
당시 응답의 방문 노드는 안정적인 URI가 아니라 라벨 또는 local name이었고, 화면도 node.label로 강조했습니다. 경로를 관찰할 수는 있었지만 같은 라벨의 노드를 구분하는 end-to-end 식별자 계약은 아니었습니다. 이 한계는 7편의 근거 강조에서도 그대로 확인됩니다.
멀티턴은 탐색 능력과 함께 변동성도 키웠습니다
관계를 여러 단계 따라가야 하는 질문에서는 멀티턴이 유용했습니다. 첫 조회에 답이 없더라도 이웃 탐색과 원문 조회를 조합해 근거를 보강할 수 있었습니다. 탐색 경로도 화면에서 확인할 수 있었습니다.
반면 질문마다 호출 횟수가 달라졌고, 같은 근거를 여러 턴에 걸쳐 쌓으면서 원문 수가 과도하게 늘어나는 경우가 생겼습니다. 단일 사실 질문도 여러 턴을 사용하면 답과 무관한 숫자와 문장이 합성 컨텍스트에 섞였습니다. 평균 응답 시간보다 긴 꼬리 지연이 운영에서 더 큰 문제가 됐습니다.
당시에는 탐색 범위를 넓히는 것이 우선이었기 때문에 이 구조를 선택했습니다. 이후 질문별 실행 경로를 측정해 보니, 모든 질문에 루프가 필요한 것은 아니었습니다. 검색 구조를 바꾼 근거와 결과는 6편에서 평가 과정과 함께 이어갑니다.
먼저 검색보다 앞에 있는 빌드가 긴 작업으로 바뀌면서 생긴 운영 문제를 해결해야 했습니다. 다음 편에서는 진행 상태, 취소, 입력 판별, 정형·비정형 라우팅을 하나의 빌드 실행 계약으로 묶습니다.
이전 편 → 질문을 온톨로지 빌드에서 뺀 이유 다음 편 → 몇 시간 걸리는 온톨로지 빌드를 작업으로 다루기

