← Lecture Note
PART III · ARCHITECTURE

RAG 기반 AI 서비스는 어떻게 도는가

모델 API는 어디서 호출되고, DB는 어떻게 구성되며, 각 역할이 어떻게 맞물려 도는지 — 실제 배포된 서비스들의 요청 생명주기 전체를 한 장에.

🧠 모델 API🗄 DB / 벡터스토어🌐 브라우저🔒 키는 서버에만
① 모델 API는 100% 서버에서

OpenAI·Claude·ElevenLabs 호출은 전부 Vercel 함수(/api/*) 안에서만. 키는 브라우저에 절대 안 감.

② RAG = 검색 후 생성

질문을 임베딩→유사도 검색으로 '근거'를 찾고, 그 근거를 프롬프트에 넣어 LLM이 답하게 한다.

③ DB는 두 얼굴

지식(벡터 스토어) + 운영 데이터(대화로그·인텔·FAQ). Supabase Postgres에 RLS로 안전하게.

📐 한눈에 보는 구조 모형도

① 입력부터 ⑩ 응답까지 — 모델 API·DB가 어디서 붙는지 한 장(PPT 형식)으로.

RAG 기반 AI 서비스 요청 생명주기 구조도 (① → ⑩)

요청 생명주기 — 단계별 상세

사용자가 질문하면 → 아래로 흐릅니다. 오른쪽은 그 단계가 부르는 모델 API · DB.

1
브라우저 (클라이언트)

텍스트 · 🎙 음성 · 📍 위치(GPS) 입력. React(Next.js) 화면. — 키는 절대 여기 없음.

🌐 브라우저 직호출
GPS · 날씨 API (키 불필요, 브라우저 직호출)
2
Vercel 서버리스 함수 — /api/chat

오케스트레이터 라우트. 여기서부터 서버(비공개). 모든 모델 API 호출은 이 안에서만 일어남(키 노출 0).

3
음성 입력이면 → STT

녹음 오디오(Blob)를 텍스트로 변환.

🧠 모델 API
ElevenLabs Scribe (STT)
4
질문 임베딩

질문 문장을 1536차원 벡터로 변환 — 의미 검색의 좌표.

🧠 모델 API
OpenAI text-embedding-3-small
5
벡터 검색 — Top-k

질문 벡터와 문서 벡터의 코사인 유사도로 관련 청크 K개 + 출처를 뽑음.

🗄 DB
벡터 스토어 (in-memory JSON / Supabase pgvector)
6
프롬프트 조립

시스템 프롬프트 + 검색된 컨텍스트(근거) + 대화 history를 하나로 합침. — RAG의 'R'과 'G'를 잇는 지점.

7
LLM 생성 (+웹검색 +리플렉션)

근거를 바탕으로 답 생성. 필요 시 실시간 웹검색, 2차 자기검증(리플렉션)으로 사실성 강화.

🧠 모델 API
Anthropic Claude (claude-sonnet-4-5) + web_search
8
환각 차단 · 출처 부착

근거 밖 주장 억제, 모르면 모른다고. 검색 청크의 출처(코드/문서)를 답에 함께 노출.

9
음성 모드면 → TTS

답변을 복제된 목소리(Hans17 voice)로 음성 합성.

🧠 모델 API
ElevenLabs TTS (voice clone)
10
브라우저로 응답

텍스트 답변(+출처) + 오디오를 클라이언트로 스트리밍/반환. 대화 로그는 DB에 적재.

🗄 DB
Supabase — 대화로그 insert
OFFLINE · 빌드 타임

지식 인제스션 (임베딩 파이프라인)

검색이 되려면, 먼저 문서를 벡터로 만들어 저장해 둬야 합니다. 이건 요청과 별개로 미리 1회.

📄 원본 문서content/*.md · 방송 대본 · 매뉴얼
✂️ 청킹의미 단위로 잘라 조각(chunk)으로
🧠 임베딩OpenAI text-embedding-3-small → 1536d 벡터
🗄 저장embeddings.json (Type A) · pgvector upsert (Type B)
DATA · Supabase Postgres

DB는 어떻게 구성되나

DB는 두 역할 — 지식(벡터)운영 데이터. 접근은 RLS로 통제.

documents / embeddings — pgvector 컬럼(vector 1536) + ivfflat 인덱스 · Type B의 지식창고
chat_logs — 질문·답변·출처·보이스 로그
region_intel · faq · qa · prompts — 서비스별 운영 데이터(누적 인텔·게시판)
RLS — anon은 읽기만, 쓰기는 서버 전용 service_role 키로만

같은 뼈대, 3가지 Type

위 파이프라인은 공통. 벡터를 어디에 두느냐 / 입력이 무엇이냐에 따라 세 갈래로 나뉩니다.

A벡터 DB 0
Type A · 인메모리 코사인 RAG
쓰는 서비스
Hans17 Academy(강사 Agent) · 여비/Yeobi
구조

빌드 타임에 문서를 임베딩해 embeddings.json으로 번들. 런타임엔 메모리에서 코사인 유사도 계산. 별도 벡터 인프라·종속 없음.

언제

소~중규모 지식(강의노트·가이드). 배포 초간단, 이식 쉬움.

BSupabase pgvector
Type B · pgvector 벡터 DB RAG
쓰는 서비스
GHOSTSHIN (고스트스테이션 403개 방송 · 약 700만 자)
구조

임베딩을 Supabase Postgres의 pgvector에 저장(ivfflat 인덱스). 런타임엔 SQL 벡터 검색으로 Top-k. 대용량·증분 업데이트에 강함.

언제

대규모 코퍼스, 계속 늘어나는 지식, 다중 사용자.

C이미지 + 텍스트
Type C · 멀티모달 / Vision RAG
쓰는 서비스
AmedicalI(증상 사진·약 분석) · 핏미러(카메라 실측)
구조

이미지를 Vision 모델로 분석해 구조화 텍스트로 변환 → 그 결과를 텍스트 RAG 파이프라인(4~8단계)에 그대로 태움.

언제

사진·실측 등 비텍스트 입력이 핵심인 현장 서비스.

역할 · API · 키 한눈에

구성요소역할호출 위치키(env)
OpenAI Embeddings질문·문서를 벡터로서버(/api)OPENAI_API_KEY
Anthropic Claude답변 생성 · 웹검색 · 리플렉션서버(/api)ANTHROPIC_API_KEY
ElevenLabsSTT(듣기) · TTS(내 목소리)서버(/api)ELEVENLABS_API_KEY
Supabase Postgres벡터 스토어(pgvector) + 운영 데이터서버(/api)SUPABASE_* (service_role)
Vercel Function오케스트레이터 · 모든 API 중계Vercel(Fluid)
브라우저입력·재생 · GPS/날씨 직호출클라이언트키 없음

핵심: 모델 API·DB 접근은 전부 서버(Vercel 함수)에서. 브라우저는 키를 모르고, 오직 결과만 받습니다.