LLM 기반 AI 서비스의 가장 큰 한계 중 하나는 최신 정보 부족도메인 데이터 부재다.
아무리 강력한 모델이라도 회사 내부 문서, 최신 정책, 특정 업무 매뉴얼, 사내 지식 같은 정보는 기본적으로 알지 못한다.

이 문제를 해결하기 위해 많이 사용하는 구조가 바로 RAG(Retrieval-Augmented Generation) 이다.

RAG는 단순히 “문서를 검색해서 붙여주는 기술”이 아니라,
LLM 서비스의 정확도·신뢰도·업무 활용도를 높이기 위한 아키텍처 패턴이다.

이 글에서는 RAG의 개념을 넘어서, 실제 AI 서비스에서 사용할 수 있는 RAG 시스템 설계 패턴을 백엔드 아키텍처 관점에서 정리해본다.


1. RAG란 무엇인가

RAG는 사용자의 질문에 답하기 전에 관련 문서를 먼저 검색하고,
그 검색 결과를 LLM의 입력 컨텍스트로 제공하여 더 정확한 답변을 생성하는 방식이다.

기본 흐름은 다음과 같다.

User Question
      ↓
Retriever
      ↓
Relevant Documents
      ↓
LLM Prompt Context
      ↓
Generated Answer

 

즉, LLM이 자기 머리만 믿고 답하는 것이 아니라
외부 지식 기반을 조회한 뒤 답변하도록 만드는 구조다.


2. 왜 RAG가 필요한가

LLM 단독 서비스는 다음 문제가 있다.

1) 최신 정보를 모른다

모델 학습 이후에 생긴 정보는 알지 못한다.

2) 내부 문서를 모른다

사내 위키, 정책 문서, 업무 가이드, 고객 문서 등은 기본적으로 접근할 수 없다.

3) 환각(Hallucination)이 발생한다

모르는 내용을 그럴듯하게 만들어내는 경우가 있다.

4) 출처 기반 답변이 어렵다

업무 시스템에서는 “왜 그렇게 답했는가”가 중요하다.

RAG는 이 문제를 다음 방식으로 완화한다.

  • 최신 정보 반영
  • 내부 데이터 활용
  • 답변 근거 제공
  • 환각 감소

3. RAG의 기본 아키텍처

가장 기본적인 RAG 구조는 다음과 같다.

[문서 수집]
   ↓
[문서 분할 Chunking]
   ↓
[Embedding 생성]
   ↓
[Vector DB 저장]
   ↓
--------------------------------
[사용자 질문]
   ↓
[질문 Embedding]
   ↓
[유사 문서 검색]
   ↓
[Prompt 구성]
   ↓
[LLM 응답 생성]

여기서 핵심 구성요소는 4개다.

  • Ingestion Pipeline
  • Embedding Model
  • Retriever
  • LLM Generation Layer

4. RAG 시스템의 핵심 설계 포인트

RAG는 “붙이면 된다” 수준이 아니다.
실제로 품질 차이는 대부분 아래 설계 포인트에서 갈린다.

4.1 문서 수집 방식

입력 데이터의 품질이 낮으면 검색 품질도 낮다.

대표적인 입력 소스는 다음과 같다.

  • PDF
  • HTML
  • 사내 위키
  • DB 데이터
  • FAQ
  • 정책 문서
  • 매뉴얼
  • Jira / Confluence / Notion 문서

이 단계에서 중요한 것은 단순 수집이 아니라 정규화다.

예를 들어 PDF에서 다음 문제가 생긴다.

  • 줄바꿈 깨짐
  • 표 구조 손실
  • 머리글/바닥글 반복
  • 목차 노이즈
  • OCR 오류

그래서 실제 운영에서는 수집 후 아래 처리가 필요하다.

  • 불필요 문구 제거
  • 제목/본문 구조 분리
  • 표/리스트 보존
  • 문서 메타데이터 부여
  • 최신 버전 기준 정리

4.2 Chunking 전략

RAG 품질에서 가장 중요한 설계 요소 중 하나가 Chunking이다.

문서를 너무 크게 자르면 검색 정밀도가 떨어지고,
너무 작게 자르면 문맥이 끊긴다.

대표 패턴은 다음과 같다.

1) Fixed-size Chunking

일정 길이 기준으로 자른다.

예:

  • 500자
  • 1000 tokens

장점:

  • 구현이 단순함

단점:

  • 문맥 단위가 깨질 수 있음

2) Overlapping Chunking

청크 간 일부 구간을 겹치게 자른다.

예:

  • chunk size 800
  • overlap 150

장점:

  • 문맥 단절 완화

단점:

  • 저장량 증가
  • 중복 검색 가능성

3) Semantic Chunking

문단, 제목, 섹션 단위 등 의미 기준으로 자른다.

장점:

  • 문맥 보존에 유리함

단점:

  • 구현 복잡도 증가

4) Hierarchical Chunking

문서 계층 구조를 유지한 채 자른다.

예:

  • 문서
        • 문단

장점:

  • 큰 문맥과 작은 문맥을 함께 다룰 수 있음

이 방식은 정책 문서, 기술 문서, 메뉴얼에서 특히 효과적이다.


5. RAG 설계 패턴

이제 실제 서비스에서 자주 쓰는 설계 패턴을 정리해보자.


패턴 1. Naive RAG

가장 단순한 형태다.

User Question
   ↓
Vector Search
   ↓
Top-K Documents
   ↓
LLM

장점:

  • 빠르게 구현 가능
  • PoC에 적합

단점:

  • 검색 정확도 한계
  • 질문 의도 파악 부족
  • 불필요 문서 유입 가능

이 구조는 데모 단계에서는 좋지만, 운영 단계로 가면 곧 한계가 보인다.


패턴 2. Query Rewrite RAG

사용자 질문을 그대로 검색하지 않고,
검색에 유리한 형태로 질문을 재작성한다.

User Question
   ↓
Query Rewriter
   ↓
Optimized Search Query
   ↓
Retriever
   ↓
LLM

예:

  • “연차 이월 기준이 뭐야?”
    → “연차휴가 이월 조건 및 정책 기준”

장점:

  • 검색 품질 향상
  • 사용자 표현의 모호성 보완

특히 실무에서는 사용자가 질문을 정확히 안 하기 때문에 매우 유용하다.


패턴 3. Hybrid Search RAG

벡터 검색만 쓰지 않고, 키워드 검색(BM25 등)을 함께 사용한다.

 

User Question
   ↓
 ┌───────────────┬───────────────┐
Vector Search    Keyword Search
 └───────────────┴───────────────┘
         ↓
   Result Merge / Re-rank
         ↓
         LLM

 

장점:

  • 의미 기반 검색 + 정확한 키워드 검색 결합
  • 상품명, 코드, 버전명, 정책 번호 같은 데이터에 강함

예를 들어

  • 에러 코드
  • 정책 조항 번호
  • API endpoint 이름
  • 클래스명 / 테이블명

이런 것은 키워드 검색이 훨씬 잘 잡는다.

실무형 RAG는 보통 Hybrid Search가 더 낫다.


패턴 4. Re-ranking RAG

1차 검색 결과를 그대로 LLM에 넘기지 않고,
별도의 Re-ranker가 관련도를 재정렬한다.

User Question
   ↓
Retriever
   ↓
Top 20 Chunks
   ↓
Re-ranker
   ↓
Top 5 Chunks
   ↓
LLM

장점:

  • 최종 컨텍스트 품질 향상
  • 노이즈 감소
  • 긴 문서군에서 성능 개선

이 패턴은 검색량이 많아질수록 중요해진다.

 

패턴 5. Multi-step RAG

질문이 복잡하면 한 번의 검색으로 부족하다.
이때는 여러 단계로 검색과 reasoning을 반복한다.

 

User Question
   ↓
Question Decomposition
   ↓
Sub-query 1 / 2 / 3
   ↓
각각 Retrieval
   ↓
Result Aggregation
   ↓
LLM Answer

 

예:
“우리 회사 육아단축근무 규정이랑 연차 차감 방식, 그리고 급여 반영 기준까지 정리해줘”

이 질문은 사실 하나가 아니라 세 개다.

  • 육아단축근무 규정
  • 연차 차감 정책
  • 급여 계산 기준

이럴 때 질문을 분해해서 각각 찾고, 마지막에 합치는 방식이 훨씬 정확하다.


패턴 6. Agentic RAG

Retriever 하나만 두는 게 아니라,
에이전트가 어떤 도구를 사용할지 선택한다.

User Question
   ↓
Agent
   ↓
[Vector Search / SQL Query / API Call / Web Search]
   ↓
Collected Context
   ↓
LLM

장점:

  • 정형 데이터와 비정형 데이터 동시 활용
  • 복합 질의 대응 가능

예:

  • 문서 내용은 Vector DB에서
  • 최신 상태는 DB에서
  • 실시간 정보는 API에서 조회

즉 실제 업무형 AI 서비스에 가까워진다.


6. Vector DB 설계 포인트

RAG 품질은 Vector DB 제품보다 인덱싱 설계가 더 중요하다.

대표 선택지는 다음과 같다.

  • pgvector
  • Elasticsearch
  • Pinecone
  • Weaviate
  • Milvus
  • Qdrant

선정 기준은 이렇다.

pgvector

  • PostgreSQL 기반
  • 기존 RDB 운영 경험이 있다면 접근 쉬움
  • 작은 규모나 초기 서비스에 적합

Elasticsearch

  • 전문 검색 + 벡터 검색 동시 가능
  • Hybrid Search에 강함

Pinecone / Weaviate / Qdrant / Milvus

  • 대규모 벡터 검색 특화
  • AI 서비스 중심 구조에 적합

르무엘님처럼 백엔드/운영 관점이면 초기에는
PostgreSQL + pgvector 또는 Elasticsearch hybrid가 현실적입니다.


7. Metadata Filtering 패턴

실무에서는 단순 유사도 검색만으로 부족하다.
문서 범위를 줄이는 metadata filter가 매우 중요하다.

예:

  • 문서 유형 = 인사정책
  • 작성 부서 = HR
  • 버전 = 최신
  • 국가 = KR
  • 제품군 = A 서비스
  • 공개 범위 = 내부 전용

구조 예시는 이렇다.

 

User Question
   ↓
Metadata Filter
   ↓
Scoped Retrieval
   ↓
Top-K Search

 

장점:

  • 검색 정확도 상승
  • 노이즈 감소
  • 권한 분리 대응 가능

운영형 RAG에서는 거의 필수다.


8. Prompt 구성 패턴

좋은 검색 결과가 있어도 Prompt가 나쁘면 답이 흔들린다.

RAG Prompt는 보통 다음 요소를 포함한다.

  • 시스템 역할
  • 답변 규칙
  • 검색된 문서
  • 출처 표기 규칙
  • 모르면 모른다고 말하라는 규칙

예시 구조:

너는 사내 정책 문서를 기반으로 답변하는 AI다.
반드시 제공된 문서 내용만 사용하라.
문서에 없는 내용은 추측하지 말고 모른다고 답하라.
가능하면 답변 하단에 참고 문서명을 표시하라.

[검색 문서]
...
[질문]
...

 

핵심은 이거다.

RAG는 검색 품질 + Prompt 통제가 같이 가야 한다.

 


9. 운영 관점에서의 문제

RAG는 만들기보다 운영이 어렵다.

대표 이슈는 다음과 같다.

1) 문서 최신화

원본 문서가 변경되면 embedding도 다시 생성해야 한다.

2) 권한 문제

사용자마다 볼 수 있는 문서가 다를 수 있다.

3) 응답 지연

검색 + 재정렬 + LLM 호출로 latency가 커진다.

4) 비용 문제

embedding, retrieval, LLM 호출 모두 비용 요소다.

5) 품질 평가

정확도, 재현율, grounding quality를 측정해야 한다.

즉 RAG는 단순 기능이 아니라 운영 시스템이다.


10. RAG 평가 패턴

실제 서비스에서는 “잘 되는 것 같다”로 끝내면 안 된다.
평가 체계가 필요하다.

대표 평가 항목:

  • Retrieval Precision
  • Retrieval Recall
  • Context Relevance
  • Answer Groundedness
  • Hallucination Rate
  • Latency
  • Cost per Request

실무에서는 테스트셋을 만들어서
“질문-정답-근거 문서” 형태로 검증하는 방식이 좋다.


11. 백엔드 관점에서 본 RAG 시스템 구조

백엔드 엔지니어 시각에서 RAG는 다음처럼 볼 수 있다.

Client
  ↓
API Gateway
  ↓
FastAPI / Spring Backend
  ↓
RAG Service
  ├ Query Rewrite
  ├ Retriever
  ├ Re-ranker
  ├ Prompt Builder
  └ LLM Client
  ↓
Vector DB / Metadata DB / Object Storage

 

즉 RAG는 단순 AI 기능이 아니라
하나의 검색 + 조합 + 생성 파이프라인 서비스다.

백엔드적으로 보면 다음 고민이 필요하다.

  • 캐시 전략
  • 비동기 처리
  • 재시도 정책
  • timeout
  • observability
  • 권한 필터링
  • 문서 인덱싱 배치

이 지점부터 RAG는 “AI 장난감”이 아니라 “서비스 설계”가 된다.

 

12. 어떤 패턴부터 시작해야 하나

실무에서는 처음부터 복잡하게 가면 실패한다.
보통 다음 순서가 현실적이다.

1단계

Naive RAG

  • 빠른 PoC
  • 문서 ingest 실험
  • chunking 검증

2단계

Hybrid Search + Metadata Filter

  • 검색 정확도 향상
  • 운영 대응 강화

3단계

Re-ranking + Query Rewrite

  • 품질 최적화

4단계

Multi-step / Agentic RAG

  • 복잡한 업무 질의 대응

단계적 진화가 맞다.


13. 정리

RAG는 단순히 LLM에 문서를 붙여주는 기술이 아니다.
실제로는 검색 시스템, 데이터 파이프라인, 프롬프트 제어, 운영 체계가 결합된 아키텍처다.

좋은 RAG 시스템을 만들기 위해 중요한 것은 다음과 같다.

  • 문서 품질
  • Chunking 전략
  • Retrieval 방식
  • Re-ranking
  • Metadata filtering
  • Prompt 통제
  • 운영 및 평가 체계

결국 RAG의 본질은 이것이다.

“LLM이 잘 답하게 만드는 기술”이 아니라,
“LLM이 근거를 가지고 틀리지 않게 답하도록 설계하는 시스템”

AI 서비스가 업무 시스템으로 들어갈수록,
이 RAG 설계 역량은 점점 더 중요한 백엔드 아키텍처 역량이 될 것이다.

 

 

LIST

최근 AI 서비스는 단순한 LLM API 호출을 넘어
검색, 데이터 처리, API 연동, 자동화를 결합하는 방향으로 발전하고 있다.

이러한 AI 애플리케이션을 구축하기 위해서는
LLM뿐 아니라 다양한 기술 스택이 함께 필요하다.

대표적인 AI 서비스 개발 스택은 다음과 같이 구성된다.

AI Service Stack

Frontend

API Server (FastAPI)

AI Orchestration (LangChain)

LLM

Vector Database

External Data / Tools
 

이 글에서는 AI 서비스에서 가장 많이 사용되는
LangChain, FastAPI, Vector Database의 역할과 구조를 정리한다.


1. FastAPI: AI 서비스 API 서버

FastAPI는 Python 기반 고성능 웹 프레임워크
AI 서비스에서 API 서버 역할을 담당한다.

AI 시스템에서는 다음과 같은 구조가 일반적이다.

User

HTTP API

FastAPI

AI Pipeline

LLM
 

FastAPI가 많이 사용되는 이유는 다음과 같다.

비동기 처리 지원

AI 서비스는

  • LLM 호출
  • Vector 검색
  • 외부 API

등 네트워크 작업이 많기 때문에
비동기 처리가 중요한데 FastAPI는 이를 잘 지원한다.


Python 생태계와의 궁합

AI 개발은 대부분 Python 기반이다.

대표적인 라이브러리

  • LangChain
  • LlamaIndex
  • HuggingFace
  • Pandas

FastAPI는 이러한 Python 라이브러리와 자연스럽게 통합된다.


REST API 구축

AI 서비스를 API 형태로 제공할 수 있다.

POST /chat
POST /rag/query
POST /agent/run
 

2. LangChain: AI Orchestration Layer

LangChain은 LLM 기반 애플리케이션을 구축하기 위한 프레임워크이다.

AI 서비스에서는 단순히 LLM을 호출하는 것이 아니라
다양한 작업을 연결해야 한다.

  • 문서 검색
  • 데이터 처리
  • API 호출
  • 멀티 스텝 reasoning

LangChain은 이러한 흐름을 체인(Chain) 구조로 구성한다.

User Question

Document Retrieval

Context 생성

LLM 호출

Response
 

이러한 구조를 RAG(Retrieval Augmented Generation) 라고 한다.


LangChain의 주요 기능

Chain

여러 AI 작업을 연결하는 구조

Search → Context → LLM
 

Agent

LLM이 어떤 도구를 사용할지 판단하는 시스템

User Question

Agent

Search Tool / API

LLM
 

Memory

대화 상태를 유지하는 기능


3. Vector Database: AI 검색 엔진

LLM은 기본적으로 학습된 데이터만 알고 있기 때문에
최신 정보나 내부 데이터를 사용할 수 없다.

이 문제를 해결하기 위해 Vector Database가 사용된다.

Vector Database는 문서를 Embedding 벡터 형태로 저장하고
유사한 문서를 검색하는 시스템이다.

RAG 시스템의 구조는 다음과 같다.

User Question

Embedding 생성

Vector Database 검색

Relevant Documents

LLM

Response
 

대표적인 Vector Database는 다음과 같다.

Vector DB특징
Pinecone 관리형 서비스
Weaviate AI 검색 엔진
Chroma 경량 Vector DB
pgvector PostgreSQL 기반
Elasticsearch 벡터 검색 지원

4. AI 서비스 전체 아키텍처

AI 서비스는 보통 다음과 같은 구조를 가진다.

Client

Frontend

FastAPI

LangChain

LLM

Vector Database

Document Storage
 

여기에 다음 시스템이 추가되기도 한다.

  • Redis (캐시)
  • Kafka (이벤트 처리)
  • Kubernetes (배포)
  • Prometheus / Grafana (모니터링)

5. AI 서비스 개발 흐름

AI 애플리케이션 개발 과정은 다음과 같다.

1. 데이터 준비

문서 수집

  • PDF
  • 웹 페이지
  • 내부 문서

2. Embedding 생성

문서를 벡터로 변환


3. Vector DB 저장

벡터 형태로 저장


4. 질문 처리

사용자 질문을 벡터로 변환


5. 문서 검색

유사 문서 검색


6. LLM 응답 생성

검색된 문서를 기반으로 답변 생성


6. AI 서비스 개발 스택 정리

AI 서비스 개발에서는 다음 기술 스택이 자주 사용된다.

Backend
├ FastAPI
├ LangChain
└ Python

AI Model
├ OpenAI
├ Claude
└ Llama

Data
├ Vector DB
├ PostgreSQL
└ Elasticsearch

Infrastructure
├ Docker
├ Kubernetes
└ Monitoring
 

7. 정리

AI 서비스는 단순한 LLM 호출이 아니라
검색, 데이터, API, 자동화가 결합된 시스템이다.

대표적인 AI 서비스 스택은 다음과 같다.

  • FastAPI → AI API 서버
  • LangChain → AI workflow orchestration
  • Vector Database → 문서 검색 시스템

이 세 가지를 결합하면
RAG 기반 AI 서비스를 구축할 수 있다.

앞으로 AI 서비스 아키텍처에서는
이러한 구조가 하나의 표준 패턴이 될 가능성이 높다

LIST

최근 AI 서비스 개발 방식은 크게 변하고 있다.
이전에는 개발자가 직접 코드를 작성하는 방식이 중심이었다면,
현재는 AI와 협업하는 개발 환경(AI Assisted Development) 이 빠르게 확산되고 있다.

특히 AI 서비스 개발에서는 IDE와 AI 코딩 모델의 역할이 분리된 구조가 일반적이다.

대표적인 조합이 다음과 같다.

IDE (개발 환경)

PyCharm

AI Coding Assistant

Claude Code
 

이 글에서는 AI 서비스 개발에서 PyCharm과 Claude Code가 어떤 역할을 하는지 정리해본다.


1. PyCharm의 역할

PyCharm은 Python 개발을 위한 IDE(Integrated Development Environment) 이다.

AI 서비스 개발에서 Python은 사실상 표준 언어가 되었기 때문에
PyCharm은 AI 프로젝트 개발 환경으로 많이 사용된다.

PyCharm의 주요 역할은 다음과 같다.

코드 작성 환경

Python 코드 작성

FastAPI
LangChain
AI Agent
RAG 시스템
 

프로젝트 관리

AI 프로젝트는 다음과 같은 구조를 가진다.

ai-service
├ api
├ agents
├ rag
├ vector
├ prompts
└ tools
 

PyCharm은 이러한 프로젝트 구조를 효율적으로 관리할 수 있다.


디버깅

AI 서비스 개발에서는 다음 문제가 자주 발생한다.

  • Prompt 오류
  • API 호출 오류
  • 데이터 처리 문제

PyCharm은 디버깅 기능을 통해 문제를 쉽게 추적할 수 있다.


Python 생태계 지원

AI 개발에서 사용하는 주요 라이브러리

  • LangChain
  • LlamaIndex
  • FastAPI
  • Pandas
  • NumPy

PyCharm은 Python 패키지 관리와 가상환경 관리에 강점을 가진다.


2. Claude Code의 역할

Claude Code는 AI 기반 코딩 모델이다.

개발자가 코드를 작성할 때 다음과 같은 작업을 수행한다.

  • 코드 생성
  • 코드 리팩토링
  • 코드 설명
  • 아키텍처 설계
  • 버그 수정

즉 Claude Code는 AI 개발 파트너 역할을 한다.

예를 들어 개발자는 다음과 같은 요청을 할 수 있다.

FastAPI 기반 RAG API 만들어줘
 

Claude Code는 다음과 같은 코드를 생성할 수 있다.

FastAPI
Vector Search
LangChain
LLM 호출
 

이러한 방식으로 개발 속도가 크게 증가한다.


3. AI 서비스 개발에서의 협업 구조

AI 서비스 개발에서는 다음과 같은 구조로 작업이 이루어진다.

Developer

IDE (PyCharm)

AI Coding Assistant (Claude Code)

Python Code

AI Service
 

즉 개발자는

  • 설계를 담당하고
  • AI는 코드 작성을 보조하는 방식이다.

4. AI 개발 생산성 변화

AI 코딩 도구가 등장하면서 개발 생산성이 크게 변했다.

기존 개발 방식

문서 검색

코드 작성

테스트

수정
 

AI 협업 개발 방식

설계

AI 코드 생성

검증

리팩토링
 

개발자는 이제 코드를 직접 작성하기보다는 설계와 검증 역할에 집중하게 된다.


5. AI 서비스 개발 스택

AI 서비스 개발 환경은 보통 다음과 같이 구성된다.

Development Environment
├ PyCharm
├ Git
└ Docker

AI Coding Assistant
├ Claude Code
├ Copilot
└ ChatGPT

AI Framework
├ LangChain
├ LlamaIndex
└ FastAPI

AI Infrastructure
├ Vector DB
├ Kubernetes
└ Monitoring
 

이러한 스택은 AI 서비스 개발의 기본 구조가 되고 있다.


6. AI 개발자의 역할 변화

AI 코딩 도구가 발전하면서 개발자의 역할도 변하고 있다.

과거

코드 작성 중심 개발
 

현재

아키텍처 설계
AI 활용
코드 검증
시스템 통합
 

즉 AI 시대의 개발자는 AI와 협업하는 시스템 설계자 역할에 가까워지고 있다.


7. 정리

AI 서비스 개발에서는 IDE와 AI 코딩 모델의 역할이 분리된 구조가 일반적이다.

PyCharm의 역할

  • Python 개발 환경
  • 프로젝트 관리
  • 디버깅

Claude Code의 역할

  • 코드 생성
  • 코드 리팩토링
  • AI 코딩 보조

이 두 도구를 함께 사용하면 AI 서비스 개발 생산성을 크게 높일 수 있다.

앞으로 개발 환경은 IDE + AI Coding Assistant 구조로 발전할 가능성이 높다.

LIST

최근 AI 서비스는 단순한 ChatGPT API 호출을 넘어
검색, 데이터 분석, API 호출, 자동화 등 다양한 기능을 결합하는 방향으로 발전하고 있다.

이러한 AI 애플리케이션을 구축하기 위해 등장한 대표적인 프레임워크가 LangChain이다.

LangChain은 LLM 기반 애플리케이션을 쉽게 개발하기 위한 프레임워크로,
AI 모델과 다양한 데이터 및 시스템을 연결하는 역할을 한다.


1. LangChain이 필요한 이유

기본적인 LLM API 사용 방식은 다음과 같다.

User Question

LLM API

Response
 

이 구조는 간단하지만 실제 서비스에서는 다음 문제가 발생한다.

  • 최신 정보를 모른다
  • 회사 내부 데이터를 사용할 수 없다
  • 복잡한 작업을 수행하기 어렵다
  • 외부 API와 연동하기 어렵다

그래서 AI 서비스에서는 다음과 같은 기능이 필요하다.

  • 문서 검색
  • 데이터베이스 조회
  • API 호출
  • 업무 자동화
  • 멀티 스텝 작업 처리

LangChain은 이러한 문제를 해결하기 위해 등장했다.


2. LangChain의 핵심 개념

LangChain은 LLM을 중심으로 다양한 컴포넌트를 연결하는 구조를 제공한다.

핵심 구성 요소는 다음과 같다.

1️⃣ LLM

AI 모델과 연결하는 역할

OpenAI
Claude
Llama
Gemini
 

2️⃣ Prompt Template

LLM에 전달할 프롬프트를 구조화한다.

You are a helpful assistant.

Question:
{question}

Answer:
 

프롬프트를 템플릿화하면 재사용성과 관리가 좋아진다.


3️⃣ Chains

여러 작업을 연결하는 구조이다.

User Question

Document Search

Context 생성

LLM 호출

Response
 

이러한 작업 흐름을 Chain이라고 한다.


4️⃣ Agents

Agent는 LLM이 스스로 어떤 도구를 사용할지 판단하는 시스템이다.

User: 오늘 서울 날씨 알려줘
 

Agent는 다음과 같이 판단한다.

LLM reasoning

Weather API 호출

결과 반환
 

즉 Agent는 LLM 기반 의사결정 시스템이다.


5️⃣ Memory

대화 기록을 유지하는 기능이다.

User: 내 이름은 르무엘이야
User: 내 이름이 뭐야?
 

Memory가 없다면 LLM은 이전 대화를 기억하지 못한다.

LangChain은 대화 상태 관리 기능을 제공한다.


3. RAG와 LangChain

LangChain이 가장 많이 사용되는 분야는 RAG 시스템이다.

RAG(Retrieval Augmented Generation)는
외부 데이터를 검색해서 LLM에 제공하는 방식이다.

구조는 다음과 같다.

User Question

Embedding

Vector Database

Relevant Documents

LLM

Response
 

LangChain은 이 과정을 쉽게 구현할 수 있도록 도와준다.

대표적인 Vector Database

  • Pinecone
  • Weaviate
  • Chroma
  • pgvector
  • Elasticsearch

4. LangChain 기반 AI 서비스 아키텍처

실제 AI 서비스에서는 다음과 같은 구조가 많이 사용된다.

User

API Server (FastAPI / Spring)

LangChain

LLM

Vector DB

External Tools
 

LangChain은 AI 애플리케이션의 orchestration layer 역할을 한다.

즉 LLM과 데이터, API, 도구를 연결하는 AI 서비스 엔진이다.


5. LangChain 사용 예시

예를 들어 회사 문서 검색 AI 서비스를 만든다고 가정해보자.

구조는 다음과 같다.

User

Question

Embedding 생성

Vector DB 검색

관련 문서 추출

LLM Context 전달

Answer 생성
 

LangChain은 이러한 흐름을 하나의 체인으로 구성할 수 있다.


6. LangChain의 장점

1️⃣ AI 서비스 개발 속도 향상

LLM 기반 시스템을 빠르게 구축할 수 있다.


2️⃣ 다양한 LLM 지원

다양한 모델을 쉽게 교체할 수 있다.

OpenAI → Claude → Local LLM
 

3️⃣ Tool Integration

다양한 시스템과 연결 가능하다.

  • API
  • Database
  • Vector DB
  • Search Engine

4️⃣ Agent 기반 AI 시스템

복잡한 AI 자동화 시스템을 구축할 수 있다.


7. LangChain의 한계

LangChain은 강력하지만 몇 가지 한계도 존재한다.

복잡성 증가

AI 시스템이 커질수록 구조가 복잡해질 수 있다.


성능 문제

체인과 Agent가 많아지면 latency가 증가할 수 있다.


운영 난이도

AI 서비스는

  • Prompt 관리
  • 모델 비용
  • 응답 품질 관리

등이 필요하다.


8. 정리

LangChain은 LLM 기반 애플리케이션을 위한 핵심 프레임워크이다.

AI 서비스 개발에서는 다음 역할을 한다.

  • LLM orchestration
  • 데이터 연결
  • Agent 시스템
  • RAG 구현

앞으로 AI 서비스 아키텍처에서 LangChain과 같은 프레임워크는
Backend Framework처럼 중요한 역할을 하게 될 가능성이 높다.

LIST

최근 AI 서비스 구조는 단순한 LLM API 호출을 넘어 Multi-Agent Architecture로 빠르게 발전하고 있다.
특히 RAG, 자동화, AI 서비스 플랫폼에서는 여러 개의 AI Agent가 협력하는 구조가 점점 일반적인 패턴이 되고 있다.

이 글에서는 Multi-Agent의 개념, 왜 필요한지, 그리고 실제 서비스 아키텍처에서 어떻게 사용하는지 정리해본다.


1. Agent란 무엇인가

AI 시스템에서 Agent는 다음과 같은 역할을 수행하는 프로그램이다.

  • 입력을 이해한다
  • 필요한 행동을 판단한다
  • 외부 시스템과 상호작용한다
  • 결과를 생성한다

즉 단순한 LLM 호출이 아니라 목표 기반 행동 시스템이다.

예를 들어 하나의 Agent는 다음과 같은 구조를 가진다.

User Question

Agent

Tool / API / DB

LLM reasoning

Response
 

대표적인 Agent 프레임워크

  • LangChain Agent
  • AutoGPT
  • CrewAI
  • OpenAI Agents

2. Single Agent의 한계

초기 AI 서비스는 대부분 Single Agent 구조였다.

User

LLM

Response
 

문제는 실제 서비스에서는 다음과 같은 작업이 동시에 필요하다.

  • 검색
  • 데이터 분석
  • 코드 생성
  • API 호출
  • 업무 자동화

이 모든 역할을 하나의 Agent가 처리하면 복잡도가 폭발한다.

그래서 등장한 개념이 Multi-Agent Architecture이다.


3. Multi-Agent Architecture

Multi-Agent 시스템은 여러 Agent가 역할을 나누어 협력하는 구조이다.

예시

User Request

Orchestrator Agent

┌───────────────┬───────────────┬───────────────┐
Research Agent             Coding Agent          Analysis Agent
↓ ↓ ↓
Search API Code  Tool Data Tool
↓ ↓ ↓
Result Integration
 

이 구조의 핵심은 역할 분리(Role Separation) 이다.

각 Agent는 하나의 책임만 가진다.

Agent역할
Orchestrator 전체 작업 계획
Research Agent 정보 검색
Analysis Agent 데이터 분석
Coding Agent 코드 생성
Review Agent 결과 검증

이 구조는 Microservice Architecture와 매우 유사하다.


4. Multi-Agent의 장점

1️⃣ 역할 분리

Agent마다 역할을 분리하면 시스템이 단순해진다.

Search Agent → 검색만 담당
Coding Agent → 코드만 생성
Review Agent → 결과 검증
 

2️⃣ 확장성

Agent는 쉽게 추가할 수 있다.

AI Writing Service

Orchestrator
├ Research Agent
├ Writing Agent
├ Fact Check Agent
└ Editing Agent
 

3️⃣ 품질 향상

여러 Agent가 협력하면 AI hallucination을 줄일 수 있다.

Research Agent → 자료 수집
Analysis Agent → 데이터 해석
Review Agent → 결과 검증
 

4️⃣ 서비스 자동화

Multi-Agent는 복잡한 워크플로우 자동화에 적합하다.

  • 고객 지원 AI
  • 개발 자동화
  • 업무 자동화
  • 데이터 분석 자동화

5. Multi-Agent 시스템 아키텍처

실제 서비스에서는 다음 구조가 많이 사용된다.

User

API Gateway

Orchestrator Agent

Agent Pool
├ Search Agent
├ RAG Agent
├ Analysis Agent
├ Coding Agent
└ Review Agent

Vector DB / Tools / API

Response
 

핵심 구성요소

  • Orchestrator Agent
  • Specialized Agents
  • Tool / API Integration
  • Vector Database
  • Memory System

6. Multi-Agent + RAG

현재 가장 많이 사용하는 구조는 다음이다.

User

Orchestrator Agent

RAG Agent

Vector DB

Context Retrieval

LLM Reasoning

Response
 

여기에 추가로

Evaluation Agent
 

를 두어 결과 품질을 검증하기도 한다.


7. Multi-Agent Framework

대표적인 프레임워크

Framework특징
LangChain 가장 널리 사용
CrewAI 협업 Agent 구조
AutoGen Microsoft 연구
OpenAI Agents OpenAI 기반 Agent

8. Multi-Agent가 중요한 이유

앞으로 AI 서비스는 다음 방향으로 발전할 가능성이 높다.

Single LLM

Tool-Using LLM

Agent

Multi-Agent Systems
 

즉 AI 서비스는 점점 "여러 AI가 협력하는 시스템" 으로 발전하고 있다.

이 구조는 특히 다음 영역에서 중요하다.

  • AI SaaS
  • AI 자동화 플랫폼
  • DevOps 자동화
  • AI 코딩 도구

9. 정리

Multi-Agent Architecture는 AI 서비스를 확장 가능하게 만드는 핵심 설계 패턴이다.

핵심 개념은 다음 세 가지이다.

  • Agent 역할 분리
  • 협력 기반 AI 시스템
  • Orchestrator 중심 아키텍처

앞으로 AI 서비스 설계에서는 Multi-Agent 구조가 하나의 표준 패턴이 될 가능성이 높다.

LIST

최근 AI 서비스에서는 단순히 LLM을 호출하는 것만으로는 부족하다.
기업 서비스에서는 외부 지식, 데이터베이스, 문서 시스템을 함께 활용해야 한다.

이를 위해 등장한 구조가 바로

  • RAG (Retrieval Augmented Generation)
  • Multi-Agent 시스템

이다.

이 글에서는 AI 서비스 백엔드 관점에서 RAG와 Multi-Agent 아키텍처를 정리해본다.

1. LLM의 한계

기본적인 LLM(ChatGPT, Claude 등)은 다음과 같은 한계를 가진다.

1️⃣ 최신 데이터 접근 불가

LLM은 학습 데이터 이후의 정보를 모른다.

회사 내부 문서
최근 정책
고객 데이터
 

이런 정보는 LLM이 알 수 없다.


2️⃣ 기업 내부 데이터 접근 불가

예를 들어

사내 위키
Notion
DB
PDF 문서
코드 저장소
 

LLM은 기본적으로 접근할 수 없다.


3️⃣ hallucination (환각)

LLM은 모르는 내용도 그럴듯하게 만들어낸다.

이 문제를 해결하기 위해 나온 구조가

RAG (Retrieval Augmented Generation) 이다.


2. RAG (Retrieval Augmented Generation)

RAG는 검색 + LLM 구조다.

LLM이 답변을 만들기 전에
관련 문서를 먼저 검색해서 context로 제공한다.


RAG 기본 구조

흐름은 다음과 같다.

1️⃣ 사용자 질문
2️⃣ 질문을 embedding으로 변환
3️⃣ Vector DB에서 유사 문서 검색
4️⃣ 문서를 LLM context로 전달
5️⃣ LLM이 답변 생성


Vector Database

RAG 시스템에서는 보통 Vector DB를 사용한다.

대표적인 Vector DB

Pinecone
Milvus
Weaviate
Chroma
ElasticSearch Vector
 

문서 저장 방식

문서 → chunk 분할
chunk → embedding 생성
embedding → vector DB 저장
 

RAG의 장점

최신 데이터 사용

LLM이 학습하지 않은 데이터도 활용 가능하다.

회사 정책
기술 문서
고객 데이터
 

hallucination 감소

LLM이 검색된 문서를 기반으로 답변한다.


3. Multi-Agent 시스템

RAG만으로 해결되지 않는 문제도 있다.

복잡한 작업
여러 단계 처리
툴 호출
데이터 분석
 

이때 등장하는 것이 Multi-Agent 시스템이다.


Agent란 무엇인가

Agent는 LLM 기반 작업 단위라고 볼 수 있다.

검색 Agent
요약 Agent
분석 Agent
코드 생성 Agent
 

각 Agent는 특정 역할을 가진다.


Multi-Agent 구조


Multi-Agent의 특징

역할 분리

각 Agent가 특정 작업을 수행한다.

Research Agent → 정보 검색
RAG Agent → 문서 검색
Analysis Agent → 데이터 분석
 

복잡한 작업 처리

사용자 질문

우리 회사 제품과 경쟁사 제품 비교 분석해줘
 

Multi-Agent 처리

Agent 1 → 경쟁사 정보 검색
Agent 2 → 내부 문서 검색
Agent 3 → 분석
Agent 4 → 보고서 작성
 

4. RAG + Multi-Agent 결합

최근 AI 서비스는 보통 이 구조를 사용한다.

 
 
 

실제 서비스 예

기업 챗봇

RAG → 회사 문서 검색
Agent → 고객 질문 분석
Agent → 답변 생성
 

개발자 AI Assistant

RAG → 코드 저장소 검색
Agent → 코드 분석
Agent → 코드 생성
 

업무 자동화 AI

Agent → 이메일 분석
Agent → 데이터 조회
Agent → 보고서 생성
 

5. 기술 스택

RAG + Agent 시스템은 보통 다음 스택을 사용한다.

LLM Framework

LangChain
LlamaIndex
Semantic Kernel
 

Agent Framework

LangGraph
CrewAI
AutoGen
 

Vector DB

Pinecone
Milvus
Weaviate
Chroma
 

Backend

Python
FastAPI
Redis
PostgreSQL
 

6. AI 서비스 아키텍처 관점

AI 서비스는 이제 단순 LLM 호출이 아니라
플랫폼 형태로 발전하고 있다.

 
 
 

이 구조에서 중요한 것은

LLM
+
검색 시스템
+
Agent orchestration
 

이다.


정리

AI 서비스의 핵심 구조는 다음과 같다.

RAG

검색 기반 LLM
 

Multi-Agent

LLM 작업 분산 시스템
 

두 기술이 결합되면

지식 기반 AI 시스템
 

을 구축할 수 있다.


마무리

LLM 시대의 백엔드 개발자는 단순 API 개발을 넘어서

RAG 시스템
Agent 시스템
Vector Database
AI 서비스 아키텍처
 

를 이해해야 한다.

AI 서비스는 이제 LLM 호출이 아니라 시스템 설계 문제가 되고 있다.

LIST

[왕초보] 마케터, 기획자를 위한 실전 데이터 분석 5주차[파이썬,python] -스파르타코딩클럽

 

import pandas as pd
import matplotlib.pyplot as plt
plt.rc('font', family='NanumBarunGothic') #한글 깨짐 방지 설정
sparta_data = pd.read_csv('파일경로')
#마지막 5개의 데이터 확인 하기
sparta_data.tail()

#나이대별로 수강률 합 구하기
progress_rate_by_age = sparta_data.groupby('age')['progress_rate'].sum()
progress_rate_by_age

#나이대별 수강인원 구하기
number_people_by_age = sparta_data.groupby('age')['_id'].count()
number_people_by_age

#나이대별 완주율 평균 구하기
average = progress_rate_by_age/number_people_by_age
average

#plt.figure(width, height) : 넓이와 높이 만큼 이미지를 생성한다는 것을 말해줍니다!
plt.figure(figsize=(6,6))

#그래프의 x축 눈금 설정
plt.xticks([10,20,30,40,50])

#plt.bar(X축값, Y축값)
plt.bar("x축", "y축")


#그래프의 바에 각 수치율을 추가 해 볼까요?
bar = plt.bar("x축", "y축",width="너비")
for rect in bar:
    height = rect.get_height()
    plt.text(rect.get_x() + rect.get_width()/2.0, height, '%.1f' % height, ha='center', va='bottom', size = 12)


#그래프의 제목
#타이틀과 그래프와의 간격은 pad= 수치 로 나타내어요!
plt.title('[나이대 별 평균 수강율]',fontsize=15,pad=20)

#그래프의 x축 라벨 이름
#labelpad 파라미터는 축 레이블의 여백을 지정합니다.
plt.xlabel('나이',fontsize=12,labelpad=20)

#그래프의 y축 라벨 이름
plt.ylabel('수강생(명)',fontsize=14,rotation=360,labelpad=35)

#그래프를 화면에 나타나도록 합니다.
plt.show()

#plt.figure(width, height) : 넓이와 높이 만큼 이미지를 생성한다는 것을 말해줍니다!
plt.figure(figsize=(6,6))

#그래프의 x축 눈금 설정
plt.xticks([10,20,30,40,50])

#plt.bar(X축값, Y축값)
plt.bar(average.index, average,width=8)


#그래프의 바에 각 수치율을 추가 해 볼까요?
bar = plt.bar(average.index, average,width=8)
for rect in bar:
    height = rect.get_height()
    plt.text(rect.get_x() + rect.get_width()/2.0, height, '%.1f' % height, ha='center', va='bottom', size = 12)


#그래프의 제목
plt.title('[나이대별 평균 수강율]',fontsize=15,pad=20)plt.title('[나이대별 평균 수강율]',fontsize=15,pad=20)

#그래프의 x축 라벨 이름
plt.xlabel('나이',fontsize=12,labelpad=20)

#그래프의 y축 라벨 이름
plt.ylabel('수강생(명)',fontsize=14,rotation=360,labelpad=35)

#그래프를 화면에 나타나도록 합니다.
plt.show()

!sudo apt-get install -y fonts-nanum
!sudo fc-cache -fv
!rm ~/.cache/matplotlib -rf

 

 

 

#라이브러리 불러오기
import pandas as pd
import matplotlib.pyplot as plt
# 한글깨짐 방지
plt.rc('font', family='NanumBarunGothic')

sparta_data = pd.read_table('파일경로',sep=',')
#하위 5개의 데이터 확인하기
sparta_data.tail()

#나이대별 수강율 평균 구하기
progress_rate_by_age = sparta_data.groupby('age')['progress_rate'].sum()
progress_rate_by_age
number_people_by_age = sparta_data.groupby('age')['_id'].count()
number_people_by_age
average = progress_rate_by_age/number_people_by_age

#plt.figure(width, height) : 넓이와 높이 만큼 이미지를 생성한다는 것을 말해줍니다!
plt.figure(figsize=(6,6))

#그래프의 x축 눈금 설정
plt.xticks([10,20,30,40,50])

#plt.bar(X축값, Y축값)
plt.bar(average.index, average,width=8)


#그래프의 바에 각 수치율을 추가하기
bar = plt.bar(average.index, average,width=8)
for rect in bar:
    height = rect.get_height()
    plt.text(rect.get_x() + rect.get_width()/2.0, height, '%.1f' % height, ha='center', va='bottom', size = 12)


#그래프의 제목
plt.title('[나이대별 평균 수강율]',fontsize=15,pad=20)

#그래프의 x축 라벨 이름
plt.xlabel('나이',fontsize=12,labelpad=20)

#그래프의 y축 라벨 이름
plt.ylabel('수강생(명)',fontsize=14,rotation=360,labelpad=35)

#그래프를 화면에 나타나도록 합니다.
plt.show()

 

#라이브러리 불러오기
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
plt.rc('font', family='NanumBarunGothic')
sparta_data = pd.read_csv('파일경로')
managed = ['TRUE','FALSE'] # 데이터 수정하기
managed

#관리 여부에 따라, 수강완료율 평균 구하기
managed_data_avg = sparta_data.groupby('managed')['progress_rate'].sum()/sparta_data.groupby('managed')['_id'].count()
managed_data_avg

#plt.figure(width, height) : 넓이와 높이 만큼 이미지를 생성한다는 것을 말해줍니다!
plt.figure(figsize=(6,6))


#각각 어떤 값이 들어가야 하는지 입력해 볼까요?
#plt.bar(X축값, Y축값)
plt.bar("x축 기입" ,"y축 기입")

#그래프의 바에 각 수치율을 추가 해 볼까요?
bar = plt.bar("x축 기입" ,"y축 기입")
for rect in bar:
    height = rect.get_height()
    plt.text(rect.get_x() + rect.get_width()/2.0, height, '%.1f' % height, ha='center', va='bottom', size = 12)


#그래프의 제목
plt.title('찐한관리 유무에 따른 평균 완주율',fontsize=14)
#그래프의 x축 라벨 이름
plt.xlabel('평균 완주율',fontsize=12)
#x축 눈금 레이블 지정하기
#기존의 0,1이라는 x축 레이블을, labels =["..."]로 변경 가능 합니다 :)
plt.xticks([0,1], labels=["찐한관리 비 신청자","찐한관리 신청자"])
#그래프의 y축 라벨 이름
plt.ylabel('찐한관리 여부',fontsize=12,rotation=360,labelpad=35)
#x축 눈금의 글씨를 45도 회전
plt.xticks(rotation=45)
#y축 눈금의 글씨를 360도 회전
plt.yticks(rotation=360)
#그래프를 화면에 나타나도록 합니다.
plt.show()

 

찐한관리를 하면 완주율이 높아질까?

#라이브러리 불러오기
import pandas as pd
import matplotlib.pyplot as plt
plt.rc('font', family='NanumBarunGothic')

#파일 불러오기
sparta_data = pd.read_table('/content/sparta_data.csv',sep=',')

#결측치 제거
sparta_data = sparta_data.dropna()

#데이터 확인 하기
sparta_data.tail() 
managed = ['TRUE','FALSE'] # 데이터 수정하기

# sparta_data.groupby('managed')['progress_rate'].count()
managed_data_avg = sparta_data.groupby('managed')['progress_rate'].sum()/sparta_data.groupby('managed')['_id'].count()

#plt.figure(width, height) : 넓이와 높이 만큼 이미지를 생성한다는 것을 말해줍니다!
plt.figure(figsize=(6,6))

#plt.bar(X축값, Y축값)
plt.bar(managed_data_avg.index,managed_data_avg.values)

#그래프의 바에 각 수치율을 추가
bar = plt.bar(managed_data_avg.index,managed_data_avg.values)
for rect in bar:
    height = rect.get_height()
    plt.text(rect.get_x() + rect.get_width()/2.0, height, '%.1f' % height, ha='center', va='bottom', size = 12)


#그래프의 제목
plt.title('찐한관리 유무에 따른 평균 완주율',fontsize=14)
#그래프의 x축 라벨 이름
plt.xlabel('평균 완주율',fontsize=12)
#x축 눈금 레이블 지정하기
plt.xticks([0,1], labels=["찐한관리 비 신청자","찐한관리 신청자"])
#그래프의 y축 라벨 이름
plt.ylabel('찐한관리 여부',fontsize=12,rotation=360,labelpad=35)
#x축 눈금의 글씨를 45도 회전
plt.xticks(rotation=45)
#y축 눈금의 글씨를 360도 회전
plt.yticks(rotation=360)
#그래프를 화면에 나타나도록 합니다.
plt.show()

 

프로덕트 개선은 정말 도움이 되었을까?_ 전처리 및 분석

#라이브러리 불러오기
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
plt.rc('font', family='NanumBarunGothic')
sparta_data = pd.read_table('파일 경로',sep=',')
#테이블 하위 5개의 정보 확인하기
sparta_data.tail()

#파이썬의 type()함수를 쓰면, 데이터의 종류를 확인 할수 있어요 :)
print(type(sparta_data['created_at'][1]))
#sparta_date 정보에서 access_date 열에서 데이터 첫번째 부분만 확인 하면 되겠죠?

format='%Y-%m-%dT%H:%M:%S.%f'
sparta_data['start_time'] = pd.to_datetime(sparta_data['created_at'], format=format,infer_datetime_format=True)
sparta_data.tail()

#수강 시작 주 구하고, 테이블의 열로 추가 하기
sparta_data['start_week']= sparta_data['start_time'].dt.isocalendar().week
sparta_data.tail()

#이전에 배웠듯이 set()은 set안의 데이터는 순서가 정해져있지 않고, 중복되지 않는 고유한 요소를 가져옵니다!
category_range = set(sparta_data['start_week'])
category_range

progress_rate = list(sparta_data['progress_rate'])

#범주를 구분하는 기준 bins 처음(0)과 끝(100) 잊지 말고 기입 해주세요!
bins = [0,4.11,26.03,41.10,61.64,80.82,100]
#구분한 범주의 라벨 labels
labes=[0,1,2,3,4,5]


#범주화에 사용하는 함수 pd.cut
cuts = pd.cut(progress_rate,bins, right=True,include_lowest=True, labels=labes)
cuts

#결과물을 테이블로 변경하기
cuts = pd.DataFrame(cuts)
cuts.tail()

#concat() 함수를 이용하여, sparta_data 테이블과, cuts 테이블 병합 할수 있습니다 :)
sparta_data = pd.concat([sparta_data,cuts],axis=1, join='inner')
sparta_data.head()

sparta_data.columns[6]="weeks"
#6번째의 컬럼의 이름만 "weeks" 변경 해주면 되겠죠?
#하지만 이렇게 작성하면 오류가 발생 할꺼예요!

#그래서, 귀찮더라도, 우리가 원하는 컬럼의 이름을 다 작성해 줍시다!
sparta_data.columns=['created_at','user_id','name','progress_rate','start_time','start_week',"week"]
sparta_data.head()

#기존의 테이블을, start_week와, week로 묶어줍니다!
grouping = sparta_data.groupby(['start_week','week'])
grouping.head()

cohort_data = grouping['user_id'].apply(pd.Series.nunique)
cohort_data = pd.DataFrame(cohort_data)
cohort_data.head(5)

#첫 주가 31주니 변수를 하나 만들어 줍니다!
f=31
#처음 수강 시작한 주의 범위가 {31,32,33,34,35,36} 이니, range(6)으로 합시다!
for i in range(6):
	#5주차의 강의가 마지막이고, 0주차까지 이니, 시작은 5에서 시작해 1씩 0까지 감소 시킬수 있어요!
  for j in range(5, 0, -1):
    cohort_data.at[(f,j-1), 'user_id'] = int(cohort_data.at[(f,j),'user_id']) +  int(cohort_data.at[(f,j-1),'user_id'])
	#주차는(31부터 32 33..) 1씩 늘어나죠?
  f=f+1
  
cohort_data = cohort_data.reset_index()
cohort_data.head()

#피벗테이블 만들기
cohort_counts = cohort_data.pivot(index="start_week",
                                  columns="week",
                                  values="user_id")
cohort_counts


#리텐션 테이블 만들기(지속적수요 파악)
# 앞서 만든 피벗 테이블을 retention 변수에 저장하기
retention = cohort_counts

#각 주(week) 별 최초 수강생 수만 가져오기 (나눠줄때, 분모가 되는 부분!)
cohort_sizes = cohort_counts.iloc[:,0]
cohort_sizes.head()

#각 수치 퍼센트로 변경하기
#round 함수로 3자리 수에서 반올림 한 후, 100을 곱해 줍니다!
retention.round(3)*100


# 히트맵 사용하기( 두개 테이터 비교 분석)
sns.heatmap(data="필요한 데이터 입력하기",
           annot=True, #각 cell의 데이터 표기 유무를 나타냅니다!
           fmt='.0%', #values(데이터의 값) 값의 소수점 표기
           vmin=0,#최소값 설정
           vmax=1,#최댓값 설정
           cmap="BuGn" #히트맵의 색을 설정합니다 
						)
                        
#테이블 크기 설정 하기
plt.figure(figsize=(10,8))

sns.heatmap(data="필요한 데이터 입력하기",
           annot=True,
           fmt='.0%',
           vmin=0,
           vmax=1,
           cmap="BuGn")


plt.xlabel('주차', fontsize=14,labelpad=30)

plt.ylabel('개강일', fontsize=14,rotation=360,labelpad=30)
plt.yticks(rotation=360)

plt.show()

#테이블 크기 설정 하기
plt.figure(figsize=(10,8))

sns.heatmap(data=retention,
           annot=True,
           fmt='.0%',
           vmin=0,
           vmax=1,
           cmap="BuGn")


plt.xlabel('주차', fontsize=14,labelpad=30)
plt.ylabel('개강일', fontsize=14,rotation=360,labelpad=30)
#y축 레이블 축 변경 하기
plt.yticks(rotation=360)
#테이블 보여주기
plt.show()

 

 

 

#라이브러리 불러오기
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
plt.rc('font', family='NanumBarunGothic')

# 한글깨짐 방지
plt.rc('font', family='NanumBarunGothic')
sparta_data = pd.read_table('파일경로',sep=',')
sparta_data.tail()

#날짜 데이터 타입 변경
format='%Y-%m-%dT%H:%M:%S.%f'
sparta_data['start_time'] = pd.to_datetime(sparta_data['created_at'], format=format,infer_datetime_format=True)
sparta_data.tail()

#시작 week 구하기
sparta_data['start_week']= sparta_data['start_time'].dt.isocalendar().week
sparta_data.tail()

#시작 주 범위 알기
category_range = set(sparta_data['start_week'])
category_range

# 범주화 하기
#번주화할 데이터 
progress_rate = list(sparta_data['progress_rate'])
progress_rate

#범주를 구분하는 기준 bins
bins = [0,4.11,26.03,41.10,61.64,80.82,100]

#구분한 범주의 라벨 labels
labes=[0,1,2,3,4,5]

#범주화에 사용하는 함수 pd.cut
cuts = pd.cut(progress_rate,bins, right=True,include_lowest=True, labels=labes)
cuts
cuts = pd.DataFrame(cuts)
cuts.tail()


# 표 합치기
sparta_data = pd.concat([sparta_data,cuts],axis=1, join='inner')
sparta_data.head()

#표 인덱스 변경하기
sparta_data.columns=['created_at','user_id','name','progress_rate','start_time','start_week',"week"]
sparta_data.head()

#시작주와, 수강 주차별 기준으로 표 grouping 하기
grouping = sparta_data.groupby(['start_week','week'])
grouping.head()

#시작주와, 수강 주차별에 해당하는 수강생 수 구하기
cohort_data = grouping['user_id'].apply(pd.Series.nunique)
cohort_data = pd.DataFrame(cohort_data)
cohort_data.head(10)

#각 주차별 수강한 수강생 총 합 구하기
k=31
for i in range(6):
  for j in range(5, 0, -1):
    cohort_data.at[(k,j-1), 'user_id'] = int(cohort_data.at[(k,j),'user_id']) +  int(cohort_data.at[(k,j-1),'user_id'])
  k=k+1
cohort_data = cohort_data.reset_index()
cohort_data.head()


cohort_counts = cohort_data.pivot(index="start_week",
                                  columns="week",
                                  values="user_id")
cohort_counts

# 앞서 만든 피벗 테이블을 retention 변수에 저장하기
retention = cohort_counts
#각 주(week) 별 최초 수강생 수만 가져오기
cohort_sizes = cohort_counts.iloc[:,0]
cohort_sizes.head()

# 최초 수강생 수를 각 데이터에 나눠주기
retention = cohort_counts.divide(cohort_sizes, axis=0)
retention

#각 수치 퍼센트로 변경하기
retention.round(3)*100

#테이블 크기 설정 하기
plt.figure(figsize=(10,8))

sns.heatmap(data="필요한 데이터 입력하기",
           annot=True,
           fmt='.0%',
           vmin=0,
           vmax=1,
           cmap="BuGn")


plt.xlabel('주차', fontsize=14,labelpad=30)

plt.ylabel('개강일', fontsize=14,rotation=360,labelpad=30)
plt.yticks(rotation=360)

plt.show()

주차 간 전환율 리텐션 테이블 만들기 ,주차 간 전환율 그래프로 나타내기

#라이브러리 불러오기
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
plt.rc('font', family='NanumBarunGothic')

# 한글깨짐 방지
plt.rc('font', family='NanumBarunGothic')
sparta_data = pd.read_table('파일경로',sep=',')
sparta_data.tail()

#날짜 데이터 타입 변경
format='%Y-%m-%dT%H:%M:%S.%f'
sparta_data['start_time'] = pd.to_datetime(sparta_data['created_at'], format=format,infer_datetime_format=True)
sparta_data.tail()

#시작 week 구하기
sparta_data['start_week']= sparta_data['start_time'].dt.isocalendar().week
sparta_data.tail()

#시작 주 범위 알기
category_range = set(sparta_data['start_week'])
category_range

# 범주화 하기
#번주화할 데이터 
progress_rate = list(sparta_data['progress_rate'])
progress_rate

#범주를 구분하는 기준 bins
bins = [0,4.11,26.03,41.10,61.64,80.82,100]

#구분한 범주의 라벨 labels
labes=[0,1,2,3,4,5]

#범주화에 사용하는 함수 pd.cut
cuts = pd.cut(progress_rate,bins, right=True,include_lowest=True, labels=labes)
cuts
cuts = pd.DataFrame(cuts)
cuts.tail()


# 표 합치기
sparta_data = pd.concat([sparta_data,cuts],axis=1, join='inner')
sparta_data.head()

#표 인덱스 변경하기
sparta_data.columns=['created_at','user_id','name','progress_rate','start_time','start_week',"week"]
sparta_data.head()

#시작주와, 수강 주차별 기준으로 표 grouping 하기
grouping = sparta_data.groupby(['start_week','week'])
grouping.head()

#시작주와, 수강 주차별에 해당하는 수강생 수 구하기
cohort_data = grouping['user_id'].apply(pd.Series.nunique)
cohort_data = pd.DataFrame(cohort_data)
cohort_data.head(10)

#각 주차별 수강한 수강생 총 합 구하기
k=31
for i in range(6):
  for j in range(5, 0, -1):
    cohort_data.at[(k,j-1), 'user_id'] = int(cohort_data.at[(k,j),'user_id']) +  int(cohort_data.at[(k,j-1),'user_id'])
  k=k+1
cohort_data = cohort_data.reset_index()
cohort_data.head()


cohort_counts = cohort_data.pivot(index="start_week",
                                  columns="week",
                                  values="user_id")
cohort_counts

# 앞서 만든 피벗 테이블을 retention 변수에 저장하기
retention = cohort_counts
#각 주(week) 별 최초 수강생 수만 가져오기
cohort_sizes = cohort_counts.iloc[:,0]
cohort_sizes.head()

# 최초 수강생 수를 각 데이터에 나눠주기
retention = cohort_counts.divide(cohort_sizes, axis=0)
retention

#각 수치 퍼센트로 변경하기
retention.round(3)*100

#주차별 수강 전환율 구하기
w=31
for i in range(6):
  for j in range(5, 1, -1):
    retention.at[(w,j)] = retention.at[(w,j)]/retention.at[(w,j-1)]
  w=w+1


retention

#주차별 수강 전환율 히트맵 
plt.figure(figsize=(10,8))

sns.heatmap(data=retention,
           annot=True,
           fmt='.0%',
           vmin=0,
           vmax=1,
           cmap="BuGn")



plt.title('개강일별 주차 간 전환율', fontsize=20)
plt.xlabel('주차', fontsize=14,labelpad=30)
plt.ylabel('개강일', fontsize=14,rotation=360,labelpad=30)
plt.yticks(rotation=360)

plt.show()
LIST

+ Recent posts