π€ 3λ¨κ³ : μλΉμ€ μν€ν μ³ λͺ¨λν - 100-hours-a-week/7-team-ddb-wiki GitHub Wiki
dolpin_ai/
βββ app/
β βββ main.py # FastAPI μ§μ
μ
β βββ api/ # μλν¬μΈνΈ μ μ
β β βββ deps.py # Depends μμ‘΄μ±
β β βββ v1/
β β βββ endpoints/
β β β βββ recommend.py # μΆμ² μμ² μλν¬μΈνΈ
β β β βββ embed.py # μλ² λ© μ²λ¦¬μ© (μ₯μ, μ¬μ©μ μμ² μλ² λ©)
β β βββ router.py # v1 router ν΅ν©
β βββ services/ # μλΉμ€ λ‘μ§
β β βββ recommender.py # μΆμ² μκ³ λ¦¬μ¦
β β βββ rag_engine.py # RAG μ²΄μΈ λλ ν둬ννΈ μ²΄μΈ
β β βββ prompt_manager.py # ν둬ννΈ κ΅¬μ± λ° ν
νλ¦Ώ μ²λ¦¬
β β βββ vector_store.py # FAISS/Chroma λ± λ²‘ν°DB μ°λ
β βββ ml/ # λͺ¨λΈ λ‘λ© λ° μΆλ‘
β β βββ model_loader.py # LLM λλ embedding λͺ¨λΈ λ‘λ©
β β βββ inference.py # μΆλ‘ μμ§ μ€ν (gemini -> local llm)
β βββ schemas/ # Pydantic λͺ¨λΈ
β β βββ recommend_schema.py # μ
λ ₯/μΆλ ₯ μ€ν€λ§
β β βββ embed_schema.py
β βββ core/ # μ€μ , 보μ, CORS λ±
β β βββ config.py
β β βββ init_app.py # λ‘κ±°, DB μ΄κΈ°ν λ± FastAPI μ± λΆνΈμ€νΈλ© ν¨μ
---------------------------------------v1----------------------------------------
β βββ utils/ # 보쑰 μ νΈ ν¨μ
β β βββ logger.py # loguru λλ structlog κΈ°λ° λ‘κ±° μ€μ
β β βββ text_cleaner.py # ν
μ€νΈ μ μ²λ¦¬ μ νΈ (μ΄λͺ¨μ§ μ κ±°, μ κ·ν λ±)
β β βββ timer.py # μΆλ‘ μκ° μΈ‘μ λ°μ½λ μ΄ν° ν¨μ
βββ workers/ # λ©μμ§ ν/λΉλκΈ° μ컀 (μ ν)
β βββ embedding_worker.py # μλ² λ© μμ± λ° DB μ μ₯ λ±μ λΉλκΈ° μ²λ¦¬ μ μ© μ컀 (ex. Celery/RQ)
β βββ celery_app.py # Celery μΈμ€ν΄μ€ μ μ λ° μ€μ λ‘λ©
βββ tests/ # ν
μ€νΈ
β βββ unit/ # λ¨μ ν
μ€νΈ: prompt_manager, recommender, vector_store λ±
β βββ integration/ # ν΅ν© ν
μ€νΈ: /recommend API νΈμΆ μ end-to-end νμΈ
βββ config/ # νκ²½ μ€μ νμΌ
β βββ .env.dev # κ°λ° νκ²½ μ€μ νμΌ
β βββ .env.prod # μ΄μ νκ²½ μ€μ νμΌ
β βββ gunicorn_conf.py # Gunicorn νλ‘μΈμ€ κ΄λ¦¬ μ€μ (Docker λ°°ν¬ μ μ¬μ©)
βββ Dockerfile # FastAPI μλ² + λͺ¨λΈ μ’
μ ν¨ν€μ§ ν¬ν¨ 컨ν
μ΄λ μ€μ
βββ docker-compose.yml # API μλ² + 벑ν°DB + Redis (μ΅μ
) λ± μ¬λ¬ 컨ν
μ΄λ μ μ
βββ requirements.txt # νμ ν¨ν€μ§ 리μ€νΈ (FastAPI, pydantic, openai, langchain, chromadb λ±)
βββ README.md # μλΉμ€ κ°μ, μ€μΉ λ°©λ², API μ€λͺ
λ± λ¬Έμ
λͺ¨λλͺ | μ± μ(λλ©μΈ) | μ£Όμ κΈ°λ₯ |
---|---|---|
API Gateway (main.py) | FastAPI μ§μ μ | - HTTP μμ² μμ - CORS λ° λ―Έλ€μ¨μ΄ μ€μ - API Router ν΅ν© |
Routers (/api/v1/endpoints) | API μΈν°νμ΄μ€ | - /recommend, /embed λ±μ REST μλν¬μΈνΈ μ μ- μμ² νλΌλ―Έν° λ°μΈλ©- μ€ν€λ§ μ ν¨μ± κ²μ¬ |
Router (/api/v1/router.py) | API λ²μ ν΅ν© | - v1 λΌμ°ν° λ¬Άμ λ±λ‘- /api/v1 κ²½λ‘ νμλ‘ κ° κΈ°λ₯ μ°κ²° |
Dependencies (api/deps.py) | κ³΅ν΅ μμ‘΄μ± κ΄λ¦¬ | - DB μΈμ , μΈμ¦ ν ν° κ²μ¦ λ± κ³΅ν΅ Depends() μ 곡 |
Services:Recommender | μΆμ² μμ± | - μ¬μ©μ μ λ ₯ κΈ°λ° ν둬ννΈ κ΅¬μ±- λ²‘ν° κ²μ κ²°κ³Ό λ°μ- LLM κ²°κ³Ό νμ± ν μΆμ² μμ± |
Services:RAG Engine | κ²μ κΈ°λ° μμ± (RAG) | - ν둬ννΈ + λ²‘ν° κΈ°λ° context μ‘°ν©- LLM νΈμΆμ© ν μ€νΈ μμ± |
Services:Prompt Manager | ν둬ννΈ ν νλ¦Ώ κ΄λ¦¬ | - μ¬μ©μ μ λ ₯, νκ·Έ, νμ€ν 리 κΈ°λ° ν νλ¦Ώ ꡬμ±- λ€μν μ λ ₯ ν¬λ§·μ λν μ μ°ν ν¬λ§·ν |
Services:Vector Store | μ μ¬λ κΈ°λ° κ²μ | - μ¬μ©μ ν μ€νΈ μλ² λ©- FAISS/Chroma κ²μ μ°λ- κ΄λ ¨ context μΆμΆ |
Model Loader (ml/model_loader.py) | λͺ¨λΈ μ€λΉ | - embedding λͺ¨λΈ λλ LLM API μ΄κΈ°ν- GPU/CPU μ€μ κ³ λ €ν λ‘λ© |
Inference (ml/inference.py) | LLM μΆλ‘ νΈμΆ | - OpenAI / HuggingFace / local λ± LLM μΈν°νμ΄μ€- μλ΅ νμ± λ° μ€λ₯ μ²λ¦¬ |
Schemas (schemas/) | λ°μ΄ν° ꡬ쑰 μ μ | - RecommendationInput, RecommendationOutput μ μ- Pydantic κΈ°λ° μ λ ₯/μΆλ ₯ κ²μ¦ |
Core (core/config.py) | νκ²½ μ€μ | - .env κΈ°λ° μ€μ λ‘λ- API Key, νΈμ€νΈ μ£Όμ λ± κ΄λ¦¬ |
V2 | ||
Core (core/init_app.py) | μ± μ΄κΈ°ν | - λ‘κΉ μ€μ - DB λ° κΈ°ν λͺ¨λ μ΄κΈ°ν ν μ 곡 |
Utils (utils/) | μ νΈ ν¨μ λͺ¨μ | - λ‘κ±° μ€μ - ν μ€νΈ μ μ - μ€ν μκ° μΈ‘μ λ°μ½λ μ΄ν° λ± |
Workers (workers/) | λΉλκΈ° λ°±κ·ΈλΌμ΄λ μμ | - μλ² λ© μμ± μμ μ²λ¦¬- Celery task λ±λ‘ |
Tests (tests/) | μ λ/ν΅ν© ν μ€νΈ | - μλΉμ€ λ¨μ μ λ ν μ€νΈ- μ 체 μΆμ² νλ¦μ λν API ν΅ν© ν μ€νΈ |
Request (Pydantic: RecommendationInput
)
{
"userQuery": "λ΄μΌ μ λ
μ μμ½ κ°λ₯ν νμμ₯μ μλ €μ€, λ©λ΄λ ν΄μ°λ¬Όλ‘"
}
Response (Pydantic: RecommendationOutput
)
{
"data": [
{"place_id": 21, "similarity_score": 0.92},
{"place_id": 36, "similarity_score": 0.86},
{"place_id": 16, "similarity_score": 0.87},
{"place_id": 41, "similarity_score": 0.93},
{"place_id": 12, "similarity_score": 0.91}
]
}
recommender.py
def generate_recommendation(input: RecommendationInput) -> RecommendationOutput:
prompt = build_prompt(input)
context = retrieve_context(input)
result = call_llm(prompt, context)
return parse_response(result)
prompt_manager.py
def build_prompt(input: RecommendationInput) -> str:
return f"""
...
"""
- λͺ¨λλ³ μ± μμ΄ λͺ ν β κΈ°λ₯ μμ μ μν₯ μ΅μν
-
prompt_manager
,recommender
,inference
λ± λ 립 λ¨μλ³ λ³κ²½ κ°λ₯
-
/api/v2/
μΆκ° μ,v2/
λλ ν λ¦¬λ§ μμ±νλ©΄ λ²μ λΆλ¦¬ κ°λ₯ - Vector DB κ΅μ²΄(μ: Chroma β Weaviate) μ
vector_store.py
λ§ μμ
- λ¨μλ³ μ λ ν
μ€νΈ κ°λ₯ (
prompt_manager
,rag_engine
,recommender
) - μ€λ₯ μΆμ λ²μ μΆμ β λλ²κΉ μλ ν₯μ
- API, μλΉμ€, λͺ¨λΈ μμ λΆλ¦¬ β μν κΈ°λ° νμ ꡬ쑰 νμ±
- νλ‘ νΈ/λͺ¨λΈ/λ°±μλ κ° μμ λ³λ ¬ν κ°λ₯
- μλΉμ€ μ₯μ μ ν΄λΉ λͺ¨λλ§ Hotfix κ°λ₯
- μ€μ , λͺ¨λΈ, λ‘κ·Έ λ± μΈνλΌ μ½λλ λΆλ¦¬λμ΄ λ°°ν¬ μΆ©λ μ΅μν