본문 바로가기
AI 오케스트레이션 캠프/일차별 회고

35일차 회고|RAG·벡터 검색·MCP 툴 연동|AI 오케스트레이션 개발자 국비지원

by 랩보다 AI 더 잘해지기 2026. 8. 28.
728x90

오늘 배운 내용

35일차에는 어제까지 학습했던 MCP(Model Context Protocol)RAG(Retrieval-Augmented Generation)를 연결하면서, AI 에이전트가 단순히 여러 툴을 호출하는 것을 넘어 외부 데이터를 검색하고 그 결과를 LLM에게 전달해 답변을 만드는 과정을 집중적으로 살펴봤다.

특히 오늘은 RAG의 핵심인 임베딩(Embedding), 벡터 데이터베이스, 유사도 검색, 청크(Chunk)를 다시 정리하고, 이를 MCP 툴로 만들었을 때 AI 에이전트가 어떤 방식으로 활용할 수 있는지 확인했다.


1. RAG에서 데이터가 어떻게 저장되는가

오늘 수업에서는 먼저 RAG의 전체적인 구조를 다시 확인했다.

RAG는 LLM이 모든 정보를 직접 알고 있다고 가정하는 방식이 아니라,

문서를 저장 → 사용자의 질문과 비슷한 문서를 검색 → 검색 결과를 LLM에게 전달 → 답변 생성

의 과정을 거친다.

예를 들어 호텔의 취소 규정이 다음과 같은 문서에 있다고 해보자.

"교육용 예약은 3일 전까지 취소 가능합니다."

사용자가

"호텔을 당일 취소하면 환불받을 수 있나요?"

라고 질문하면 단순히 LLM에게 질문하는 것과 RAG를 사용하는 것은 결과가 달라질 수 있다.

LLM에게 질문만 하면 일반적인 호텔 취소 정책을 바탕으로 답할 수밖에 없다. 반면 RAG를 사용하면 먼저 저장된 호텔 규정에서 질문과 관련된 내용을 찾아낸 뒤, 사용자의 질문 + 검색된 규정을 함께 LLM에게 전달할 수 있다.

결국 RAG의 중요한 목적은 우리 서비스가 가지고 있는 데이터를 근거로 답변하도록 만드는 것이라고 이해했다.


2. 임베딩과 벡터 검색

오늘 가장 중요하게 다시 정리한 개념 중 하나는 임베딩이었다.

임베딩은 문장을 단순히 글자 하나하나를 숫자로 바꾸는 것이 아니라, 문장의 의미를 숫자 벡터로 표현하는 과정이다.

예를 들어

"오늘은 금요일이고 비가 온다."

라는 문장이 있다면 단순히 안녕의 ㄴ, ㅇ 같은 글자를 숫자로 변환하는 방식이 아니다.

임베딩 모델이 문장의 의미와 맥락을 파악하고 이를 일정한 규칙에 따라 벡터로 표현한다.

그리고 여기서 중요한 문제가 하나 있었다.

문서를 저장할 때 사용한 임베딩 모델과 검색할 때 사용하는 임베딩 모델이 달라지면 호환되지 않을 수 있다.

수업에서는 예시로 EmbeddingGemma와 OpenAI 임베딩 등을 이야기했다. 문서를 A 임베딩 모델로 벡터화해서 저장했다면, 사용자의 질문 역시 같은 기준으로 임베딩해야 제대로 비교할 수 있다.

이 부분을 통해 단순히 "텍스트를 숫자로 바꾼다"라고만 이해했던 임베딩의 개념을 조금 더 정확하게 이해할 수 있었다.


3. 청크(Chunk)가 중요한 이유

문서를 RAG에 저장할 때 문서 전체를 한 덩어리로 넣는 것이 아니라 적당한 크기로 나누는 과정이 필요하다.

이렇게 나눈 문서의 작은 덩어리를 청크(Chunk)라고 한다.

예를 들어 아주 긴 법률 문서나 호텔 규정집이 있다면 이를 그대로 하나의 데이터로 저장하는 것이 아니라 일정한 크기로 잘라서 저장한다.

그런데 여기서 단순히 글자 수만 생각해서 자르면 문제가 생길 수 있다.

문장이

"안녕하세요."

처럼 의미가 연결되어 있는데 중간에서 잘려버리면 검색 결과의 의미가 깨질 수 있기 때문이다.

그래서 청크를 나눌 때 Overlap(중첩)을 사용하는 방법도 배웠다.

일부 내용을 다음 청크와 겹치게 만들어 문장이 잘리는 문제를 줄이는 방식이다.

오늘 수업을 들으면서 RAG에서 단순히 "문서를 DB에 넣는다"가 끝이 아니라, 어떤 기준으로 문서를 잘라 저장할 것인지 자체가 검색 품질에 큰 영향을 줄 수 있다는 점을 알게 됐다.


4. 벡터 데이터베이스와 PostgreSQL

오늘은 실제로 PostgreSQL에 저장된 RAG 데이터를 확인하면서 벡터 데이터가 일반적인 테이블과 어떻게 함께 저장되는지도 살펴봤다.

PostgreSQL은 원래 일반적인 관계형 데이터베이스이지만 pgvector를 사용하면 벡터를 저장하고 유사도 검색에 활용할 수 있다.

RAG 데이터에는 단순히 텍스트만 들어가는 것이 아니라 여러 메타데이터도 함께 저장할 수 있다.

예를 들면 다음과 같다.

  • collection_name
  • title
  • source
  • content
  • chunk_id
  • embedding

여기서 특히 인상적이었던 것은 구분자 역할을 하는 메타데이터였다.

예를 들어 여러 종류의 문서가 하나의 데이터베이스에 들어 있다면 collection_name이나 title 등을 기준으로 검색 범위를 좁힐 수 있다.

"호텔 정책"을 검색해야 하는데 데이터베이스에 호텔 정보, 여행 후기, 법률 문서까지 모두 들어 있다면 전체 데이터를 대상으로 검색하는 것보다 호텔 정책이라는 범위 안에서 검색하는 것이 더 효율적이다.


5. 유사도 검색과 Top-K

사용자의 질문을 임베딩한 뒤 데이터베이스에 저장된 벡터들과 비교하면 질문과 가장 비슷한 데이터를 찾을 수 있다.

이때 사용되는 대표적인 방법이 코사인 유사도(Cosine Similarity)다.

예를 들어 검색 결과가 다음과 같이 나왔다고 생각해보자.

  • 0.8
  • 0.6
  • 0.3

그리고 Top-K = 2라면 가장 유사도가 높은 2개의 결과인 0.8과 0.6을 가져오게 된다.

오늘 실습에서도 Top 3를 설정해서 질문과 유사한 데이터 3개를 가져오는 과정을 확인했다.

다만 무조건 Top-K만 사용하는 것이 아니라 유사도 임계값을 설정하는 방법도 생각해볼 수 있다.

예를 들어

"유사도가 0.7 이상인 데이터만 가져와라."

라고 설정하면 낮은 유사도의 데이터를 제외할 수 있다.

결국 RAG 검색 품질을 높이려면

몇 개를 가져올 것인지 + 어느 정도 유사해야 가져올 것인지

를 함께 고민해야 한다는 것을 배웠다.


6. RAG를 MCP 툴로 만들기

오늘 수업에서 가장 중요한 부분은 여기였다.

어제까지 MCP를 통해 날씨 조회, 호텔 검색, 관광지나 맛집 검색 등의 툴을 만들었다면, 오늘은 여기에 RAG 검색 기능을 하나의 MCP 툴로 추가하는 방향을 생각했다.

구조를 단순하게 표현하면 다음과 같다.

사용자 질문
   ↓
LLM
   ↓
어떤 툴을 사용할지 판단
   ↓
RAG 검색 Tool 호출
   ↓
사용자 질문 임베딩
   ↓
벡터 DB 유사도 검색
   ↓
관련 호텔 규정 반환
   ↓
LLM
   ↓
최종 답변

즉 RAG 자체가 최종 답변을 만드는 것이 아니라, 관련 데이터를 찾아서 LLM에게 전달하는 역할을 한다.

예를 들어 사용자가

"호텔 당일 취소하면 환불받을 수 있어?"

라고 질문한다면 LLM이 RAG 검색 툴을 호출하고, 해당 툴이 호텔 규정 데이터를 찾아서 반환한다.

그 결과를 다시 LLM에게 전달하면 LLM이 사용자가 이해하기 쉬운 자연스러운 문장으로 답변을 만들어준다.


7. MCP에서 Tool Description이 중요한 이유

오늘 다시 강조된 내용 중 하나가 툴 설명(Tool Description)이었다.

AI 에이전트는 사용자의 질문을 보고 어떤 MCP 툴을 호출할지 판단한다.

예를 들어 MCP 서버에

  • 날씨 조회 Tool
  • 호텔 검색 Tool
  • 맛집 검색 Tool
  • 호텔 규정 검색 Tool

이 있다고 하자.

사용자가

"호텔 당일 취소 규정을 알려줘."

라고 했을 때 AI가 호텔 검색 Tool이 아니라 호텔 규정 검색 Tool을 선택해야 한다.

이 판단에 중요한 역할을 하는 것이 각 Tool의 설명이다.

따라서 단순히 함수를 만들어 놓는 것만으로 끝나는 것이 아니라,

이 툴이 언제 사용되는지
어떤 인자를 받는지
어떤 결과를 반환하는지

를 LLM이 이해할 수 있도록 명확하게 작성해야 한다.

지금까지 MCP 툴을 만들면서 설명 부분을 단순한 문서 정도로 생각했다면, 오늘 수업을 통해 Tool Description 자체가 AI 에이전트의 의사결정에 영향을 주는 중요한 정보라는 점을 이해하게 됐다.


8. 하나의 에이전트에서 여러 툴을 사용하는 구조

오늘은 단순히 RAG만 배운 것이 아니라 기존에 만들었던 MCP 툴들과 연결했을 때의 전체적인 흐름도 생각해봤다.

예를 들어 사용자가 한 번에

"부산 여행을 가려고 하는데 오늘 날씨 알려주고 15만 원 이하 호텔이랑 맛집도 찾아줘."

라고 질문할 수 있다.

그러면 LLM은 사용자의 의도를 분석하고 필요한 툴을 선택한다.

사용자 질문
      ↓
     LLM
 ┌────┼────┐
 ↓    ↓    ↓
날씨  호텔  맛집
Tool  Tool  Tool
 └────┼────┘
      ↓
     LLM
      ↓
  최종 답변

여기에 오늘 배운 RAG 규정 검색 Tool까지 추가할 수 있다.

이렇게 되면 하나의 AI 에이전트 안에서 여러 MCP Tool을 상황에 맞게 호출할 수 있게 된다.


9. 한 번에 끝나는 시스템에서 대화형 에이전트로

오늘 수업에서 개인적으로 가장 흥미로웠던 부분은 대화의 맥락을 이어가는 에이전트에 대한 이야기였다.

예를 들어 처음에

"부산에서 15만 원 이하 호텔 찾아줘."

라고 해서 호텔 목록을 받았다고 하자.

그 다음 사용자가

"그중에서 주변 맛집도 알려줘."

라고 했을 때 AI가 이전에 검색한 호텔 정보를 기억하고 주변 맛집을 찾아줄 수 있다면 훨씬 자연스러운 서비스가 된다.

또 이어서

"아까 첫 번째 호텔의 취소 규정은?"

이라고 물었을 때 이전에 검색했던 호텔과 현재 질문을 연결해서 해당 호텔의 규정을 RAG로 검색할 수도 있다.

이런 구조가 만들어지면 단순히 버튼을 누르고 검색 결과를 보는 기존 시스템과 달리 사용자와 계속 대화하면서 필요한 작업을 수행하는 AI 에이전트에 가까워진다.

이번 프로젝트에서 이런 방향까지 발전시켜보면 좋겠다는 생각이 들었다.


10. MCP 서버 실행 환경도 다시 점검

오늘은 개념뿐만 아니라 실제 개발 환경도 다시 점검했다.

현재 프로젝트에서는 여러 서버가 함께 동작하기 때문에 각각의 역할과 연결 방식을 정확히 이해하는 것이 중요했다.

특히 MCP 서버의 연결 방식에서 STDIO와 Streamable HTTP 방식의 차이를 다시 확인했다.

STDIO

같은 컴퓨터에서 프로세스 간 직접 연결하는 방식으로, 일반적으로 별도의 IP와 포트를 지정하지 않고 MCP 서버와 통신할 수 있다.

Streamable HTTP

HTTP 기반으로 MCP 서버에 연결하는 방식이다.

예를 들어

127.0.0.1:8010

처럼 주소와 포트를 통해 서버에 접근한다.

둘 다 로컬 컴퓨터에서 실행할 수 있지만 백엔드에서 MCP 서버에 접근하는 방식 자체가 다르다는 점을 다시 정리했다.

여러 서버를 동시에 실행하다 보니 단순히 "실행된다"에서 끝나는 것이 아니라 각각의 서버가 어떤 방식으로 연결되어 있는지 확인하는 것이 필요했다.


오늘 새롭게 이해한 점

오늘 수업을 통해 가장 크게 달라진 부분은 RAG를 하나의 기술로만 바라보지 않게 된 것이다.

처음에는

"RAG = 문서를 검색해서 LLM에게 넣는 것"

정도로 생각했다.

하지만 오늘 전체 흐름을 다시 연결해보니 실제로는 여러 단계가 이어져 있었다.

PDF / 문서
 ↓
텍스트 추출
 ↓
Chunk 분할
 ↓
Embedding
 ↓
Vector DB 저장
 ↓
사용자 질문
 ↓
질문 Embedding
 ↓
유사도 검색
 ↓
Top-K 결과
 ↓
LLM에 전달
 ↓
최종 답변

그리고 이 과정을 MCP Tool로 만들어 AI 에이전트가 필요할 때 호출하게 만들면,

RAG + MCP + LLM이 하나의 AI 에이전트 구조로 연결된다.

이 연결 관계를 이해한 것이 오늘 가장 큰 수확이었다.


오늘의 회고

오늘은 RAG의 핵심 개념을 다시 정리하면서 벡터 데이터베이스, 임베딩, 청크, 유사도 검색, Top-K가 각각 따로 존재하는 기술이 아니라 하나의 검색 과정으로 연결되어 있다는 것을 이해할 수 있었다.

특히 지금까지 공부했던 MCP와 연결하면서 "툴을 여러 개 만드는 것"에서 한 단계 더 나아가 LLM이 상황에 맞는 툴을 선택하고, 필요한 데이터를 검색한 뒤 그 결과를 바탕으로 답변하는 구조를 생각해볼 수 있었다.

아직 직접 구현하는 과정에서는 신경 써야 할 부분이 많다. 특히 임베딩 모델의 일관성, 청크 크기와 Overlap, 검색 결과의 유사도 기준, Tool Description 작성처럼 실제 서비스의 품질에 영향을 주는 요소들은 더 연습이 필요하다.

그래도 오늘 수업을 통해 지금까지 배운 기술들이 각각 따로 존재하는 것이 아니라,

LLM → MCP Tool → RAG → Vector DB → 검색 결과 → LLM

이라는 하나의 흐름으로 연결될 수 있다는 점을 조금 더 명확하게 이해하게 됐다.

다음 단계에서는 오늘 배운 내용을 실제 프로젝트에 적용하면서 사용자의 질문에 따라 여러 MCP 툴을 선택적으로 호출하고, RAG를 통해 필요한 규정을 찾아 답변하는 구조를 직접 만들어보는 것이 중요한 과제가 될 것 같다.

댓글