검색을 넘어, 의도를 이해하는 AI 백엔드로

1. 왜 RAG 아키텍처를 설계했는가

기존의 키워드 검색은 한계가 분명합니다.

사용자는 자연어로 질문하지만,
시스템은 보통 단어 일치 여부로만 결과를 반환합니다.
이 방식은 단순 검색에는 유효하지만,
사용자의 의도와 맥락을 이해해야 하는 질문에서는 성능이 급격히 떨어집니다.

예를 들어 사용자가 이렇게 묻는 경우가 있습니다.

  • “환불 완료된 주문만 다시 보고 싶다”
  • “지난주에 내가 결제했다가 부분취소한 건 있어?”
  • “이 상품 배송 언제 시작돼?”

이런 질문은 단순 키워드 검색으로 처리하기 어렵습니다.
질문의 의도를 해석해야 하고,
필요하면 여러 데이터 소스를 조합해야 하며,
최종적으로는 자연어 형태로 답변까지 생성해야 합니다.

이 문제를 해결하기 위해
저는 Spring AI 기반 RAG(Retrieval-Augmented Generation) 아키텍처를 설계했습니다.

핵심 목표는 하나였습니다.

검색 결과를 나열하는 시스템이 아니라,
사용자 질문의 의도를 이해하고 근거 기반으로 답변하는 시스템을 만든다.


2. 기존 검색 구조의 한계

기존 검색 시스템은 보통 다음과 같은 구조를 가집니다.

  • 사용자가 키워드 입력
  • DB 또는 검색엔진에서 일치 항목 조회
  • 결과 목록 반환

이 방식의 문제는 세 가지입니다.

1) 질의 의도를 이해하지 못한다

사용자가 “부분환불”을 말했더라도
실제로는 “부분취소”, “환불 내역”, “정산 조정”을 의미할 수 있습니다.

2) 데이터가 여러 저장소에 흩어져 있다

상품 정보, 주문 정보, 환불 정보, 문서 정보가
각각 다른 테이블 혹은 시스템에 존재할 수 있습니다.

3) 검색 결과가 답변이 아니다

검색은 문서를 찾는 것이고,
사용자가 원하는 것은 질문에 대한 답변입니다.

이 지점에서 RAG가 필요해집니다.


3. RAG를 왜 Spring AI로 구현했는가

RAG 자체는 Python 생태계에서 많이 다뤄집니다.
하지만 제가 Spring AI를 선택한 이유는 분명했습니다.

첫째, 기존 백엔드와의 통합성이 높습니다

실무 서비스는 이미 Java/Spring 기반인 경우가 많습니다.
인증, 권한, 결제, 정산, 주문, 배치, 외부 API 연동 등
핵심 도메인 로직이 대부분 Spring 서비스 안에 있습니다.

RAG를 별도 실험 서버로 두는 것이 아니라
실제 서비스 흐름 안으로 편입하려면
기존 애플리케이션과 자연스럽게 붙어야 합니다.

둘째, 운영 관점에서 일관성을 유지할 수 있습니다

Spring Boot 기반으로 구성하면 다음이 편합니다.

  • 공통 설정 관리
  • DI 기반 구성
  • 트랜잭션 경계 관리
  • Actuator 기반 관측성
  • 테스트 코드 구조화

즉, “AI 기능만 따로 존재하는 서비스”가 아니라
운영 가능한 백엔드 서비스의 일부로 AI를 넣을 수 있습니다.

셋째, AI를 기능이 아니라 아키텍처 구성요소로 다룰 수 있습니다

중요한 것은 LLM 호출 자체가 아닙니다.
더 중요한 것은:

  • 어떤 문서를 검색할 것인가
  • 어떤 기준으로 컨텍스트를 조합할 것인가
  • 어떤 프롬프트를 구성할 것인가
  • 어떤 결과를 근거와 함께 반환할 것인가

이 전체 흐름을 서비스 레벨에서 통제하려면, Spring 기반 설계가 상당히 잘 맞습니다.


4. 전체 아키텍처 개요

제가 설계한 Spring AI 기반 RAG 아키텍처는 크게 아래 단계로 구성됩니다.

1) 사용자 질문 입력

사용자가 자연어 질문을 입력합니다.

예:

  • “부분환불된 주문만 보여줘”
  • “이 상품 재입고 예정 있어?”
  • “이번 달 정산에서 차감된 환불 건 알려줘”

2) 질의 의도 분석

질문을 단순 텍스트로 보지 않고
LLM 또는 사전 분석기를 통해 의도를 분류합니다.

예:

  • 주문 조회
  • 환불 조회
  • 상품 QA
  • 배송 문의
  • 정산 관련 문의

질의 의도 분석은 매우 중요합니다.
이 단계가 있어야 어떤 데이터 소스를 우선 조회할지 결정할 수 있습니다.

3) 검색 전략 결정

질의 성격에 따라 검색 방식을 나눕니다.

  • 정형 데이터 조회: RDB 기반 SQL/서비스 조회
  • 비정형 문서 검색: 벡터 검색
  • FAQ/정책 문서: 임베딩 기반 유사도 검색
  • 복합 질의: 둘 이상 조합

즉, 모든 질문을 무조건 벡터 검색으로 처리하지 않습니다.
RAG는 검색 전략 설계가 핵심입니다.

4) 문서 임베딩 및 벡터 검색

상품 설명, FAQ, 정책 문서, 주문 관련 문서 등 비정형 데이터를 임베딩하여 벡터 저장소에 보관합니다.

이후 사용자 질문도 동일한 방식으로 임베딩하여 유사 문서를 검색합니다.

제가 중요하게 본 포인트는 다음입니다.

  • 문서 chunking 전략
  • 메타데이터 설계
  • 검색 결과 필터링
  • Top-K 튜닝

5) 컨텍스트 조합

검색 결과를 그대로 LLM에 던지지 않고 질문 의도에 맞는 문서만 선별해서 컨텍스트를 구성합니다. 예를 들어:

  • 환불 문의인데 상품 홍보 문구가 들어가면 안 됨
  • 배송 문의인데 오래된 정책 문서가 섞이면 안 됨

즉, 컨텍스트 조합 단계는 RAG의 정확도를 결정하는 핵심 구간입니다.

6) LLM 응답 생성

구성된 컨텍스트와 프롬프트를 기반으로 LLM이 최종 답변을 생성합니다. 이때 중요한 원칙은 명확합니다.

  • 근거 없는 추론 금지
  • 제공된 컨텍스트 기준으로만 답변
  • 불확실하면 모른다고 답변
  • 가능하면 출처 또는 근거 포함

7) 응답 후처리

최종 응답은 그대로 노출하지 않고 필요시 아래를 포함해 정제합니다.

  • 근거 문서 요약
  • 출처 링크
  • 관련 엔티티 정보
  • UI 표시용 구조화 데이터

5. 핵심 구성 요소

이 아키텍처를 구성할 때 핵심은 “LLM 호출”이 아니라 주변 시스템 설계였습니다.

1) Embedding Layer

문서를 벡터화하는 계층입니다. 여기서 중요한 것은 모델 선택보다 문서를 어떻게 자를 것인가입니다. 문서 chunk가 너무 크면 검색 정확도가 떨어지고, 너무 작으면 문맥이 깨집니다. 그래서 문서 성격에 따라 다르게 설계해야 합니다.

  • FAQ: 비교적 작은 chunk
  • 정책 문서: 문단 단위 chunk
  • 상품 설명: 속성 중심 chunk
  • 주문/환불 설명: 이벤트 흐름 기준 chunk

2) Vector Store

벡터 저장소는 단순 저장소가 아니라 검색 품질에 직접 영향을 주는 계층입니다. 여기서 중요했던 포인트는 다음입니다.

  • 벡터 차원 수
  • 메타데이터 필터링
  • 인덱싱 속도
  • 검색 정확도
  • 운영 편의성

실무에서는 단순 유사도 검색만으로는 부족하고, 카테고리, 상태, 생성일시 같은 메타데이터를 함께 써야 의미 있는 결과가 나옵니다.

3) Retrieval Orchestrator

이 계층이 사실상 RAG의 두뇌입니다. 질문을 받아서 판단합니다.

  • 이 질문은 벡터 검색이 필요한가?
  • 아니면 정형 DB 조회가 우선인가?
  • 두 결과를 합쳐야 하는가?
  • 어떤 문서를 제외해야 하는가?

많은 예제는 검색 후 바로 LLM으로 넘기지만,
실무형 시스템은 이 계층이 있어야 합니다.

4) Prompt Composer

프롬프트를 한 군데서 조합하는 계층입니다. 여기서 중요한 것은 프롬프트를 코드 곳곳에 흩뿌리지 않는 것입니다. 역할별로 분리해야 합니다.

  • 질의 분류용 프롬프트
  • 답변 생성용 프롬프트
  • 요약용 프롬프트
  • 관리자 검토용 프롬프트

이렇게 분리해야 유지보수가 됩니다.

5) Answer Guardrail

AI 응답은 잘 만드는 것보다,  잘못 답하지 않게 막는 것이 더 중요합니다. 그래서 다음과 같은 가드레일이 필요합니다.

  • 컨텍스트 밖 정보 생성 금지
  • 정책성 응답은 근거 문서 강제
  • 불확실 시 재질문 유도
  • 민감 정보 마스킹
  • 금지어/보안 규칙 검사

6. 실무 설계에서 중요했던 포인트

1) 모든 질의를 RAG로 풀지 않는다

이게 정말 중요합니다.

예를 들어 주문 상세 조회나 환불 상태 조회는
굳이 벡터 검색과 LLM 생성이 필요 없습니다.
이건 정확한 SQL과 비즈니스 로직이 더 낫습니다.

RAG는 아래 같은 문제에 적합합니다.

  • 자연어 질의
  • 문서 기반 질의응답
  • FAQ/정책 검색
  • 의미 기반 검색

문맥이 필요한 응답 즉, RAG는 만능이 아니라 적합한 문제에만 써야 하는 아키텍처 패턴입니다.

2) 정형 데이터와 비정형 데이터를 분리해서 다뤄야 한다

실무에서는 이 둘이 섞여 있습니다.

  • 정형 데이터: 주문, 결제, 환불, 정산
  • 비정형 데이터: 가이드, 정책, 설명서, 매뉴얼

좋은 RAG 시스템은 이 둘을 같은 방식으로 처리하지 않습니다. 정형 데이터는 정확성, 비정형 데이터는 유사성 기반으로 접근해야 합니다.

3) 응답 품질보다 검색 품질이 먼저다

많은 사람들이 프롬프트를 계속 손봅니다. 하지만 실제로는 검색 결과가 나쁘면, 아무리 프롬프트를 잘 써도 답이 좋아지지 않습니다. RAG 품질의 핵심은 대체로 다음 순서입니다.

문서 품질 → chunking → metadata → retrieval → prompt

즉, 문제의 대부분은 LLM이 아니라 검색 계층에서 발생합니다.


7. 확장 방향: Agent와 Tool Calling

RAG만으로 해결되지 않는 질문도 있습니다.

예를 들면:

  • “이번 달 정산에서 환불 차감 총액 계산해줘”
  • “배송 지연 주문 중 환불 가능 대상만 추려줘”
  • “최근 7일간 취소율 높은 상품 보여줘”

이건 문서 검색만으로 안 됩니다.
실제 도구 호출이 필요합니다.

그래서 다음 단계로 확장할 수 있습니다.

  • SQL 조회 도구
  • 외부 API 호출 도구
  • 통계 계산 도구
  • 사내 문서 검색 도구

이때 Spring AI 기반으로  Tool Calling, Advisor, Agent 패턴을 얹으면 단순 Q&A를 넘어 행동 가능한 AI 백엔드로 확장할 수 있습니다. 즉,

  • RAG = 근거를 찾는 구조
  • Agent = 필요한 행동을 수행하는 구조

로 볼 수 있습니다.


8. 운영 관점에서 본 장점

Spring AI 기반으로 RAG를 설계하면서 가장 큰 장점은 “실험”이 아니라 , 운영 가능한 형태로 시스템을 가져갈 수 있었다는 점입니다.

LIST

+ Recent posts