CoolFace
Apppublic

ilangs/AI_Math_Tutor_HF

sourceHugging Facemitupdated 6mo agoView on Hugging Face
0likes
App README

🐰 AI Math Tutor β€” 루미와 ν•¨κ»˜ν•˜λŠ” μ΄ˆλ“± μˆ˜ν•™

AI Agent κ³Όμ • νŒ€ ν”„λ‘œμ νŠΈ | 4νŒ€ μ΄ˆλ“±ν•™κ΅ 3ν•™λ…„ 학생을 μœ„ν•œ AI 기반 1:1 μˆ˜ν•™ νŠœν„°λ§ μ„œλΉ„μŠ€ LangChain Β· LangGraph Β· FastAPI Β· ChromaDB Β· OpenAI

πŸ“Œ ν”„λ‘œμ νŠΈ κ°œμš”

ν•­λͺ©λ‚΄μš©
ν”„λ‘œμ νŠΈλͺ…AI Math Tutor β€” 루미와 ν•¨κ»˜ν•˜λŠ” μ΄ˆλ“± μˆ˜ν•™
νŒ€λͺ…4νŒ€
λŒ€μƒμ΄ˆλ“±ν•™κ΅ 3ν•™λ…„ 학생
λͺ©μ AIλ₯Ό ν™œμš©ν•œ 개인 λ§žμΆ€ν˜• μˆ˜ν•™ νŠœν„°λ§μœΌλ‘œ ν•™μŠ΅ 효율 κ·ΉλŒ€ν™”
개발 κΈ°κ°„2026λ…„ 3μ›” (3μ£Ό)
기술 κ³Όμ •3μ£Ό AI Agent κ³Όμ • 쀑간 ν”„λ‘œμ νŠΈ

μ„œλΉ„μŠ€ μ†Œκ°œ

루미(Lumi)λŠ” μ΄ˆλ“±ν•™κ΅ 3ν•™λ…„ ν•™μƒμ˜ μˆ˜ν•™ ν•™μŠ΅μ„ λ•λŠ” AI νŠœν„° μΊλ¦­ν„°μž…λ‹ˆλ‹€. λ‹¨μˆœ 문제 풀이λ₯Ό λ„˜μ–΄ κ°œλ… μ„€λͺ… β†’ 이해도 확인 β†’ 문제 ν’€κΈ° β†’ AI μ±„μ μ˜ μ™„μ „ν•œ ν•™μŠ΅ 사이클을 μ œκ³΅ν•˜λ©°, RAG(Retrieval-Augmented Generation) 기반 자유 질문과 μ‹œν—˜ κΈ°λŠ₯, 성적 λŒ€μ‹œλ³΄λ“œκΉŒμ§€ κ°–μΆ˜ μ’…ν•© ν•™μŠ΅ ν”Œλž«νΌμž…λ‹ˆλ‹€.


✨ μ£Όμš” κΈ°λŠ₯

1. 였늘의 ν•™μŠ΅ (단계별 ν•™μŠ΅ 사이클)

단원 선택 β†’ AI κ°œλ… μ„€λͺ… β†’ 이해도 평가 β†’ 문제 ν’€κΈ° β†’ AI 채점
  • —단원 선택: CSV λ°μ΄ν„°μ…‹μ—μ„œ μΆ”μΆœν•œ μ‹€μ œ 3ν•™λ…„ μˆ˜ν•™ 단원 λͺ©λ‘ 제곡
  • β€”AI κ°œλ… μ„€λͺ…: OpenAIκ°€ 루미 μΊλ¦­ν„°λ‘œ ν•΄λ‹Ή 단원 κ°œλ…μ„ μ΄ˆλ“±ν•™μƒ λˆˆλ†’μ΄μ— 맞게 μ„€λͺ…
  • —보좩 μ„€λͺ…: "λ‹€μ‹œ μ„€λͺ…ν•΄μ€˜" λ²„νŠΌμœΌλ‘œ 더 μ‰¬μš΄ μΆ”κ°€ μ„€λͺ… μš”μ²­ κ°€λŠ₯
  • —이해도 평가: 학생이 μžμ‹ μ˜ 말둜 κ°œλ…μ„ μ„€λͺ…ν•˜λ©΄ AIκ°€ [PASS] / [FAIL] νŒμ • + 격렀 ν”Όλ“œλ°± 제곡
  • β€”λ¬Έμ œ ν’€κΈ°: 선택 λ‹¨μ›μ—μ„œ λ¬΄μž‘μœ„ 문제 1개 좜제
  • β€”AI 채점: 학생 닡변을 OpenAIκ°€ μ±„μ ν•˜κ³  [μ •λ‹΅] / [μ˜€λ‹΅] + 상세 풀이 ν”Όλ“œλ°± 제곡
  • β€”TTS μŒμ„±: OpenAI TTS(nova λͺ©μ†Œλ¦¬)둜 κ°œλ… μ„€λͺ…κ³Ό ν”Όλ“œλ°±μ„ μŒμ„±μœΌλ‘œ μž¬μƒ

2. AI μžμœ ν•™μŠ΅ μ±„νŒ… (RAG + LLM)

학생 질문 μž…λ ₯ β†’ μˆ˜ν•™ 질문 λΆ„λ₯˜ β†’ ChromaDB RAG 검색 β†’ OpenAI 맞좀 λ‹΅λ³€
  • β€”μ •ν•΄μ§„ 단원 없이 자유둭게 μˆ˜ν•™ κ΄€λ ¨ 질문 κ°€λŠ₯
  • β€”μˆ˜ν•™ 질문 필터링: LLM이 λ¨Όμ € μˆ˜ν•™ κ΄€λ ¨ μ§ˆλ¬ΈμΈμ§€ λΆ„λ₯˜ (λΉ„κ΄€λ ¨ 질문 차단)
  • β€”RAG 기반 λ‹΅λ³€: ChromaDBμ—μ„œ 의미적으둜 μœ μ‚¬ν•œ 기좜 λ¬Έμ œΒ·ν’€μ΄λ₯Ό κ²€μƒ‰ν•˜μ—¬ λ§₯락 μžˆλŠ” 힌트 제곡
  • β€”λŒ€ν™” 기둝 μœ μ§€: 이전 λŒ€ν™” μ»¨ν…μŠ€νŠΈλ₯Ό ν¬ν•¨ν•˜μ—¬ 연속 질문 κ°€λŠ₯
  • β€”μ±„νŒ… 기둝 μ €μž₯: λŒ€ν™” λ‚΄μš©μ΄ DB에 μ €μž₯λ˜μ–΄ μž¬μ ‘μ† μ‹œ 이전 λŒ€ν™” 볡원

3. 단원 μ‹œν—˜ (μžλ™ 좜제 β†’ 채점 β†’ κ²°κ³Ό μ €μž₯)

단원 선택 β†’ 10문제 μžλ™ 좜제 β†’ 일괄 제좜 β†’ AI 병렬 채점 β†’ κ²°κ³Ό μ €μž₯
  • β€”μžλ™ 좜제: 선택 λ‹¨μ›μ—μ„œ 10문제λ₯Ό λ¬΄μž‘μœ„λ‘œ μΆ”μΆœ (CSV 직접 쑰회)
  • —일괄 채점: asyncio.gather()둜 10문제λ₯Ό 병렬 μ²˜λ¦¬ν•˜μ—¬ 채점 속도 μ΅œμ ν™”
  • β€”κ²°κ³Ό μ €μž₯: 점수, μ˜€λ‹΅ 번호, AI ν”Όλ“œλ°±μ„ DB에 μ €μž₯
  • β€”μ‹œν—˜ 이λ ₯ 쑰회: 성적 λŒ€μ‹œλ³΄λ“œμ—μ„œ κ³Όκ±° μ‹œν—˜ 이λ ₯ 확인 κ°€λŠ₯

4. 성적 λŒ€μ‹œλ³΄λ“œ (ν•™μŠ΅ 이λ ₯ Β· μ •λ‹΅λ₯ )

  • β€”ν•™μŠ΅ 이λ ₯: 였늘의 ν•™μŠ΅μ—μ„œ ν‘Ό 문제 기둝 (단원, μ •μ˜€λ‹΅, μΌμ‹œ)
  • β€”μ •λ‹΅λ₯  톡계: 전체 ν•™μŠ΅ 기둝 기반 μ •λ‹΅λ₯ (%) 계산 및 μ‹œκ°ν™”
  • β€”μ‹œν—˜ 이λ ₯: 단원별 μ‹œν—˜ 점수 좔이 및 κ³Όκ±° μ‹œν—˜ κ²°κ³Ό λͺ©λ‘

5. 토큰 μ‚¬μš© 둜그 (LLM API λΉ„μš© 좔적)

  • β€”μ‹€μ‹œκ°„ 기둝: LLM ν˜ΈμΆœλ§ˆλ‹€ get_openai_callback()으둜 토큰 μˆ˜Β·λΉ„μš©μ„ 캑처
  • β€”λ‘œμ»¬ DB μ €μž₯: LangSmith 의쑴 없이 둜컬 SQLite(token_logs ν…Œμ΄λΈ”)에 μ €μž₯
  • β€”κΈ°λŠ₯별 λΆ„λ₯˜: κ°œλ…μ„€λͺ… / 이해도평가 / 채점 / Q&A / AIμžμœ ν•™μŠ΅ / μ‹œν—˜μ±„μ  λ“± action별 집계
  • β€”λΉ„μš© ν™˜μ‚°: ν”„λ‘¬ν”„νŠΈΒ·μ»΄ν”Œλ¦¬μ…˜ 토큰을 λ‹¬λŸ¬($) 및 원화(β‚©)둜 ν™˜μ‚°ν•˜μ—¬ ν‘œμ‹œ

πŸ—οΈ μ‹œμŠ€ν…œ μ•„ν‚€ν…μ²˜

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    Frontend (HTML / JS)                        β”‚
β”‚   login.html Β· app.html Β· section1~5.js                         β”‚
β”‚   - 둜그인/νšŒμ›κ°€μž… UI                                           β”‚
β”‚   - μ„Ήμ…˜λ³„ κΈ°λŠ₯ ν™”λ©΄ (ν•™μŠ΅/μ±„νŒ…/μ‹œν—˜/λŒ€μ‹œλ³΄λ“œ/ν† ν°λ‘œκ·Έ)              β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                           β”‚  HTTP fetch (JWT Bearer Token)
                           β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚               FastAPI Server (server.py)                       β”‚
β”‚                                                                β”‚
β”‚   /auth/*  β†’ routers/auth.py   (λ‘œκ·ΈμΈΒ·νšŒμ›κ°€μž…Β·JWT λ°œκΈ‰)        β”‚
β”‚   /api/*   β†’ routers/tutor.py  (AI νŠœν„° κΈ°λŠ₯ 전체)               β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                           β”‚
                           β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚             Service Layer (app/services/tutor_service.py)      β”‚
β”‚                      λΉ„μ¦ˆλ‹ˆμŠ€ 둜직 처리                         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                           β”‚
                           β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚          LangChain Integration (app/tutor/integration.py)      β”‚
β”‚                                                                β”‚
β”‚   explain_chain Β· reexplain_chain Β· concept_chain               β”‚
β”‚   answer_chain Β· rag_chain Β· classify_chain                    β”‚
β”‚   generate_speech_with_cache (TTS + MD5 캐싱)                   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
         β”‚                               β”‚
         β–Ό                               β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  OpenAI OpenAI  β”‚         β”‚         Two-Track 데이터 쑰회      β”‚
β”‚  (LLM + TTS)    β”‚         β”‚                                   β”‚
β”‚                 β”‚         β”‚  Track 1: CSV / SQLite 직접 쑰회    β”‚
β”‚  text-embedding β”‚         β”‚  - 였늘의 ν•™μŠ΅ (μ •ν™•ν•œ 단원 필터링)  β”‚
β”‚  -3-small       β”‚         β”‚  - 단원 μ‹œν—˜ (λ¬΄μž‘μœ„ 10문제 μΆ”μΆœ)    β”‚
β”‚  (RAG Embed)    β”‚         β”‚                                    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜         β”‚  Track 2: ChromaDB RAG 검색         β”‚
                            β”‚  - AI μžμœ ν•™μŠ΅ μ±„νŒ…                 β”‚
                            β”‚  - μ‹œλ§¨ν‹±(의미) μœ μ‚¬λ„ 검색         β”‚
                            β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
         β”‚
         β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    Data Layer                                  β”‚
β”‚   database/user_db.sqlite   - μ‚¬μš©μžΒ·ν•™μŠ΅Β·μ‹œν—˜Β·μ±„νŒ…Β·ν† ν° 둜그      β”‚
β”‚   database/vector_store/    - ChromaDB 벑터 인덱슀              β”‚
β”‚   data/processed/*.csv      - μˆ˜ν•™ 문제 데이터셋                β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Two-Track 데이터 쑰회 ꡬ쑰

μ‹€μ œ AI ꡐ윑 μ„œλΉ„μŠ€μ—μ„œλ„ μ‚¬μš©ν•˜λŠ” μ•ˆμ •μ μΈ ν•˜μ΄λΈŒλ¦¬λ“œ μ•„ν‚€ν…μ²˜μž…λ‹ˆλ‹€.

ꡬ뢄Track 1 (CSV / SQLite)Track 2 (ChromaDB RAG)
μ‚¬μš© κΈ°λŠ₯였늘의 ν•™μŠ΅, 단원 μ‹œν—˜AI μžμœ ν•™μŠ΅ μ±„νŒ…
쿼리 λ°©μ‹λ‹¨μ›Β·λ‚œμ΄λ„ 쑰건 μ •ν™• ν•„ν„°λ§μ˜λ―Έ(semantic) μœ μ‚¬λ„ 검색
μž₯점빠λ₯Έ 속도, μ •ν™•ν•œ 단원 보μž₯자유둜운 μžμ—°μ–΄ 질문 처리
λΉ„μœ κ΅κ³Όμ„œ λͺ©μ°¨λ‘œ νŽ˜μ΄μ§€ λ°”λ‘œ μ°ΎκΈ°μ„ μƒλ‹˜μ΄ λΉ„μŠ·ν•œ 예제 μ°Ύμ•„μ£ΌκΈ°

πŸ› οΈ 기술 μŠ€νƒ

λΆ„λ₯˜κΈ°μˆ λ²„μ „μ‚¬μš© 이유
Web FrameworkFastAPIlatest비동기 처리, μžλ™ Swagger λ¬Έμ„œ, νƒ€μž… 기반 μœ νš¨μ„± 검사
LLM OrchestrationLangChainlatestLLM 체인 ꡬ성, ν”„λ‘¬ν”„νŠΈ 관리, 콜백 처리
Agent WorkflowLangGraphlatestμƒνƒœ 기반 μ›Œν¬ν”Œλ‘œμš°, λ…Έλ“œ κ°„ 쑰건 λΆ„κΈ° 처리
LLM MonitoringLangSmithlatestμ—μ΄μ „νŠΈ μ‹€ν–‰ 좔적 및 디버깅 (선택적 μ‚¬μš©)
Vector DBChromaDBlatest둜컬 벑터 μ €μž₯μ†Œ, μ‹œλ§¨ν‹± 검색, 별도 μ„œλ²„ λΆˆν•„μš”
LLMOpenAI GPT-4olatestκ³ μ„±λŠ₯ μΆ”λ‘ , μ΄ˆλ“± λˆˆλ†’μ΄ 맞좀 μ„€λͺ…, ν•œκ΅­μ–΄ 우수
TTSOpenAI TTS (nova)latestμžμ—°μŠ€λŸ¬μš΄ ν•œκ΅­μ–΄ μŒμ„± ν•©μ„±
Embeddingtext-embedding-3-smalllatestRAG 벑터 생성, λΉ„μš© 효율적
DatabaseSQLite3.x별도 DB μ„œλ²„ λΆˆν•„μš”, 둜컬 κ°œλ°œμ— 적합
인증JWT (python-jose)latestStateless 인증, μ„Έμ…˜ μ„œλ²„ λΆˆν•„μš”
λΉ„λ°€λ²ˆν˜Έ λ³΄μ•ˆbcrypt (passlib)latest단방ν–₯ ν•΄μ‹œ, μ†”νŠΈ(salt) μžλ™ 처리
FrontendVanilla HTML/JS-ν”„λ ˆμž„μ›Œν¬ 의쑴 없이 λΉ λ₯Έ ν”„λ‘œν† νƒ€μ΄ν•‘
RuntimePython3.10LangChain μƒνƒœκ³„ ν˜Έν™˜μ„±

πŸ”„ 데이터 νŒŒμ΄ν”„λΌμΈ (RAG ꡬ좕 4단계)

원본 ZIP (JSON νŒŒμΌλ“€)
         β”‚
         β–Ό
[1단계] collect_data_tutor.py
  - ZIP λ‚΄λΆ€ JSON 순회 β†’ OCR ν…μŠ€νŠΈ μΆ”μΆœ
  - 문제(question) : μ •λ‹΅(answer) 1:1 λ§€μΉ­
  - 좜λ ₯: 초기 톡합 CSV (풀이및정닡 컬럼)
         β”‚
         β–Ό
[2단계] csv_refiner.py
  - OpenAI둜 데이터 μ •μ œ
  - '풀이및정닡' β†’ 'μ •λ‹΅' + 'μΉœμ ˆν•œ 풀이' 컬럼 뢄리
  - μ΄ˆλ“±ν•™μƒ λˆˆλ†’μ΄ μ–Έμ–΄λ‘œ λ³€ν™˜
  - 좜λ ₯: μ΅œμ’… ν•™μŠ΅μš© CSV (math_tutor_dataset.csv)
         β”‚
         β–Ό
[3단계] rag_helper.py
  - μž„λ² λ”© λͺ¨λΈ μ„€μ • (text-embedding-3-small)
  - ChromaDB μ—°κ²° 및 배치(Batch) μ €μž₯ 도ꡬ μ •μ˜
  - RAG 검색 ν•¨μˆ˜ μ •μ˜
         β”‚
         β–Ό
[4단계] build_vector_db.py  ← μ‹€ν–‰ μ§„μž…μ 
  - python build_vector_db.py λͺ…λ ΉμœΌλ‘œ μ‹€ν–‰
  - CSV 읽기 β†’ rag_helper 호좜 β†’ ChromaDB 벑터 μ €μž₯
  - 좜λ ₯: database/vector_store/ (ChromaDB 인덱슀)
         β”‚
         β–Ό
ChromaDB 벑터 DB μ™„μ„±
(AI μžμœ ν•™μŠ΅ μ±„νŒ…μ—μ„œ RAG 검색에 μ‚¬μš©)

πŸ“ ν”„λ‘œμ νŠΈ ꡬ쑰

AI_Math_Tutor_4team/
β”‚
β”œβ”€β”€ server.py                     # FastAPI μ•± μ§„μž…μ , λ―Έλ“€μ›¨μ–΄Β·λΌμš°ν„° 등둝
β”œβ”€β”€ requirements.txt              # Python νŒ¨ν‚€μ§€ μ˜μ‘΄μ„± λͺ©λ‘
β”œβ”€β”€ .env                          # ν™˜κ²½λ³€μˆ˜ (API ν‚€, JWT μ‹œν¬λ¦Ώ λ“±)
β”‚
β”œβ”€β”€ app/                          # λ°±μ—”λ“œ μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μ½”μ–΄
β”‚   β”œβ”€β”€ routers/
β”‚   β”‚   β”œβ”€β”€ auth.py               # λ‘œκ·ΈμΈΒ·νšŒμ›κ°€μž…Β·JWT λ°œκΈ‰ API (/auth/*)
β”‚   β”‚   └── tutor.py              # AI νŠœν„° κΈ°λŠ₯ 전체 API (/api/*)
β”‚   β”œβ”€β”€ services/
β”‚   β”‚   └── tutor_service.py      # λΉ„μ¦ˆλ‹ˆμŠ€ 둜직 (LLM 호좜 쑰율)
β”‚   β”œβ”€β”€ tutor/
β”‚   β”‚   └── integration.py        # LangChain 체인 μ •μ˜, TTS 캐싱
β”‚   └── utils/
β”‚       └── db_manager.py         # SQLite CRUD, bcrypt λΉ„λ°€λ²ˆν˜Έ 관리
β”‚
β”œβ”€β”€ frontend/                     # ν”„λ‘ νŠΈμ—”λ“œ 정적 파일
β”‚   β”œβ”€β”€ login.html                # λ‘œκ·ΈμΈΒ·νšŒμ›κ°€μž… ν™”λ©΄
β”‚   β”œβ”€β”€ app.html                  # 메인 μ•± ν™”λ©΄ (둜그인 ν›„)
β”‚   β”œβ”€β”€ js/
β”‚   β”‚   β”œβ”€β”€ app.js                # 곡톡 JS (인증, API fetch μœ ν‹Έ)
β”‚   β”‚   β”œβ”€β”€ section1.js           # 였늘의 ν•™μŠ΅ ν™”λ©΄ (ν•™μŠ΅ 흐름 UI)
β”‚   β”‚   β”œβ”€β”€ section2.js           # AI μžμœ ν•™μŠ΅ μ±„νŒ…
β”‚   β”‚   β”œβ”€β”€ section3.js           # μ‹œν—˜ ν™”λ©΄ + μ‹œν—˜ κ²°κ³Ό λͺ¨λ‹¬ UI
β”‚   β”‚   β”œβ”€β”€ section4.js           # 성적 둜그 λŒ€μ‹œλ³΄λ“œ (κ·Έλž˜ν”„ + μ‹œν—˜ 기둝 UI)
β”‚   β”‚   └── section5.js           # 토큰 μ‚¬μš© 둜그
β”‚   β”œβ”€β”€ css/                      # μŠ€νƒ€μΌμ‹œνŠΈ
β”‚   └── assets/                   # μ΄λ―Έμ§€Β·μ•„μ΄μ½˜ λ“± λ―Έλ””μ–΄ 파일
β”‚
β”œβ”€β”€ RAG_sys/                      # RAG 데이터 νŒŒμ΄ν”„λΌμΈ
β”‚   β”œβ”€β”€ collect_data_tutor.py     # [1단계] 원본 데이터 μˆ˜μ§‘Β·λ³‘ν•©
β”‚   β”œβ”€β”€ csv_refiner.py            # [2단계] AI 기반 데이터 μ •μ œ
β”‚   β”œβ”€β”€ rag_helper.py             # [3단계] ChromaDB μ €μž₯ λͺ¨λ“ˆ μ •μ˜
β”‚   └── build_vector_db.py        # [4단계] 벑터 DB ꡬ좕 μ‹€ν–‰ 슀크립트
β”‚
β”œβ”€β”€ data/
β”‚   └── processed/
β”‚       β”œβ”€β”€ math_dataset.csv        # ZIP λ‚΄λΆ€ JSON 순회 OCR ν…μŠ€νŠΈ μΆ”μΆœ
β”‚       └── math_tutor_dataset.csv  # μ •μ œλœ μ΅œμ’… μˆ˜ν•™ 문제 데이터셋
β”‚
└── database/
    β”œβ”€β”€ user_db.sqlite              # SQLite DB (μ‚¬μš©μžΒ·ν•™μŠ΅Β·μ‹œν—˜Β·μ±„νŒ…Β·ν† ν°)
    └── vector_store/
        └── chroma.sqlite3          # ChromaDB 벑터 인덱슀

πŸ”Œ μ£Όμš” API μ—”λ“œν¬μΈνŠΈ

인증 (Authentication)

MethodPathμ„€λͺ…인증 ν•„μš”
POST/auth/login둜그인 β†’ JWT 토큰 λ°œκΈ‰βŒ
POST/auth/registerνšŒμ›κ°€μž…βŒ
GET/auth/meν˜„μž¬ 둜그인 μ‚¬μš©μž 정보 μ‘°νšŒβœ…
POST/auth/logoutλ‘œκ·Έμ•„μ›ƒ (ν΄λΌμ΄μ–ΈνŠΈ 토큰 μ‚­μ œ μ•ˆλ‚΄)βœ…

였늘의 ν•™μŠ΅

MethodPathμ„€λͺ…LLM μ‚¬μš©
GET/api/units단원 λͺ©λ‘ 쑰회 (CSVμ—μ„œ μΆ”μΆœ)❌
GET/api/problem?unit=...단원별 λ¬΄μž‘μœ„ 문제 1개 쑰회❌
POST/api/explainAI κ°œλ… μ„€λͺ… μƒμ„±βœ…
POST/api/reexplainAI 보좩(재) μ„€λͺ… μƒμ„±βœ…
POST/api/explain/evaluate학생 이해도 평가 (PASS/FAIL)βœ…
POST/api/askν•™μŠ΅ 쀑 Q&A μ§ˆλ¬Έβœ…
POST/api/evaluate학생 λ‹΅λ³€ μ±„μ βœ…
POST/api/historyν•™μŠ΅ 기둝 μ €μž₯❌
GET/api/historyν•™μŠ΅ 기둝·정닡λ₯  쑰회❌
GET/api/history/incorrectμ˜€λ‹΅ 문제 λͺ©λ‘ 쑰회❌

AI μžμœ ν•™μŠ΅ μ±„νŒ…

MethodPathμ„€λͺ…LLM μ‚¬μš©
POST/api/free/chatRAG + LLM 자유 ν•™μŠ΅ μ±„νŒ…βœ… (μ΅œλŒ€ 2회)
GET/api/free/historyμ±„νŒ… 기둝 쑰회 (졜근 50건)❌

단원 μ‹œν—˜

MethodPathμ„€λͺ…LLM μ‚¬μš©
POST/api/exam/generate단원별 μ‹œν—˜ 문제 10개 좜제❌
POST/api/exam/submitμ‹œν—˜ 일괄 채점 (병렬 처리)βœ… (Γ—λ¬Έμ œ 수)
POST/api/exam/save-resultμ‹œν—˜ κ²°κ³Ό μ €μž₯❌
GET/api/exam/resultsμ‹œν—˜ 이λ ₯ 쑰회❌

기타

MethodPathμ„€λͺ…LLM μ‚¬μš©
POST/api/ttsν…μŠ€νŠΈ β†’ μŒμ„± λ³€ν™˜ (MD5 캐싱)βœ… (TTS)
GET/api/token/logs토큰 μ‚¬μš©λŸ‰ 톡계 쑰회❌
GET/healthμ„œλ²„ μƒνƒœ 확인 (ν—¬μŠ€μ²΄ν¬)❌
λͺ¨λ“  /api/* μ—”λ“œν¬μΈνŠΈλŠ” Authorization: Bearer <JWT> 헀더 ν•„μš” Swagger λ¬Έμ„œ: http://localhost:8000/docs

πŸš€ μ‹€ν–‰ 방법

1. μ €μž₯μ†Œ 클둠

bash
git clone https://github.com/ilangs/AI_Math_Tutor_4team

2. κ°€μƒν™˜κ²½ 생성 및 ν™œμ„±ν™”

bash
# κ°€μƒν™˜κ²½ 생성
py -3.10 -m venv .venv

# Windows
.venv\Scripts\activate

# macOS / Linux
source .venv/bin/activate

3. νŒ¨ν‚€μ§€ μ„€μΉ˜

bash
pip install -r requirements.txt

4. ν™˜κ²½λ³€μˆ˜ μ„€μ •

ν”„λ‘œμ νŠΈ λ£¨νŠΈμ— .env νŒŒμΌμ„ μƒμ„±ν•˜κ³  μ•„λž˜ 값을 μ±„μ›Œμ£Όμ„Έμš”. (μ•„λž˜ [ν™˜κ²½λ³€μˆ˜ μ„€μ •] μ„Ήμ…˜ μ°Έκ³ )

5. μ„œλ²„ μ‹€ν–‰

bash
uvicorn server:app --reload --port 8000

6. λΈŒλΌμš°μ € 접속

http://127.0.0.1:8000/

βš™οΈ ν™˜κ²½λ³€μˆ˜ μ„€μ •

ν”„λ‘œμ νŠΈ λ£¨νŠΈμ— .env νŒŒμΌμ„ μƒμ„±ν•©λ‹ˆλ‹€:

bash
# ── OpenAI API ───────────────────────────────────────────
OPENAI_API_KEY="sk-..."           # OpenAI API ν‚€ (ν•„μˆ˜)

# ── JWT 인증 ─────────────────────────────────────────────
# μ•„λž˜ λͺ…λ ΉμœΌλ‘œ 생성:
#   python -c "import secrets; print(secrets.token_hex(32))"
JWT_SECRET_KEY="여기에_λ°œκΈ‰λœ_μ‹œν¬λ¦Ώ_ν‚€_μž…λ ₯"
주의: .env νŒŒμΌμ€ μ ˆλŒ€ git에 μ»€λ°‹ν•˜μ§€ λ§ˆμ„Έμš”. .gitignore에 μΆ”κ°€ν•˜μ—¬ κ΄€λ¦¬ν•©λ‹ˆλ‹€.

πŸ“Š 토큰 μ‚¬μš©λŸ‰ 좔적 방식

LangSmith 없이도 LLM API λΉ„μš©μ„ μ •ν™•ν•˜κ²Œ μΆ”μ ν•˜λŠ” 둜컬 기반 방식을 μ±„νƒν–ˆμŠ΅λ‹ˆλ‹€.

μž‘λ™ 원리

python
# routers/tutor.py μ—μ„œ LLM ν˜ΈμΆœλ§ˆλ‹€ 적용
from langchain_community.callbacks import get_openai_callback

with get_openai_callback() as cb:
    result = await some_llm_function(...)   # LLM 호좜

# with 블둝 μ’…λ£Œ ν›„ cb에 토큰 정보가 μžλ™ 집계됨
save_token_usage(
    username=current_user["username"],
    action="κ°œλ…μ„€λͺ…",                       # κΈ°λŠ₯λͺ… λΆ„λ₯˜
    prompt=cb.prompt_tokens,               # μž…λ ₯ 토큰 수
    completion=cb.completion_tokens,       # 좜λ ₯ 토큰 수
    total=cb.total_tokens,                 # 합계 토큰 수
    cost=cb.total_cost,                    # λ‹¬λŸ¬ λΉ„μš©
)

DB ν…Œμ΄λΈ” ꡬ쑰 (token_logs)

μ»¬λŸΌνƒ€μž…μ„€λͺ…
idINTEGERPK (μžλ™ 증가)
usernameTEXTμ‚¬μš©μž 아이디
actionTEXTκΈ°λŠ₯ λΆ„λ₯˜ (κ°œλ…μ„€λͺ…/채점/Q&A λ“±)
prompt_tokensINTEGERμž…λ ₯(ν”„λ‘¬ν”„νŠΈ) 토큰 수
completion_tokensINTEGER좜λ ₯(μ»΄ν”Œλ¦¬μ…˜) 토큰 수
total_tokensINTEGER합계 토큰 수
cost_usdREALλ‹¬λŸ¬ ν™˜μ‚° λΉ„μš©
created_atTIMESTAMP호좜 μ‹œκ°

λΉ„μš© ν™˜μ‚° κΈ°μ€€ (OpenAI)

ꡬ뢄단가
μž…λ ₯ 토큰$0.000005 / token
좜λ ₯ 토큰$0.000015 / token
λ‹¬λŸ¬β†’μ› ν™˜μœ¨1,350원/$ (κ³ μ •κ°’)
κΈ°μ‘΄ 방식 λŒ€λΉ„ κ°œμ„ : LangSmith API ν• λ‹ΉλŸ‰ 초과 μ‹œ 항상 0이 λ°˜ν™˜λ˜λ˜ 문제λ₯Ό 둜컬 SQLite 직접 μ €μž₯ λ°©μ‹μœΌλ‘œ μ „ν™˜ν•˜μ—¬ 항상 μ •ν™•ν•œ 토큰 데이터λ₯Ό 보μž₯ν•©λ‹ˆλ‹€.

πŸ‘₯ νŒ€ ꡬ성

이름역할담당 μ˜μ—­
민덕기Project Leaderν”„λ‘œμ νŠΈ 총괄, λ°œν‘œ 및 LangChain μ›Œν¬ν”Œλ‘œμš°(Chain) 섀계
이은미Data Engineer데이터 νŒŒμ΄ν”„λΌμΈ(μˆ˜μ§‘Β·μ •μ œ) ꡬ좕, RAG μ΅œμ ν™” 및 Vector DB
μœ μ£Όμ„Backend DeveloperFastAPI 기반 API μ„œλ²„ 섀계, JWT λ³΄μ•ˆ 인증, DB 섀계
μ˜€μ§€μˆ˜Frontend DeveloperUI/UX κ΅¬ν˜„(HTML/JS), ν”„λ‘ νŠΈ-λ°±μ—”λ“œ κΈ°λŠ₯ 연동
이미지QA & DevRelμ‹œμŠ€ν…œ 톡합 ν…ŒμŠ€νŠΈ, μ‚¬μš©μž ν”Όλ“œλ°± 뢄석, ν”„λ‘œμ νŠΈ μ‹œμ—° 자료 μ œμž‘
κ°•μŠΉν˜ΈProduct Plannerν”„λ‘œμ νŠΈ μ•„μ΄λ°μ΄μ…˜(Ideation), 컨셉 및 λΉ„μ¦ˆλ‹ˆμŠ€ 둜직 기획

πŸ“‹ 개발 ν™˜κ²½

  • β€”Python 3.10
  • β€”OS Windows 11
  • β€”IDE VS Code
  • β€”API λ¬Έμ„œ http://localhost:8000/docs (Swagger UI μžλ™ 생성)

πŸ“„ λΌμ΄μ„ μŠ€

λ³Έ ν”„λ‘œμ νŠΈλŠ” ꡐ윑 λͺ©μ μœΌλ‘œ μ œμž‘λ˜μ—ˆμŠ΅λ‹ˆλ‹€. 3μ£Ό AI Agent κ³Όμ • 쀑간 ν”„λ‘œμ νŠΈ κ²°κ³Όλ¬Όμž…λ‹ˆλ‹€.

Hugging Face 배포

https://huggingface.co/spaces/ilangs/AIMathTutor_HF