튼튼발자 개발 성장기🏋️

RAG, 들어는 봤는데… 내 서비스엔 어떻게 쓰지? 본문

기타/타사 기술 블로그 읽기

RAG, 들어는 봤는데… 내 서비스엔 어떻게 쓰지?

시뻘건 튼튼발자 2026. 5. 11. 13:47
반응형

우아한형제들 기술블로그에서 [RAG, 들어는 봤는데… 내 서비스엔 어떻게 쓰지?]라는 글을 읽었다. 솔직히 RAG에 대해서는 기본적인 개념만 알고 있고, 실제로 구현해본적은 딱 한 번 있다. 당시에 RAG를 왜 써야하는지, 임베딩을 할때 텍스트(데이터)를 어떻게 청킹해서 벡터화 해야하는지 등 많은 난제에 부딪혔었다. 이 글은 마치 선배 개발자가 옆에서 "우리도 이렇게 삽질했어!"라고 말해주는 것처럼 구체적이고 솔직한 것 같다. 특히 MCP를 먼저 시도했다가 결국 RAG 서버를 직접 구현하게 된 과정이 매우 공감되었다.

MCP의 꿈과 현실

나도 처음에는 MCP가 뭔가 표준화된 은탄환이 될 줄 알았다. Anthropic에서 제안한 프로토콜이니까 앞으로 모든 LLM 도구들이 이걸 따르지 않을까 하는 기대가 있었다. 근데 글을 보니 현실은 전혀 달랐다. 모든 사용자가 MCP를 지원하는 LLM을 사용해야 한다는 점이 가장 큰 문제였고, 로컬에서 실행돼야 한다는 제약 때문에 VPC 내부의 DB에 접근 못 하는 문제는 정말 치명적이다. 나도 비슷한 상황에서 고민해봤는데, 사내 인프라는 대부분 private망이나 VPC 안에 있으니까 MCP 서버를 로컬에 띄우는 건 실용성이 떨어진다는 생각이 들었다.

결국 RAG 서버 직접 구현이 어쩌면 현재 시점에서는 가장 현실적인 답일 것이라 생각한다. 특히 빠른 검증을 위해 처음부터 완벽한 시스템을 만들려 하지 않았다는 점이 공감된다. 나도 Butler 프로젝트를 시작할 때 종종 "아키텍처를 제대로 설계해야지!" 하면서 너무 많은 시간을 끌 때가 있는데, 일단 [색인 > 검색 > 생성 > 평가]라는 파이프라인을 한 바퀴 돌려보고 고치는 게 훨씬 낫다는 걸 깨달았다.

청킹의 딜레마

글에서 청크 크기 최적화가 핵심이라고 했는데, 이 부분이 정말 어렵다고 생각한다. 너무 작게 자르면 문맥이 끊겨서 "이 문서의 앞부분에서는 A라고 했는데 뒷부분에서는 B라고 한다."는 식의 연결성을 LLM이 이해 못 하고, 너무 크게 자르면 Context Window를 금방 채워버려서 비용도 비용이고 성능도 떨어진다.

글에서 제시한 부모-자식 구조(Parent-Child Structure)는 꽤 흥미로운 접근이다. 검색할 때는 작은 단위(자식)로 임베딩해서 정확도를 높이고, 실제로 LLM에 넘길 때는 큰 단위(부모)를 넘겨서 문맥을 유지하는 방식인데, 이건 좀 더 살펴봐야겠다. 나의 경우에는 Butler 프로젝트에서 초기에 재귀적 문자 텍스트 분할 방식을 사용했는데, 실제로는 문서의 논리적 구조(제목, 섹션, 문단)를 고려한 청킹이 필요하지 않을까 하는 고민이 있었다. 특히 코드나 마크다운 문서를 다룰 때는 단순히 문자열 길이로 자르는 것보다 의미 단위로 자르는 게 훨씬 효과적일 것 같다는 생각을 했었다. 그래서 시멘틱 청커를 사용하는 것으로 개선하니까 비용은 비슷할지 몰라도, 성능은 크게 향상된 것을 볼 수 있었다.

평가 파이프라인의 중요성

사실 RAG를 만들 때 가장 간과하기 쉬운 부분이 평가인 것 같다. 대부분 "잘 되는 것 같아!" 하고 넘어가기 쉽지만, 이 글에서 제시한 세 가지 지표(컨텍스트 관련성, 답변 충실성, 답변 관련성)는 RAG의 품질을 객관적으로 측정하는 데 필수적인 것 같다.

특히 답변 충실성은 hallucination을 방지하는 데 핵심이지 않을까? LLM이 검색된 컨텍스트에 없는 내용을 마구 만들어내는 걸 막기 위해서 "검색된 내용으로만 답변해!"라는 프롬프트만으로는 부족하다. LLM은 착한 거짓말쟁이가(?) 되어서 관련 없는 내용을 억지로 연결하려 하기 때문이다. 이걸 자동으로 측정하려는 시도 자체가 의미 있다고 본다.

다만 역방향 질문 생성 방식으로 답변 관련성을 측정하는 부분은 조금 비용이 들 것 같다는 생각이 든다. 답변마다 LLM을 한 번 더 호출해서 질문을 생성하고, 그걸 원래 질문과 비교하는 과정이니까. 평가용 LLM을 별도로 두라는 조언이 현실적이다. 실제로 운영 환경에서는 GPT-4 같은 고성능 모델로 답변을 생성하고, 평가는 GPT-3.5나 작은 오픈소스 모델로 하는 식의 전략이 필요할 것 같다. 사실 이런 평가용 LLM은 파인튜닝에서 따온 것 같다는 생각이 들었다.. 파인튜닝을 한 이후에 학습이 제대로 되었는지 평가를 할때 비슷한 방식으로 평가를 하게 되는데, 그 부분에서 아이디어를 얻어온게 아닐까?ㅎㅎ

Spring AI vs LangChain. 팀의 숙련도가 우선?

프레임워크 선택 부분은 비교적 공감되지 않았다. 물론 기술적 우수성보다 팀이 익숙한 환경을 선택해야 한다는 건 정말 중요한 부분이다. 평소의 환경이었다면, 팀이 Java/Spring 중심이라면 굳이 LangChain을 고집할 필요가 없다. Spring AI가 Spring 생태계와 잘 통합되고, 기존에 쓰던 모니터링 툴이나 배포 파이프라인을 그대로 쓸 수 있다는 장점 또한 절대 무시할 수 없다.

반면에 Python 생태계가 아직은 AI 관련 라이브러리가 더 풍부하다. 또, Langchain에서 지원되는 것들이 Spring AI에서는 지원되지 않는 경우도 많다.

자, 고민을 해보자. 단순 언어의 차이(java vs python)을 보았을 때, 그리고 프레임워크 측면에서 보았을 때(Langchain vs Spring AI) 우리는 무엇을 선택해야하는가?

AI 시대인 지금, [조직에서 익숙한 환경]이 과연 고려해야하는 부분일지 의문이 든다. 비개발자가 AI를 통해 python은 물론이고 java, Ruby 등 많은 언어로 개발할 수 있는 환경에서, java만을 사용하는 개발 조직에서 python을 사용하기 꺼려진다는 것은 적합하지 않은 것 같다. 물론, 기본적인 python의 기본 특성이나 Langchain이라는 프레임워크의 라이프사이클 등 학습이 필요한 것은 사실이다. 때에 따라서, 조직 단위로 학습을 하고 더 적합한 환경을 선택할 수 있다면, 그것이 베스트가 아닐까한다.

참고

반응형