오늘 만든 모든 조각을 하나의 서비스로
박수현 · (사)한국정보공학기술사회 · 2026
🎯 목표: 개별 구현한 API 를 한 화면에서 동작하는 완결된 서비스로 통합.
4개 화면 동작 → Flask REST(4개 API) → 서비스 계층 → ChromaDB+uploads/
💡 4개 API + 서비스 계층 + 영속 저장 = 지금까지 구현한 구성요소의 총합.
5.file_manager_restapi)는 /files 계열13.document_qa)는 /documents 계열/upload·/documents·/ask 를 기준으로 한다.
최종 문서 QA 챗봇 UI · 좌측 업로드·문서목록(삭제), 우측 질의응답·스트리밍·출처(Source) 표시
🔑 프론트엔드는 JSON 을 수신해 화면에 렌더링하며, 로직은 전부 백엔드에 위치한다.
┌──────────────┬─────────────────┐
│ 📄 문서 │ 💬 문서 QA │
│ ┌──────────┐ │ Q: NVMe 가? │
│ │ 끌어다놓기│ │ A: NVMe 는 … │
│ └──────────┘ │ 📎 nvme.pdf │
│ nvme.pdf [x] │ │
│ ssd.txt [x] │ [질문 입력] [전송]│
└──────────────┴─────────────────┘
POST /uploadGET /documents / DELETEPOST /asksources🔑 좌측 사이드바(업로드·목록·삭제)와 우측 채팅(스트리밍·출처)으로 구성.
similarity_search(question, k=3) 로 근거 검색stream=True 로 토큰 단위 생성data: ...\n\n)로 전송sources → [DONE] 전송def generate():
response = client.chat.completions.create(
model="gpt-4o-mini", stream=True,
messages=[...context + question...])
for chunk in response:
c = chunk.choices[0].delta.content
if c:
yield f"data: {json.dumps({'content': c})}\n\n"
yield f"data: {json.dumps({'sources': sources})}\n\n"
yield "data: [DONE]\n\n"
💡 동일한 답변이라도 체감 응답성이 크게 향상된다. 프론트엔드는
content누적 →sources표시 →[DONE]종료 순으로 처리한다.
| 항목 | 구현 |
|---|---|
| OpenAI API 사용 | ✅ |
| Embedding 생성 · Vector Search | ✅ |
| ChromaDB 영속 | ✅ |
| LangChain RAG Chain | ✅ |
| PDF/TXT 업로드 (DOCX 확장 가능) | ✅ |
| 문서 목록 · 삭제 (CRUD) | ✅ |
| 질의응답 + 출처 표시 | ✅ |
| SSE 스트리밍 응답 | ✅ |
| Chat History (멀티턴 확장) | ✅ |
| 실제 RAG 웹서비스 | ✅ |
💡 여기까지가 사내 문서검색 챗봇 한 세트다. 문서만 교체하면 실무에 바로 투입할 수 있다.
style.css 만 교체해 화면 디자인 바꾸기