8.5.5 JSON 구조화 출력을 통한 인용 메타데이터의 자동 검증

8.5.5 JSON 구조화 출력을 통한 인용 메타데이터의 자동 검증

지금까지 설명한 모든 정규표현식(Regex) 기반의 텍스트 파싱이나 문자열 비교 추출 방식은, 결국 타겟 LLM이 생성해 내는 유연하고 변칙적인 자연어(Natural Language) 텍스트 스트림 위에서 벌어지는 불안정한 검열 방식일 수밖에 없다. 모델이 괄호의 형태를 치명적으로 왜곡(예: [Doc1_Chunk2}<Doc1_Chunk2>)해버리면, 가장 완벽하게 팩트를 나열해 둔 정답이라도 융통성 없는 파서에 의해 기각당하는 에러(False Negative)가 발생하기 마련이다.

현대 RAG 오라클 엔지니어링의 정점은, 이러한 자연어 파싱의 한계를 근본적으로 타파하기 위해 LLM의 최종 응답 포맷 자체를 순수한 기계어인 JSON 구조화 출력(Structured Output) 모드로 강제하는 것이다.

텍스트와 메타데이터가 완벽하게 분리된 JSON 스키마(Schema)를 통해 응답을 렌더링하도록 타겟 모델을 강제하면, 시스템 오라클 파이프라인은 더 이상 정규표현식 삽질을 할 필요 없이 단 한 줄의 json.loads() 코드만으로도 완벽하게 투명한 인용-출처 인덱싱 트리를 획득할 수 있다.

1. 응답-인용 결합 체계의 JSON 스키마(Schema) 컴파일

오라클 미들웨어는 타겟 LLM이 프롬프트를 렌더링하기 전, Function Calling(또는 Tools/Structured Outputs) 레이어를 통해 다음과 같이 엄격하고 하드코딩된 JSON Schema를 강제로 주입한다.

{
  "name": "generate_cited_answer",
  "description": "사용자의 질문에 대한 답변과 그 문장별 출처를 구조화하여 반환한다.",
  "parameters": {
    "type": "object",
    "required": ["statements"],
    "properties": {
      "statements": {
        "type": "array",
        "items": {
          "type": "object",
          "required": ["sentence", "citation_ids"],
          "properties": {
            "sentence": {
              "type": "string",
              "description": "사용자에게 보여질 단일 마침표 단위의 독립된 답변 문장"
            },
            "citation_ids": {
              "type": "array",
              "items": { "type": "string" },
              "description": "이 문장을 연역하는 데 사용된 원본 문서의 [DocX_ChunkY] 식별자 배열"
            }
          }
        }
      }
    }
  }
}

이 고정된 스키마 구조는 타겟 모델이 자신의 답변을 “문장(Sentence)” 텐서와 그 문장을 지지하는 배열 형태의 순수 “식별자(Citation IDs)” 메타데이터로 물리적으로 분할하여 렌더링하도록 뇌 구조를 개조해 버린다.

2. 오라클의 O(1) 결정론적 논리 스캐닝

타겟 모델이 이 JSON 형태로 렌더링을 마치고 나면, 프론트엔드로 보내지기 전 백엔드의 오라클 파이프라인에서 눈부시게 빠르고 엄격한 **‘Type & Schema Validation (타입 및 스키마 검증)’**이 기계적으로 진행된다.

  1. 타입 무결성 검사 (Type Integrity): 오라클은 citation_ids가 문자열(String)이 아닌 정상적인 자바스크립트 배열 타입(Array)으로 넘어왔는지 즉시 확인한다. 타입 캐스팅 과정이 실패하면 즉시 Reject 한다.
  2. 역참조 배열 전수 조사: 응답받은 거대한 statements 배열을 순회하며, 오라클은 citation_ids 안의 원소([Doc1_Chunk2] 등)들이 검색 단계에서 주입했던 원본 Context의 HashSet에 존재하는지 O(1) 시간 복잡도로 빠르게 대조한다.
  3. 지시 위반(Empty Citation) 즉각 적발: 만약 타겟 모델이 자신이 생성한 문장 sentence에 대해 출처를 도저히 찾지 못해 citation_ids: []처럼 빈 배열을 반환했다면, 오라클은 즉시 이 문장을 ’출처가 없는 할루시네이션(Unsupported Claim)’으로 확정 짓고, 인간의 언어로 파싱해 볼 필요도 없이 해당 배열 객체를 드랍(Drop)시켜버린다.

3. 프론트엔드 연동을 위한 무결점 데이터 전송

오라클의 이 차갑고 가혹한 JSON 구조화 검열을 모두 무사히 통과한 데이터만이 최종적으로 클라이언트(프론트엔드) API로 전송된다. 프론트엔드 코드는 이 JSON 배열을 순회하면서, sentence 노드를 차례대로 이어 붙여 유저 친화적인 단락(Paragraph) 텍스트를 구성하고, citation_ids 배열의 길이에 맞춰 문장 끝에 클릭 가능한 [1], [2] 형태의 UI 하이퍼링크 뱃지를 기계적으로 렌더링한다.

자연어의 맥락이나 띄어쓰기, 괄호 등 문자열 파라미터 변형의 모든 리스크가 배제된 이 순수 ‘데이터 구조 객체’ 기반의 검열망이야말로, 현대 엔터프라이즈 RAG 오라클 시스템이 지향하는 가장 이상적이고 공학적인 Zero-Hallucination(제로 환각) 렌더링 아키텍처의 종착점이다. 문자열(String)을 믿지 말고, 강제된 데이터 스키마와 타입(Type)만을 숭배하라.