ν‹°μŠ€ν† λ¦¬ λ·°

λ°˜μ‘ν˜•

🚨 AI λͺ¨λΈ μž₯μ•  λŒ€μ‘ μ „λž΅

– “OpenAIκ°€ 터져도 μ„œλΉ„μŠ€λŠ” μ•ˆ 죽게 λ§Œλ“œλŠ” ꡬ쑰”
(RAG · NestJS · SaaS μš΄μ˜μ—μ„œ μ§„μ§œ ν•„μš”ν–ˆλ˜ λŒ€μ‘ μ‹œλ‚˜λ¦¬μ˜€)


AI κΈ°λŠ₯을 μ‹€μ„œλΉ„μŠ€μ— 올리고 λ‚˜λ©΄
μ–Έμ  κ°€ λ°˜λ“œμ‹œ 이 μˆœκ°„μ΄ μ˜΅λ‹ˆλ‹€.

“AI 응닡이 μ•ˆ μ™€μš”.”
“μ–΄μ œκΉŒμ§€ 되던 게 κ°‘μžκΈ° λ©ˆμ·„μ–΄μš”.”
“OpenAI μƒνƒœ νŽ˜μ΄μ§€ λ³΄μ…¨μ–΄μš”…?”

μ΄λ•Œ μ„œλΉ„μŠ€κ°€ 같이 λ©ˆμΆ”λ©΄
그건 **AI μ„œλΉ„μŠ€κ°€ μ•„λ‹ˆλΌ ‘AI 의쑴 μ„œλΉ„μŠ€’**μž…λ‹ˆλ‹€.

이번 글은
AI λͺ¨λΈ(OpenAI, μ™ΈλΆ€ LLM)이 μž₯μ• λ₯Ό μΌμœΌμΌœλ„
πŸ‘‰ 우리 μ„œλΉ„μŠ€λŠ” 계속 μ‚΄μ•„ 있게 λ§Œλ“œλŠ” μ „λž΅μ„
μš΄μ˜μ—μ„œ μ‹€μ œλ‘œ 썼던 ꡬ쑰 κ·ΈλŒ€λ‘œ μ •λ¦¬ν•©λ‹ˆλ‹€.


🧭 이 κΈ€μ˜ λͺ©ν‘œ

  • AI μž₯μ•  μœ ν˜•μ„ μ •ν™•νžˆ λΆ„λ₯˜
  • μž₯μ•  μ‹œ “무쑰건 μ‹€νŒ¨”κ°€ μ•„λ‹Œ 단계적 λŒ€μ‘
  • RAG / LLM / Vector DB 각각의 fallback μ „λž΅
  • PM·λŒ€ν‘œμ—κ²Œ μ„€λͺ… κ°€λŠ₯ν•œ 운영 ꡬ쑰 λ§Œλ“€κΈ°

1️⃣ AI μž₯μ• λŠ” 생각보닀 자주, λ‹€μ–‘ν•œ ν˜•νƒœλ‘œ μ˜¨λ‹€

μš΄μ˜ν•˜λ©΄μ„œ κ²ͺ은 μž₯μ•  μœ ν˜•μ€ λŒ€λž΅ μ΄λ ‡μŠ΅λ‹ˆλ‹€.

1) LLM API μ™„μ „ μž₯μ• 

  • 5xx
  • timeout
  • rate limit 폭발

2) λΆ€λΆ„ μž₯μ• 

  • 응닡은 μ˜€λŠ”λ° κ·Ήλ‹¨μ μœΌλ‘œ 느림
  • νŠΉμ • λͺ¨λΈλ§Œ μž₯μ• 

3) κ°„μ ‘ μž₯μ• 

  • μž„λ² λ”© API μž₯μ• 
  • Vector DB μž₯μ• 
  • λ„€νŠΈμ›Œν¬ 이슈

πŸ‘‰ μ€‘μš”ν•œ 건
“AI μž₯μ•  = 전체 μ„œλΉ„μŠ€ μž₯μ• ”κ°€ 되면 μ•ˆ λœλ‹€λŠ” 점.


2️⃣ κ°€μž₯ μœ„ν—˜ν•œ ꡬ쑰 (μ ˆλŒ€ μ΄λ ‡κ²Œ ν•˜μ§€ 말자)

@Post('/ai/chat')
async chat(@Body() query: string) {
  return this.openai.chat.completions.create(...);
}

이 ꡬ쑰의 문제점:

  • AI μ•ˆ 였면 → API 자체 μ‹€νŒ¨
  • ν”„λ‘ νŠΈλŠ” 흰 ν™”λ©΄
  • μ‚¬μš©μžλŠ” “μ„œλΉ„μŠ€ 죽음”으둜 인식

πŸ‘‰ 이건 운영 κ΄€μ μ—μ„œ μ΅œμ•…μž…λ‹ˆλ‹€.


3️⃣ κΈ°λ³Έ 원칙: AIλŠ” “ν•„μˆ˜ κΈ°λŠ₯”이 μ•„λ‹ˆλΌ “κ°€μΉ˜ μΆ”κ°€ κΈ°λŠ₯”

운영 κΈ°μ€€μ—μ„œ AIλŠ” μ΄λ ‡κ²Œ 봐야 ν•©λ‹ˆλ‹€.

❌ AI = μ„œλΉ„μŠ€μ˜ μ „λΆ€
βœ… AI = μ„œλΉ„μŠ€μ˜ λΆ€κ°€ κ°€μΉ˜

이 관점이 μžˆμ–΄μ•Ό
fallback μ „λž΅μ΄ μžμ—°μŠ€λŸ½κ²Œ μ„€κ³„λ©λ‹ˆλ‹€.


4️⃣ 1단계 λŒ€μ‘: Timeout + Circuit Breaker

❗ AI ν˜ΈμΆœμ€ λ°˜λ“œμ‹œ νƒ€μž„μ•„μ›ƒμ΄ μžˆμ–΄μ•Ό ν•œλ‹€

const breaker = new CircuitBreaker(
  () => openai.chat.completions.create(...),
  {
    timeout: 5000,
    errorThresholdPercentage: 50,
    resetTimeout: 30000,
  }
);
  • 5초 μ•ˆμ— 응닡 μ—†μœΌλ©΄ μ‹€νŒ¨
  • 일정 λΉ„μœ¨ 이상 μ‹€νŒ¨ μ‹œ μžλ™ 차단
  • 30초 ν›„ λ‹€μ‹œ μ‹œλ„

πŸ‘‰ 이걸 μ•ˆ ν•˜λ©΄
느린 AIκ°€ μ„œλ²„ 전체λ₯Ό λ¬Άμ–΄λ²„λ¦½λ‹ˆλ‹€.


5️⃣ 2단계 λŒ€μ‘: RAG fallback μ „λž΅

λ°˜μ‘ν˜•

RAGμ—μ„œμ˜ fallback μš°μ„ μˆœμœ„

1. μΊμ‹œλœ 이전 λ‹΅λ³€
2. Vector DB 검색 κ²°κ³Ό μš”μ•½
3. FAQ / 정적 응닡
4. "ν˜„μž¬ AI 응닡이 μ§€μ—°λ˜κ³  μžˆμŠ΅λ‹ˆλ‹€" λ©”μ‹œμ§€

1️⃣ μΊμ‹œλœ λ‹΅λ³€ λ°˜ν™˜

const cached = await redis.get(cacheKey);
if (cached) return cached;

πŸ‘‰ μ‚¬μš©μžλŠ”
**“응닡을 λͺ» λ°›μ•˜λ‹€”κ°€ μ•„λ‹ˆλΌ
“쑰금 덜 λ˜‘λ˜‘ν•œ 닡변을 λ°›μ•˜λ‹€”**κ³  λŠλ‚λ‹ˆλ‹€.


2️⃣ Vector DB 검색 결과만 λ°˜ν™˜

const docs = await qdrant.search(...);

return {
  mode: 'fallback',
  results: docs.map(d => d.summary),
};

πŸ‘‰ AI 생성은 μ—†μ§€λ§Œ
μ •λ³΄λŠ” 제곡됨


3️⃣ FAQ / 정적 λ‹΅λ³€

if (isFaq(query)) {
  return faqService.answer(query);
}

πŸ‘‰ 고객센터·ν—¬ν”„ μ˜μ—­μ—μ„œ 특히 μ€‘μš”


6️⃣ 3단계 λŒ€μ‘: “AI 응닡 μ—†μŒ”을 UX둜 μˆ¨κΈ°μ§€ 말 것

이건 μ˜μ™Έλ‘œ μ€‘μš”ν•œ ν¬μΈνŠΈμž…λ‹ˆλ‹€.

❌ μ΄λ ‡κ²Œ ν•˜λ©΄ μ•ˆ λ©λ‹ˆλ‹€.

“μž μ‹œ ν›„ λ‹€μ‹œ μ‹œλ„ν•΄μ£Όμ„Έμš”.”

μ‚¬μš©μžλŠ”

  • μ™œ μ•ˆ λ˜λŠ”μ§€ λͺ¨λ₯΄κ³ 
  • 계속 μƒˆλ‘œκ³ μΉ¨ν•˜κ³ 
  • κ²°κ΅­ λ– λ‚©λ‹ˆλ‹€.

βœ… μ΄λ ‡κ²Œ 말해야 ν•©λ‹ˆλ‹€

“ν˜„μž¬ AI 응닡이 μΌμ‹œμ μœΌλ‘œ μ§€μ—°λ˜κ³  μžˆμŠ΅λ‹ˆλ‹€.
λŒ€μ‹  κ΄€λ ¨ λ¬Έμ„œλ₯Ό λ°”λ‘œ λ³΄μ—¬λ“œλ¦΄κ²Œμš”.”

πŸ‘‰ 투λͺ… + λŒ€μ•ˆ μ œμ‹œ
이게 UX κ΄€μ μ—μ„œ 훨씬 λ‚«μŠ΅λ‹ˆλ‹€.


7️⃣ 4단계 λŒ€μ‘: λͺ¨λΈ 닀쀑화 (κ°€λŠ₯ν•˜λ‹€λ©΄)

이건 μ—¬μœ  μžˆμ„ λ•Œ λ„μž…ν•©λ‹ˆλ‹€.

μ˜ˆμ‹œ μ „λž΅

μš°μ„ μˆœμœ„λͺ¨λΈ

1 OpenAI
2 λ‹€λ₯Έ OpenAI λͺ¨λΈ
3 둜컬 LLM
4 정적 응닡
try {
  return await openaiMain.chat(...);
} catch {
  return await openaiBackup.chat(...);
}

πŸ‘‰ λͺ¨λ“  μ„œλΉ„μŠ€μ— ν•„μˆ˜λŠ” μ•„λ‹ˆμ§€λ§Œ
μ—”ν„°ν”„λΌμ΄μ¦ˆμ— κ°€κΉŒμ›Œμ§ˆμˆ˜λ‘ μ€‘μš”


8️⃣ μž₯μ•  감지 & μ•Œλ¦Ό (운영의 핡심)

AI μž₯μ• λŠ”
μ‚¬μš©μžλ³΄λ‹€ μš°λ¦¬κ°€ λ¨Όμ € μ•Œμ•„μ•Ό ν•©λ‹ˆλ‹€.


λ°˜λ“œμ‹œ 감지해야 ν•  μ§€ν‘œ

  • AI 응닡 μ‹€νŒ¨μœ¨
  • 평균 응닡 μ‹œκ°„
  • timeout λ°œμƒ 횟수
  • fallback μ§„μž… 횟수
if (fallbackUsed) {
  metrics.increment('ai_fallback');
}

Slack μ•Œλ¦Ό μ˜ˆμ‹œ

🚨 AI 응닡 μž₯μ•  감지
- μ‹€νŒ¨μœ¨: 62%
- 평균 응닡 μ‹œκ°„: 7.2s
- fallback μ§„μž…: 183회 (5λΆ„)

πŸ‘‰ 이 μ•Œλ¦Όμ΄ 와야
μš΄μ˜μžκ°€ μž μ—μ„œ κΉΉλ‹ˆλ‹€.


9️⃣ μž₯μ•  λŒ€μ‘ μ‹œλ‚˜λ¦¬μ˜€ (Runbook μš”μ•½)

상황 1: OpenAI μ™„μ „ μž₯μ• 

1. Circuit Breaker 차단 확인
2. μΊμ‹œ 응닡 ν™œμ„±ν™”
3. RAG → λ¬Έμ„œ 검색 λͺ¨λ“œ μ „ν™˜
4. Slack 곡지
5. μƒνƒœ νŽ˜μ΄μ§€ 확인

상황 2: 응닡 μ§€μ—°λ§Œ λ°œμƒ

1. timeout κ°μ†Œ
2. context 길이 μΆ•μ†Œ
3. κ³ κΈ‰ λͺ¨λΈ → κ²½λŸ‰ λͺ¨λΈ μ „ν™˜

10️⃣ μš΄μ˜ν•˜λ©΄μ„œ 깨달은 μ§„μ§œ 핡심

이건 정말 μ€‘μš”ν•œ λ¬Έμž₯μž…λ‹ˆλ‹€.

AI μž₯μ•  λŒ€μ‘μ€
기술 λ¬Έμ œκ°€ μ•„λ‹ˆλΌ
μ„œλΉ„μŠ€ 섀계 λ¬Έμ œλ‹€.

  • AIκ°€ λ©ˆμ·„μ„ λ•Œ
  • μ„œλΉ„μŠ€κ°€ 같이 λ©ˆμΆ”λ©΄ ❌
  • μ„œλΉ„μŠ€κ°€ μš°νšŒν•΄μ„œ 계속 λ™μž‘ν•˜λ©΄ β­•

이 차이가
데λͺ¨ μ„œλΉ„μŠ€μ™€
μ‹€μ œ μ„œλΉ„μŠ€λ₯Ό κ°€λ¦…λ‹ˆλ‹€.


λ‹€μŒ κΈ€ 예고

λ‹€μŒ κΈ€μ—μ„œλŠ”
πŸ‘‰ “AI κΈ°λŠ₯을 ‘μ„ νƒν˜• κΈ°λŠ₯’으둜 μ„€κ³„ν•˜λŠ” UX/기획 μ „λž΅”
을 λ‹€λ£Ήλ‹ˆλ‹€.

  • AIλ₯Ό 전면에 λ‘˜ λ•Œ vs 뒀에 λ‘˜ λ•Œ
  • AI 없이도 μ“Έ 수 μžˆλŠ” μ„œλΉ„μŠ€ ꡬ쑰
  • μ‚¬μš©μž 뢈만이 μ€„μ–΄λ“œλŠ” 섀계

기술 + 기획 μ–˜κΈ°λ‘œ λ„˜μ–΄κ°‘λ‹ˆλ‹€.


 

AIμž₯μ• λŒ€μ‘, RAG운영, OpenAIμž₯μ• , SaaS운영, NestJS, AIμ„œλΉ„μŠ€μ„€κ³„, CircuitBreaker, AIUX, λ°±μ—”λ“œμš΄μ˜

β€» 이 ν¬μŠ€νŒ…μ€ 쿠팑 νŒŒνŠΈλ„ˆμŠ€ ν™œλ™μ˜ μΌν™˜μœΌλ‘œ, 이에 λ”°λ₯Έ μΌμ •μ•‘μ˜ 수수료λ₯Ό μ œκ³΅λ°›μŠ΅λ‹ˆλ‹€.
곡지사항
μ΅œκ·Όμ— 올라온 κΈ€
μ΅œκ·Όμ— 달린 λŒ“κΈ€
Total
Today
Yesterday
링크
Β«   2026/01   Β»
일 μ›” ν™” 수 λͺ© 금 ν† 
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
κΈ€ 보관함
λ°˜μ‘ν˜•