AI κΈ°λ° νμ κ΄λ¦¬ νλ«νΌ DialoGμ AI μλ² (FastAPI)
- νμ μκ°
- μ£Όμ λΌμ΄λΈλ¬λ¦¬
- νλ‘μ νΈ κ΅¬μ‘°
- ν΅μ¬ κΈ°λ₯
- μν¬νλ‘μ°
- λΉμ© μ΅μ ν μ λ΅
- μ£Όμ νΉμ§
| μ΄λ¦ | λ΄λΉ μ 무 |
|---|---|
| κΉλμ΄ | μ€μκ° STT κ°λ° (WebSocket κΈ°λ°) νμ κ΅¬λΆ λΆμ μμ€ν ꡬν |
| μ₯λ¬Έμ | μ±λ΄ μμ€ν
κ°λ° (νμ κ²μ + IT μ©μ΄ FAQ) CI/CD νμ΄νλΌμΈ κ΅¬μΆ (GitHub Actions) |
| μ§μΉμ½ | HyperCLOVA X νμ μμ½ μμ± μ‘μ μμ΄ν μλ μΆμΆ κΈ°λ₯ κ°λ° |
fastapi==0.121.0
uvicorn==0.33.0
websockets==13.1
python-multipart
pymysql
mysql-connector-python
redis
httpx==0.27.0 # λΉλκΈ° HTTP ν΄λΌμ΄μΈνΈ
grpcio==1.70.0 # gRPC ν΅μ
protobuf==5.29.5 # μ§λ ¬ν
pydub==0.25.1 # μ€λμ€ λ³ν
soundfile==0.13.1 # μ€λμ€ I/O
boto3==1.6.19 # AWS SDK
python-dotenv==1.0.1 # νκ²½ λ³μ
pydantic==2.10.6 # λ°μ΄ν° κ²μ¦
loguru==0.7.3 # λ‘κΉ
arrow # λ μ§ μ²λ¦¬
python-dateutil # λ μ§ νμ±
dialog-ai-server/
β
βββ π main.py # FastAPI λ©μΈ μλν¬μΈνΈ
β
βββ π€ STT κ΄λ ¨
β βββ sttStreaming.py # μ€μκ° STT (WebSocket gRPC)
β βββ sttSpeaker.py # νμ κ΅¬λΆ λΆμ
β βββ nest.proto # gRPC νλ‘ν μ½ μ μ
β βββ nest_pb2.py # gRPC μμ± μ½λ
β
βββ π μμ½ & μ‘μ
μμ΄ν
β βββ summary_service.py # νμ μμ½ μμ±
β βββ action_service.py # μ‘μ
μμ΄ν
μμ±
β
βββ π€ μ±λ΄ μμ€ν
β β
β βββ π chatbotFAQ/
β β βββ π data/
β β β βββ terms_database.json # IT μ©μ΄ λ°μ΄ν°λ² μ΄μ€
β β βββ chatbotFAQMain.py # IT μ©μ΄ FAQ μ±λ΄
β β
β βββ π chatbotSearch/
β βββ chatbotSearchMain.py # νμ κ²μ μ±λ΄ (λ©μΈ)
β βββ search.py # νμ κ²μ λ‘μ§
β βββ selection.py # 쿼리 νμ
λΆλ₯
β βββ formatting.py # μλ΅ ν¬λ§·ν
β βββ llm.py # HyperCLOVA X API νΈμΆ
β βββ database.py # MySQL μ°κ²° κ΄λ¦¬
β βββ context.py # Redis 컨ν
μ€νΈ κ΄λ¦¬
β βββ models.py # Pydantic λ°μ΄ν° λͺ¨λΈ
β βββ config.py # νκ²½ λ³μ μ€μ
β
βββ π λ°°ν¬
βββ Dockerfile # 컨ν
μ΄λ μ΄λ―Έμ§
βββ deploy.yml # GitHub Actions CI/CD
βββ requirements.txt # Python λΌμ΄λΈλ¬λ¦¬
βββ .env # νκ²½ λ³μ
λ΄λΉ: κΉλμ΄
- CLOVA Speech API νμ©ν μ€μκ° μμ± μΈμ
- WebSocket κΈ°λ° gRPC μ€νΈλ¦¬λ°
- μ€μκ° ν μ€νΈ λ³ν λ° μ μ‘
# sttStreaming.py
# WebSocketμΌλ‘ μ€μκ° μμ± λ°μ΄ν° μμ β gRPCλ‘ CLOVAμ μ μ‘ β ν
μ€νΈ λ°νλ΄λΉ: κΉλμ΄
- CLOVA Speech ExternalURL Async API νμ©
- OBS(Object Storage)λ₯Ό ν΅ν λΉλκΈ° μ²λ¦¬
- λ°νμλ³ λ°μΈ μκ°, λΉμ¨ ν΅κ³ μ 곡
μ§μ κΈ°λ₯:
- β μ΅μ 2λͺ ~ μ΅λ 10λͺ νμ μλ μΈμ
- β λ°νμλ³ λ°μΈ μκ° λ° λΉμ¨ κ³μ°
- β νμμ€ν¬ν κΈ°λ° μΈκ·Έλ¨ΌνΈ λΆλ¦¬
λ΄λΉ: μ§μΉμ½
- HyperCLOVA X κΈ°λ° AI μμ½
μμ± νλͺ© (5κ°μ§):
| νλͺ© | μ€λͺ | μμ |
|---|---|---|
| νμ λͺ©μ | ν λ¬Έμ₯ μμ½ | "Q4 μμ° νμ λ° μΌμ λ Όμ" |
| μ£Όμ μ건 | 3~5κ° ν€μλ | "μμ° νμ , μΌμ μ‘°μ¨, μΈλ ₯ λ°°μΉ" |
| μ 체 μμ½ | μμ ν 3λ¬Έμ₯ | "Q4 μμ°μ 1μ΅μΌλ‘ νμ λμμΌλ©°..." |
| μ€μλ | HIGH/MEDIUM/LOW + μ¬μ | "HIGH - μμ° κ²°μ μΌλ‘ νλ‘μ νΈ μ°©μ κ°λ₯" |
| ν€μλ | ν΅μ¬ λͺ μ¬ 5κ° | "μμ°, μΌμ , μΈλ ₯, API, λ°μ΄ν°λ² μ΄μ€" |
μ§λ¬΄λ³ νλ₯΄μλ μ§μ:
- π§ νλ‘μ νΈ λ§€λμ (PM)
- π¨ νλ‘ νΈμλ κ°λ°μ
- βοΈ λ°±μλ κ°λ°μ
- ποΈ λ°μ΄ν°λ² μ΄μ€ κ΄λ¦¬μ (DBA)
- π 보μ μ λ¬Έκ°
- π μΌλ° (κΈ°λ³Έκ°)
λ΄λΉ: μ§μΉμ½
- νμ λ΄μ©μμ μ¬μ©μμ ν μΌ μλ μΆμΆ
- λ μ§ μλ κ³μ° (νμ λ μ§ κΈ°μ€)
- λ΄λΉμ μλ λ§€ν (νμ β μ€λͺ λ³ν)
μΆμΆ μ ν (3κ°μ§):
1οΈβ£ λ³ΈμΈ μμ
"API λͺ
μΈμ μμ± (μ₯λ¬Έμ ) [2025-12-15]"
2οΈβ£ μ§μλ°μ μμ
"DB μ€ν€λ§ μ€κ³ (μ₯λ¬Έμ ) [2025-12-20]"
3οΈβ£ ν μ 체 μμ
"[λ°±μλν] μλ² μ±λ₯ μ΅μ ν (λ΄λΉμ λ―Έμ§μ ) [2025-12-30]"
λ΄λΉ: μ₯λ¬Έμ
- Template κΈ°λ° RAG μν€ν μ² (λΉμ© μ΅μ ν)
- Redis κΈ°λ° μ»¨ν μ€νΈ κ΄λ¦¬ (λ€νμ°¨ λν μ§μ)
- μμ°μ΄ μ§λ¬Έ β SQL 쿼리 μλ λ³ν
κΈ°λ³Έ κ²μ μ ν (4κ°μ§):
| κ²μ μ ν | μμ μ§λ¬Έ | μ²λ¦¬ λ°©μ |
|---|---|---|
| λ μ§ κ²μ | "μ΄μ νμ 보μ¬μ€", "μ§λμ£Ό νμ" | meeting_date 쑰건 κ²μ |
| ν€μλ κ²μ | "API κ΄λ ¨ νμ", "λ°μ΄ν°λ² μ΄μ€ λ Όμ" | keywords, purpose, agenda LIKE κ²μ |
| μ°Έκ°μ κ²μ | "κΉλμ΄λ μ°Έμν νμ" | participants μ»¬λΌ κ²μ |
| ν μΌ κ²μ | "λ΄ ν μΌ", "λ―Έμλ£ μ 무" | action_items ν
μ΄λΈ μ‘°μΈ |
κ³ κΈ κΈ°λ₯:
1οΈβ£ μ‘°ν© μ§λ¬Έ μ²λ¦¬
"μ§λμ£Ό κΉλμ΄λμ΄ μ°Έμν API κ΄λ ¨ νμ"
β λ μ§ + μ°Έκ°μ + ν€μλ μ‘°ν© κ²μ
2οΈβ£ λ¨κ³μ μν (κ²μ κ²°κ³Ό μμ λ)
1μ°¨ μλ: λͺ¨λ 쑰건 λ§μ‘±νλ νμ κ²μ
β κ²°κ³Ό μμ
2μ°¨ μλ: μΌλΆ 쑰건 μν (μ: λ μ§ λ²μ νλ)
β κ²°κ³Ό μμ
3μ°¨ μλ: ν΅μ¬ ν€μλλ§μΌλ‘ μ¬κ²μ
3οΈβ£ μνλ³ λΆλ¦¬ νμ
- β μλ£λ ν μΌ - μ²΄ν¬ νμμ ν¨κ» νμ
- β° μμ λ ν μΌ - λ§κ°μΌ κ°μ‘° νμ
β οΈ μ§μ°λ ν μΌ - κ²½κ³ νμ
4οΈβ£ μμ°μ΄ λ μ§ νμ±
"μ΄λ²μ£Ό" β 2025-12-09 ~ 2025-12-15
"10μ 27μΌλΆν° μ€λ" β 2025-10-27 ~ 2025-12-09
"μ΄μ " β 2025-12-08
"μ§λμ£Ό κΈμμΌ" β 2025-12-06
5οΈβ£ νμΈ μ§λ¬Έ μ²λ¦¬ (컨ν μ€νΈ κΈ°λ°)
μ¬μ©μ: "μ΄μ νμ λνμ΄?"
μ±λ΄: [νμ 2κ° νμ]
μ¬μ©μ: "κ·Έκ±° νλμΌ?"
μ±λ΄: "λ€, μ΄μ λ μ΄ 2κ°μ νμκ° μμμ΅λλ€."
μ¬μ©μ: "λ μμ΄?"
μ±λ΄: "μ΄μ νμλ μ΄κ²μ΄ μ λΆμ
λλ€."
μ£Όμ κΈ°λ₯:
- β νλ₯΄μλ 컀μ€ν°λ§μ΄μ§ (μ§λ¬΄λ³ λ§μΆ€ μλ΅)
- β 컨ν μ€νΈ μ μ§ (μ΄μ μ§λ¬Έ κΈ°μ΅)
- β μμ°μ€λ¬μ΄ λν체 μλ΅
- β λ³΅ν© μ‘°κ±΄ κ²μ μ§μ
- β μ§λ₯ν μ€λ₯ 볡ꡬ (λ¨κ³μ μν)
λ΄λΉ: μ₯λ¬Έμ
- 3-tier ν΄λ°± μμ€ν (λΉμ© μ΅μ ν)
βββββββββββββββββββββββββββββββββββββββ
β Tier 1: JSON λ°μ΄ν°λ² μ΄μ€ κ²μ β β λ¬΄λ£ (μ°μ μλ)
β (terms_database.json) β
βββββββββββββββββββββββββββββββββββββββ
β μ€ν¨ μ
βββββββββββββββββββββββββββββββββββββββ
β Tier 2: CLOVA Chatbot Builder β β μ λΉμ©
βββββββββββββββββββββββββββββββββββββββ
β μ€ν¨ μ
βββββββββββββββββββββββββββββββββββββββ
β Tier 3: HyperCLOVA X β β κ³ λΉμ© (μ΅μ’
ν΄λ°±)
βββββββββββββββββββββββββββββββββββββββ
μ£Όμ κΈ°λ₯:
- β 100κ° μ΄μ IT μ©μ΄ λ°μ΄ν°λ² μ΄μ€
- β μ μ¬ μ©μ΄ μλ λ§€μΉ
- β μ€ν μ²λ¦¬ λ° λΉκ³΅μ νν μ§μ
ββββββββββββββββββ
β νμ μμ β
ββββββββββ¬ββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββ
β μ€μκ° STT (sttStreaming.py) β β WebSocket + gRPC
β μμ± β ν
μ€νΈ λ³ν β
ββββββββββ¬βββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββ
β νμ μ’
λ£ β μμ± νμΌ OBS μ
λ‘λ β
ββββββββββ¬βββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββ
β νμ κ΅¬λΆ λΆμ (sttSpeaker.py) β β Async μ²λ¦¬
β λ°νμ μ 보 μΆμΆ β
ββββββββββ¬βββββββββββββββββββββββββββββ
β
ββββββββββββββββββββ¬βββββββββββββββββββ
β β β
βΌ βΌ βΌ
βββββββββββββββββββ ββββββββββββββββ ββββββββββββββββ
β AI μμ½ μμ± β β μ‘μ
μμ΄ν
β β μ€μλ νκ° β
β (5κ°μ§ νλͺ©) β β μμ± β β (HIGH/LOW) β
ββββββββββ¬βββββββββ ββββββββ¬ββββββββ ββββββββ¬ββββββββ
β β β
ββββββββββββββββββββ΄βββββββββββββββββββ
β
βΌ
βββββββββββββββββββ
β MySQL μ μ₯ β
βββββββββββββββββββ
βββββββββββββββββββββββ
β μ¬μ©μ μ§λ¬Έ μ
λ ₯ β μ: "μ΄μ νμ λνμ΄?"
ββββββββββββ¬βββββββββββ
β
βΌ
ββββββββββββββββββββββββββββββββββββββββ
β μΈμ
νμΈ (Redis) β
β - μ΄μ λν 컨ν
μ€νΈ λ‘λ β
ββββββββββββ¬ββββββββββββββββββββββββββββ
β
βΌ
ββββββββββββββββββββββββββββββββββββββββ
β 쿼리 νμ
λΆλ₯ (selection.py) β
β β λ μ§ / ν€μλ / μ°Έκ°μ / ν μΌ β
ββββββββββββ¬ββββββββββββββββββββββββββββ
β
βΌ
ββββββββββββββββββββββββββββββββββββββββ
β Template κΈ°λ° κ²μ (search.py) β β HyperCLOVA X μμ΄ μ²λ¦¬
β - SQL 쿼리 μλ μμ± β (λΉμ© 0μ)
β - MySQL κ²μ μ€ν β
ββββββββββββ¬ββββββββββββββββββββββββββββ
β
βΌ
ββββββββββββββββββββββββββββββββββββββββ
β μλ΅ ν¬λ§·ν
(formatting.py) β
β - κ²μ κ²°κ³Ό β μμ°μ΄ λ³ν β
ββββββββββββ¬ββββββββββββββββββββββββββββ
β
βΌ
ββββββββββββββββββββββββββββββββββββββββ
β 컨ν
μ€νΈ μ μ₯ (Redis, TTL 10λΆ) β
ββββββββββββ¬ββββββββββββββββββββββββββββ
β
βΌ
ββββββββββββββββββββββββββββββββββββββββ
β μ¬μ©μμκ² μλ΅ λ°ν β
ββββββββββββββββββββββββββββββββββββββββ
βββββββββββββββββββββββ
β μ¬μ©μ μ©μ΄ μ§λ¬Έ β μ: "REST APIκ° λμΌ?"
ββββββββββββ¬βββββββββββ
β
βΌ
ββββββββββββββββββββββββββββββββββββββββ
β Tier 1: JSON DB κ²μ β β
무λ£
β (terms_database.json) β
ββββββββββββ¬ββββββββββββββββββββββββββββ
β
β λ§€μΉ μ€ν¨ μ
βΌ
ββββββββββββββββββββββββββββββββββββββββ
β Tier 2: CLOVA Chatbot Builder β π° μ λΉμ©
ββββββββββββ¬ββββββββββββββββββββββββββββ
β
β λ§€μΉ μ€ν¨ μ
βΌ
ββββββββββββββββββββββββββββββββββββββββ
β Tier 3: HyperCLOVA X β π°π° κ³ λΉμ©
ββββββββββββ¬ββββββββββββββββββββββββββββ
β
βΌ
ββββββββββββββββββββββββββββββββββββββββ
β μλ΅ λ°ν β
ββββββββββββββββββββββββββββββββββββββββ
κΈ°μ‘΄ λ°©μ: λͺ¨λ μ§λ¬Έ β HyperCLOVA X β π°π°π°
μ΅μ ν λ°©μ: Template ν¨ν΄ μ¬μ© β π° (0μ)
β
κ²°κ³Ό: 80% λΉμ© μ κ°
Tier 1: JSON κ²μ (무λ£) β λλΆλΆ μ¬κΈ°μ ν΄κ²°
Tier 2: CLOVA Chatbot Builder β μ λΉμ©
Tier 3: HyperCLOVA X β μ΅μ’
μλ¨
# 5κ° νλͺ©μ μμ°¨ νΈμΆ β 25μ΄
# 5κ° νλͺ©μ λ³λ ¬ νΈμΆ β 5μ΄ (asyncio.gather μ¬μ©)
β
κ²°κ³Ό: μλ΅ μκ° 80% λ¨μΆ + μλ² λ¦¬μμ€ μ μ½- 컨ν
μ€νΈ TTL: 10λΆ
- λΆνμν DB μ‘°ν κ°μ
- λΉ λ₯Έ μλ΅ μλ
- β
μλΉμ€λ³ λͺ¨λ λΆλ¦¬ (
summary_service,action_service,chatbot) - β μ§λ¬΄λ³ νλ₯΄μλ νμ₯ κ°λ₯
- β μλ‘μ΄ κ²μ μ ν μΆκ° μ©μ΄
- β
λͺ¨λ API νΈμΆμ
try-exceptμ μ© - β νμμμ μ€μ (30μ΄)
- β
μμΈν μλ¬ λ‘κΉ
(
loguru)
- β WebSocket κΈ°λ° μ€μκ° STT
- β
λΉλκΈ° μ²λ¦¬ (
asyncio,httpx) - β λ³λ ¬ API νΈμΆ
- β Template μ°μ β LLM μ΅μν
- β 3-tier ν΄λ°± μμ€ν
- β Redis μΊμ±