νλ‘μ νΈ κΈ°κ°: 2μ£Ό (10 working days) ν ꡬμ±: 4λͺ (ν1: QA μμ€ν 2λͺ , ν2: λ¬Έμ μμ± 2λͺ ) λͺ©ν: νμ΅μλ£(PDF/PPT) κΈ°λ° 1-2μ΄ μλ΅ QA + λμ΄λλ³ μ€μ΅ λ¬Έμ μλ μμ±
- νμ΅μλ£ μ λ‘λ λ° νμ± (Upstage Document Parse)
- μ¦κ° μλ΅ QA μμ€ν (1-2μ΄ μλ΅, LangChain RAG)
- λμ΄λλ³ μ€μ΅ λ¬Έμ μμ± (μ΄κΈ/μ€κΈ/κ³ κΈ, LangGraph Agent)
- νμ΅ κ΄λ¦¬ λ° μΆμ (Spring Boot Backend)
| μꡬμ¬ν | ꡬν λ°©λ² |
|---|---|
| β LangChain Framework | RAG νμ΄νλΌμΈ κ΅¬μΆ |
| β Upstage API | Parse, Embeddings, Chat |
| β ChromaDB | Vector Database |
| β 1-2μ΄ μλ΅ | μ΅μ νλ Retrieve + Generate |
| β LangGraph | Agent Workflow κ΅¬μΆ |
| β RAG μν€ν μ² | λ€μ΄μ΄κ·Έλ¨ μμ± |
- λ΄λΉ: κ°λ°μ A, B (2λͺ )
- λ΄μ©: μλ£ μ λ‘λ, Upstage Parse, μλ² λ©, ChromaDB μ μ₯, QA RAG νμ΄νλΌμΈ
- λͺ©ν: Retrieve ν¬ν¨ 1-2μ΄ μλ΅
μ£Όμ ꡬν λ΄μ©:
- Upstage Document Parseλ‘ PDF/PPT νμ±
- Upstage Embeddingsλ‘ λ²‘ν°ν
- ChromaDB μ μ₯ λ° κ²μ
- LangGraph QA Agent (Retrieve β Generate)
- μλ΅ μλ μ΅μ ν (μΊμ±, λ©ν° 쿼리)
- λ΄λΉ: κ°λ°μ C, D (2λͺ )
- λ΄μ©: νμ΅ λ΄μ© λΆμ, λμ΄λλ³ λ¬Έμ μμ±, κ²μ¦
- λͺ©ν: λμ΄λλ³(μ΄κΈ/μ€κΈ/κ³ κΈ) μ€μ΅ λ¬Έμ μλ μμ±
μ£Όμ ꡬν λ΄μ©:
- νμ΅ λ΄μ© λΆμ (ChromaDB κ²μ)
- λμ΄λλ³ Generator (Beginner/Intermediate/Advanced)
- λ¬Έμ κ²μ¦ μμ€ν (μ΅μ κΈΈμ΄, λμ΄λ μ μ, ν μ€νΈ μΌμ΄μ€)
- LangGraph Problem Agent (Analyze β Generate β Validate)
- μ¬μμ± λ‘μ§
- λ΄λΉ: κ³΅ν΅ (ν΅ν© λ¨κ³)
- λ΄μ©: Python AI Engine β Spring Boot Backend μ°λ
- κΈ°μ : Java 21, Spring Boot 3.2.0, WebClient
μ£Όμ ꡬν λ΄μ©:
- WebClient μ€μ (Python μλ² ν΅μ )
- λλ©μΈ μν°ν° (User, Material, QASession, Problem)
- PythonClient ꡬν
- REST API Controller
- PostgreSQL μ°λ
- λ΄μ©: μ 체 μμ€ν κ°μ, λ°μ΄ν° νλ¦, API λͺ μΈ
- λ€μ΄μ΄κ·Έλ¨: Mermaid κΈ°λ° μν€ν μ² λ€μ΄μ΄κ·Έλ¨
μ£Όμ λ΄μ©:
- μμ€ν ꡬ쑰λ
- λ°μ΄ν° νλ¦λ (μ λ‘λ, QA, λ¬Έμ μμ±)
- λ°μ΄ν°λ² μ΄μ€ μ€ν€λ§
- API λͺ μΈμ
- Docker Compose μ€μ
- λ΄λΉ: κ³΅ν΅ (μΈνλΌ)
- λ΄μ©: Dockerλ₯Ό νμ©ν λ°μ΄ν°λ² μ΄μ€ λ° μμ€ν κ΄λ¦¬
- κΈ°μ : Docker, Docker Compose, PostgreSQL, ChromaDB
μ£Όμ ꡬν λ΄μ©:
- PostgreSQL Docker μ€μ λ° μ΄κΈ°ν
- ChromaDB Docker μ€μ
- λ°μ΄ν° μμμ± κ΄λ¦¬ (Volumes)
- λ°±μ λ° λ³΅μ μ λ΅
- νΈλ¬λΈμν κ°μ΄λ
- λ΄λΉ: κ³΅ν΅ (μν€ν μ²)
- λ΄μ©: νλ³ RAG νμ΄νλΌμΈ μμΈ κ΅¬μ‘° λ° λ°μ΄ν° νλ¦
- λ€μ΄μ΄κ·Έλ¨: Mermaid κΈ°λ° νμ΄νλΌμΈ μκ°ν
μ£Όμ λ΄μ©:
- μ 체 μμ€ν RAG μν€ν μ²
- ν1 QA RAG νμ΄νλΌμΈ (μλ£ νμ± β μλ² λ© β κ²μ β μμ±)
- ν2 λ¬Έμ μμ± RAG νμ΄νλΌμΈ (λ΄μ© λΆμ β μμ± β κ²μ¦)
- λμ΄λλ³ Generator μμΈ νλ¦
- μ±λ₯ μ΅μ ν μ λ΅
- Spring Boot: 3.2.0 (Java 21)
- Database: PostgreSQL 15
- Security: Spring Security + JWT
- HTTP Client: WebClient (WebFlux)
- Framework: FastAPI
- LLM: Upstage Solar API
- Orchestration: LangChain + LangGraph
- Vector DB: ChromaDB
- PDF/PPT Parsing: PyMuPDF, python-pptx
- Container: Docker + Docker Compose
- Version Control: Git
| λ μ§ | ν1 (QA) | ν2 (λ¬Έμ μμ±) | κ³΅ν΅ |
|---|---|---|---|
| Day 1 | νκ²½ μ€μ , ChromaDB μ°λ | νκ²½ μ€μ , Upstage API ν μ€νΈ | DB μ€κ³, Spring Boot νλ‘μ νΈ |
| Day 2 | μλ£ μ λ‘λ + Upstage Parse | λμ΄λ λΆλ₯ λ‘μ§ μ€κ³ | Python FastAPI μλ² κ΅¬μΆ |
| Day 3 | μλ² λ© + ChromaDB μ μ₯ | λ¬Έμ μμ± Agent ꡬ쑰 μ€κ³ | Spring β Python μ°λ |
| Day 4 | QA RAG νμ΄νλΌμΈ ꡬν | μ΄κΈ λ¬Έμ μμ± κ΅¬ν | - |
| Day 5 | μλ΅ μλ μ΅μ ν (1-2μ΄) | μ€κΈ/κ³ κΈ λ¬Έμ μμ± κ΅¬ν | ν΅ν© ν μ€νΈ |
| λ μ§ | ν1 (QA) | ν2 (λ¬Έμ μμ±) | κ³΅ν΅ |
|---|---|---|---|
| Day 6 | LangGraph Agent μν¬νλ‘μ° | LangGraph Agent μν¬νλ‘μ° | - |
| Day 7 | μΆμ² νμ κΈ°λ₯ | λ¬Έμ κ²μ¦ λ‘μ§ | - |
| Day 8 | μΊμ± λ° μ±λ₯ κ°μ | λμ΄λ μλ μ‘°μ | ν΅ν© ν μ€νΈ |
| Day 9 | μ 체 QA ν μ€νΈ | μ 체 λ¬Έμ μμ± ν μ€νΈ | UI μ°λ |
| Day 10 | λ²κ·Έ μμ , λ¬Έμν | λ²κ·Έ μμ , λ¬Έμν | RAG μν€ν μ² λ€μ΄μ΄κ·Έλ¨ |
git clone https://github.com/your-team/edumentor.git
cd edumentor# Python μλ² λλ ν λ¦¬λ‘ μ΄λ
cd python-server
# .env νμΌ μμ±
cp .env.example .env
# νμ νκ²½ λ³μ μ
λ ₯
vim .env # λλ μ νΈνλ μλν° μ¬μ©νμ μ€μ :
UPSTAGE_API_KEY=your_upstage_api_key # Upstage API ν€
POSTGRES_PASSWORD=your_password # PostgreSQL λΉλ°λ²νΈ (μ΄μ νκ²½μμλ κ°λ ₯ν λΉλ°λ²νΈ μ¬μ©)
JWT_SECRET=your_jwt_secret # JWT μλͺ
ν€μ€μ: PostgreSQLκ³Ό ChromaDBλ Dockerλ‘ κ΄λ¦¬λ©λλ€.
# PostgreSQL + ChromaDB μμ
docker-compose up -d postgres chromadb
# λ°μ΄ν°λ² μ΄μ€ μ΄κΈ°ν νμΈ (μ΅μ΄ μ€ν μ μλ μ΄κΈ°ν)
docker-compose logs postgres | grep "database system is ready"
# μν λ°μ΄ν° νμΈ
docker exec -it edumentor-postgres psql -U admin -d edumentor -c "SELECT * FROM users;"μλ μ΄κΈ°ν λ΄μ©:
- ν μ΄λΈ μμ± (users, learning_materials, qa_sessions, practice_problems)
- μΈλ±μ€ μμ± (μ±λ₯ μ΅μ ν)
- μν μ¬μ©μ μμ± (instructor1, student1 / password: password123)
# μ 체 μμ€ν
λΉλ λ° μ€ν
docker-compose up --build
# λ°±κ·ΈλΌμ΄λ μ€ν
docker-compose up -d
# μν νμΈ
docker-compose ps# PostgreSQL & ChromaDB
docker-compose up -d postgres chromadb
# Python ν΅ν© μλ² (Port 8000)
cd python-server
pip install -r requirements.txt
python main.py
# Spring Boot (Port 8080)
cd spring-backend
./gradlew bootRun- Spring Boot API: http://localhost:8080
- Python AI API: http://localhost:8000/docs
curl -X POST http://localhost:8080/api/materials/upload \
-H "Authorization: Bearer {token}" \
-F "file=@spring_guide.pdf" \
-F "title=Spring Boot μ
λ¬Έ"curl -X POST http://localhost:8080/api/qa/ask \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"materialId": 1,
"question": "JPA Entityλ 무μμΈκ°μ?"
}'μλ΅ μμ:
{
"answer": "JPA Entityλ λ°μ΄ν°λ² μ΄μ€ ν
μ΄λΈκ³Ό λ§€νλλ Java ν΄λμ€μ
λλ€. @Entity μ΄λ
Έν
μ΄μ
μ μ¬μ©νμ¬ μ μνλ©°...",
"sources": [
{
"page": 23,
"excerpt": "JPA Entityλ λ°μ΄ν°λ² μ΄μ€..."
}
],
"responseTimeMs": 1230
}curl -X POST http://localhost:8080/api/problems/generate \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"materialId": 1,
"difficulty": "BEGINNER",
"problemCount": 3
}'μλ΅ μμ:
{
"problems": [
{
"question": "User μν°ν° ν΄λμ€λ₯Ό μμ±νμΈμ...",
"answer": "@Entity\npublic class User {...}",
"hints": ["@Entity μ΄λ
Έν
μ΄μ
μ¬μ©", "@Idλ‘ κΈ°λ³Έν€ μ§μ "],
"difficultyScore": 2,
"problemType": "CODING",
"testCases": [
{"input": "...", "expected": "..."}
]
}
],
"difficulty": "BEGINNER",
"generatedCount": 3,
"rejectedCount": 0
}# ν1 μ±λ₯ ν
μ€νΈ
cd python-ai/paper_qa
python tests/test_performance.pyκΈ°λ κ²°κ³Ό:
Question: JPA Entityλ 무μμΈκ°μ?
μλ΅ μκ°: 1.234s - β
PASS
Question: @Transactionalμ μΈμ μ¬μ©νλμ?
μλ΅ μκ°: 1.567s - β
PASS
μ΄ ν
μ€νΈ: 3
ν΅κ³Ό: 3/3
νκ· μλ΅ μκ°: 1.401s
# ν2 λ¬Έμ μμ± ν
μ€νΈ
cd python-ai/paper_problem
python tests/test_problem_generation.pyβββββββββββββββ
β Frontend β
β (React/Vue) β
ββββββββ¬βββββββ
β REST API
β
βββββββββββββββ
β Spring Boot β
β (Java 21) β
ββββββββ¬βββββββ
β HTTP Client
β
βββββββββββββββ¬ββββββββββββββ
β Python QA β Python β
β (Port 8000)β Problem β
β β (Port 8001)β
ββββββββ¬βββββββ΄βββββββ¬βββββββ
β β
β β
ββββββββββββ¬ββββββββββββββ
βChromaDB β PostgreSQL β
β(Vector) β (Metadata) β
ββββββββββββ΄ββββββββββββββ
- Upstage API μ°λ (Parse, Embeddings, Chat)
- ChromaDB λ²‘ν° μ μ₯ λ° κ²μ
- LangGraph QA Agent (1-2μ΄ μλ΅)
- LangGraph Problem Agent (λμ΄λλ³ μμ±)
- Spring Boot Backend (Java 21)
- REST API ꡬν
- QA μλ΅ μκ° < 2μ΄
- λ¬Έμ μμ± μκ° < 30μ΄
- νμ± μ±κ³΅λ₯ > 95%
- λ¬Έμ κ²μ¦ ν΅κ³Όμ¨ > 80%
- RAG μν€ν μ² λ€μ΄μ΄κ·Έλ¨
- API λ¬Έμ (Swagger)
- νλ³ κ΅¬ν κ°μ΄λ
- README.md
- λ¨μ ν μ€νΈ
- ν΅ν© ν μ€νΈ
- μ±λ₯ ν μ€νΈ
- E2E ν μ€νΈ
- κ°λ°μ A: μλ£ μ λ‘λ, Upstage Parse, μλ² λ©, ChromaDB μ μ₯
- κ°λ°μ B: QA RAG νμ΄νλΌμΈ, LangGraph Agent, μλ΅ μλ μ΅μ ν
- κ°λ°μ C: λμ΄λ λΆμ, νμ΅ λ΄μ© μΆμΆ, LangGraph Agent ꡬ쑰
- κ°λ°μ D: λ¬Έμ μμ± λ‘μ§, κ²μ¦, λ΅μ μμ±
- Spring Boot ν΅ν© (μ 체)
- ν΅ν© ν μ€νΈ (μ 체)
- λ¬Έμν (μ 체)
- μ΄μ νΈλ컀: GitHub Issues
- μ΄λ©μΌ: team@edumentor.ai
- λ¬Έμ: μ 체_μμ€ν _μν€ν μ².md
MIT License
νλ‘μ νΈ μμ: 2025-10-28 λͺ©ν μλ£: 2025-11-08 (2μ£Ό) ν: 4λͺ (2 + 2)