JUN0.DEV
JUN0.DEV

RAG 파이프라인으로 LLM 환각 현상 완화하기

Published on
  • avatarJunyoung Yang

PNU x Upstage DOCUMENT AI CHALLENGE에서 해외 파견 의료진을 돕는 챗봇 서비스 DocDoc을 만들었다. 목표는 사용자가 질문하면 관련 의학 문서를 근거로 답변을 만들어주는 것이었다.

처음에는 질문을 그대로 LLM에 전달해 답변을 생성하는 방식으로 시작했다. 하지만 의료·논문 맥락에서는 자연스러운 문장이 오히려 위험할 수 있었다. 답변이 읽기 좋게 보이더라도 실제 문서에 없는 내용을 섞거나, 출처가 모호한 내용을 단정하면 사용자가 잘못 받아들일 수 있기 때문이다.

그래서 이 기능은 의료 조언을 직접 제공하는 도구가 아니라, 관련 문서를 찾고 근거를 확인하는 보조 도구로 범위를 정했다. 이 글은 LLM 답변에 근거를 어떻게 연결할지 고민하면서 RAG 파이프라인을 적용한 기록이다.

처음 보인 문제

초기 구현은 단순했다. 사용자가 질문하면 LLM에 질문을 전달하고, 모델이 답변을 생성했다. 기능만 보면 빠르게 결과가 나왔지만, 실제 사용 시나리오를 생각하면 문제가 있었다.

  • 근거 없는 문장이 섞일 수 있었다.
  • 존재하지 않는 내용을 실제 문서 내용처럼 말할 수 있었다.
  • 답변의 출처가 불명확했다.
  • 의료·논문 맥락에서는 자연스러운 문장 자체가 리스크가 될 수 있었다.

이 문제는 성능이 더 좋은 모델로 바꾼다고 완전히 사라지는 종류가 아니라고 판단했다. 모델이 무엇을 근거로 답해야 하는지 시스템에서 먼저 제한해줘야 했다.

해결 방안

핵심은 모델이 근거 없이 단정하지 않게 만드는 것이었다. 그래서 답변 생성 전에 관련 문서 조각을 먼저 찾고, 그 결과를 컨텍스트로 제공하는 RAG 구조로 바꿨다.

RAG pipeline

구현 흐름은 아래처럼 잡았다.

  1. 사용자 질문을 임베딩 벡터로 변환한다.
  2. Vector DB인 Pinecone에서 유사한 문서 조각을 검색한다.
  3. 검색 결과를 LLM 프롬프트에 컨텍스트로 포함한다.
  4. LLM은 컨텍스트 범위 안에서 답변을 생성하고, 근거를 함께 보여준다.

이 구조로 바꾼 뒤에도 답변이 완전히 안전해졌다고 말할 수는 없지만, 적어도 사용자가 답변의 근거를 함께 확인할 수 있는 형태가 되었다.

적용 및 구현

RAG를 적용할 때 중요하게 본 것은 모델의 표현을 통제하는 것만이 아니었다. 답변 이전 단계에서 검색 범위를 먼저 좁히는 것이 핵심이었다.

문서 조각이 너무 넓으면 관련 없는 내용이 함께 들어가고, 너무 좁으면 필요한 문맥이 빠질 수 있다. 그래서 검색 결과를 어떻게 자르고, 어떤 순서로 컨텍스트에 넣을지 계속 확인해야 했다.

당시 사용한 구성은 아래와 같았다.

  • Vector DB: Pinecone
  • Embedding: Upstage Embeddings
  • LLM: Upstage Solar Pro 2
  • Framework: LangChain
  • Backend: Node.js, Express

기술을 적용하는 것보다 더 중요했던 것은 답변의 책임 범위를 정하는 일이었다. 모델이 문서를 기반으로 설명하게 만들되, 문서 밖의 내용을 단정하지 않도록 설계를 맞췄다.

SSE 스트리밍을 적용한 이유

RAG를 적용하면 답변이 더 느려질 수밖에 없다. 검색을 하고, 검색 결과를 프롬프트에 넣고, 다시 답변을 생성해야 하기 때문이다.

사용자 입장에서는 로딩만 오래 보이면 서비스가 멈춘 것처럼 느낄 수 있다. 그래서 응답을 한 번에 보내지 않고 Server-Sent Events(SSE)로 생성되는 내용을 조금씩 흘려보내는 방식을 적용했다.

이 방식으로 얻고 싶었던 것은 두 가지였다.

  • 생성 과정이 화면에 보이게 해서 대기감을 줄이다.
  • 전체 답변이 끝나기 전에도 사용자가 진행 중임을 확인할 수 있게 한다.

LLM 기능에서는 품질만큼 사용자 체감도 중요했다. 특히 RAG처럼 검색과 생성이 함께 들어가는 구조에서는 응답 흐름을 어떻게 보여줄지도 함께 고려해야 했다.

마무리

이 경험을 통해 LLM 관련 문제는 모델만 교체해서 해결하기보다 시스템 설계로 줄여야 하는 경우가 많다는 점을 확인했다.

특히 문서 기반 답변에서는 아래 기준이 중요했다.

  • 답변이 어떤 문서를 근거로 하는가
  • 모델이 컨텍스트 밖 내용을 단정하지 않는가
  • 사용자가 답변의 근거를 확인할 수 있는가
  • 생성 시간이 길어질 때 사용자에게 진행 상태를 보여주는가

RAG는 환각을 완전히 없애는 도구라기보다, 답변의 근거를 시스템 안에 넣기 위한 구조였다. DocDoc에서는 이 구조를 통해 LLM 답변을 조금 더 검증 가능한 형태로 만들 수 있었다.