Mini RAG Projectλ RAG(Retrieval-Augmented Generation) μμ€ν μ κ°μνλ ꡬν체μ λλ€. NestJSμ Pythonμ νμ©νμ¬ κΈ°λ³Έμ μΈ RAG κΈ°λ₯μ ꡬννμ΅λλ€.
μ΄ νλ‘μ νΈλ λ€μκ³Ό κ°μ κΈ°λ₯μ μ 곡ν©λλ€:
- ν μ€νΈ νμΌ μ λ‘λ λ° μ²λ¦¬
- λ¬Έλ¨ λ¨μ ν μ€νΈ λΆν
- Sentence Transformersλ₯Ό νμ©ν μλ² λ© μμ±
- ChromaDBλ₯Ό ν΅ν λ²‘ν° μ μ₯ λ° κ²μ
- OpenAI GPTλ₯Ό νμ©ν μ§μμλ΅
βββββββββββββββ HTTP Request βββββββββββββββ HTTP Request βββββββββββββββ
β Client β βββββββββββββββββββΊ β NestJS API β βββββββββββββββββββΊ β Python AI β
β (Postman) β β Gateway β β Service β
βββββββββββββββ βββββββββββββββ βββββββββββββββ
β β
βΌ βΌ
File Upload Text Processing
Validation (Chunking, Embedding)
β
βΌ
βββββββββββββββ
β ChromaDB β
β (Vector DB) β
βββββββββββββββ
mini-rag-project/
βββ README.md # μ΄ νμΌ
βββ .gitignore # ν΅ν©λ Git 무μ νμΌ
βββ mini-rag/ # NestJS API Gateway
β βββ src/
β β βββ ingest/
β β β βββ ingest.controller.ts # νμΌ μ
λ‘λ API
β β β βββ ingest.service.ts # Python μλ² ν΅μ
β β β βββ ingest.module.ts # λͺ¨λ μ€μ
β β βββ app.module.ts # λ£¨νΈ λͺ¨λ
β βββ package.json
β βββ .env (νμμ μμ±)
βββ mini-rag-ai-service/ # Python AI Service
βββ main.py # FastAPI μ ν리μΌμ΄μ
βββ requirements.txt # Python μμ‘΄μ±
βββ .env # OpenAI API ν€
βββ venv/ # Python κ°μνκ²½
βββ chroma_db/ # ChromaDB λ°μ΄ν° μ μ₯μ
- Node.js (v18+)
- Python (3.9+)
- OpenAI API Key
git clone <repository-url>
cd mini-rag-project# Python AI Service λλ ν λ¦¬λ‘ μ΄λ
cd mini-rag-ai-service
# κ°μνκ²½ μμ± λ° νμ±ν
python3 -m venv venv
source venv/bin/activate # Mac/Linux
# venv\Scripts\activate # Windows
# μμ‘΄μ± μ€μΉ
pip install -r requirements.txt
# νκ²½ λ³μ μ€μ
echo 'OPENAI_API_KEY="your-openai-api-key-here"' > .env
# AI μλΉμ€ μ€ν
uvicorn main:app --reloadAI μλΉμ€λ http://localhost:8000μμ μ€νλ©λλ€.
# μ ν°λ―Έλμμ NestJS μλΉμ€ λλ ν λ¦¬λ‘ μ΄λ
cd mini-rag
# μμ‘΄μ± μ€μΉ
npm install
# νκ²½ λ³μ μ€μ (μ νμ¬ν)
echo 'PYTHON_SERVICE_URL=http://localhost:8000' > .env
# API Gateway μ€ν
npm run start:devAPI Gatewayλ http://localhost:3000μμ μ€νλ©λλ€.
νμΌμ μ λ‘λνμ¬ AI μλΉμ€λ‘ μ μ‘ν©λλ€.
Request:
- Content-Type:
multipart/form-data - Body:
file(ν μ€νΈ νμΌ)
Response:
{
"message": "Successfully processed and stored 3 chunks from sample.txt.",
"chunkCount": 3
}ν μ€νΈλ₯Ό λ°μμ μ²νΉ, μλ² λ©, λ²‘ν° DB μ μ₯μ μνν©λλ€.
Request:
{
"text": "μ
λ‘λλ ν
μ€νΈ λ΄μ©...",
"filename": "sample.txt"
}μ¬μ©μ μ§λ¬Έμ λ°μμ κ΄λ ¨ λ¬Έμλ₯Ό κ²μνκ³ λ΅λ³μ μμ±ν©λλ€.
Request:
{
"query": "RAG μμ€ν
μ΄ λ¬΄μμΈκ°μ?"
}Response:
{
"answer": "RAG μμ€ν
μ λν λ΅λ³...",
"retrieved_documents": [
"κ΄λ ¨ λ¬Έμ μ‘°κ° 1",
"κ΄λ ¨ λ¬Έμ μ‘°κ° 2",
"κ΄λ ¨ λ¬Έμ μ‘°κ° 3"
]
}OPENAI_API_KEY=sk-your-openai-api-key-herePYTHON_SERVICE_URL=http://localhost:8000- Framework: NestJS 10.0+
- HTTP Client: Axios
- File Upload: Multer
- Port: 3000
- Framework: FastAPI 0.100+
- Vector DB: ChromaDB
- Embedding Model: all-MiniLM-L6-v2 (384μ°¨μ)
- LLM: OpenAI GPT-3.5-turbo
- Port: 8000
Postmanμ΄λ curlμ μ¬μ©νμ¬ νμΌ μ λ‘λλ₯Ό ν μ€νΈν μ μμ΅λλ€:
curl -X POST http://localhost:3000/ingest/upload \
-F "file=@sample.txt"curl -X POST http://localhost:8000/chat \
-H "Content-Type: application/json" \
-d '{"query": "μ
λ‘λλ λ¬Έμμ λν΄ μ§λ¬ΈνκΈ°"}'- NestJS API:
http://localhost:3000(κΈ°λ³Έ NestJS λ¬Έμ) - Python AI Service:
http://localhost:8000/docs(Swagger UI)
- νμΌ μ λ‘λ: ν΄λΌμ΄μΈνΈκ° NestJS API Gatewayλ‘ ν μ€νΈ νμΌ μ λ‘λ
- ν μ€νΈ μ μ‘: NestJSκ° νμΌ λ΄μ©μ Python AI Serviceλ‘ μ μ‘
- ν μ€νΈ λΆν : Python μλΉμ€κ° λ¬Έλ¨ λ¨μλ‘ ν μ€νΈ λΆν
- μλ² λ© μμ±: κ° μ²ν¬λ₯Ό 384μ°¨μ 벑ν°λ‘ λ³ν
- λ²‘ν° μ μ₯: ChromaDBμ 벑ν°μ μλ³Έ ν μ€νΈ μ μ₯
- μ§μ μ²λ¦¬: μ¬μ©μ μ§λ¬Έμ λν΄ κ΄λ ¨ λ¬Έμ κ²μ λ° λ΅λ³ μμ±
# Python AI Service κ°λ° λͺ¨λ
cd mini-rag-ai-service
source venv/bin/activate
uvicorn main:app --reload
# NestJS API Gateway κ°λ° λͺ¨λ (μ ν°λ―Έλ)
cd mini-rag
npm run start:dev- Python μλΉμ€: FastAPIμ μλ λ¬Έμν κΈ°λ₯ νμ© (
/docs) - NestJS μλΉμ€: NestJS λ‘κΉ λ° κ°λ° λͺ¨λ νμ©
- μ΄ νλ‘μ νΈλ νμ΅ λͺ©μ μΌλ‘ μ μλμμΌλ©°, μ€μ νλ‘λμ νκ²½μμλ μΆκ°μ μΈ λ³΄μ λ° μ±λ₯ μ΅μ νκ° νμν©λλ€.
- νμ¬ κ΅¬νμ λ¨μν λ¬Έλ¨ λ¨μ λΆν μ μ¬μ©ν©λλ€.