๋์ ๋ฐ์ดํฐ ๋ถ์ ๋ฐ AI ์๋น์ค๋ฅผ ์ํ FastAPI ๋ฐฑ์๋ ์๋ฒ
backend/
โโโ app/ # ๋ฉ์ธ ์ ํ๋ฆฌ์ผ์ด์
โ โโโ __init__.py
โ โโโ main.py # FastAPI ์ฑ ์ง์
์
โ โโโ api/ # API ์๋ํฌ์ธํธ
โ โ โโโ __init__.py
โ โ โโโ v1/ # API ๋ฒ์ 1
โ โ โโโ __init__.py
โ โโโ core/ # ํต์ฌ ์ค์ ๋ฐ ์ ํธ๋ฆฌํฐ
โ โ โโโ __init__.py
โ โ โโโ config.py # ํ๊ฒฝ ์ค์
โ โ โโโ database.py # ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ
โ โโโ models/ # SQLAlchemy ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ชจ๋ธ
โ โ โโโ __init__.py
โ โโโ schemas/ # Pydantic ์คํค๋ง (์์ฒญ/์๋ต ๋ชจ๋ธ)
โ โ โโโ __init__.py
โ โโโ services/ # ๋น์ฆ๋์ค ๋ก์ง
โ โ โโโ __init__.py
โ โโโ utils/ # ๊ณตํต ์ ํธ๋ฆฌํฐ ํจ์
โ โโโ __init__.py
โโโ alembic/ # ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ง์ด๊ทธ๋ ์ด์
โโโ tests/ # ํ
์คํธ ์ฝ๋
โ โโโ __init__.py
โโโ scripts/ # ์ ํธ๋ฆฌํฐ ์คํฌ๋ฆฝํธ
โโโ sentinel_farm_analysis/ # Sentinel ์์ฑ ๋ฐ์ดํฐ ๋ถ์ (๊ธฐ์กด)
โ โโโ test_response.py
โ โโโ test_2024_data.json
โโโ requirements.txt # ํ๋ก์ ํธ ์์กด์ฑ
โโโ .env # ํ๊ฒฝ ๋ณ์ (Git์์ ์ ์ธ)
โโโ .gitignore # Git ์ ์ธ ํ์ผ
โโโ main.py # PyCharm ํ
ํ๋ฆฟ (์ ๊ฑฐ ์์ )
โโโ test_farm_api.py # ํ๋งต API ํ
์คํธ (๊ธฐ์กด)
โโโ test_farmmap_api.py # ํ๋งต API ํ
์คํธ (๊ธฐ์กด)
- Framework: FastAPI
- Database: PostgreSQL
- ORM: SQLAlchemy
- Migration: Alembic
- ASGI Server: Uvicorn
- Testing: Pytest
- AI/ML: Sentence-Transformers, Google Gemini API
- Embeddings: Korean SBERT (jhgan/ko-sroberta-multitask)
# PostgreSQL ์ค์น
brew install postgresql@16
brew services start postgresql@16
# ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ฐ ์ฌ์ฉ์ ์์ฑ
psql -d postgres
CREATE USER postgres WITH PASSWORD 'nh-challenge' CREATEDB;
CREATE DATABASE nh_challenge OWNER postgres;
\q# PostgreSQL ์ค์น
sudo apt update
sudo apt install postgresql postgresql-contrib
# ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ฐ ์ฌ์ฉ์ ์์ฑ
sudo -u postgres psql
CREATE USER postgres WITH PASSWORD 'nh-challenge' CREATEDB;
CREATE DATABASE nh_challenge OWNER postgres;
\qgit clone https://github.com/nh-ai-challenge/backend.git
cd backendpython3 -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activatepip install --upgrade pip
pip install -r backend/requirements.txt
# PyTorch ์ค์น (CPU ๋ฒ์ )
pip install torch --index-url https://download.pytorch.org/whl/cpu
# ๋๋ GPU ๋ฒ์ (CUDA 11.8)
pip install torch --index-url https://download.pytorch.org/whl/cu118๋ฃจํธ ๋๋ ํ ๋ฆฌ์ .env ํ์ผ์ ์์ฑํฉ๋๋ค (backend ํด๋๊ฐ ์๋ ํ๋ก์ ํธ ๋ฃจํธ):
# .env.example ๋ณต์ฌ
cp .env.example .env
# ๋๋ ์ง์ ์์ฑ
cat > .env << EOF
# Database Configuration
DATABASE_URL=postgresql+asyncpg://postgres:nh-challenge@localhost:5432/nh_challenge
# Gemini API (AI ๋งค์นญ ์ค๋ช
์์ฑ)
GEMINI_API_KEY=your_gemini_api_key_here
# External APIs (Optional)
FARMMAP_SERVICE_KEY=your_farmmap_key
FARMMAP_ENCODED_KEY=your_farmmap_encoded_key
SENTINEL_CLIENT_ID=your_sentinel_client_id
SENTINEL_CLIENT_SECRET=your_client_secret
EOFcd backend
# ๋ฐฉ๋ฒ 1: ์๋ ๋ง์ด๊ทธ๋ ์ด์
์คํฌ๋ฆฝํธ (๊ถ์ฅ)
python init_migration.py
# ๋ฐฉ๋ฒ 2: Alembic ๋ง์ด๊ทธ๋ ์ด์
alembic upgrade head
# ํ
์ด๋ธ ์์ฑ ํ์ธ
psql -U postgres -d nh_challenge -c "\dt"์์๋๋ ํ ์ด๋ธ ๋ชฉ๋ก:
- users (์ฌ์ฉ์ ์ ๋ณด)
- senior_profiles_v2 (์๋์ด ํ๋กํ + AI ์๋ฒ ๋ฉ)
- youth_profiles_v2 (์ฒญ๋ ํ๋กํ + AI ์๋ฒ ๋ฉ)
- matches (๋งค์นญ ๊ฒฐ๊ณผ)
- match_requests (๋งค์นญ ์์ฒญ)
- matching_scores (๋งค์นญ ์ ์)
# ๊ฐ๋ฐ ์๋ฒ ์คํ (์๋ ๋ฆฌ๋ก๋)
uvicorn app.main:app --reload --host 0.0.0.0 --port 8000
# ๋๋ Python ๋ชจ๋๋ก ์คํ
python -m uvicorn app.main:app --reload์๋ฒ๋ http://localhost:8000 ์์ ์คํ๋ฉ๋๋ค. API ๋ฌธ์๋ http://localhost:8000/docs ์์ ํ์ธํ ์ ์์ต๋๋ค.
- Swagger UI: http://localhost:8000/docs
- ReDoc: http://localhost:8000/redoc
- ํฌ์ค์ฒดํฌ: http://localhost:8000/api/v1/health
- DB ์ฐ๊ฒฐ ํ ์คํธ: http://localhost:8000/api/v1/health/db
POST /api/v1/auth/register- ํ์๊ฐ์POST /api/v1/auth/login- ๋ก๊ทธ์ธGET /api/v1/auth/me- ํ์ฌ ์ฌ์ฉ์ ์ ๋ณด
GET /api/v1/profiles/me- ๋ด ํ๋กํ ์กฐํPUT /api/v1/profiles/me/profile-text- ํ๋กํ ํ ์คํธ ์ ๋ฐ์ดํธ (์๋ ์๋ฒ ๋ฉ ์์ฑ)
POST /api/v1/surveys/senior- ์๋์ด ์ค๋ฌธ ์ ์ถPOST /api/v1/surveys/youth- ์ฒญ๋ ์ค๋ฌธ ์ ์ถGET /api/v1/surveys/senior/profile- ์๋์ด ํ๋กํ ์กฐํGET /api/v1/surveys/youth/profile- ์ฒญ๋ ํ๋กํ ์กฐํ
GET /api/v1/matches/recommendations/hybrid- AI ํ์ด๋ธ๋ฆฌ๋ ๋งค์นญ ์ถ์ฒGET /api/v1/matches/{id}?generate_explanation=true- ๋งค์นญ ์์ธ + AI ์ค๋ชPOST /api/v1/matches/calculate- ๋งค์นญ ์ ์ ๊ณ์ฐ
-
ํ ์คํธ ์๋ฒ ๋ฉ (30%)
- ํ๊ตญ์ด SBERT ๋ชจ๋ธ ์ฌ์ฉ (jhgan/ko-sroberta-multitask)
- 768์ฐจ์ ๋ฒกํฐ๋ก ํ๋กํ ํ ์คํธ ์ธ์ฝ๋ฉ
- ์ฝ์ฌ์ธ ์ ์ฌ๋๋ก ์๋ฏธ์ ๋งค์นญ
-
SCI ์ ์ (70%)
- ๋์ ์ฒ ํ (40%)
- ์ฌ์ ์ด์ (20%)
- ๋ฉํ ์ญ (20%)
- ์ฌ๋ฌด ์กฐ๊ฑด (20%)
-
2๋จ๊ณ ํํฐ๋ง
- 1์ฐจ: ์๋ฒ ๋ฉ ์ ์ฌ๋ ํํฐ (์์ ํ๋ณด ์ ๋ณ)
- 2์ฐจ: ์์ธ SCI ์ ์ ๊ณ์ฐ (์ต์ข ์์)
- ๋งค์นญ ์ด์ ๋ฅผ ํ๊ตญ์ด ์์ฐ์ด๋ก ์ค๋ช
- ํ๋กํ ๋ฐ์ดํฐ ๊ธฐ๋ฐ ๊ตฌ์กฐํ๋ ๋ถ์
- ๋งค์นญ ๊ฐ์ , ์ฃผ์์ฌํญ, ์ฑ๊ณต ๊ฐ๋ฅ์ฑ ์ ์
cd backend
python scripts/generate_test_data.py --seniors 100 --youths 100์ด ์คํฌ๋ฆฝํธ๋:
- ๋ค์ํ ํ๋ฅด์๋์ ์๋์ด/์ฒญ๋ ์ฌ์ฉ์ ์์ฑ
- ํ๋กํ ํ ์คํธ ์๋ ์์ฑ ๋ฐ ์๋ฒ ๋ฉ ๊ณ์ฐ
- ์ค์ ๊ฐ์ ์ค๋ฌธ ์๋ต ์๋ฎฌ๋ ์ด์
Python 3.13 ์ฌ์ฉ์ SQLAlchemy ๋น๋๊ธฐ ๊ธฐ๋ฅ ์ค๋ฅ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค.
pip install greenlet==3.1.1# ๋ชจ๋ธ ์๋ ๋ค์ด๋ก๋
python -c "from sentence_transformers import SentenceTransformer; SentenceTransformer('jhgan/ko-sroberta-multitask')"- API ํค ํ์ธ: https://makersuite.google.com/app/apikey
- ํ๊ฒฝ ๋ณ์ ํ์ธ:
echo $GEMINI_API_KEY - Rate limit ํ์ธ (๋ฌด๋ฃ tier: 60 requests/minute)
# PostgreSQL ์๋น์ค ์ํ ํ์ธ
brew services list | grep postgresql # macOS
sudo systemctl status postgresql # Linux
# ์๋น์ค ์ฌ์์
brew services restart postgresql@16 # macOS
sudo systemctl restart postgresql # Linux# CPU ์ ์ฉ PyTorch ์ค์น๋ก ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ ๊ฐ์
pip uninstall torch torchvision torchaudio
pip install torch --index-url https://download.pytorch.org/whl/cpu- ์๋ฒ ๋ฉ ์บ์ฑ: ํ๋กํ ํ ์คํธ ๋ณ๊ฒฝ ์์๋ง ์ฌ๊ณ์ฐ
- ๋ฐฐ์น ์ฒ๋ฆฌ: ์ฌ๋ฌ ํ ์คํธ ๋์ ์๋ฒ ๋ฉ ์์ฑ
- ์ธ๋ฑ์ฑ: embedding_updated_at ํ๋์ ์ธ๋ฑ์ค ์ถ๊ฐ
- ์ฐ๊ฒฐ ํ: PostgreSQL ์ฐ๊ฒฐ ํ ํฌ๊ธฐ ์กฐ์
- Python 3.9 ์ด์ (3.11 ๊ถ์ฅ)
- PostgreSQL 14 ์ด์
- RAM 8GB ์ด์ (์๋ฒ ๋ฉ ๋ชจ๋ธ์ฉ)
- SSD ์คํ ๋ฆฌ์ง (๋ชจ๋ธ ๋ก๋ฉ ์๋)