<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>DevelopmentNote</title>
    <link>https://dudghks2814.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Sun, 12 Jul 2026 06:48:07 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>코딩은 내 여친</managingEditor>
    <image>
      <title>DevelopmentNote</title>
      <url>https://tistory1.daumcdn.net/tistory/5153209/attach/00c05674a5f0420b807e34a94a16d781</url>
      <link>https://dudghks2814.tistory.com</link>
    </image>
    <item>
      <title>AI 영화 리뷰 감성 분석 서비스 아키텍처 설계</title>
      <link>https://dudghks2814.tistory.com/73</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;이번에는 가상의 서비스로 &lt;b&gt;AI 영화 리뷰 감성 분석 웹 서비스&lt;/b&gt;를 선정해보았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 서비스는 사용자가 영화 리뷰를 입력하면 AI 모델이 해당 리뷰를 분석하여&lt;br /&gt;&lt;b&gt;긍정 리뷰인지, 부정 리뷰인지&lt;/b&gt;를 예측해주는 서비스이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금까지 학습한 Docker, 추론 최적화, Streamlit, FastAPI를 활용한다고 가정하면&lt;br /&gt;전체 아키텍처는 다음과 같이 구성할 수 있다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. 전체 서비스 구조&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서비스는 크게 네 부분으로 나눌 수 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;사용자 화면: Streamlit&lt;/li&gt;
&lt;li&gt;API 서버: FastAPI&lt;/li&gt;
&lt;li&gt;AI 모델 추론 서버: ONNX 또는 TensorRT 기반 모델&lt;/li&gt;
&lt;li&gt;배포 환경: Docker와 클라우드 서버&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전체 흐름은 다음과 같다.&lt;/p&gt;
&lt;pre class=&quot;properties&quot;&gt;&lt;code&gt;사용자
  &amp;darr;
Streamlit 웹 화면
  &amp;darr;
FastAPI 서버
  &amp;darr;
AI 모델 추론
  &amp;darr;
분석 결과 반환
  &amp;darr;
Streamlit 화면에 결과 출력
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용자는 Streamlit 화면에서 영화 리뷰를 입력한다.&lt;br /&gt;입력된 리뷰는 FastAPI 서버로 전달되고, FastAPI는 AI 모델을 이용해 감성 분석을 수행한다.&lt;br /&gt;이후 예측 결과를 다시 Streamlit 화면으로 보내 사용자에게 보여준다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. Streamlit 역할&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Streamlit은 사용자가 직접 이용하는 웹 화면 역할을 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용자는 Streamlit 화면에서 영화 리뷰 문장을 입력하고,&lt;br /&gt;분석 버튼을 누르면 결과를 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Streamlit에서 담당하는 기능은 다음과 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;리뷰 텍스트 입력&lt;/li&gt;
&lt;li&gt;분석 요청 버튼&lt;/li&gt;
&lt;li&gt;FastAPI 서버로 요청 전송&lt;/li&gt;
&lt;li&gt;예측 결과 출력&lt;/li&gt;
&lt;li&gt;긍정/부정 결과 시각화&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 사용자가&lt;br /&gt;&amp;ldquo;이 영화는 스토리가 좋고 배우 연기도 훌륭했다.&amp;rdquo;&lt;br /&gt;라고 입력하면 Streamlit은 이 문장을 FastAPI 서버로 전달한다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. FastAPI 역할&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;FastAPI는 Streamlit과 AI 모델 사이에서 API 서버 역할을 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;FastAPI는 사용자의 요청을 받고, 입력 데이터를 검증한 뒤 모델 추론 함수로 전달한다.&lt;br /&gt;그리고 모델이 예측한 결과를 JSON 형태로 다시 반환한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;FastAPI에서 담당하는 기능은 다음과 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;/predict API 제공&lt;/li&gt;
&lt;li&gt;입력 데이터 검증&lt;/li&gt;
&lt;li&gt;모델 추론 요청 처리&lt;/li&gt;
&lt;li&gt;예측 결과 반환&lt;/li&gt;
&lt;li&gt;오류 발생 시 예외 처리&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예시 응답 형태는 다음과 같다.&lt;/p&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;{
  &quot;text&quot;: &quot;이 영화는 정말 재미있었다.&quot;,
  &quot;label&quot;: &quot;긍정&quot;,
  &quot;score&quot;: 0.92
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 API 서버를 따로 분리하면 나중에 Streamlit뿐만 아니라 모바일 앱, 다른 웹 서비스에서도 같은 API를 사용할 수 있다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4. AI 모델 추론 최적화&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AI 모델은 학습이 끝난 후 그대로 사용하는 것이 아니라&lt;br /&gt;ONNX 또는 TensorRT 형식으로 변환해 추론 속도를 높일 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 PyTorch로 학습한 감성 분석 모델을 ONNX로 변환하면&lt;br /&gt;FastAPI 서버에서 더 가볍고 빠르게 실행할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;추론 최적화의 목적은 다음과 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;응답 속도 향상&lt;/li&gt;
&lt;li&gt;서버 자원 사용량 감소&lt;/li&gt;
&lt;li&gt;모델 배포 환경 호환성 향상&lt;/li&gt;
&lt;li&gt;동시에 여러 요청 처리 가능성 증가&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 GPU 서버를 사용한다면 TensorRT를 활용해 더 빠른 추론도 가능하다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;5. Docker를 활용한 배포 구조&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Docker는 서비스 실행 환경을 컨테이너로 묶어주는 역할을 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Streamlit, FastAPI, 모델 추론 환경을 각각 Docker 이미지로 만들면&lt;br /&gt;다른 컴퓨터나 클라우드 서버에서도 동일한 환경으로 실행할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예시 구조는 다음과 같다.&lt;/p&gt;
&lt;pre class=&quot;markdown&quot;&gt;&lt;code&gt;docker-compose.yml

streamlit-app 컨테이너
  - 사용자 웹 화면 실행

fastapi-server 컨테이너
  - API 서버 실행
  - 모델 로드 및 추론 처리

model 파일
  - ONNX 모델 저장
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Docker를 사용하면 Python 버전, 라이브러리 버전, 실행 환경 차이로 생기는 문제를 줄일 수 있다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;6. 보안 요소&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제 서비스에서는 보안 설정도 필요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가장 기본적으로 CORS 설정을 통해 허용된 프론트엔드 주소에서만 API 요청을 받을 수 있도록 제한할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 Streamlit 주소만 FastAPI에 접근할 수 있도록 설정한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 다음과 같은 보안 요소도 고려할 수 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;CORS 설정&lt;/li&gt;
&lt;li&gt;HTTPS 적용&lt;/li&gt;
&lt;li&gt;API 요청 크기 제한&lt;/li&gt;
&lt;li&gt;악성 입력 필터링&lt;/li&gt;
&lt;li&gt;비정상적인 반복 요청 차단&lt;/li&gt;
&lt;li&gt;환경 변수로 API 키 관리&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특히 사용자가 입력하는 텍스트 데이터는 서버로 전달되기 때문에&lt;br /&gt;개인정보나 민감한 정보가 저장되지 않도록 주의해야 한다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;7. 멀티유저 요청 처리 방안&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제 서비스에서는 여러 사용자가 동시에 요청을 보낼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요청이 적을 때는 FastAPI가 바로 모델 추론을 처리해도 괜찮다.&lt;br /&gt;하지만 사용자가 많아지면 요청이 밀리거나 서버가 느려질 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 해결하기 위해 다음과 같은 방식을 사용할 수 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;비동기 처리&lt;/li&gt;
&lt;li&gt;요청 대기 큐 사용&lt;/li&gt;
&lt;li&gt;여러 개의 API 서버 인스턴스 실행&lt;/li&gt;
&lt;li&gt;로드밸런서 사용&lt;/li&gt;
&lt;li&gt;GPU 추론 서버 분리&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 사용자의 요청을 바로 처리하기 어렵다면&lt;br /&gt;요청을 대기 큐에 넣고 순서대로 처리할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구조는 다음과 같다.&lt;/p&gt;
&lt;pre class=&quot;properties&quot;&gt;&lt;code&gt;사용자 요청
  &amp;darr;
FastAPI 서버
  &amp;darr;
작업 큐
  &amp;darr;
모델 추론 Worker
  &amp;darr;
결과 반환
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 하면 동시에 많은 요청이 들어와도 서버가 갑자기 멈추는 문제를 줄일 수 있다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;8. 클라우드 배포 구조&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서비스를 외부에서 접속 가능하게 하려면 AWS, GCP 같은 클라우드에 배포할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 AWS를 사용한다면 다음과 같이 구성할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;properties&quot;&gt;&lt;code&gt;사용자
  &amp;darr;
AWS Load Balancer
  &amp;darr;
Streamlit 서버
  &amp;darr;
FastAPI 서버
  &amp;darr;
AI 모델 추론 서버
  &amp;darr;
CloudWatch 로그 저장
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GCP를 사용한다면 Cloud Run, Compute Engine, Vertex AI 등을 활용할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간단한 프로젝트라면 Docker 이미지를 만든 뒤&lt;br /&gt;Cloud Run이나 EC2 같은 서버에 배포하는 방식이 적합하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서비스 규모가 커지면 다음과 같은 구조를 고려할 수 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Load Balancer로 트래픽 분산&lt;/li&gt;
&lt;li&gt;컨테이너 기반 배포&lt;/li&gt;
&lt;li&gt;모델 서버 분리&lt;/li&gt;
&lt;li&gt;데이터베이스 연결&lt;/li&gt;
&lt;li&gt;로그 저장 시스템 구성&lt;/li&gt;
&lt;li&gt;자동 확장 설정&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;9. 모니터링 및 로깅 전략&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서비스 배포 후에는 정상적으로 작동하는지 계속 확인해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모니터링해야 할 항목은 다음과 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;API 응답 시간&lt;/li&gt;
&lt;li&gt;요청 성공률&lt;/li&gt;
&lt;li&gt;오류 발생률&lt;/li&gt;
&lt;li&gt;서버 CPU 사용량&lt;/li&gt;
&lt;li&gt;메모리 사용량&lt;/li&gt;
&lt;li&gt;모델 추론 시간&lt;/li&gt;
&lt;li&gt;사용자 요청 수&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;로그에는 다음과 같은 정보를 남길 수 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;요청 시간&lt;/li&gt;
&lt;li&gt;입력 데이터 길이&lt;/li&gt;
&lt;li&gt;예측 결과&lt;/li&gt;
&lt;li&gt;추론 소요 시간&lt;/li&gt;
&lt;li&gt;오류 메시지&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단, 사용자의 실제 입력 문장을 그대로 저장하면 개인정보 문제가 생길 수 있다.&lt;br /&gt;따라서 필요한 경우 입력 원문은 저장하지 않고, 길이나 통계 정보만 저장하는 것이 좋다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;10. 전체 아키텍처 정리&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AI 영화 리뷰 감성 분석 서비스의 전체 아키텍처는 다음과 같이 정리할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;cs&quot;&gt;&lt;code&gt;[사용자]
   &amp;darr;
[Streamlit 프론트엔드]
   &amp;darr;
[FastAPI 백엔드 API]
   &amp;darr;
[전처리 로직]
   &amp;darr;
[ONNX/TensorRT 모델 추론]
   &amp;darr;
[후처리 로직]
   &amp;darr;
[JSON 결과 반환]
   &amp;darr;
[Streamlit 결과 화면 출력]
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배포 환경에서는 각 기능을 Docker 컨테이너로 분리하고,&lt;br /&gt;클라우드 서버에서 실행할 수 있다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;정리&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AI 웹/앱 서비스를 구현할 때는 단순히 모델만 만드는 것이 아니라&lt;br /&gt;사용자 화면, API 서버, 모델 추론, 배포, 보안, 모니터링까지 함께 고려해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 예시에서는 AI 영화 리뷰 감성 분석 서비스를 기준으로 전체 구조를 설계했다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Streamlit은 사용자 화면을 담당한다.&lt;/li&gt;
&lt;li&gt;FastAPI는 API 요청과 응답을 처리한다.&lt;/li&gt;
&lt;li&gt;ONNX 또는 TensorRT는 모델 추론 속도를 최적화한다.&lt;/li&gt;
&lt;li&gt;Docker는 실행 환경을 컨테이너로 묶어 배포를 쉽게 만든다.&lt;/li&gt;
&lt;li&gt;CORS, HTTPS, 요청 제한 등을 통해 보안을 강화한다.&lt;/li&gt;
&lt;li&gt;비동기 처리와 대기 큐를 통해 여러 사용자 요청을 안정적으로 처리한다.&lt;/li&gt;
&lt;li&gt;AWS 또는 GCP를 활용해 클라우드 환경에 배포할 수 있다.&lt;/li&gt;
&lt;li&gt;로그와 모니터링을 통해 서비스 상태를 지속적으로 확인한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국 AI 서비스 아키텍처는 모델 성능뿐만 아니라&lt;br /&gt;사용자가 안정적으로 서비스를 이용할 수 있는 전체 시스템 구조를 설계하는 과정이라고 볼 수 있다.&lt;/p&gt;</description>
      <category>AI &amp;amp; Python Lab/Concept Notes</category>
      <author>코딩은 내 여친</author>
      <guid isPermaLink="true">https://dudghks2814.tistory.com/73</guid>
      <comments>https://dudghks2814.tistory.com/73#entry73comment</comments>
      <pubDate>Mon, 29 Jun 2026 02:51:53 +0900</pubDate>
    </item>
    <item>
      <title>FastAPI를 활용한 AI 모델 웹 API 서버 코드 구조</title>
      <link>https://dudghks2814.tistory.com/72</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;AI 모델을 실제 서비스에서 사용하려면 단순히 모델을 실행하는 코드만 작성하는 것이 아니라,&lt;br /&gt;사용자 요청을 받고 모델 추론 결과를 응답하는 API 서버 구조를 만들어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;FastAPI는 Python 기반의 웹 프레임워크로, AI 모델을 API 형태로 제공할 때 많이 사용된다.&lt;br /&gt;특히 기능별로 코드를 나누면 유지보수와 확장이 쉬워진다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. 전체 폴더 구조 예시&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;FastAPI를 활용한 AI 모델 API 서버는 다음과 같이 구성할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;stylus&quot;&gt;&lt;code&gt;project/
│
├── app/
│   ├── main.py
│   ├── api/
│   │   └── predict.py
│   ├── core/
│   │   └── config.py
│   ├── models/
│   │   └── model_loader.py
│   ├── schemas/
│   │   └── request_response.py
│   └── services/
│       └── predict_service.py
│
├── model/
│   └── sentiment_model.onnx
│
├── requirements.txt
└── README.md
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 기능별로 파일을 분리하면 코드가 길어져도 구조를 이해하기 쉽다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. main.py&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;main.py는 FastAPI 서버가 시작되는 중심 파일이다.&lt;br /&gt;FastAPI 앱을 생성하고, API 라우터를 연결하는 역할을 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 /predict 같은 예측 API를 등록하고, 서버가 실행될 수 있도록 구성한다.&lt;/p&gt;
&lt;pre class=&quot;reasonml&quot;&gt;&lt;code&gt;from fastapi import FastAPI
from app.api.predict import router as predict_router

app = FastAPI(title=&quot;AI Model API&quot;)

app.include_router(predict_router)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. api 폴더&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;api 폴더는 실제 API 주소를 정의하는 부분이다.&lt;br /&gt;예를 들어 사용자가 /predict 주소로 요청을 보내면 어떤 함수가 실행될지 정한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 파일에서는 요청을 받고, 서비스 로직을 호출한 뒤 결과를 반환한다.&lt;/p&gt;
&lt;pre class=&quot;nimrod&quot;&gt;&lt;code&gt;from fastapi import APIRouter
from app.schemas.request_response import PredictRequest, PredictResponse
from app.services.predict_service import predict_text

router = APIRouter()

@router.post(&quot;/predict&quot;, response_model=PredictResponse)
def predict(request: PredictRequest):
    result = predict_text(request.text)
    return PredictResponse(result=result)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4. schemas 폴더&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;schemas 폴더는 요청과 응답 데이터의 형태를 정의하는 부분이다.&lt;br /&gt;FastAPI에서는 Pydantic을 사용해 데이터 구조를 명확하게 만들 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 사용자가 입력해야 하는 값과 서버가 반환할 값을 미리 정해둘 수 있다.&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;from pydantic import BaseModel

class PredictRequest(BaseModel):
    text: str

class PredictResponse(BaseModel):
    result: str
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 작성하면 잘못된 형식의 요청이 들어왔을 때 오류를 쉽게 확인할 수 있다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;5. models 폴더&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;models 폴더는 학습된 AI 모델을 불러오는 역할을 한다.&lt;br /&gt;PyTorch, TensorFlow, ONNX 등 어떤 모델을 사용하는지에 따라 로드 방식이 달라질 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모델은 요청이 들어올 때마다 새로 불러오면 비효율적이다.&lt;br /&gt;따라서 서버가 시작될 때 한 번만 로드하고, 계속 재사용하는 방식이 좋다.&lt;/p&gt;
&lt;pre class=&quot;python&quot;&gt;&lt;code&gt;import onnxruntime as ort

def load_model():
    session = ort.InferenceSession(&quot;model/sentiment_model.onnx&quot;)
    return session
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;6. services 폴더&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;services 폴더는 실제 비즈니스 로직이나 모델 추론 로직을 처리하는 부분이다.&lt;br /&gt;입력 데이터를 전처리하고, 모델에 넣어 예측한 뒤, 결과를 후처리한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;API 파일에는 요청과 응답 처리만 두고,&lt;br /&gt;실제 예측 로직은 service 파일로 분리하는 것이 좋다.&lt;/p&gt;
&lt;pre class=&quot;python&quot;&gt;&lt;code&gt;from app.models.model_loader import load_model

model = load_model()

def predict_text(text: str):
    # 1. 입력 데이터 전처리
    # 2. 모델 추론
    # 3. 결과 후처리

    result = &quot;긍정&quot;
    return result
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;7. core 폴더&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;core 폴더는 설정값을 관리하는 부분이다.&lt;br /&gt;예를 들어 모델 경로, 서버 환경, API 설정값 등을 따로 관리할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;ini&quot;&gt;&lt;code&gt;MODEL_PATH = &quot;model/sentiment_model.onnx&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설정값을 한 곳에서 관리하면 나중에 모델 파일 위치나 서버 환경이 바뀌어도 수정하기 쉽다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;8. 전체 흐름&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;FastAPI 기반 AI 모델 API 서버의 전체 흐름은 다음과 같다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;사용자가 /predict API로 데이터를 보낸다.&lt;/li&gt;
&lt;li&gt;API 라우터가 요청 데이터를 받는다.&lt;/li&gt;
&lt;li&gt;schema를 통해 입력 데이터 형식을 확인한다.&lt;/li&gt;
&lt;li&gt;service에서 입력 데이터를 전처리한다.&lt;/li&gt;
&lt;li&gt;model_loader에서 불러온 모델로 추론한다.&lt;/li&gt;
&lt;li&gt;예측 결과를 후처리한다.&lt;/li&gt;
&lt;li&gt;사용자에게 JSON 형태로 결과를 반환한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;정리&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;FastAPI로 AI 모델을 통합한 웹 API를 구현할 때는 기능별로 코드를 나누는 것이 좋다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;main.py: FastAPI 앱 생성 및 라우터 등록&lt;/li&gt;
&lt;li&gt;api: API 주소와 요청 처리&lt;/li&gt;
&lt;li&gt;schemas: 요청과 응답 데이터 구조 정의&lt;/li&gt;
&lt;li&gt;models: AI 모델 로드&lt;/li&gt;
&lt;li&gt;services: 전처리, 추론, 후처리 로직 처리&lt;/li&gt;
&lt;li&gt;core: 설정값 관리&lt;/li&gt;
&lt;li&gt;model: 학습된 모델 파일 저장&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국 좋은 API 서버 구조는 단순히 코드가 실행되는 것에서 끝나는 것이 아니라,&lt;br /&gt;기능별 역할을 명확히 나누어 유지보수와 확장이 쉬운 형태로 만드는 것이다.&lt;/p&gt;</description>
      <category>AI &amp;amp; Python Lab/Concept Notes</category>
      <author>코딩은 내 여친</author>
      <guid isPermaLink="true">https://dudghks2814.tistory.com/72</guid>
      <comments>https://dudghks2814.tistory.com/72#entry72comment</comments>
      <pubDate>Mon, 29 Jun 2026 02:50:09 +0900</pubDate>
    </item>
    <item>
      <title>Streamlit을 사용해 AI 모델을 웹 애플리케이션에 통합하는 과정</title>
      <link>https://dudghks2814.tistory.com/71</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;AI 모델을 실제 사용자가 사용할 수 있게 하려면 웹 애플리케이션 형태로 만드는 과정이 필요하다.&lt;br /&gt;Streamlit은 Python 코드만으로 간단하게 웹 화면을 만들 수 있어 AI 모델 실습이나 프로토타입 제작에 많이 사용된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Streamlit에서 AI 모델을 웹 애플리케이션에 통합할 때는 보통 다음 세 가지 단계를 거친다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;모델 로드&lt;/li&gt;
&lt;li&gt;사용자 입력&lt;/li&gt;
&lt;li&gt;결과 출력&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. 모델 로드 단계&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모델 로드는 학습이 완료된 AI 모델을 웹 애플리케이션에서 사용할 수 있도록 불러오는 단계이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 PyTorch 모델이라면 .pth 파일을 불러오고,&lt;br /&gt;ONNX 모델이라면 .onnx 파일을 불러와 추론할 수 있는 상태로 준비한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 단계에서는 모델을 한 번만 불러오도록 처리하는 것이 중요하다.&lt;br /&gt;사용자가 입력할 때마다 모델을 다시 불러오면 속도가 느려지고 자원이 낭비될 수 있기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Streamlit에서는 st.cache_resource 같은 기능을 사용해 모델을 캐싱할 수 있다.&lt;br /&gt;이렇게 하면 앱이 실행되는 동안 모델을 효율적으로 재사용할 수 있다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. 사용자 입력 단계&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용자 입력 단계는 사용자가 웹 화면에서 데이터를 입력하는 부분이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AI 모델의 종류에 따라 입력 방식은 달라질 수 있다.&lt;br /&gt;이미지 분류 모델이라면 이미지 업로드 기능을 사용할 수 있고,&lt;br /&gt;텍스트 감성 분석 모델이라면 문장을 입력하는 텍스트 박스를 사용할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Streamlit에서는 다음과 같은 입력 기능을 사용할 수 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;st.file_uploader: 이미지나 파일 업로드&lt;/li&gt;
&lt;li&gt;st.text_input: 짧은 텍스트 입력&lt;/li&gt;
&lt;li&gt;st.text_area: 긴 문장 입력&lt;/li&gt;
&lt;li&gt;st.slider: 숫자 값 선택&lt;/li&gt;
&lt;li&gt;st.button: 버튼 클릭&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용자가 입력한 데이터는 모델이 이해할 수 있는 형태로 전처리해야 한다.&lt;br /&gt;예를 들어 이미지는 크기 조정과 정규화를 하고, 텍스트는 토큰화나 인코딩 과정을 거칠 수 있다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. 결과 출력 단계&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과 출력 단계는 모델이 예측한 결과를 사용자에게 보여주는 단계이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모델은 보통 숫자나 확률값 형태로 결과를 반환한다.&lt;br /&gt;하지만 사용자가 이해하기 쉽게 클래스 이름, 예측 결과, 확률 등으로 변환해서 보여줘야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 숫자 이미지 분류 모델이라면&lt;br /&gt;&amp;ldquo;예측 결과: 7&amp;rdquo;처럼 보여줄 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;감성 분석 모델이라면&lt;br /&gt;&amp;ldquo;예측 결과: 긍정&amp;rdquo; 또는 &amp;ldquo;예측 결과: 부정&amp;rdquo;처럼 출력할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Streamlit에서는 st.write, st.success, st.image, st.metric 등을 사용해 결과를 보기 좋게 표시할 수 있다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4. 전체 흐름&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Streamlit에서 AI 모델을 웹 애플리케이션에 통합하는 전체 흐름은 다음과 같다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;학습된 모델 파일을 불러온다.&lt;/li&gt;
&lt;li&gt;사용자가 웹 화면에서 데이터를 입력한다.&lt;/li&gt;
&lt;li&gt;입력 데이터를 모델에 맞게 전처리한다.&lt;/li&gt;
&lt;li&gt;모델이 예측을 수행한다.&lt;/li&gt;
&lt;li&gt;예측 결과를 사용자가 이해하기 쉽게 출력한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 단순히 모델만 불러오는 것이 아니라&lt;br /&gt;사용자 입력부터 전처리, 추론, 결과 출력까지 하나의 흐름으로 연결해야 한다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;정리&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Streamlit을 사용해 AI 모델을 웹 애플리케이션에 통합할 때는 다음 단계를 거친다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;모델 로드: 학습된 모델을 불러와 추론할 수 있는 상태로 준비한다.&lt;/li&gt;
&lt;li&gt;사용자 입력: 이미지, 텍스트, 숫자 등 사용자의 데이터를 입력받는다.&lt;/li&gt;
&lt;li&gt;전처리: 입력 데이터를 모델이 사용할 수 있는 형태로 변환한다.&lt;/li&gt;
&lt;li&gt;결과 출력: 모델의 예측 결과를 사용자가 이해하기 쉽게 보여준다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국 Streamlit은 AI 모델을 단순한 코드 실행 결과가 아니라,&lt;br /&gt;사용자가 직접 입력하고 결과를 확인할 수 있는 웹 애플리케이션 형태로 만드는 데 도움을 주는 도구이다.&lt;/p&gt;</description>
      <category>AI &amp;amp; Python Lab/Concept Notes</category>
      <author>코딩은 내 여친</author>
      <guid isPermaLink="true">https://dudghks2814.tistory.com/71</guid>
      <comments>https://dudghks2814.tistory.com/71#entry71comment</comments>
      <pubDate>Mon, 29 Jun 2026 02:48:47 +0900</pubDate>
    </item>
    <item>
      <title>양자화나 모델 경량화 후 필요한 테스트와 확인 절차</title>
      <link>https://dudghks2814.tistory.com/70</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;딥러닝 모델을 실제 서비스에 적용할 때는 모델을 더 빠르고 가볍게 만들기 위해 양자화나 모델 경량화를 진행한다.&lt;br /&gt;하지만 모델을 줄였다고 해서 바로 서비스에 적용하면 안 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모델 크기와 속도는 좋아졌지만, 정확도나 안정성이 떨어질 수 있기 때문이다.&lt;br /&gt;따라서 경량화 후에는 반드시 여러 가지 테스트와 확인 절차가 필요하다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. 기존 모델과 성능 비교하기&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가장 먼저 해야 할 일은 경량화 전 모델과 경량화 후 모델의 성능을 비교하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 이미지 분류 모델이라면 정확도, F1-score, 오차율 등을 비교할 수 있다.&lt;br /&gt;감성 분석 모델이라면 Accuracy, Precision, Recall, F1-score 같은 지표를 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;중요한 것은 단순히 모델이 실행되는지 확인하는 것이 아니라,&lt;br /&gt;기존 모델과 비교했을 때 성능이 얼마나 유지되는지 확인하는 것이다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. 실제 데이터와 비슷한 데이터로 테스트하기&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테스트 데이터는 실제 서비스에서 들어올 데이터와 비슷해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;학습 데이터나 정리된 테스트 데이터에서는 성능이 좋아 보여도,&lt;br /&gt;실제 사용자가 입력하는 데이터에서는 성능이 떨어질 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 이미지 모델이라면 어두운 사진, 흔들린 사진, 배경이 복잡한 사진도 확인해야 한다.&lt;br /&gt;텍스트 모델이라면 오타, 짧은 문장, 긴 문장, 은어 등이 포함된 데이터도 테스트해야 한다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. 추론 속도 확인하기&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;경량화의 목적 중 하나는 추론 속도를 높이는 것이다.&lt;br /&gt;따라서 실제 서비스 환경에서 응답 시간이 얼마나 줄었는지 확인해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단순히 개발 환경에서 빠른 것만 확인하면 부족하다.&lt;br /&gt;서버, GPU, CPU, 모바일 기기 등 실제 배포 환경에서 테스트하는 것이 중요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;확인할 수 있는 항목은 다음과 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;한 번 예측하는 데 걸리는 시간&lt;/li&gt;
&lt;li&gt;동시에 여러 요청이 들어왔을 때의 처리 속도&lt;/li&gt;
&lt;li&gt;평균 응답 시간&lt;/li&gt;
&lt;li&gt;가장 느린 응답 시간&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4. 메모리와 자원 사용량 확인하기&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모델 경량화 후에는 메모리 사용량과 CPU, GPU 사용량도 확인해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모델 크기는 줄었지만 실행 중 메모리 사용량이 크게 줄지 않을 수도 있다.&lt;br /&gt;또는 특정 환경에서는 오히려 변환된 모델이 비효율적으로 실행될 수도 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 실제 서비스 환경에서 모델이 안정적으로 실행되는지 확인해야 한다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;5. 예측 결과가 크게 달라지는 경우 확인하기&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;경량화 전 모델과 후 모델이 같은 입력에 대해 비슷한 결과를 내는지도 확인해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 기존 모델은 &amp;ldquo;긍정&amp;rdquo;으로 예측했는데,&lt;br /&gt;경량화 후 모델은 같은 문장을 &amp;ldquo;부정&amp;rdquo;으로 예측한다면 문제가 될 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특히 신뢰도가 낮은 예측이나 애매한 입력에서 결과가 크게 바뀌는지 확인해야 한다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;6. 예외 상황 테스트하기&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제 서비스에서는 항상 정상적인 입력만 들어오지 않는다.&lt;br /&gt;잘못된 형식의 파일, 너무 큰 이미지, 빈 문장, 특수문자만 있는 입력 등이 들어올 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 예외 상황에서도 모델이나 서비스가 멈추지 않는지 확인해야 한다.&lt;br /&gt;오류가 발생하더라도 사용자에게 적절한 안내가 제공되어야 한다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;7. 실제 서비스 환경에서 모니터링하기&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테스트를 통과했더라도 실제 서비스에 배포한 뒤에는 계속 모니터링해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서비스 환경에서는 예상하지 못한 데이터가 들어올 수 있고,&lt;br /&gt;시간이 지나면서 사용자 입력 패턴이 달라질 수도 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 배포 후에도 정확도, 응답 시간, 오류율, 서버 자원 사용량 등을 지속적으로 확인하는 것이 좋다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;정리&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;양자화나 모델 경량화 후에는 다음과 같은 확인 절차가 필요하다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;기존 모델과 정확도 비교하기&lt;/li&gt;
&lt;li&gt;실제 서비스 데이터와 비슷한 데이터로 테스트하기&lt;/li&gt;
&lt;li&gt;추론 속도 확인하기&lt;/li&gt;
&lt;li&gt;메모리와 CPU, GPU 사용량 확인하기&lt;/li&gt;
&lt;li&gt;경량화 전후의 예측 결과 비교하기&lt;/li&gt;
&lt;li&gt;비정상 입력에 대한 예외 상황 테스트하기&lt;/li&gt;
&lt;li&gt;배포 후 지속적으로 모니터링하기&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국 모델 경량화는 단순히 모델을 작고 빠르게 만드는 작업이 아니다.&lt;br /&gt;실제 서비스에서 정확도와 안정성을 유지하면서 사용할 수 있는지 확인하는 과정까지 함께 진행되어야 한다.&lt;/p&gt;</description>
      <category>AI &amp;amp; Python Lab/Concept Notes</category>
      <author>코딩은 내 여친</author>
      <guid isPermaLink="true">https://dudghks2814.tistory.com/70</guid>
      <comments>https://dudghks2814.tistory.com/70#entry70comment</comments>
      <pubDate>Mon, 29 Jun 2026 02:45:04 +0900</pubDate>
    </item>
    <item>
      <title>양자화 기법인 Post-Training Quantization과 Quantization-Aware Training의 차이</title>
      <link>https://dudghks2814.tistory.com/69</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;딥러닝 모델을 실제 서비스에 배포할 때는 모델의 크기와 추론 속도가 중요하다.&lt;br /&gt;이때 사용하는 대표적인 최적화 기법 중 하나가 &lt;b&gt;양자화(Quantization)&lt;/b&gt; 이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;양자화는 모델의 가중치나 연산에 사용되는 숫자의 정밀도를 낮추는 방법이다.&lt;br /&gt;예를 들어 FP32 형식의 값을 INT8처럼 더 가벼운 형식으로 바꾸면 모델 크기와 연산량을 줄일 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;양자화 방식에는 대표적으로 &lt;b&gt;Post-Training Quantization(PTQ)&lt;/b&gt; 과 &lt;b&gt;Quantization-Aware Training(QAT)&lt;/b&gt; 이 있다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. Post-Training Quantization이란?&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Post-Training Quantization은 말 그대로 &lt;b&gt;학습이 끝난 모델을 나중에 양자화하는 방식&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이미 학습이 완료된 모델을 가져와서 추가 학습 없이 가중치나 연산 정밀도를 낮춘다.&lt;br /&gt;따라서 적용 과정이 비교적 간단하고 빠르다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PTQ는 모델을 빠르게 경량화하고 싶을 때 많이 사용된다.&lt;br /&gt;하지만 모델에 따라 양자화 후 정확도가 떨어질 수 있다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. Quantization-Aware Training이란?&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Quantization-Aware Training은 &lt;b&gt;학습 과정에서 양자화가 적용될 상황을 미리 반영하는 방식&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모델을 학습할 때부터 낮은 정밀도로 계산되는 상황을 가정한다.&lt;br /&gt;그래서 실제 양자화 후에도 정확도 손실이 적도록 모델이 적응하게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;QAT는 PTQ보다 과정이 복잡하고 시간이 더 걸린다.&lt;br /&gt;하지만 정확도를 더 잘 유지할 수 있다는 장점이 있다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. 두 방식의 차이&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PTQ와 QAT의 가장 큰 차이는 &lt;b&gt;양자화를 언제 반영하느냐&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PTQ는 학습이 끝난 뒤에 양자화를 적용한다.&lt;br /&gt;반면 QAT는 학습 과정에서부터 양자화를 고려한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, PTQ는 빠르고 간단하지만 정확도 손실이 생길 수 있고,&lt;br /&gt;QAT는 시간이 더 걸리지만 정확도 유지에 더 유리하다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4. 언제 어떤 방식을 사용할까?&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;빠르게 모델을 배포하거나 정확도 손실이 크지 않은 경우에는 PTQ를 사용할 수 있다.&lt;br /&gt;반대로 정확도가 중요한 서비스이거나 PTQ 적용 후 성능 저하가 크다면 QAT를 고려하는 것이 좋다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 간단한 이미지 분류 모델은 PTQ만으로도 충분할 수 있다.&lt;br /&gt;하지만 자율주행, 의료 이미지 분석, 보안 시스템처럼 정확도가 중요한 분야에서는 QAT가 더 적합할 수 있다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;정리&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Post-Training Quantization과 Quantization-Aware Training의 차이는 다음과 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;PTQ는 학습이 끝난 모델을 나중에 양자화하는 방식이다.&lt;/li&gt;
&lt;li&gt;QAT는 학습 과정에서 양자화를 미리 고려하는 방식이다.&lt;/li&gt;
&lt;li&gt;PTQ는 적용이 빠르고 간단하다.&lt;/li&gt;
&lt;li&gt;QAT는 시간이 더 걸리지만 정확도 유지에 유리하다.&lt;/li&gt;
&lt;li&gt;정확도 손실이 작으면 PTQ, 정확도가 중요하면 QAT를 고려할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국 PTQ와 QAT는 모두 모델을 가볍고 빠르게 만들기 위한 양자화 기법이다.&lt;br /&gt;다만 PTQ는 간단한 배포 최적화에 적합하고, QAT는 정확도까지 안정적으로 유지해야 하는 상황에 더 적합하다.&lt;/p&gt;</description>
      <category>AI &amp;amp; Python Lab/Concept Notes</category>
      <author>코딩은 내 여친</author>
      <guid isPermaLink="true">https://dudghks2814.tistory.com/69</guid>
      <comments>https://dudghks2814.tistory.com/69#entry69comment</comments>
      <pubDate>Mon, 29 Jun 2026 02:43:38 +0900</pubDate>
    </item>
    <item>
      <title>딥러닝 모델을 ONNX, TensorRT 등의 포맷으로 변환해야 하는 이유</title>
      <link>https://dudghks2814.tistory.com/68</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;딥러닝 모델을 학습할 때는 보통 PyTorch, TensorFlow 같은 프레임워크를 사용한다.&lt;br /&gt;하지만 실제 서비스에 모델을 적용할 때는 학습한 그대로 사용하는 것보다 ONNX, TensorRT 같은 포맷으로 변환하는 경우가 많다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 이유는 &lt;b&gt;모델을 더 빠르고 가볍게 실행하기 위해서&lt;/b&gt;이다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. 다양한 환경에서 모델을 실행하기 위해&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PyTorch로 학습한 모델은 기본적으로 PyTorch 환경이 있어야 실행할 수 있다.&lt;br /&gt;하지만 실제 서비스에서는 서버, 웹, 모바일, 임베디드 기기 등 다양한 환경에서 모델을 실행해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ONNX는 서로 다른 딥러닝 프레임워크 사이에서 모델을 호환할 수 있게 해주는 중간 포맷이다.&lt;br /&gt;즉, PyTorch에서 만든 모델을 ONNX로 변환하면 다른 실행 환경에서도 비교적 쉽게 사용할 수 있다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. 추론 속도를 높이기 위해&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모델을 서비스에 적용할 때 중요한 것은 학습이 아니라 &lt;b&gt;추론 속도&lt;/b&gt;이다.&lt;br /&gt;사용자가 이미지를 업로드하거나 문장을 입력했을 때 결과가 빠르게 나와야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TensorRT는 NVIDIA GPU에서 모델이 더 빠르게 실행되도록 최적화해주는 도구이다.&lt;br /&gt;불필요한 연산을 줄이고, GPU에 맞게 계산 과정을 최적화하여 추론 속도를 높일 수 있다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. 모델 용량과 연산 비용을 줄이기 위해&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;딥러닝 모델은 크기가 크고 연산량이 많을 수 있다.&lt;br /&gt;이 경우 서버 비용이 증가하거나, 모바일&amp;middot;엣지 디바이스에서 실행하기 어려울 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ONNX나 TensorRT로 변환하는 과정에서 모델 구조를 최적화하거나 정밀도를 낮추는 방식으로 용량과 연산량을 줄일 수 있다.&lt;br /&gt;예를 들어 FP32를 FP16이나 INT8로 바꾸면 더 적은 자원으로 모델을 실행할 수 있다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4. 실제 서비스 배포에 적합하게 만들기 위해&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;연구나 실습 단계에서는 모델이 정확히 동작하는 것이 중요하다.&lt;br /&gt;하지만 실제 서비스에서는 속도, 비용, 안정성, 호환성도 중요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모델 포맷 변환은 학습한 모델을 실서비스 환경에 맞게 준비하는 과정이다.&lt;br /&gt;즉, 단순히 모델을 만드는 것에서 끝나는 것이 아니라, 실제 사용자가 빠르고 안정적으로 사용할 수 있도록 배포하기 위한 단계라고 볼 수 있다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;정리&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;딥러닝 모델을 ONNX, TensorRT 등의 포맷으로 변환하는 이유는 다음과 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;다양한 환경에서 실행하기 위해&lt;/li&gt;
&lt;li&gt;추론 속도를 높이기 위해&lt;/li&gt;
&lt;li&gt;모델 용량과 연산 비용을 줄이기 위해&lt;/li&gt;
&lt;li&gt;실제 서비스 배포에 적합하게 만들기 위해&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국 모델 변환은 딥러닝 모델을 단순한 실험 결과가 아니라, 실제 서비스에서 사용할 수 있는 형태로 만드는 중요한 과정이다.&lt;/p&gt;</description>
      <category>AI &amp;amp; Python Lab/Concept Notes</category>
      <author>코딩은 내 여친</author>
      <guid isPermaLink="true">https://dudghks2814.tistory.com/68</guid>
      <comments>https://dudghks2814.tistory.com/68#entry68comment</comments>
      <pubDate>Mon, 29 Jun 2026 02:43:00 +0900</pubDate>
    </item>
    <item>
      <title>Docker 이미지와 컨테이너, Docker Compose, Kubernetes 개념 정리</title>
      <link>https://dudghks2814.tistory.com/67</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;Docker를 공부하다 보면 가장 먼저 헷갈리는 개념이 있습니다. 바로 &lt;b&gt;이미지(Image)&lt;/b&gt;와 &lt;b&gt;컨테이너(Container)&lt;/b&gt;입니다. 여기에 조금 더 나아가면 &lt;b&gt;Docker Compose&lt;/b&gt;와 &lt;b&gt;Kubernetes&lt;/b&gt;라는 개념도 등장합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음에는 모두 비슷해 보이지만, 실제 역할은 서로 다릅니다. 이번 글에서는 Docker 이미지와 컨테이너의 차이, Docker Compose가 유용한 상황, 그리고 Kubernetes가 Docker와 어떤 관계를 가지는지 정리해보겠습니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. Docker 이미지와 컨테이너의 차이&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Docker 이미지는 애플리케이션을 실행하기 위해 필요한 파일, 라이브러리, 실행 환경, 설정 등을 하나로 묶어 놓은 &lt;b&gt;실행 템플릿&lt;/b&gt;입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반면 Docker 컨테이너는 이 이미지를 바탕으로 실제 실행된 &lt;b&gt;프로세스 환경&lt;/b&gt;입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쉽게 비유하면 다음과 같습니다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;구분&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;비유&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;설명&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;이미지&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;설계도 또는 실행 파일&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;컨테이너를 만들기 위한 읽기 전용 템플릿&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;컨테이너&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;실제 실행 중인 프로그램&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;이미지를 기반으로 실행된 독립적인 환경&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 nginx 이미지는 Nginx 서버를 실행하기 위한 파일과 설정을 포함하고 있습니다. 이 이미지를 docker run 명령어로 실행하면 실제 Nginx 서버가 동작하는 컨테이너가 만들어집니다.&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;docker pull nginx
docker run -d -p 8080:80 nginx
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 명령어에서 nginx는 이미지이고, docker run을 통해 실행된 결과물이 컨테이너입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이미지는 직접 실행되는 것이 아니라, 컨테이너를 만들기 위한 기반입니다. 하나의 이미지로 여러 개의 컨테이너를 만들 수도 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 같은 nginx 이미지로 3개의 컨테이너를 실행하면, 모두 같은 기본 환경을 가지지만 각각 독립적으로 동작합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;이미지와 컨테이너의 핵심 차이&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이미지는 정적인 파일 묶음이고, 컨테이너는 동적으로 실행 중인 환경입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이미지는 읽기 전용에 가깝고, 컨테이너는 실행 중에 로그, 임시 파일, 프로세스 상태 같은 변경 사항을 가질 수 있습니다. 다만 컨테이너 내부의 변경 사항은 기본적으로 컨테이너가 삭제되면 함께 사라질 수 있기 때문에, 데이터를 유지하려면 볼륨을 사용해야 합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;docker-image.png&quot; data-origin-width=&quot;1695&quot; data-origin-height=&quot;969&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/9E6GE/dJMcaglwNdW/E7bFgzFk7lhdhVLVYtpPnK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/9E6GE/dJMcaglwNdW/E7bFgzFk7lhdhVLVYtpPnK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/9E6GE/dJMcaglwNdW/E7bFgzFk7lhdhVLVYtpPnK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F9E6GE%2FdJMcaglwNdW%2FE7bFgzFk7lhdhVLVYtpPnK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1695&quot; height=&quot;969&quot; data-filename=&quot;docker-image.png&quot; data-origin-width=&quot;1695&quot; data-origin-height=&quot;969&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. Docker Compose는 어떤 상황에서 유용할까?&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Docker Compose는 여러 개의 컨테이너로 구성된 애플리케이션을 쉽게 정의하고 실행할 수 있게 해주는 도구입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일반적으로 실제 서비스는 컨테이너 하나만으로 구성되지 않습니다. 예를 들어 웹 애플리케이션을 만든다고 하면 다음과 같은 구성 요소가 필요할 수 있습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;웹 서버&lt;/li&gt;
&lt;li&gt;백엔드 API 서버&lt;/li&gt;
&lt;li&gt;데이터베이스&lt;/li&gt;
&lt;li&gt;Redis 같은 캐시 서버&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 구성 요소를 각각 docker run 명령어로 실행할 수도 있지만, 컨테이너가 많아질수록 명령어가 길어지고 관리가 어려워집니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 Docker Compose를 사용하면 여러 컨테이너의 실행 설정을 compose.yaml 파일 하나에 정리할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 다음과 같은 구성을 생각해볼 수 있습니다.&lt;/p&gt;
&lt;pre class=&quot;less&quot;&gt;&lt;code&gt;services:
  app:
    build: .
    ports:
      - &quot;8000:8000&quot;
    depends_on:
      - db

  db:
    image: mysql:8.3.0
    environment:
      MYSQL_ROOT_PASSWORD: pw_root
      MYSQL_DATABASE: app_db
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 작성한 뒤 아래 명령어 하나로 여러 컨테이너를 한 번에 실행할 수 있습니다.&lt;/p&gt;
&lt;pre class=&quot;ebnf&quot;&gt;&lt;code&gt;docker compose up -d
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;종료할 때도 다음 명령어 하나면 됩니다.&lt;/p&gt;
&lt;pre class=&quot;ebnf&quot;&gt;&lt;code&gt;docker compose down
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Docker Compose가 유용한 상황&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Docker Compose는 특히 다음과 같은 상황에서 유용합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫째, 여러 컨테이너를 함께 실행해야 할 때 유용합니다. 예를 들어 FastAPI 서버와 MySQL 데이터베이스를 함께 실행해야 한다면 Compose 파일에 두 서비스를 함께 정의할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;둘째, 개발 환경을 팀원들과 동일하게 맞추고 싶을 때 유용합니다. compose.yaml 파일을 프로젝트에 포함하면, 다른 팀원도 같은 설정으로 컨테이너를 실행할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;셋째, 컨테이너 실행 명령어를 반복해서 입력하지 않아도 됩니다. 포트, 볼륨, 환경 변수, 네트워크 설정 등을 파일에 정리해두면 명령어가 훨씬 단순해집니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. Dockerfile과 Docker Compose의 차이&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Dockerfile과 Docker Compose는 둘 다 Docker에서 자주 사용되지만, 목적이 다릅니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Dockerfile은 &lt;b&gt;이미지를 만드는 파일&lt;/b&gt;입니다. 즉, 애플리케이션을 어떤 환경에서 실행할지 정의합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 Python 애플리케이션 이미지를 만들기 위한 Dockerfile은 다음과 같이 작성할 수 있습니다.&lt;/p&gt;
&lt;pre class=&quot;dockerfile&quot;&gt;&lt;code&gt;FROM python:3.11

WORKDIR /app

COPY requirements.txt .
RUN pip install -r requirements.txt

COPY . .

CMD [&quot;python&quot;, &quot;app.py&quot;]
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 Dockerfile은 Python 환경을 준비하고, 필요한 패키지를 설치한 뒤, 애플리케이션을 실행하는 이미지를 만들기 위한 파일입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반면 Docker Compose는 &lt;b&gt;여러 컨테이너를 어떻게 실행할지 정의하는 파일&lt;/b&gt;입니다. 이미지를 직접 만들 수도 있고, 이미 만들어진 이미지를 가져와서 실행할 수도 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정리하면 다음과 같습니다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;구분&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;Dockerfile&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;Docker Compose&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;목적&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;Docker 이미지 생성&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;여러 컨테이너 실행 및 관리&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;파일명&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;Dockerfile&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;compose.yaml 또는 docker-compose.yml&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;주요 역할&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;실행 환경 정의&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;서비스, 네트워크, 볼륨, 환경 변수 관리&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;사용 명령어&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;docker build&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;docker compose up&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;예시&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;Python 앱 이미지 만들기&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;Python 앱 + MySQL 함께 실행하기&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, Dockerfile은 &amp;ldquo;이미지를 어떻게 만들 것인가?&amp;rdquo;에 대한 답이고, Docker Compose는 &amp;ldquo;여러 컨테이너를 어떻게 함께 실행할 것인가?&amp;rdquo;에 대한 답입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;5wZxCykteNzAfJNuGXEEf8.png&quot; data-origin-width=&quot;918&quot; data-origin-height=&quot;362&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ckYTxy/dJMcagsjobY/lc21FB1un0XqVbaBSHrUGK/img.webp&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ckYTxy/dJMcagsjobY/lc21FB1un0XqVbaBSHrUGK/img.webp&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ckYTxy/dJMcagsjobY/lc21FB1un0XqVbaBSHrUGK/img.webp&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FckYTxy%2FdJMcagsjobY%2Flc21FB1un0XqVbaBSHrUGK%2Fimg.webp&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;918&quot; height=&quot;362&quot; data-filename=&quot;5wZxCykteNzAfJNuGXEEf8.png&quot; data-origin-width=&quot;918&quot; data-origin-height=&quot;362&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4. Kubernetes의 기본 개념&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Kubernetes는 컨테이너화된 애플리케이션을 자동으로 배포, 확장, 관리하기 위한 &lt;b&gt;컨테이너 오케스트레이션 플랫폼&lt;/b&gt;입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Docker가 컨테이너를 만들고 실행하는 데 초점이 있다면, Kubernetes는 여러 서버에 걸쳐 수많은 컨테이너를 안정적으로 운영하는 데 초점이 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 서비스 사용자가 많아지면 컨테이너를 여러 개로 늘려야 합니다. 특정 컨테이너가 장애로 종료되면 다시 실행해야 합니다. 여러 서버에 컨테이너를 분산 배치해야 할 수도 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 작업을 사람이 직접 관리하면 복잡하고 실수하기 쉽습니다. Kubernetes는 이런 작업을 자동화하는 역할을 합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Kubernetes의 주요 개념&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Kubernetes에서는 컨테이너를 직접 하나씩 관리하기보다는, 여러 추상화된 리소스를 통해 관리합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가장 기본이 되는 개념은 Pod입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Pod는 Kubernetes에서 배포할 수 있는 가장 작은 실행 단위입니다. 하나의 Pod 안에는 하나 이상의 컨테이너가 들어갈 수 있습니다. 보통은 하나의 Pod에 하나의 애플리케이션 컨테이너를 넣는 방식이 많이 사용됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Deployment는 Pod를 원하는 개수만큼 유지하고, 업데이트를 관리하는 역할을 합니다. 예를 들어 &amp;ldquo;내 웹 서버 Pod를 항상 3개 실행해줘&amp;rdquo;라고 설정하면 Kubernetes는 실제 상태를 계속 확인하면서 Pod 개수를 맞추려고 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Service는 Pod에 접근할 수 있는 고정된 네트워크 진입점을 제공합니다. Pod는 언제든 새로 생성되거나 삭제될 수 있기 때문에 IP가 바뀔 수 있습니다. Service는 이런 Pod들을 묶어서 안정적으로 접근할 수 있게 해줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Node는 실제 컨테이너가 실행되는 서버입니다. 여러 Node가 모여 Cluster를 구성합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정리하면 다음과 같습니다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 120px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;height: 20px; text-align: center;&quot;&gt;개념&lt;/td&gt;
&lt;td style=&quot;height: 20px; text-align: center;&quot;&gt;설명&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;height: 20px; text-align: center;&quot;&gt;Cluster&lt;/td&gt;
&lt;td style=&quot;height: 20px; text-align: center;&quot;&gt;Kubernetes가 관리하는 전체 서버 묶음&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;height: 20px; text-align: center;&quot;&gt;Node&lt;/td&gt;
&lt;td style=&quot;height: 20px; text-align: center;&quot;&gt;컨테이너가 실제로 실행되는 서버&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;height: 20px; text-align: center;&quot;&gt;Pod&lt;/td&gt;
&lt;td style=&quot;height: 20px; text-align: center;&quot;&gt;Kubernetes의 가장 작은 실행 단위&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;height: 20px; text-align: center;&quot;&gt;Deployment&lt;/td&gt;
&lt;td style=&quot;height: 20px; text-align: center;&quot;&gt;Pod의 배포, 복제, 업데이트 관리&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;height: 20px; text-align: center;&quot;&gt;Service&lt;/td&gt;
&lt;td style=&quot;height: 20px; text-align: center;&quot;&gt;Pod에 접근하기 위한 네트워크 진입점&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;5. Kubernetes와 Docker의 관계&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Docker와 Kubernetes는 경쟁 관계라기보다는 역할이 다른 도구입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Docker는 컨테이너 이미지를 만들고 컨테이너를 실행하는 데 사용됩니다. 개발자는 Dockerfile을 작성해서 이미지를 만들고, 이 이미지를 Docker Hub 같은 이미지 저장소에 올릴 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Kubernetes는 이렇게 만들어진 컨테이너 이미지를 가져와서 여러 서버에 배포하고 운영합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;흐름으로 보면 다음과 같습니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Dockerfile을 작성한다.&lt;/li&gt;
&lt;li&gt;Docker 이미지로 빌드한다.&lt;/li&gt;
&lt;li&gt;이미지를 Docker Hub 같은 Registry에 업로드한다.&lt;/li&gt;
&lt;li&gt;Kubernetes가 해당 이미지를 가져와 Pod로 실행한다.&lt;/li&gt;
&lt;li&gt;Deployment와 Service를 통해 컨테이너를 안정적으로 운영한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, Docker는 컨테이너 이미지를 만들고 실행하는 개발 및 실행 도구에 가깝고, Kubernetes는 컨테이너를 대규모 환경에서 운영하기 위한 관리 플랫폼에 가깝습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cEIjXp/dJMcacpWXd1/vL1xLnf2PVXSaDdr7Yk2o1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cEIjXp/dJMcacpWXd1/vL1xLnf2PVXSaDdr7Yk2o1/img.png&quot; data-is-animation=&quot;false&quot; data-origin-width=&quot;769&quot; data-origin-height=&quot;619&quot; data-filename=&quot;다운로드.png&quot; width=&quot;413&quot; height=&quot;332&quot; style=&quot;width: 50.8472%; margin-right: 10px;&quot; data-widthpercent=&quot;51.45&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cEIjXp/dJMcacpWXd1/vL1xLnf2PVXSaDdr7Yk2o1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcEIjXp%2FdJMcacpWXd1%2FvL1xLnf2PVXSaDdr7Yk2o1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;769&quot; height=&quot;619&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dzILZZ/dJMcadh5hiu/7YAARBCFx1Q2zXKRIljEd1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dzILZZ/dJMcadh5hiu/7YAARBCFx1Q2zXKRIljEd1/img.png&quot; data-is-animation=&quot;false&quot; data-origin-width=&quot;768&quot; data-origin-height=&quot;655&quot; data-filename=&quot;kubernetes_cluster-1-768x655.png&quot; width=&quot;428&quot; height=&quot;365&quot; style=&quot;width: 47.99%;&quot; data-widthpercent=&quot;48.55&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dzILZZ/dJMcadh5hiu/7YAARBCFx1Q2zXKRIljEd1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdzILZZ%2FdJMcadh5hiu%2F7YAARBCFx1Q2zXKRIljEd1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;768&quot; height=&quot;655&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;정리&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Docker 이미지와 컨테이너, Docker Compose, Kubernetes는 모두 컨테이너 기반 개발과 배포에서 중요한 개념입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Docker 이미지는 컨테이너 실행을 위한 템플릿이고, 컨테이너는 이미지를 기반으로 실제 실행된 환경입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Dockerfile은 이미지를 만들기 위한 파일이고, Docker Compose는 여러 컨테이너를 한 번에 실행하고 관리하기 위한 도구입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Kubernetes는 여러 서버 환경에서 컨테이너를 자동으로 배포하고, 확장하고, 복구하고, 관리하는 오케스트레이션 플랫폼입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개발 단계에서는 Dockerfile과 Docker Compose를 많이 사용하고, 운영 환경이나 대규모 서비스에서는 Kubernetes를 사용하는 경우가 많습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음에는 개념이 비슷해 보여 헷갈릴 수 있지만, 다음과 같이 기억하면 이해하기 쉽습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;도구/개념&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;한 줄 요약&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;Docker Image&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;컨테이너를 만들기 위한 실행 템플릿&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;Docker Container&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;이미지를 기반으로 실행된 독립 환경&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;Dockerfile&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;이미지를 만드는 방법을 적은 파일&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;Docker Compose&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;여러 컨테이너를 한 번에 실행하는 도구&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;Kubernetes&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;여러 컨테이너를 자동으로 배포하고 운영하는 플랫폼&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국 Docker는 컨테이너를 만들고 실행하는 기반 기술이고, Docker Compose는 여러 컨테이너를 편리하게 실행하는 도구이며, Kubernetes는 컨테이너를 실제 운영 환경에서 안정적으로 관리하기 위한 플랫폼이라고 볼 수 있습니다.&lt;/p&gt;</description>
      <category>AI &amp;amp; Python Lab/Concept Notes</category>
      <author>코딩은 내 여친</author>
      <guid isPermaLink="true">https://dudghks2814.tistory.com/67</guid>
      <comments>https://dudghks2814.tistory.com/67#entry67comment</comments>
      <pubDate>Fri, 12 Jun 2026 22:38:57 +0900</pubDate>
    </item>
    <item>
      <title>RAG 시스템 'Agent' 개념 및 구현 방법</title>
      <link>https://dudghks2814.tistory.com/66</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;최근 RAG 시스템은 단순한 &lt;b&gt;검색 &amp;rarr; 생성 구조&lt;/b&gt;를 넘어서,&lt;br /&gt;&lt;b&gt;스스로 판단하고 도구를 선택하는 Agent 기반 구조&lt;/b&gt;로 발전하고 있습니다.&lt;/p&gt;
&lt;p data-end=&quot;366&quot; data-start=&quot;273&quot; data-ke-size=&quot;size16&quot;&gt;특히 LangChain, LangGraph, LlamaIndex 같은 프레임워크에서는&lt;br /&gt;Agent가 &lt;b&gt;전체 RAG 흐름을 제어하는 핵심 컴포넌트&lt;/b&gt; 역할을 합니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-end=&quot;398&quot; data-start=&quot;373&quot; data-ke-size=&quot;size26&quot;&gt;Agent 기반 RAG 구조 한눈에 보기&lt;/h2&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bqNUdy/dJMcabqlV5P/LLO3monfKb4KayngDIFxUK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bqNUdy/dJMcabqlV5P/LLO3monfKb4KayngDIFxUK/img.jpg&quot; data-origin-width=&quot;1118&quot; data-origin-height=&quot;860&quot; data-is-animation=&quot;false&quot; width=&quot;508&quot; height=&quot;391&quot; data-widthpercent=&quot;47.64&quot; style=&quot;width: 47.09%; margin-right: 10px;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bqNUdy/dJMcabqlV5P/LLO3monfKb4KayngDIFxUK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbqNUdy%2FdJMcabqlV5P%2FLLO3monfKb4KayngDIFxUK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1118&quot; height=&quot;860&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Zrk4G/dJMcabqlV5Q/cjV6sk4WBqWK749XflFyD1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Zrk4G/dJMcabqlV5Q/cjV6sk4WBqWK749XflFyD1/img.jpg&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;560&quot; data-is-animation=&quot;false&quot; width=&quot;440&quot; height=&quot;308&quot; data-widthpercent=&quot;52.36&quot; style=&quot;width: 51.7472%;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Zrk4G/dJMcabqlV5Q/cjV6sk4WBqWK749XflFyD1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZrk4G%2FdJMcabqlV5Q%2FcjV6sk4WBqWK749XflFyD1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;800&quot; height=&quot;560&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;p style=&quot;position: absolute;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;448&quot; data-start=&quot;442&quot; data-ke-size=&quot;size16&quot;&gt;핵심 차이:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;522&quot; data-start=&quot;450&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;483&quot; data-start=&quot;450&quot;&gt;기존 RAG &amp;rarr; 정해진 순서대로 동작 (Pipeline)&lt;/li&gt;
&lt;li data-end=&quot;522&quot; data-start=&quot;484&quot;&gt;Agent 기반 RAG &amp;rarr; 상황에 따라 &lt;b&gt;스스로 행동을 결정&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;526&quot; data-start=&quot;524&quot; data-ke-size=&quot;size16&quot;&gt;즉,&lt;/p&gt;
&lt;blockquote data-end=&quot;569&quot; data-start=&quot;528&quot; data-ke-style=&quot;style2&quot;&gt;
&lt;p data-end=&quot;569&quot; data-start=&quot;530&quot; data-ke-size=&quot;size16&quot;&gt;RAG는 정보를 가져오고, Agent는 어떻게 가져올지 결정한다&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h1 data-end=&quot;599&quot; data-start=&quot;576&quot;&gt;RAG에서 Agent란 무엇인가?&lt;/h1&gt;
&lt;h2 data-end=&quot;611&quot; data-start=&quot;601&quot; data-ke-size=&quot;size26&quot;&gt;정의&lt;/h2&gt;
&lt;p data-end=&quot;635&quot; data-start=&quot;613&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Agent는 문제를 해결하기 위해&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;721&quot; data-start=&quot;637&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;655&quot; data-start=&quot;637&quot;&gt;어떤 작업을 할지 결정하고&lt;/li&gt;
&lt;li data-end=&quot;676&quot; data-start=&quot;656&quot;&gt;어떤 도구를 사용할지 선택하며&lt;/li&gt;
&lt;li data-end=&quot;721&quot; data-start=&quot;677&quot;&gt;필요하면 여러 단계를 반복 수행하는&lt;br /&gt;&lt;b&gt;의사결정 중심 컴포넌트&lt;/b&gt;입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;729&quot; data-start=&quot;723&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어:&lt;/p&gt;
&lt;p data-end=&quot;738&quot; data-start=&quot;731&quot; data-ke-size=&quot;size16&quot;&gt;사용자 질문:&lt;/p&gt;
&lt;blockquote data-end=&quot;773&quot; data-start=&quot;740&quot; data-ke-style=&quot;style2&quot;&gt;
&lt;p data-end=&quot;773&quot; data-start=&quot;742&quot; data-ke-size=&quot;size16&quot;&gt;&quot;우리 회사 매출 데이터를 분석해서 다음 분기 예측해줘&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;792&quot; data-start=&quot;775&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;792&quot; data-start=&quot;775&quot; data-ke-size=&quot;size16&quot;&gt;Agent는 이렇게 판단합니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;836&quot; data-start=&quot;794&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;807&quot; data-start=&quot;794&quot;&gt;DB 조회 필요&lt;/li&gt;
&lt;li data-end=&quot;822&quot; data-start=&quot;808&quot;&gt;데이터 분석 필요&lt;/li&gt;
&lt;li data-end=&quot;836&quot; data-start=&quot;823&quot;&gt;결과 요약 필요&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-end=&quot;846&quot; data-start=&quot;838&quot; data-ke-size=&quot;size16&quot;&gt;그리고 실제로:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;876&quot; data-start=&quot;848&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;856&quot; data-start=&quot;848&quot;&gt;SQL 실행&lt;/li&gt;
&lt;li data-end=&quot;868&quot; data-start=&quot;857&quot;&gt;Python 실행&lt;/li&gt;
&lt;li data-end=&quot;876&quot; data-start=&quot;869&quot;&gt;결과 요약&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;895&quot; data-start=&quot;878&quot; data-ke-size=&quot;size16&quot;&gt;이 과정을 자동으로 수행합니다.&lt;/p&gt;
&lt;h2 data-end=&quot;927&quot; data-start=&quot;902&quot; data-ke-size=&quot;size26&quot;&gt;기존 RAG vs Agent 기반 RAG&lt;/h2&gt;
&lt;div&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;1110&quot; data-start=&quot;929&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;구분&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;기존 RAG&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;Agent 기반 RAG&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1019&quot; data-start=&quot;996&quot;&gt;
&lt;td style=&quot;text-align: center;&quot; data-col-size=&quot;sm&quot; data-end=&quot;1001&quot; data-start=&quot;996&quot;&gt;구조&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; data-end=&quot;1010&quot; data-start=&quot;1001&quot; data-col-size=&quot;sm&quot;&gt;고정된 흐름&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; data-end=&quot;1019&quot; data-start=&quot;1010&quot; data-col-size=&quot;sm&quot;&gt;동적 결정&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1046&quot; data-start=&quot;1020&quot;&gt;
&lt;td style=&quot;text-align: center;&quot; data-col-size=&quot;sm&quot; data-end=&quot;1025&quot; data-start=&quot;1020&quot;&gt;역할&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; data-end=&quot;1035&quot; data-start=&quot;1025&quot; data-col-size=&quot;sm&quot;&gt;검색 + 생성&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; data-end=&quot;1046&quot; data-start=&quot;1035&quot; data-col-size=&quot;sm&quot;&gt;계획 + 실행&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1063&quot; data-start=&quot;1047&quot;&gt;
&lt;td style=&quot;text-align: center;&quot; data-col-size=&quot;sm&quot; data-end=&quot;1052&quot; data-start=&quot;1047&quot;&gt;판단&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; data-end=&quot;1057&quot; data-start=&quot;1052&quot; data-col-size=&quot;sm&quot;&gt;없음&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; data-end=&quot;1063&quot; data-start=&quot;1057&quot; data-col-size=&quot;sm&quot;&gt;있음&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1084&quot; data-start=&quot;1064&quot;&gt;
&lt;td style=&quot;text-align: center;&quot; data-col-size=&quot;sm&quot; data-end=&quot;1072&quot; data-start=&quot;1064&quot;&gt;반복 실행&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; data-end=&quot;1078&quot; data-start=&quot;1072&quot; data-col-size=&quot;sm&quot;&gt;불가능&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; data-end=&quot;1084&quot; data-start=&quot;1078&quot; data-col-size=&quot;sm&quot;&gt;가능&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1110&quot; data-start=&quot;1085&quot;&gt;
&lt;td style=&quot;text-align: center;&quot; data-col-size=&quot;sm&quot; data-end=&quot;1093&quot; data-start=&quot;1085&quot;&gt;도구 사용&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; data-end=&quot;1099&quot; data-start=&quot;1093&quot; data-col-size=&quot;sm&quot;&gt;제한적&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; data-end=&quot;1110&quot; data-start=&quot;1099&quot; data-col-size=&quot;sm&quot;&gt;자유롭게 선택&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p data-end=&quot;1118&quot; data-start=&quot;1112&quot; data-ke-size=&quot;size16&quot;&gt;핵심 요약:&lt;/p&gt;
&lt;blockquote data-end=&quot;1157&quot; data-start=&quot;1120&quot; data-ke-style=&quot;style2&quot;&gt;
&lt;p data-end=&quot;1157&quot; data-start=&quot;1122&quot; data-ke-size=&quot;size16&quot;&gt;Agent는 &quot;생각하고 행동하는 RAG&quot;라고 보면 됩니다&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h1 data-end=&quot;1188&quot; data-start=&quot;1164&quot;&gt;RAG에서 Agent가 필요한 이유&lt;/h1&gt;
&lt;h2 data-end=&quot;1209&quot; data-start=&quot;1190&quot; data-ke-size=&quot;size26&quot;&gt;이유 1 &amp;mdash; 복잡한 질문 처리&lt;/h2&gt;
&lt;blockquote data-end=&quot;1248&quot; data-start=&quot;1215&quot; data-ke-style=&quot;style2&quot;&gt;
&lt;p data-end=&quot;1248&quot; data-start=&quot;1217&quot; data-ke-size=&quot;size16&quot;&gt;&quot;2023년 매출 감소 원인 분석하고 경쟁사와 비교해줘&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;1273&quot; data-start=&quot;1250&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1273&quot; data-start=&quot;1250&quot; data-ke-size=&quot;size16&quot;&gt;이건 한 번의 검색으로 해결 불가능합니다.&lt;/p&gt;
&lt;p data-end=&quot;1282&quot; data-start=&quot;1275&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1282&quot; data-start=&quot;1275&quot; data-ke-size=&quot;size16&quot;&gt;필요한 단계:&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;1335&quot; data-start=&quot;1284&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;1298&quot; data-start=&quot;1284&quot;&gt;내부 데이터 검색&lt;/li&gt;
&lt;li data-end=&quot;1313&quot; data-start=&quot;1299&quot;&gt;외부 데이터 검색&lt;/li&gt;
&lt;li data-end=&quot;1324&quot; data-start=&quot;1314&quot;&gt;비교 분석&lt;/li&gt;
&lt;li data-end=&quot;1335&quot; data-start=&quot;1325&quot;&gt;결과 생성&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-end=&quot;1371&quot; data-start=&quot;1337&quot; data-ke-size=&quot;size16&quot;&gt;Agent는 이 과정을 &lt;b&gt;단계적으로 계획&lt;/b&gt;할 수 있습니다.&lt;/p&gt;
&lt;p data-end=&quot;1477&quot; data-start=&quot;1373&quot; data-ke-size=&quot;size16&quot;&gt;연구에서도 복잡한 multi-step 질의에서는 여러 Agent가 협력하는 구조가 더 높은 정확도를 보였습니다.&lt;/p&gt;
&lt;h2 data-end=&quot;1505&quot; data-start=&quot;1484&quot; data-ke-size=&quot;size26&quot;&gt;이유 2 &amp;mdash; Tool 사용 자동화&lt;/h2&gt;
&lt;p data-end=&quot;1541&quot; data-start=&quot;1507&quot; data-ke-size=&quot;size16&quot;&gt;Agent는 다음과 같은 도구를 자동으로 선택할 수 있습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1610&quot; data-start=&quot;1547&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1558&quot; data-start=&quot;1547&quot;&gt;Vector DB&lt;/li&gt;
&lt;li data-end=&quot;1571&quot; data-start=&quot;1559&quot;&gt;Web Search&lt;/li&gt;
&lt;li data-end=&quot;1584&quot; data-start=&quot;1572&quot;&gt;Calculator&lt;/li&gt;
&lt;li data-end=&quot;1593&quot; data-start=&quot;1585&quot;&gt;Python&lt;/li&gt;
&lt;li data-end=&quot;1599&quot; data-start=&quot;1594&quot;&gt;API&lt;/li&gt;
&lt;li data-end=&quot;1610&quot; data-start=&quot;1600&quot;&gt;Database&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote data-end=&quot;1669&quot; data-start=&quot;1616&quot; data-ke-style=&quot;style2&quot;&gt;
&lt;p data-end=&quot;1669&quot; data-start=&quot;1618&quot; data-ke-size=&quot;size16&quot;&gt;LLM이 단순히 답변하는 것이 아니라&lt;br /&gt;실제로 작업을 수행하는 시스템이 됩니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 data-end=&quot;1699&quot; data-start=&quot;1676&quot; data-ke-size=&quot;size26&quot;&gt;이유 3 &amp;mdash; 반복적 개선 (Loop)&lt;/h2&gt;
&lt;p data-end=&quot;1731&quot; data-start=&quot;1701&quot; data-ke-size=&quot;size16&quot;&gt;Agent는 필요하면 작업을 다시 수행할 수 있습니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;1769&quot; data-start=&quot;1737&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;1744&quot; data-start=&quot;1737&quot;&gt;검색&lt;/li&gt;
&lt;li data-end=&quot;1755&quot; data-start=&quot;1745&quot;&gt;결과 확인&lt;/li&gt;
&lt;li data-end=&quot;1769&quot; data-start=&quot;1756&quot;&gt;부족하면 재검색&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-end=&quot;1798&quot; data-start=&quot;1771&quot; data-ke-size=&quot;size16&quot;&gt;이 구조는 &lt;b&gt;정확도 개선에 매우 중요&lt;/b&gt;합니다.&lt;/p&gt;
&lt;p data-end=&quot;1863&quot; data-start=&quot;1800&quot; data-ke-size=&quot;size16&quot;&gt;실제로 Agent 기반 RAG는 계획, 도구 사용, 검증 반복을 통해 시스템 신뢰성을 높일 수 있습니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h1 data-end=&quot;1890&quot; data-start=&quot;1870&quot;&gt;Agent의 핵심 구성 요소&lt;/h1&gt;
&lt;p data-end=&quot;1919&quot; data-start=&quot;1892&quot; data-ke-size=&quot;size16&quot;&gt;Agent는 보통 다음 4가지 요소로 구성됩니다.&lt;/p&gt;
&lt;h2 data-end=&quot;1943&quot; data-start=&quot;1926&quot; data-ke-size=&quot;size26&quot;&gt;1) LLM &amp;mdash; 판단 엔진&lt;/h2&gt;
&lt;p data-end=&quot;1948&quot; data-start=&quot;1945&quot; data-ke-size=&quot;size16&quot;&gt;역할:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1972&quot; data-start=&quot;1950&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1961&quot; data-start=&quot;1950&quot;&gt;무엇을 할지 결정&lt;/li&gt;
&lt;li data-end=&quot;1972&quot; data-start=&quot;1962&quot;&gt;다음 행동 선택&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1976&quot; data-start=&quot;1974&quot; data-ke-size=&quot;size16&quot;&gt;예:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1998&quot; data-start=&quot;1978&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1984&quot; data-start=&quot;1978&quot;&gt;검색할지&lt;/li&gt;
&lt;li data-end=&quot;1991&quot; data-start=&quot;1985&quot;&gt;계산할지&lt;/li&gt;
&lt;li data-end=&quot;1998&quot; data-start=&quot;1992&quot;&gt;답변할지&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;2007&quot; data-start=&quot;2000&quot; data-ke-size=&quot;size16&quot;&gt;한 줄 요약:&lt;/p&gt;
&lt;blockquote data-end=&quot;2024&quot; data-start=&quot;2009&quot; data-ke-style=&quot;style2&quot;&gt;
&lt;p data-end=&quot;2024&quot; data-start=&quot;2011&quot; data-ke-size=&quot;size16&quot;&gt;Agent의 두뇌&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-end=&quot;2050&quot; data-start=&quot;2031&quot; data-ke-size=&quot;size26&quot;&gt;2) Tools &amp;mdash; 실행 도구&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2106&quot; data-start=&quot;2056&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2067&quot; data-start=&quot;2056&quot;&gt;Retriever&lt;/li&gt;
&lt;li data-end=&quot;2080&quot; data-start=&quot;2068&quot;&gt;Web Search&lt;/li&gt;
&lt;li data-end=&quot;2089&quot; data-start=&quot;2081&quot;&gt;Python&lt;/li&gt;
&lt;li data-end=&quot;2100&quot; data-start=&quot;2090&quot;&gt;Database&lt;/li&gt;
&lt;li data-end=&quot;2106&quot; data-start=&quot;2101&quot;&gt;API&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;2132&quot; data-start=&quot;2108&quot; data-ke-size=&quot;size16&quot;&gt;Agent는 상황에 따라 도구를 선택합니다.&lt;/p&gt;
&lt;p data-end=&quot;2141&quot; data-start=&quot;2138&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-end=&quot;2156&quot; data-start=&quot;2143&quot; data-ke-style=&quot;style2&quot;&gt;
&lt;p data-end=&quot;2156&quot; data-start=&quot;2145&quot; data-ke-size=&quot;size16&quot;&gt;&quot;현재 환율 알려줘&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;2167&quot; data-start=&quot;2158&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;2167&quot; data-start=&quot;2158&quot; data-ke-size=&quot;size16&quot;&gt;Agent 행동:&lt;/p&gt;
&lt;p data-end=&quot;2184&quot; data-start=&quot;2169&quot; data-ke-size=&quot;size16&quot;&gt;&amp;rarr; Web Search 호출&lt;/p&gt;
&lt;h2 data-end=&quot;2208&quot; data-start=&quot;2191&quot; data-ke-size=&quot;size26&quot;&gt;3) Memory &amp;mdash; 기억&lt;/h2&gt;
&lt;p data-end=&quot;2213&quot; data-start=&quot;2210&quot; data-ke-size=&quot;size16&quot;&gt;역할:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2244&quot; data-start=&quot;2215&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2225&quot; data-start=&quot;2215&quot;&gt;이전 대화 저장&lt;/li&gt;
&lt;li data-end=&quot;2236&quot; data-start=&quot;2226&quot;&gt;중간 결과 저장&lt;/li&gt;
&lt;li data-end=&quot;2244&quot; data-start=&quot;2237&quot;&gt;상태 관리&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;2249&quot; data-start=&quot;2246&quot; data-ke-size=&quot;size16&quot;&gt;종류:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2289&quot; data-start=&quot;2251&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2270&quot; data-start=&quot;2251&quot;&gt;Short-term memory&lt;/li&gt;
&lt;li data-end=&quot;2289&quot; data-start=&quot;2271&quot;&gt;Long-term memory&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;2298&quot; data-start=&quot;2291&quot; data-ke-size=&quot;size16&quot;&gt;한 줄 요약:&lt;/p&gt;
&lt;blockquote data-end=&quot;2315&quot; data-start=&quot;2300&quot; data-ke-style=&quot;style2&quot;&gt;
&lt;p data-end=&quot;2315&quot; data-start=&quot;2302&quot; data-ke-size=&quot;size16&quot;&gt;Agent의 기억&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 data-end=&quot;2341&quot; data-start=&quot;2322&quot; data-ke-size=&quot;size26&quot;&gt;4) Planning &amp;mdash; 계획&lt;/h2&gt;
&lt;p data-end=&quot;2346&quot; data-start=&quot;2343&quot; data-ke-size=&quot;size16&quot;&gt;역할:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2366&quot; data-start=&quot;2348&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2358&quot; data-start=&quot;2348&quot;&gt;작업 순서 결정&lt;/li&gt;
&lt;li data-end=&quot;2366&quot; data-start=&quot;2359&quot;&gt;단계 분할&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote data-end=&quot;2400&quot; data-start=&quot;2377&quot; data-ke-style=&quot;style2&quot;&gt;
&lt;p data-end=&quot;2400&quot; data-start=&quot;2379&quot; data-ke-size=&quot;size16&quot;&gt;&quot;논문 요약하고 주요 키워드 추출해줘&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;2407&quot; data-start=&quot;2402&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;2407&quot; data-start=&quot;2402&quot; data-ke-size=&quot;size16&quot;&gt;Plan:&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;2442&quot; data-start=&quot;2409&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;2419&quot; data-start=&quot;2409&quot;&gt;문서 읽기&lt;/li&gt;
&lt;li data-end=&quot;2430&quot; data-start=&quot;2420&quot;&gt;요약 생성&lt;/li&gt;
&lt;li data-end=&quot;2442&quot; data-start=&quot;2431&quot;&gt;키워드 추출&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-end=&quot;2451&quot; data-start=&quot;2444&quot; data-ke-size=&quot;size16&quot;&gt;한 줄 요약:&lt;/p&gt;
&lt;blockquote data-end=&quot;2468&quot; data-start=&quot;2453&quot; data-ke-style=&quot;style2&quot;&gt;
&lt;p data-end=&quot;2468&quot; data-start=&quot;2455&quot; data-ke-size=&quot;size16&quot;&gt;Agent의 전략&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h1 data-end=&quot;2505&quot; data-start=&quot;2475&quot;&gt;RAG Agent는 실제로 어떻게 구현하는가?&lt;/h1&gt;
&lt;p data-end=&quot;2561&quot; data-start=&quot;2507&quot; data-ke-size=&quot;size16&quot;&gt;여기서는 가장 대표적인 방법인&lt;br /&gt;&lt;b&gt;LangChain 기반 구현 흐름&lt;/b&gt;을 기준으로 설명합니다.&lt;/p&gt;
&lt;h2 data-end=&quot;2587&quot; data-start=&quot;2568&quot; data-ke-size=&quot;size26&quot;&gt;Step 1 &amp;mdash; Tool 정의&lt;/h2&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;pre id=&quot;code_1776307134583&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def retrieve(query):
return vector_db.search(query)&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2666&quot; data-start=&quot;2664&quot; data-ke-size=&quot;size16&quot;&gt;즉,&lt;/p&gt;
&lt;blockquote data-end=&quot;2687&quot; data-start=&quot;2668&quot; data-ke-style=&quot;style2&quot;&gt;검색 기능을 Tool로 등록합니다.&lt;/blockquote&gt;
&lt;h2 data-end=&quot;2714&quot; data-start=&quot;2694&quot; data-ke-size=&quot;size26&quot;&gt;Step 2 &amp;mdash; Agent 생성&lt;/h2&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;pre id=&quot;code_1776307180474&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from langchain.agents import create_agent

agent = create_agent(
model=&quot;gpt-4&quot;,
tools=[retrieve]
)&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2883&quot; data-start=&quot;2842&quot; data-ke-size=&quot;size16&quot;&gt;이렇게 생성된 Agent는 필요할 때 자동으로 검색 도구를 호출합니다.&lt;/p&gt;
&lt;p data-end=&quot;2999&quot; data-start=&quot;2885&quot; data-ke-size=&quot;size16&quot;&gt;LangChain 공식 문서에서도 Agent는 검색 도구를 실행해 RAG 흐름을 제어하는 오케스트레이터 역할을 한다고 설명합니다.&lt;/p&gt;
&lt;h2 data-end=&quot;3026&quot; data-start=&quot;3006&quot; data-ke-size=&quot;size26&quot;&gt;Step 3 &amp;mdash; Agent 실행&lt;/h2&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div id=&quot;code-block-viewer&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1776307212175&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;response = agent.run(
&quot;LangChain의 Agent 구조를 설명해줘&quot;
)&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;3112&quot; data-start=&quot;3103&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;3112&quot; data-start=&quot;3103&quot; data-ke-size=&quot;size16&quot;&gt;이때 내부에서는:&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;3165&quot; data-start=&quot;3114&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;3124&quot; data-start=&quot;3114&quot;&gt;질문 분석&lt;/li&gt;
&lt;li data-end=&quot;3141&quot; data-start=&quot;3125&quot;&gt;검색 필요 여부 판단&lt;/li&gt;
&lt;li data-end=&quot;3154&quot; data-start=&quot;3142&quot;&gt;Tool 실행&lt;/li&gt;
&lt;li data-end=&quot;3165&quot; data-start=&quot;3155&quot;&gt;답변 생성&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-end=&quot;3184&quot; data-start=&quot;3167&quot; data-ke-size=&quot;size16&quot;&gt;이 과정이 자동으로 수행됩니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h1 data-end=&quot;3226&quot; data-start=&quot;3191&quot;&gt;가장 많이 사용되는 Agent 구현 방식&lt;/h1&gt;
&lt;h2 data-end=&quot;3246&quot; data-start=&quot;3228&quot; data-ke-size=&quot;size26&quot;&gt;1) Single Agent&lt;/h2&gt;
&lt;p data-end=&quot;3251&quot; data-start=&quot;3248&quot; data-ke-size=&quot;size16&quot;&gt;구조:&lt;/p&gt;
&lt;p data-end=&quot;3279&quot; data-start=&quot;3253&quot; data-ke-size=&quot;size16&quot;&gt;User&lt;br /&gt;&amp;rarr; Agent&lt;br /&gt;&amp;rarr; Tools&lt;/p&gt;
&lt;p data-end=&quot;3284&quot; data-start=&quot;3281&quot; data-ke-size=&quot;size16&quot;&gt;특징:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;3301&quot; data-start=&quot;3286&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;3293&quot; data-start=&quot;3286&quot;&gt;가장 단순&lt;/li&gt;
&lt;li data-end=&quot;3301&quot; data-start=&quot;3294&quot;&gt;구현 쉬움&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-end=&quot;3325&quot; data-start=&quot;3308&quot; data-ke-size=&quot;size26&quot;&gt;2) Multi-Agent&lt;/h2&gt;
&lt;p data-end=&quot;3330&quot; data-start=&quot;3327&quot; data-ke-size=&quot;size16&quot;&gt;구조:&lt;/p&gt;
&lt;p data-end=&quot;3370&quot; data-start=&quot;3332&quot; data-ke-size=&quot;size16&quot;&gt;User&lt;br /&gt;&amp;rarr; Supervisor Agent&lt;br /&gt;&amp;rarr; 여러 Agent&lt;/p&gt;
&lt;p data-end=&quot;3374&quot; data-start=&quot;3372&quot; data-ke-size=&quot;size16&quot;&gt;예:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;3426&quot; data-start=&quot;3376&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;3393&quot; data-start=&quot;3376&quot;&gt;Retrieval Agent&lt;/li&gt;
&lt;li data-end=&quot;3410&quot; data-start=&quot;3394&quot;&gt;Analysis Agent&lt;/li&gt;
&lt;li data-end=&quot;3426&quot; data-start=&quot;3411&quot;&gt;Summary Agent&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;3431&quot; data-start=&quot;3428&quot; data-ke-size=&quot;size16&quot;&gt;특징:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;3454&quot; data-start=&quot;3433&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;3445&quot; data-start=&quot;3433&quot;&gt;복잡한 작업에 적합&lt;/li&gt;
&lt;li data-end=&quot;3454&quot; data-start=&quot;3446&quot;&gt;확장성 높음&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-end=&quot;3487&quot; data-start=&quot;3461&quot; data-ke-size=&quot;size26&quot;&gt;3) Agentic RAG (최신 트렌드)&lt;/h2&gt;
&lt;p data-end=&quot;3492&quot; data-start=&quot;3489&quot; data-ke-size=&quot;size16&quot;&gt;구조:&lt;/p&gt;
&lt;p data-end=&quot;3525&quot; data-start=&quot;3494&quot; data-ke-size=&quot;size16&quot;&gt;User&lt;br /&gt;&amp;rarr; Agent&lt;br /&gt;&amp;rarr; 반복 검색 + 검증&lt;/p&gt;
&lt;p data-end=&quot;3530&quot; data-start=&quot;3527&quot; data-ke-size=&quot;size16&quot;&gt;특징:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;3564&quot; data-start=&quot;3532&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;3549&quot; data-start=&quot;3532&quot;&gt;기존 RAG보다 정확도 높음&lt;/li&gt;
&lt;li data-end=&quot;3564&quot; data-start=&quot;3550&quot;&gt;복잡한 질의 처리 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h1 data-end=&quot;3589&quot; data-start=&quot;3571&quot;&gt;정리&lt;/h1&gt;
&lt;h2 data-end=&quot;3602&quot; data-start=&quot;3591&quot; data-ke-size=&quot;size26&quot;&gt;Agent 정의&lt;/h2&gt;
&lt;blockquote data-end=&quot;3661&quot; data-start=&quot;3604&quot; data-ke-style=&quot;style2&quot;&gt;
&lt;p data-end=&quot;3661&quot; data-start=&quot;3606&quot; data-ke-size=&quot;size16&quot;&gt;Agent는 문제 해결을 위해 스스로 계획하고, 도구를 선택하고, 작업을 실행하는 시스템이다&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 data-end=&quot;3679&quot; data-start=&quot;3668&quot; data-ke-size=&quot;size26&quot;&gt;Agent 역할&lt;/h2&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;3766&quot; data-start=&quot;3681&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;3702&quot; data-start=&quot;3681&quot;&gt;작업 계획 (Planning)&lt;/li&gt;
&lt;li data-end=&quot;3730&quot; data-start=&quot;3703&quot;&gt;도구 선택 (Tool selection)&lt;/li&gt;
&lt;li data-end=&quot;3750&quot; data-start=&quot;3731&quot;&gt;작업 실행 (Action)&lt;/li&gt;
&lt;li data-end=&quot;3766&quot; data-start=&quot;3751&quot;&gt;결과 검증 (Loop)&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 data-end=&quot;3787&quot; data-start=&quot;3773&quot; data-ke-size=&quot;size26&quot;&gt;Agent 구현 핵심&lt;/h2&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;3829&quot; data-start=&quot;3789&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;3801&quot; data-start=&quot;3789&quot;&gt;Tool 정의&lt;/li&gt;
&lt;li data-end=&quot;3815&quot; data-start=&quot;3802&quot;&gt;Agent 생성&lt;/li&gt;
&lt;li data-end=&quot;3829&quot; data-start=&quot;3816&quot;&gt;Agent 실행&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote data-end=&quot;3882&quot; data-start=&quot;3848&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;3882&quot; data-start=&quot;3850&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;RAG는 정보를 찾고, Agent는 문제를 해결한다&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;</description>
      <category>AI &amp;amp; Python Lab/Concept Notes</category>
      <author>코딩은 내 여친</author>
      <guid isPermaLink="true">https://dudghks2814.tistory.com/66</guid>
      <comments>https://dudghks2814.tistory.com/66#entry66comment</comments>
      <pubDate>Sat, 2 May 2026 16:53:43 +0900</pubDate>
    </item>
    <item>
      <title>RAG 시스템 성능 독립 평가 vs 종단간 평가</title>
      <link>https://dudghks2814.tistory.com/65</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;RAG 시스템은 단순히 &lt;b&gt;정답을 맞추는지&lt;/b&gt;만 보는 것이 아니라,&lt;br /&gt;&lt;b&gt;검색이 잘 되었는지&lt;/b&gt;와 &lt;b&gt;최종 답변이 적절한지&lt;/b&gt;를 각각 평가해야 합니다.&lt;/p&gt;
&lt;p data-end=&quot;248&quot; data-start=&quot;220&quot; data-ke-size=&quot;size16&quot;&gt;그래서 보통 평가 방법은 크게 두 가지로 나뉩니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;327&quot; data-start=&quot;250&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;290&quot; data-start=&quot;250&quot;&gt;&lt;b&gt;독립 평가 (Component-level Evaluation)&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;327&quot; data-start=&quot;291&quot;&gt;&lt;b&gt;종단간 평가 (End-to-End Evaluation)&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-end=&quot;353&quot; data-start=&quot;334&quot; data-ke-size=&quot;size26&quot;&gt;RAG 평가 구조 한눈에 보기&lt;/h2&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;410&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cxNWj9/dJMb99MMzWN/ixJ7xL9AsbArU9RkIBFPfk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cxNWj9/dJMb99MMzWN/ixJ7xL9AsbArU9RkIBFPfk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cxNWj9/dJMb99MMzWN/ixJ7xL9AsbArU9RkIBFPfk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcxNWj9%2FdJMb99MMzWN%2FixJ7xL9AsbArU9RkIBFPfk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1024&quot; height=&quot;410&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;410&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cck8rS/dJMcahKRyLG/Zk2gRbDXEWCNVVA9bqZHn0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cck8rS/dJMcahKRyLG/Zk2gRbDXEWCNVVA9bqZHn0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cck8rS/dJMcahKRyLG/Zk2gRbDXEWCNVVA9bqZHn0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcck8rS%2FdJMcahKRyLG%2FZk2gRbDXEWCNVVA9bqZHn0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1024&quot; height=&quot;1024&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;407&quot; data-start=&quot;397&quot; data-ke-size=&quot;size16&quot;&gt;핵심은 간단합니다.&lt;/p&gt;
&lt;blockquote data-end=&quot;456&quot; data-start=&quot;409&quot; data-ke-style=&quot;style2&quot;&gt;
&lt;p data-end=&quot;456&quot; data-start=&quot;411&quot; data-ke-size=&quot;size16&quot;&gt;검색 단계와 생성 단계를 나눠서 볼 것인가, 전체 결과만 볼 것인가의 차이&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h1 data-end=&quot;498&quot; data-start=&quot;463&quot;&gt;독립 평가 (Independent Evaluation)&lt;/h1&gt;
&lt;p data-end=&quot;543&quot; data-start=&quot;500&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;의미&lt;/b&gt;&lt;br /&gt;RAG의 각 구성 요소를 &lt;b&gt;따로따로 평가&lt;/b&gt;하는 방식입니다.&lt;/p&gt;
&lt;p data-end=&quot;547&quot; data-start=&quot;545&quot; data-ke-size=&quot;size16&quot;&gt;즉,&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;584&quot; data-start=&quot;549&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;566&quot; data-start=&quot;549&quot;&gt;검색 성능은 검색만 평가&lt;/li&gt;
&lt;li data-end=&quot;584&quot; data-start=&quot;567&quot;&gt;생성 성능은 생성만 평가&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;601&quot; data-start=&quot;586&quot; data-ke-size=&quot;size16&quot;&gt;이렇게 분리해서 분석합니다.&lt;/p&gt;
&lt;h2 data-end=&quot;643&quot; data-start=&quot;608&quot; data-ke-size=&quot;size26&quot;&gt;(1) Retrieval 평가 &amp;mdash; 검색이 잘 되었는지 확인&lt;/h2&gt;
&lt;p data-end=&quot;651&quot; data-start=&quot;645&quot; data-ke-size=&quot;size16&quot;&gt;대표 지표:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;802&quot; data-start=&quot;653&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;685&quot; data-start=&quot;653&quot;&gt;&lt;b&gt;Precision&lt;/b&gt; &amp;mdash; 가져온 문서 중 정답 비율&lt;/li&gt;
&lt;li data-end=&quot;721&quot; data-start=&quot;686&quot;&gt;&lt;b&gt;Recall&lt;/b&gt; &amp;mdash; 필요한 문서를 얼마나 놓치지 않았는지&lt;/li&gt;
&lt;li data-end=&quot;771&quot; data-start=&quot;722&quot;&gt;&lt;b&gt;MRR (Mean Reciprocal Rank)&lt;/b&gt; &amp;mdash; 정답 문서가 상위에 있는지&lt;/li&gt;
&lt;li data-end=&quot;802&quot; data-start=&quot;772&quot;&gt;&lt;b&gt;Hit Rate&lt;/b&gt; &amp;mdash; 정답 문서가 포함되었는지&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;810&quot; data-start=&quot;804&quot; data-ke-size=&quot;size16&quot;&gt;예시 질문:&lt;/p&gt;
&lt;blockquote data-end=&quot;838&quot; data-start=&quot;812&quot; data-ke-style=&quot;style2&quot;&gt;
&lt;p data-end=&quot;838&quot; data-start=&quot;814&quot; data-ke-size=&quot;size16&quot;&gt;정답 문서를 Top-5 안에 가져왔는가?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;846&quot; data-start=&quot;840&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;846&quot; data-start=&quot;840&quot; data-ke-size=&quot;size16&quot;&gt;핵심 포인트&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;898&quot; data-start=&quot;848&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;868&quot; data-start=&quot;848&quot;&gt;검색 품질을 정확히 파악 가능&lt;/li&gt;
&lt;li data-end=&quot;885&quot; data-start=&quot;869&quot;&gt;문제 원인을 찾기 쉬움&lt;/li&gt;
&lt;li data-end=&quot;898&quot; data-start=&quot;886&quot;&gt;RAG 튜닝에 필수&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;908&quot; data-start=&quot;900&quot; data-ke-size=&quot;size16&quot;&gt;한 줄 정리&lt;/p&gt;
&lt;blockquote data-end=&quot;941&quot; data-start=&quot;909&quot; data-ke-style=&quot;style2&quot;&gt;
&lt;p data-end=&quot;941&quot; data-start=&quot;911&quot; data-ke-size=&quot;size16&quot;&gt;검색과 생성 성능을 각각 따로 평가하는 방식&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 data-end=&quot;979&quot; data-start=&quot;948&quot; data-ke-size=&quot;size26&quot;&gt;(2) Generation 평가 &amp;mdash; 답변 품질 평가&lt;/h2&gt;
&lt;p data-end=&quot;987&quot; data-start=&quot;981&quot; data-ke-size=&quot;size16&quot;&gt;대표 지표:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1044&quot; data-start=&quot;989&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;999&quot; data-start=&quot;989&quot;&gt;&lt;b&gt;BLEU&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;1011&quot; data-start=&quot;1000&quot;&gt;&lt;b&gt;ROUGE&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;1026&quot; data-start=&quot;1012&quot;&gt;&lt;b&gt;F1 Score&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;1044&quot; data-start=&quot;1027&quot;&gt;&lt;b&gt;Exact Match&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1060&quot; data-start=&quot;1046&quot; data-ke-size=&quot;size16&quot;&gt;최근 많이 사용하는 방식:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1105&quot; data-start=&quot;1062&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1082&quot; data-start=&quot;1062&quot;&gt;&lt;b&gt;LLM-as-a-Judge&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;1105&quot; data-start=&quot;1083&quot;&gt;&lt;b&gt;Human Evaluation&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1116&quot; data-start=&quot;1107&quot; data-ke-size=&quot;size16&quot;&gt;예시 평가 항목:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1202&quot; data-start=&quot;1118&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1136&quot; data-start=&quot;1118&quot;&gt;정확성 (Accuracy)&lt;/li&gt;
&lt;li data-end=&quot;1156&quot; data-start=&quot;1137&quot;&gt;관련성 (Relevance)&lt;/li&gt;
&lt;li data-end=&quot;1176&quot; data-start=&quot;1157&quot;&gt;자연스러움 (Fluency)&lt;/li&gt;
&lt;li data-end=&quot;1202&quot; data-start=&quot;1177&quot;&gt;근거 기반 여부 (Groundedness)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1212&quot; data-start=&quot;1204&quot; data-ke-size=&quot;size16&quot;&gt;한 줄 정리&lt;/p&gt;
&lt;blockquote data-end=&quot;1239&quot; data-start=&quot;1213&quot; data-ke-style=&quot;style2&quot;&gt;
&lt;p data-end=&quot;1239&quot; data-start=&quot;1215&quot; data-ke-size=&quot;size16&quot;&gt;답변 자체의 품질을 평가하는 방식&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h1 data-end=&quot;1281&quot; data-start=&quot;1246&quot;&gt;종단간 평가 (End-to-End Evaluation)&lt;/h1&gt;
&lt;p data-end=&quot;1336&quot; data-start=&quot;1283&quot; data-ke-size=&quot;size16&quot;&gt;RAG 시스템을 &lt;b&gt;하나의 시스템으로 보고 전체 결과만 평가&lt;/b&gt;하는 방식입니다.&lt;/p&gt;
&lt;p data-end=&quot;1340&quot; data-start=&quot;1338&quot; data-ke-size=&quot;size16&quot;&gt;즉,&lt;/p&gt;
&lt;blockquote data-end=&quot;1385&quot; data-start=&quot;1342&quot; data-ke-style=&quot;style2&quot;&gt;
&lt;p data-end=&quot;1385&quot; data-start=&quot;1344&quot; data-ke-size=&quot;size16&quot;&gt;질문 &amp;rarr; 검색 &amp;rarr; 생성 &amp;rarr; 최종 답변&lt;br /&gt;이 전체 과정을 한 번에 평가&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 data-end=&quot;1403&quot; data-start=&quot;1392&quot; data-ke-size=&quot;size26&quot;&gt;대표 평가 방법&lt;/h2&gt;
&lt;h3 data-end=&quot;1438&quot; data-start=&quot;1405&quot; data-ke-size=&quot;size23&quot;&gt;1) 정답 기반 평가 (Ground Truth 기반)&lt;/h3&gt;
&lt;p data-end=&quot;1443&quot; data-start=&quot;1440&quot; data-ke-size=&quot;size16&quot;&gt;예시:&lt;/p&gt;
&lt;p data-end=&quot;1463&quot; data-start=&quot;1445&quot; data-ke-size=&quot;size16&quot;&gt;질문&lt;br /&gt;&amp;rarr; &quot;대한민국 수도는?&quot;&lt;/p&gt;
&lt;p data-end=&quot;1463&quot; data-start=&quot;1445&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1476&quot; data-start=&quot;1465&quot; data-ke-size=&quot;size16&quot;&gt;정답&lt;br /&gt;&amp;rarr; &quot;서울&quot;&lt;/p&gt;
&lt;p data-end=&quot;1476&quot; data-start=&quot;1465&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1492&quot; data-start=&quot;1478&quot; data-ke-size=&quot;size16&quot;&gt;모델 답변&lt;br /&gt;&amp;rarr; &quot;서울&quot;&lt;/p&gt;
&lt;p data-end=&quot;1492&quot; data-start=&quot;1478&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1499&quot; data-start=&quot;1494&quot; data-ke-size=&quot;size16&quot;&gt;이 경우:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1518&quot; data-start=&quot;1501&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1518&quot; data-start=&quot;1501&quot;&gt;Accuracy = 100%&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-end=&quot;1565&quot; data-start=&quot;1525&quot; data-ke-size=&quot;size23&quot;&gt;2) 사용자 중심 평가 (User-level Evaluation)&lt;/h3&gt;
&lt;p data-end=&quot;1573&quot; data-start=&quot;1567&quot; data-ke-size=&quot;size16&quot;&gt;예시 지표:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1654&quot; data-start=&quot;1575&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1594&quot; data-start=&quot;1575&quot;&gt;Answer Accuracy&lt;/li&gt;
&lt;li data-end=&quot;1610&quot; data-start=&quot;1595&quot;&gt;Helpfulness&lt;/li&gt;
&lt;li data-end=&quot;1632&quot; data-start=&quot;1611&quot;&gt;User Satisfaction&lt;/li&gt;
&lt;li data-end=&quot;1654&quot; data-start=&quot;1633&quot;&gt;Task Success Rate&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1681&quot; data-start=&quot;1656&quot; data-ke-size=&quot;size16&quot;&gt;실무 서비스에서는 이 지표가 매우 중요합니다.&lt;/p&gt;
&lt;h2 data-end=&quot;1700&quot; data-start=&quot;1688&quot; data-ke-size=&quot;size26&quot;&gt;종단간 평가 특징&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1758&quot; data-start=&quot;1702&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1724&quot; data-start=&quot;1702&quot;&gt;실제 사용자 경험을 가장 잘 반영&lt;/li&gt;
&lt;li data-end=&quot;1742&quot; data-start=&quot;1725&quot;&gt;서비스 품질 확인에 필수&lt;/li&gt;
&lt;li data-end=&quot;1758&quot; data-start=&quot;1743&quot;&gt;문제 원인 분석은 어려움&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1768&quot; data-start=&quot;1760&quot; data-ke-size=&quot;size16&quot;&gt;한 줄 정리&lt;/p&gt;
&lt;blockquote data-end=&quot;1795&quot; data-start=&quot;1769&quot; data-ke-style=&quot;style2&quot;&gt;
&lt;p data-end=&quot;1795&quot; data-start=&quot;1771&quot; data-ke-size=&quot;size16&quot;&gt;전체 시스템 결과만 평가하는 방식&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h1 data-end=&quot;1830&quot; data-start=&quot;1802&quot;&gt;독립 평가 vs 종단간 평가 차이&lt;/h1&gt;
&lt;div&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;2088&quot; data-start=&quot;1832&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;구분&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;독립 평가&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;종단간 평가&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1920&quot; data-start=&quot;1891&quot;&gt;
&lt;td style=&quot;text-align: center;&quot; data-col-size=&quot;sm&quot; data-end=&quot;1899&quot; data-start=&quot;1891&quot;&gt;평가 대상&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; data-end=&quot;1910&quot; data-start=&quot;1899&quot; data-col-size=&quot;sm&quot;&gt;개별 구성 요소&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; data-end=&quot;1920&quot; data-start=&quot;1910&quot; data-col-size=&quot;sm&quot;&gt;전체 시스템&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1949&quot; data-start=&quot;1921&quot;&gt;
&lt;td style=&quot;text-align: center;&quot; data-col-size=&quot;sm&quot; data-end=&quot;1926&quot; data-start=&quot;1921&quot;&gt;목적&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; data-col-size=&quot;sm&quot; data-end=&quot;1937&quot; data-start=&quot;1926&quot;&gt;문제 원인 분석&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; data-end=&quot;1949&quot; data-start=&quot;1937&quot; data-col-size=&quot;sm&quot;&gt;실제 성능 확인&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;2000&quot; data-start=&quot;1950&quot;&gt;
&lt;td style=&quot;text-align: center;&quot; data-col-size=&quot;sm&quot; data-end=&quot;1955&quot; data-start=&quot;1950&quot;&gt;예시&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; data-end=&quot;1969&quot; data-start=&quot;1955&quot; data-col-size=&quot;sm&quot;&gt;Recall, MRR&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; data-end=&quot;2000&quot; data-start=&quot;1969&quot; data-col-size=&quot;sm&quot;&gt;Accuracy, User Satisfaction&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;2029&quot; data-start=&quot;2001&quot;&gt;
&lt;td style=&quot;text-align: center;&quot; data-col-size=&quot;sm&quot; data-end=&quot;2009&quot; data-start=&quot;2001&quot;&gt;활용 단계&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; data-end=&quot;2019&quot; data-start=&quot;2009&quot; data-col-size=&quot;sm&quot;&gt;개발 / 튜닝&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; data-end=&quot;2029&quot; data-start=&quot;2019&quot; data-col-size=&quot;sm&quot;&gt;서비스 운영&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;2053&quot; data-start=&quot;2030&quot;&gt;
&lt;td style=&quot;text-align: center;&quot; data-col-size=&quot;sm&quot; data-end=&quot;2035&quot; data-start=&quot;2030&quot;&gt;장점&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; data-end=&quot;2044&quot; data-start=&quot;2035&quot; data-col-size=&quot;sm&quot;&gt;디버깅 쉬움&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; data-end=&quot;2053&quot; data-start=&quot;2044&quot; data-col-size=&quot;sm&quot;&gt;현실 반영&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;2088&quot; data-start=&quot;2054&quot;&gt;
&lt;td style=&quot;text-align: center;&quot; data-col-size=&quot;sm&quot; data-end=&quot;2059&quot; data-start=&quot;2054&quot;&gt;단점&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; data-end=&quot;2075&quot; data-start=&quot;2059&quot; data-col-size=&quot;sm&quot;&gt;사용자 경험 반영 어려움&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot; data-end=&quot;2088&quot; data-start=&quot;2075&quot; data-col-size=&quot;sm&quot;&gt;원인 분석 어려움&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h1 data-end=&quot;2117&quot; data-start=&quot;2095&quot;&gt;정리&lt;/h1&gt;
&lt;p data-end=&quot;2152&quot; data-start=&quot;2119&quot; data-ke-size=&quot;size16&quot;&gt;RAG 평가에서는 &lt;b&gt;두 가지를 반드시 함께 사용&lt;/b&gt;합니다.&lt;/p&gt;
&lt;p data-end=&quot;2157&quot; data-start=&quot;2154&quot; data-ke-size=&quot;size16&quot;&gt;이유:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2217&quot; data-start=&quot;2159&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2185&quot; data-start=&quot;2159&quot;&gt;독립 평가 &amp;rarr; 어디가 문제인지 찾기 위해&lt;/li&gt;
&lt;li data-end=&quot;2217&quot; data-start=&quot;2186&quot;&gt;종단간 평가 &amp;rarr; 전체 서비스 품질을 확인하기 위해&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;2221&quot; data-start=&quot;2219&quot; data-ke-size=&quot;size16&quot;&gt;즉,&lt;/p&gt;
&lt;blockquote data-end=&quot;2262&quot; data-start=&quot;2223&quot; data-ke-style=&quot;style2&quot;&gt;
&lt;p data-end=&quot;2262&quot; data-start=&quot;2225&quot; data-ke-size=&quot;size16&quot;&gt;튜닝할 때는 독립 평가, 서비스 품질 확인은 종단간 평가&lt;/p&gt;
&lt;/blockquote&gt;</description>
      <category>AI &amp;amp; Python Lab/Concept Notes</category>
      <author>코딩은 내 여친</author>
      <guid isPermaLink="true">https://dudghks2814.tistory.com/65</guid>
      <comments>https://dudghks2814.tistory.com/65#entry65comment</comments>
      <pubDate>Sat, 2 May 2026 14:18:09 +0900</pubDate>
    </item>
    <item>
      <title>LangChain으로 RAG 시스템 구축 시 필요한 주요 구성 요소와 역할</title>
      <link>https://dudghks2814.tistory.com/64</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;RAG(Retrieval-Augmented Generation)는 &lt;b&gt;외부 지식을 검색(Retrieval)한 뒤, &lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;이를 기반으로 답변을 생성(Generation)&lt;/b&gt; 하는 구조입니다.&lt;br /&gt;특히 &lt;b&gt;LangChain&lt;/b&gt;을 사용하면 이 과정을 모듈 형태로 쉽게 구성할 수 있어,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;챗봇&amp;middot;문서 검색 시스템&amp;middot;사내 지식 시스템 등에 널리 활용됩니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-end=&quot;332&quot; data-start=&quot;307&quot; data-ke-size=&quot;size26&quot;&gt;RAG 시스템 전체 구조&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;rag-framework.png&quot; data-origin-width=&quot;2284&quot; data-origin-height=&quot;1346&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cuB7kT/dJMcaiwbTEt/E4CS7qk0IIHzAxT3KECsN0/img.webp&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cuB7kT/dJMcaiwbTEt/E4CS7qk0IIHzAxT3KECsN0/img.webp&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cuB7kT/dJMcaiwbTEt/E4CS7qk0IIHzAxT3KECsN0/img.webp&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcuB7kT%2FdJMcaiwbTEt%2FE4CS7qk0IIHzAxT3KECsN0%2Fimg.webp&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2284&quot; height=&quot;1346&quot; data-filename=&quot;rag-framework.png&quot; data-origin-width=&quot;2284&quot; data-origin-height=&quot;1346&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;362&quot; data-start=&quot;336&quot; data-ke-size=&quot;size16&quot;&gt;RAG 시스템은 보통 다음 흐름으로 동작합니다.&lt;/p&gt;
&lt;p data-end=&quot;417&quot; data-start=&quot;364&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;문서 &amp;rarr; 임베딩 &amp;rarr; 벡터DB 저장 &amp;rarr; 질문 입력 &amp;rarr; 관련 문서 검색 &amp;rarr; LLM 답변 생성&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;450&quot; data-start=&quot;419&quot; data-ke-size=&quot;size16&quot;&gt;이 과정을 구성하는 핵심 요소들을 하나씩 살펴보겠습니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h1 data-end=&quot;485&quot; data-start=&quot;457&quot;&gt;Document Loader (문서 로더)&lt;/h1&gt;
&lt;p data-end=&quot;522&quot; data-start=&quot;487&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;역할:&lt;/b&gt;&lt;br /&gt;외부 데이터를 시스템으로 불러오는 단계입니다.&lt;/p&gt;
&lt;p data-end=&quot;534&quot; data-start=&quot;524&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;예시 데이터&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;580&quot; data-start=&quot;535&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;540&quot; data-start=&quot;535&quot;&gt;PDF&lt;/li&gt;
&lt;li data-end=&quot;555&quot; data-start=&quot;541&quot;&gt;Word / Excel&lt;/li&gt;
&lt;li data-end=&quot;562&quot; data-start=&quot;556&quot;&gt;웹페이지&lt;/li&gt;
&lt;li data-end=&quot;571&quot; data-start=&quot;563&quot;&gt;데이터베이스&lt;/li&gt;
&lt;li data-end=&quot;580&quot; data-start=&quot;572&quot;&gt;텍스트 파일&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;592&quot; data-start=&quot;582&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;핵심 포인트&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;639&quot; data-start=&quot;594&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;613&quot; data-start=&quot;594&quot;&gt;다양한 형식의 문서를 통합 처리&lt;/li&gt;
&lt;li data-end=&quot;624&quot; data-start=&quot;614&quot;&gt;RAG의 시작점&lt;/li&gt;
&lt;li data-end=&quot;639&quot; data-start=&quot;625&quot;&gt;데이터 소스 연결 역할&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;649&quot; data-start=&quot;641&quot; data-ke-size=&quot;size16&quot;&gt;한 줄 정리&lt;/p&gt;
&lt;blockquote data-end=&quot;676&quot; data-start=&quot;650&quot; data-ke-style=&quot;style2&quot;&gt;
&lt;p data-end=&quot;676&quot; data-start=&quot;652&quot; data-ke-size=&quot;size16&quot;&gt;데이터를 시스템으로 가져오는 역할&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h1 data-end=&quot;711&quot; data-start=&quot;683&quot;&gt;Text Splitter (텍스트 분할기)&lt;/h1&gt;
&lt;p data-end=&quot;753&quot; data-start=&quot;713&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;역할:&lt;/b&gt;&lt;br /&gt;긴 문서를 작은 단위(Chunk)로 나누는 단계입니다.&lt;/p&gt;
&lt;p data-end=&quot;763&quot; data-start=&quot;755&quot; data-ke-size=&quot;size16&quot;&gt;왜 필요할까요?&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;824&quot; data-start=&quot;765&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;791&quot; data-start=&quot;765&quot;&gt;LLM은 긴 문서를 한 번에 처리하기 어려움&lt;/li&gt;
&lt;li data-end=&quot;808&quot; data-start=&quot;792&quot;&gt;검색 정확도를 높이기 위해&lt;/li&gt;
&lt;li data-end=&quot;824&quot; data-start=&quot;809&quot;&gt;임베딩 성능 향상을 위해&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;832&quot; data-start=&quot;826&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;예시&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;851&quot; data-start=&quot;834&quot; data-ke-size=&quot;size16&quot;&gt;원본 문서&lt;br /&gt;&amp;rarr; 10,000자&lt;/p&gt;
&lt;p data-end=&quot;873&quot; data-start=&quot;853&quot; data-ke-size=&quot;size16&quot;&gt;분할 후&lt;br /&gt;&amp;rarr; 500자 &amp;times; 여러 개&lt;/p&gt;
&lt;p data-end=&quot;873&quot; data-start=&quot;853&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;883&quot; data-start=&quot;875&quot; data-ke-size=&quot;size16&quot;&gt;한 줄 정리&lt;/p&gt;
&lt;blockquote data-end=&quot;914&quot; data-start=&quot;884&quot; data-ke-style=&quot;style2&quot;&gt;
&lt;p data-end=&quot;914&quot; data-start=&quot;886&quot; data-ke-size=&quot;size16&quot;&gt;문서를 검색하기 좋은 크기로 나누는 역할&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h1 data-end=&quot;950&quot; data-start=&quot;921&quot;&gt;Embedding Model (임베딩 모델)&lt;/h1&gt;
&lt;p data-end=&quot;988&quot; data-start=&quot;952&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;역할:&lt;/b&gt;&lt;br /&gt;텍스트를 숫자 벡터(Vector)로 변환합니다.&lt;/p&gt;
&lt;p data-end=&quot;1003&quot; data-start=&quot;990&quot; data-ke-size=&quot;size16&quot;&gt;이 과정이 중요한 이유:&lt;/p&gt;
&lt;p data-end=&quot;1054&quot; data-start=&quot;1005&quot; data-ke-size=&quot;size16&quot;&gt;컴퓨터는 의미를 이해하지 못하기 때문에&lt;br /&gt;&lt;b&gt;문장의 의미를 수치로 표현&lt;/b&gt;해야 합니다.&lt;/p&gt;
&lt;p data-end=&quot;1065&quot; data-start=&quot;1056&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;예시 모델&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1121&quot; data-start=&quot;1067&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1086&quot; data-start=&quot;1067&quot;&gt;OpenAI Embeddings&lt;/li&gt;
&lt;li data-end=&quot;1110&quot; data-start=&quot;1087&quot;&gt;Sentence Transformers&lt;/li&gt;
&lt;li data-end=&quot;1116&quot; data-start=&quot;1111&quot;&gt;BGE&lt;/li&gt;
&lt;li data-end=&quot;1121&quot; data-start=&quot;1117&quot;&gt;E5&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1131&quot; data-start=&quot;1123&quot; data-ke-size=&quot;size16&quot;&gt;한 줄 정리&lt;/p&gt;
&lt;blockquote data-end=&quot;1162&quot; data-start=&quot;1132&quot; data-ke-style=&quot;style2&quot;&gt;
&lt;p data-end=&quot;1162&quot; data-start=&quot;1134&quot; data-ke-size=&quot;size16&quot;&gt;텍스트를 의미 기반 숫자로 변환하는 역할&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h1 data-end=&quot;1198&quot; data-start=&quot;1169&quot;&gt;Vector Store (벡터 데이터베이스)&lt;/h1&gt;
&lt;p data-end=&quot;1240&quot; data-start=&quot;1200&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;역할:&lt;/b&gt;&lt;br /&gt;임베딩된 데이터를 저장하고 검색하는 데이터베이스입니다.&lt;/p&gt;
&lt;p data-end=&quot;1254&quot; data-start=&quot;1242&quot; data-ke-size=&quot;size16&quot;&gt;일반 DB와 다른 점:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1308&quot; data-start=&quot;1256&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1291&quot; data-start=&quot;1256&quot;&gt;&lt;b&gt;의미 기반 검색 (Semantic Search)&lt;/b&gt; 가능&lt;/li&gt;
&lt;li data-end=&quot;1308&quot; data-start=&quot;1292&quot;&gt;비슷한 문서를 빠르게 찾음&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1324&quot; data-start=&quot;1310&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;대표적인 벡터 DB&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1364&quot; data-start=&quot;1326&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1333&quot; data-start=&quot;1326&quot;&gt;FAISS&lt;/li&gt;
&lt;li data-end=&quot;1342&quot; data-start=&quot;1334&quot;&gt;Chroma&lt;/li&gt;
&lt;li data-end=&quot;1353&quot; data-start=&quot;1343&quot;&gt;Pinecone&lt;/li&gt;
&lt;li data-end=&quot;1364&quot; data-start=&quot;1354&quot;&gt;Weaviate&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1374&quot; data-start=&quot;1366&quot; data-ke-size=&quot;size16&quot;&gt;한 줄 정리&lt;/p&gt;
&lt;blockquote data-end=&quot;1407&quot; data-start=&quot;1375&quot; data-ke-style=&quot;style2&quot;&gt;
&lt;p data-end=&quot;1407&quot; data-start=&quot;1377&quot; data-ke-size=&quot;size16&quot;&gt;비슷한 문서를 찾기 위해 벡터를 저장하는 곳&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h1 data-end=&quot;1434&quot; data-start=&quot;1414&quot;&gt;Retriever (검색기)&lt;/h1&gt;
&lt;p data-end=&quot;1479&quot; data-start=&quot;1436&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;역할:&lt;/b&gt;&lt;br /&gt;사용자의 질문과 가장 관련 있는 문서를 찾아오는 단계입니다.&lt;/p&gt;
&lt;p data-end=&quot;1487&quot; data-start=&quot;1481&quot; data-ke-size=&quot;size16&quot;&gt;동작 방식:&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;1540&quot; data-start=&quot;1489&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;1504&quot; data-start=&quot;1489&quot;&gt;질문을 임베딩으로 변환&lt;/li&gt;
&lt;li data-end=&quot;1525&quot; data-start=&quot;1505&quot;&gt;벡터 DB에서 유사한 문서 검색&lt;/li&gt;
&lt;li data-end=&quot;1540&quot; data-start=&quot;1526&quot;&gt;상위 k개 문서 반환&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-end=&quot;1552&quot; data-start=&quot;1542&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;핵심 포인트&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1588&quot; data-start=&quot;1554&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1569&quot; data-start=&quot;1554&quot;&gt;RAG 성능의 핵심 요소&lt;/li&gt;
&lt;li data-end=&quot;1588&quot; data-start=&quot;1570&quot;&gt;검색 품질이 답변 품질을 결정&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1598&quot; data-start=&quot;1590&quot; data-ke-size=&quot;size16&quot;&gt;한 줄 정리&lt;/p&gt;
&lt;blockquote data-end=&quot;1629&quot; data-start=&quot;1599&quot; data-ke-style=&quot;style2&quot;&gt;
&lt;p data-end=&quot;1629&quot; data-start=&quot;1601&quot; data-ke-size=&quot;size16&quot;&gt;질문과 가장 관련 있는 문서를 찾는 역할&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h1 data-end=&quot;1667&quot; data-start=&quot;1636&quot;&gt;LLM (Large Language Model)&lt;/h1&gt;
&lt;p data-end=&quot;1705&quot; data-start=&quot;1669&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;역할:&lt;/b&gt;&lt;br /&gt;검색된 문서를 기반으로 최종 답변을 생성합니다.&lt;/p&gt;
&lt;p data-end=&quot;1705&quot; data-start=&quot;1669&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1717&quot; data-start=&quot;1707&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;여기서 중요한 점:&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;1781&quot; data-start=&quot;1719&quot; data-ke-size=&quot;size16&quot;&gt;LLM은 &lt;b&gt;외부 지식을 직접 학습하지 않아도&lt;/b&gt;,&lt;br /&gt;검색된 정보를 활용해 정확한 답변을 생성할 수 있습니다.&lt;/p&gt;
&lt;p data-end=&quot;1781&quot; data-start=&quot;1719&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1792&quot; data-start=&quot;1783&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;예시 모델&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1825&quot; data-start=&quot;1794&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1799&quot; data-start=&quot;1794&quot;&gt;GPT&lt;/li&gt;
&lt;li data-end=&quot;1808&quot; data-start=&quot;1800&quot;&gt;Claude&lt;/li&gt;
&lt;li data-end=&quot;1816&quot; data-start=&quot;1809&quot;&gt;Llama&lt;/li&gt;
&lt;li data-end=&quot;1825&quot; data-start=&quot;1817&quot;&gt;Gemini&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1835&quot; data-start=&quot;1827&quot; data-ke-size=&quot;size16&quot;&gt;한 줄 정리&lt;/p&gt;
&lt;blockquote data-end=&quot;1867&quot; data-start=&quot;1836&quot; data-ke-style=&quot;style2&quot;&gt;
&lt;p data-end=&quot;1867&quot; data-start=&quot;1838&quot; data-ke-size=&quot;size16&quot;&gt;검색된 정보를 바탕으로 답변을 만드는 역할&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h1 data-end=&quot;1892&quot; data-start=&quot;1874&quot;&gt;정리&lt;/h1&gt;
&lt;p data-end=&quot;1923&quot; data-start=&quot;1894&quot; data-ke-size=&quot;size16&quot;&gt;RAG 시스템의 주요 구성 요소는 다음 6가지입니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;2127&quot; data-start=&quot;1925&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;1960&quot; data-start=&quot;1925&quot;&gt;&lt;b&gt;Document Loader&lt;/b&gt; &amp;mdash; 데이터를 불러옴&lt;/li&gt;
&lt;li data-end=&quot;1999&quot; data-start=&quot;1961&quot;&gt;&lt;b&gt;Text Splitter&lt;/b&gt; &amp;mdash; 문서를 작은 단위로 나눔&lt;/li&gt;
&lt;li data-end=&quot;2038&quot; data-start=&quot;2000&quot;&gt;&lt;b&gt;Embedding Model&lt;/b&gt; &amp;mdash; 텍스트를 벡터로 변환&lt;/li&gt;
&lt;li data-end=&quot;2074&quot; data-start=&quot;2039&quot;&gt;&lt;b&gt;Vector Store&lt;/b&gt; &amp;mdash; 벡터를 저장하고 검색&lt;/li&gt;
&lt;li data-end=&quot;2105&quot; data-start=&quot;2075&quot;&gt;&lt;b&gt;Retriever&lt;/b&gt; &amp;mdash; 관련 문서를 찾음&lt;/li&gt;
&lt;li data-end=&quot;2127&quot; data-start=&quot;2106&quot;&gt;&lt;b&gt;LLM&lt;/b&gt; &amp;mdash; 답변을 생성&lt;/li&gt;
&lt;/ol&gt;</description>
      <category>AI &amp;amp; Python Lab/Concept Notes</category>
      <author>코딩은 내 여친</author>
      <guid isPermaLink="true">https://dudghks2814.tistory.com/64</guid>
      <comments>https://dudghks2814.tistory.com/64#entry64comment</comments>
      <pubDate>Sat, 2 May 2026 11:31:16 +0900</pubDate>
    </item>
  </channel>
</rss>