π μ°ν μΊ‘μ€ν€ 22μ‘° : ReadyTalk for Academy
β» λ³Έ νλ‘μ νΈλ μ°ννλ ₯μΌλ‘ μ§νλμ΄ κΈ°μ κ³Όμ νμ½μ λ°λΌ νμ¬ λ ν¬μ§ν 리 λ° μμ€ μ½λλ μΈλΆμ 곡κ°νκΈ° μ΄λ €μ΄ μ μν΄ λΆνλ립λλ€.
1. νλ‘μ νΈ μκ°
ReadyTalk for Academyλ νμ μ΄μμ ν¨μ¨ννκ³ μ¬μ©μ λ§μΆ€ν μλ΄μ μ 곡νκΈ° μν AI κΈ°λ° μμ΄μ νΈ μμ€ν μ λλ€. λΉμΈμ¦ μ¬μ©μμκ²λ μλ΄ λ§€λ΄μΌ κΈ°λ° μλ΄μ νλ μ λλ₯Ό μ 곡νκ³ , μΈμ¦λ μ¬μ©μμκ²λ μΆκ²° κ΄λ¦¬, μμ μΌμ , 리ν¬νΈ λ± κ°μΈνλ μλΉμ€λ₯Ό μ 곡ν©λλ€. λν κΈ°μΆ λ¬Έμ μ ν λΆλ₯ λ° μ μ¬ λ¬Έμ μμ±μ ν΅ν΄ νμ΅μ μ§μνλ©°, κ΄λ¦¬μλ μλ΄ λ΄μ©μ μ μ₯Β·μμ½νμ¬ μ΄μ ν¨μ¨μ λμΌ μ μμ΅λλ€.
2. μκ° μμ
[![ReadyTalk KMU μκ° μμ]]
3. ν μκ°
![]() μμ§μ νμ₯, λ°±μλ |
![]() μ μ λ―Έ AI Agent κ°λ° νλ‘ νΈμλ |
![]() μ΄μ€μ AI Agent κ°λ° |
![]() μμΉμΌ λ¬Έμ μ 리 κ°λ° 보쑰 |
![]() μ νμ± AI Agent QA |
ReadyTalk for Academy
Vertex AI κΈ°λ° λ©ν°ν λνΈ AI μ±λ΄ νλ«νΌ
Architecture Overview
graph TB
subgraph NGINX["Nginx :80"]
direction LR
RL[Rate Limiting]
RP[Reverse Proxy]
end
subgraph FE["Frontend - React :3000"]
SA_UI[Superadmin Pages]
ADMIN_UI[Admin Pages]
CHAT_UI[Chat Pages]
CAL_UI[Calendar Pages]
end
subgraph BE["Backend - FastAPI :8000"]
R1["/api/superadmin"]
R2["/api/auth"]
R3["/api/chat"]
R4["/api/corpus"]
R5["/api/models"]
R6["/api/kakao"]
R7["/api/calendar"]
end
subgraph DB["PostgreSQL :5432"]
TENANT_DATA["tenant_id FK isolation"]
end
subgraph GCP["Google Cloud Platform"]
subgraph RAG["Vertex AI RAG Engine"]
RAG_CORPUS["RAG Corpus + Weaviate"]
end
subgraph VAS["Vertex AI Search"]
DS["DataStore + Engine"]
end
subgraph GCS["GCS Β· techready_readytalk_kmu"]
BUCKET["tenants/{slug}/{corpus}/files"]
end
GEMINI["Gemini API"]
GCAL["Google Calendar API"]
end
WEAVIATE["Weaviate :8080"]
KAKAO["KakaoTalk"] --> R6
NGINX --> FE
NGINX --> BE
BE --> DB
BE --> RAG
BE --> VAS
BE --> GCS
BE --> GEMINI
BE --> GCAL
RAG --> WEAVIATE
Tech Stack
| Layer | Technology |
|---|---|
| Frontend | React 18 Β· MUI Β· React Router v6 Β· Axios |
| Backend | FastAPI Β· SQLAlchemy Β· Alembic Β· Gunicorn + Uvicorn |
| Database | PostgreSQL 15 |
| AI/Search | Vertex AI RAG Engine Β· Vertex AI Search Β· Gemini API |
| Vector DB | Weaviate (RAG Engine λ°±μλ) |
| Storage | Google Cloud Storage |
| Calendar | Google Calendar API (OAuth 2.0) |
| Infra | Docker Compose Β· Nginx Β· GCP Compute Engine |
| Auth | JWT (python-jose) |
| Messaging | KakaoTalk Open Builder |
κ²μ μμ§ μ΄μ€ μ§μ
ν λνΈλ³λ‘ κ²μ μμ§μ μ νν μ μμ΅λλ€:
| μμ§ | μλΉμ€ | 리μμ€ κ΅¬μ‘° | μ©λ |
|---|---|---|---|
| RAG Engine (κΈ°λ³Έ) | rag_service.py |
ragCorpora β ragFiles | Weaviate νμ΄λΈλ¦¬λ κ²μ |
| Vertex AI Search | search_service.py |
dataStores β engines | Google κ΄λ¦¬ν κ²μ |
# tenant.search_backend νλλ‘ μ ν
"rag_engine" # Vertex AI RAG + Weaviate
"vertex_ai_search" # Vertex AI Search (DataStore + Engine)
Multi-Tenant Architecture
ν λνΈ κ²©λ¦¬ λ°©μ
λͺ¨λ ν
μ΄λΈμ tenant_id FKλ₯Ό λΆμ¬νμ¬ λ°μ΄ν°λ² μ΄μ€ λ 벨μμ 격리ν©λλ€.
tenants
βββ users (tenant_id FK)
βββ groups (tenant_id FK)
βββ corpora (tenant_id FK)
β βββ documents (tenant_id FK)
βββ chat_sessions (tenant_id FK)
β βββ messages (tenant_id FK)
βββ tenant_gcp_configs (1:1)
βββ tenant_kakao_configs (1:1)
βββ tenant_calendar_configs (1:1)
βββ chatbot_settings (1:1)
GCP 리μμ€ κ΅¬μ‘°
1 GCP νλ‘μ νΈ, 1 GCS λ²ν·, N ν λνΈ κ΅¬μ‘°:
GCP Project: techready-readytalk-kmu
β
βββ Vertex AI RAG (asia-northeast3)
β βββ ragCorpora/xxx β ν
λνΈA (RAG Engine)
β βββ ragCorpora/yyy β ν
λνΈB (RAG Engine)
β
βββ Vertex AI Search (global)
β βββ dataStores/aaa + engines/aaa β ν
λνΈC (Vertex AI Search)
β βββ dataStores/bbb + engines/bbb β ν
λνΈD (Vertex AI Search)
β
βββ Weaviate (Docker, weaviate-kmu.ready.talk)
β βββ Collection per RAG Corpus
β
βββ GCS Bucket: techready_readytalk_kmu
βββ tenants/
βββ tenant-a/
β βββ corpus-name/
β βββ files...
βββ tenant-b/
βββ corpus-name/
βββ files...
User Hierarchy
Superadmin (tenant_id=NULL, is_superadmin=True)
β νλ«νΌ μ 체 κ΄λ¦¬: ν
λνΈ CRUD, GCP μ€μ , κΈ°λ³Έ λͺ¨λΈ μ€μ
β
βββ Tenant Admin (is_admin=True)
β β ν
λνΈ λ΄ κ΄λ¦¬: λ¬Έμμ μ₯μ, λ¬Έμ μ
λ‘λ/μμ , μ¬μ©μ κ΄λ¦¬
β β
β βββ Regular User (κ·Έλ£Ή: κ΄λ¦¬μ/μΌλ°)
β β μ±ν
, νμΌ μ
λ‘λ, μΈμ
κ΄λ¦¬
β β
β βββ Guest User (auth_provider=guest)
β μ±ν
λ§ κ°λ₯, νμΌ μ
λ‘λ λΆκ°
β
βββ KakaoTalk User (auth_provider=kakao)
μΉ΄μΉ΄μ€ν‘ μ±λ ν΅ν΄ μλ μμ±, μ±ν
λ§ κ°λ₯
Chat Flow (Function Calling κΈ°λ°)
μ¬μ©μ μ§λ¬Έ
β
βΌ
λͺ¨λΈ κ²°μ (user.preferred_model > DEFAULT_MODEL)
β
βΌ
query_smart() β Gemini Function Calling
β
βββ search_documents() β RAG Corpus κ²μ (top_k=5)
βββ search_web() β Google Search (web_search_enabled μ)
βββ list/create/update/delete_calendar_events() β Google Calendar
βββ (none) β μΌλ° λν
β
βΌ
μλ΅ μμ± + μΆμ² μΆμΆ
β - cited_sourcesμμ νμΌλͺ
μΆμΆ
β - DBμμ display_name μ‘°ν (UUIDβμλ³Έλͺ
)
β - GCS Signed URL μμ± (μΆμ² λ§ν¬)
β
βΌ
DB μ μ₯ (messages ν
μ΄λΈ) β μλ΅ λ°ν
Google Calendar μ°λ
ν λνΈλ³ Google Calendar OAuth μ°λ:
- ν λνΈ μ΄λλ―Όμ΄ μΊλ¦°λ μ°λ (OAuth 2.0)
- μ±λ΄μμ μμ°μ΄λ‘ μΌμ κ΄λ¦¬ (Function Calling)
- βμ΄λ² μ£Ό μΌμ μλ €μ€β β
list_calendar_events - βλ΄μΌ 3μμ λ―Έν
μ‘μμ€β β
create_calendar_event - βνμ μκ° λ³κ²½ν΄μ€β β
update_calendar_event - βλ―Έν
μ·¨μν΄μ€β β
delete_calendar_event
- βμ΄λ² μ£Ό μΌμ μλ €μ€β β
KakaoTalk Integration
μΉ΄μΉ΄μ€ν‘ μ¬μ©μ β μΉ΄μΉ΄μ€ μλ² β /api/kakao/skill (webhook)
β
βββ μ¬μ©μ μλ μμ±/μ‘°ν
βββ Function Calling κΈ°λ° μ€λ§νΈ 쿼리
βββ μλ΅ λΆν (1000μ Γ μ΅λ 3κ° λ§νμ )
βββ Callback URLλ‘ λΉλκΈ° μλ΅
Superadmin κ΄λ¦¬
Platform Settings
| ν€ | μ€λͺ |
|---|---|
VERTEX_AI_PROJECT_ID |
GCP νλ‘μ νΈ ID |
VERTEX_AI_LOCATION |
Vertex AI 리μ |
GCP_CREDENTIALS_PATH |
μλΉμ€ κ³μ JSON κ²½λ‘ |
GCS_BUCKET_NAME |
GCS λ²ν·λͺ |
GEMINI_API_KEY |
Gemini API ν€ |
DEFAULT_MODEL |
κΈ°λ³Έ AI λͺ¨λΈ |
WEAVIATE_HTTP_ENDPOINT |
Weaviate μλν¬μΈνΈ |
WEAVIATE_COLLECTION_NAME |
Weaviate 컬λ μ λͺ |
WEAVIATE_API_KEY_SECRET |
Secret Manager μν¬λ¦Ώ κ²½λ‘ |
Tenant Lifecycle
μμ± μ μλ νλ‘λΉμ λ:
- Tenant λ μ½λ μμ± (name, slug, search_backend)
- GCP Config μμ± (κ³΅μ© νλ‘μ νΈ/λ²ν· μ°κ²°)
- κΈ°λ³Έ κ·Έλ£Ή μμ± (κ΄λ¦¬μ, μΌλ°)
- κ΄λ¦¬μ κ³μ μλ μμ±
- GCSμ ν λνΈ ν΄λ μμ±
μμ μ Cascade Cleanup:
- Vertex AI RAG Corpus λλ Search DataStore/Engine μμ
- GCS ν λνΈ ν΄λ λ° νμ νμΌ μμ
- DB Cascade μμ
Project Structure
readytalk-kmu/
βββ backend/
β βββ app/
β β βββ main.py
β β βββ config.py
β β βββ database.py
β β βββ models/
β β β βββ tenant.py # Tenant, GcpConfig, KakaoConfig, CalendarConfig
β β β βββ user.py
β β β βββ group.py
β β β βββ chat.py
β β β βββ corpus.py
β β β βββ chatbot_settings.py
β β β βββ prompt_template.py
β β β βββ platform_setting.py
β β β βββ store_permission.py
β β βββ routers/
β β β βββ superadmin.py # ν
λνΈ CRUD, νλ«νΌ μ€μ
β β β βββ auth.py # λ‘κ·ΈμΈ, νμκ°μ
, JWT
β β β βββ chat.py # μ€λ§νΈ 쿼리 (Function Calling)
β β β βββ corpus.py # λ¬Έμμ μ₯μ CRUD (κ²μμμ§ λΆκΈ°)
β β β βββ calendar.py # Google Calendar OAuth
β β β βββ kakao.py # μΉ΄μΉ΄μ€ν‘ webhook
β β β βββ chatbot_settings.py # μ±λ΄ μ€μ
β β β βββ prompt_templates.py # ν둬ννΈ ν
νλ¦Ώ
β β β βββ models.py # Gemini λͺ¨λΈ λͺ©λ‘
β β β βββ admin.py # ν
λνΈ μ΄λλ―Ό
β β βββ services/
β β β βββ rag_service.py # Vertex AI RAG + Weaviate
β β β βββ search_service.py # Vertex AI Search
β β β βββ chat_service.py # μ€λ§νΈ 쿼리 μμ§
β β β βββ gemini_client.py # Gemini API ν΄λΌμ΄μΈνΈ
β β β βββ gcs_service.py # GCS νμΌ κ΄λ¦¬
β β β βββ calendar_service.py # Google Calendar μ°λ
β β β βββ tenant_provisioning.py # ν
λνΈ νλ‘λΉμ λ
β β β βββ usage_service.py # μ¬μ©λ μΆμ
β β βββ schemas/
β β βββ utils/
β β βββ dependencies.py # μΈμ¦ λ―Έλ€μ¨μ΄
β β βββ security.py # JWT, λΉλ°λ²νΈ ν΄μ±
β β βββ init_data.py # μ΄κΈ° λ°μ΄ν° (superadmin)
β β βββ store_access.py # λ¬Έμμ μ₯μ μ κ·Ό κΆν
β βββ credentials/ # GCP μλΉμ€ κ³μ JSON (gitignore)
β βββ migrations/ # Alembic DB λ§μ΄κ·Έλ μ΄μ
β βββ Dockerfile
βββ frontend/
β βββ src/
β β βββ App.js # λΌμ°ν
(slug κΈ°λ° ν
λνΈ λΆκΈ°)
β β βββ pages/
β β β βββ ChatPage.js # μ±ν
UI
β β β βββ AdminPage.js # ν
λνΈ μ΄λλ―Ό
β β β βββ CalendarPage.js # μΊλ¦°λ UI
β β β βββ superadmin/ # μνΌμ΄λλ―Ό νμ΄μ§λ€
β β βββ services/api.js # Axios API ν΄λΌμ΄μΈνΈ
β β βββ context/
β β βββ AuthContext.js
β β βββ TenantContext.js
β βββ Dockerfile
βββ nginx/
β βββ backend.conf # Nginx μ€μ
βββ docker-compose.yml # λ‘컬 κ°λ°μ©
βββ docker-compose.dev.yml # κ°λ°κ³ (GCP VM)
βββ docker-compose.prod.yml # μ΄μκ³
βββ .env # λ‘컬 νκ²½λ³μ (gitignore)
βββ .env.production # μ΄μ νκ²½λ³μ (gitignore)
Getting Started
Prerequisites
- Docker & Docker Compose
- GCP μλΉμ€ κ³μ (Vertex AI + GCS + Secret Manager κΆν)
- (μ ν) Google Calendar OAuth ν΄λΌμ΄μΈνΈ
- (μ ν) μΉ΄μΉ΄μ€ν‘ μ€νλΉλ κ³μ
1. νκ²½ μ€μ
cp .env.example .env
# .env νμΌ νΈμ§
2. GCP μλΉμ€ κ³μ
mkdir -p backend/credentials
cp your-service-account.json backend/credentials/readytalk-kmu-credentials.json
3. μ€ν
docker-compose up -d --build
4. μ μ
| URL | μ€λͺ |
|---|---|
| http://localhost:8888 | λ©μΈ |
| http://localhost:8888/superadmin | μνΌμ΄λλ―Ό |
| http://localhost:8888/{slug}/chat | ν λνΈλ³ μ±ν |
| http://localhost:8888/{slug}/admin | ν λνΈλ³ μ΄λλ―Ό |
5. μ΄κΈ° μ€μ μμ
- μνΌμ΄λλ―Ό λ‘κ·ΈμΈ (
admin@academy.ready.talk) - μ€μ > GCP μ€μ μ λ ₯
- μ€μ > κΈ°λ³Έ λͺ¨λΈ μ ν
- ν λνΈ μμ± (κ²μ μμ§ μ ν: RAG Engine λλ Vertex AI Search)
- ν λνΈ μ΄λλ―Ό β λ¬Έμμ μ₯μ μμ± β νμΌ μ λ‘λ




