Spring Boot + Thymleaf + FastAPI + LangChain + MySQL + Elasticsearch๋ฅผ ํ์ฉํ AI ์ฑ๋ด ๊ธฐ๋ฐ ๊ฐ์ธํ ํ์ต ์ง์ ์๋น์ค
์ฌ์ฉ์๊ฐ ์ง์ ์ ๋ก๋ํ ๊ต์ฌ(PDF)๋ฅผ ๊ธฐ๋ฐ์ผ๋ก, ๊ฐ์ธ์ ์ดํด๋์ ๋ง์ถ ๋ฌธ์ ์์ฑ, ๊ฐ๋ ์ค๋ช ๋ฑ์ ์ ๊ณตํ๋ AI ์ฑ๋ด ๊ธฐ๋ฐ ๊ฐ์ธํ ํ์ต ์ง์ ์๋น์ค์ ๋๋ค. LangChain๊ณผ GPT-4๋ฅผ ํ์ฉํด, ๋จ์ํ ์ฑ๋ด์ด ์๋ ๋ํ ํ๋ฆ์ ๋ฐ๋ผ ๋ฐ๋ณต ํ์ต๊ณผ ์ค๋ต ํผ๋๋ฐฑ ๋ฃจํ๋ฅผ ๊ตฌ์ฑํ ์ ์์ผ๋ฉฐ, ์ด๋ฅผ ์ํด Spring Boot โ FastAPI(LangChain) โ Elasticsearch๊ฐ ์ ๊ธฐ์ ์ผ๋ก ์ฐ๊ฒฐ๋ฉ๋๋ค.
https://www.figma.com/board/Xw0B6VFKSx0Uj0tRNO2FgA/Untitled?node-id=0-1&p=f&t=8jBj2pGFQPkSKXHv-0
๋ณธ ์์คํ ์ Docker Compose ๋คํธ์ํฌ ๊ธฐ๋ฐ์ ๋ฉํฐ ์ปจํ ์ด๋ ์ํคํ ์ฒ๋ก, Spring Boot, FastAPI, MySQL, Elasticsearch ๋ฑ ์ฃผ์ ์ปดํฌ๋ํธ๋ฅผ ํตํฉํ์ฌ ๋ค์๊ณผ ๊ฐ์ ๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๋ค:
- โ๏ธ ๋ ธํธ/๋ฉ๋ชจ ๊ธฐ๋ฐ ํ์ต ์ง์
- ๐ฌ ์ํ ๊ธฐ๋ฐ ์ฑ๋ด๊ณผ์ ์์ฐ์ค๋ฌ์ด ๋ํ ํ๋ฆ
- ๐ง LangChain ๊ธฐ๋ฐ ๋ฌธ์ ์์ฑ ๋ฐ ์ค๋ต ํผ๋๋ฐฑ
- ๐ Elasticsearch๋ฅผ ํตํ ๊ต์ฌ ๊ฒ์ ๋ฐ ์ ์ฌ ๋ฌธ์ ํ์
| ๊ตฌ๋ถ | ๊ธฐ์ |
|---|---|
| ํ๋ก ํธ์๋ | Thymeleaf (Spring ๊ธฐ๋ฐ SSR) |
| ๋ฐฑ์๋ (๋ฉ์ธ) | Spring Boot (Java 17) |
| AI ์๋ฒ | FastAPI (Python 3.10) + LangChain |
| ๋ฐ์ดํฐ๋ฒ ์ด์ค | MySQL 8.0 |
| ๊ฒ์์์ง | Elasticsearch 8.x |
| ์ปจํ ์ด๋ํ | Docker, Docker Compose |
| LLM ์ฐ๋ | OpenAI GPT-4 API |
| ๋ฌธ์ ๊ฒ์ ์ต์ ํ | RAG (Retrieval-Augmented Generation) ๊ธฐ๋ฐ ๊ตฌ์กฐ |
| ๊ตฌ์ฑ ์์ | ์ญํ |
|---|---|
| ๐ฅ ์ฌ์ฉ์ | ์น UI์์ ์ฑ๋ด๊ณผ ์ํธ์์ฉ, ๋ ธํธ ์์ฑ, PDF ์ด๋ |
| ๐ฑ Spring Boot + Thymleaf | ์ํ ์ ์ด, ์ฌ์ฉ์ ์ธ์ฆ, PDF ๋ ๋๋ง ๋ฐ ๋ ธํธ ๊ด๋ฆฌ |
| โก FastAPI (LangChain) | ์์ ๋ฌธ์ ์์ฑ, ์ค๋ต ๋ถ์, ๊ฐ๋ ์ค๋ช (LLM ํธ์ถ) |
| ๐ Elasticsearch | ๊ต์ฌ ๋ฌธ์ ์๋ฒ ๋ฉ ๋ฐ RAG ๊ธฐ๋ฐ ๊ฒ์ |
| ๐ฌ MySQL | ์ฌ์ฉ์/๋ ธํธ/์ด๋ ฅ ์ ๋ณด ์ ์ฅ |
| ๐ ์ธ๋ถ API | ์ํค/๋ฐฑ๊ณผ ๋ฑ์ ํตํ ๊ฐ๋ ์ค๋ช ๋ณด๊ฐ |
[์ฌ์ฉ์ ์์ฒญ]
โ
[Spring ChatService: ์ํ ํ๋จ + ํ๋ฆ ์ ์ด]
โ โ๏ธ
[์ํ ์ ์ด์ ๋ฐ๋ฅธ ๋ก์ง ์ฒ๋ฆฌ] โ (ํ์ ์) [FastAPI (/chat)] ํธ์ถ
โ
[๋ค์ ์ํ + ๋ฉ์์ง ๊ฒฐ์ ]
โ
[ChatHistory ์ ์ฅ + ์๋ต ๋ฐํ]
๐ START โ WAITING_USER_SELECT_FEATURE
// ๊ธฐ๋ฅ ์ ํ ๋๊ธฐ (1. ๋ฌธ์ ์์ฑ / 2. ํ์ด์ง ์ฐพ๊ธฐ / 3. ๊ฐ๋
์ค๋ช
)
โโ 1. ์์ ๋ฌธ์ ์์ฑ
โ โ WAITING_PROBLEM_CRITERIA_SELECTION
โ // ๋ฌธ์ ๊ธฐ์ค ์ ํ ์์ฒญ
โ โ WAITING_PROBLEM_CONTEXT_INPUT
โ // ์ฑํฐ/๊ฐ๋
์
๋ ฅ ์์ฒญ
โ โ โก GENERATING_QUESTION_WITH_RAG
โ // FastAPI ํธ์ถ๋ก ๋ฌธ์ ์์ฑ
โ โ โก EVALUATING_ANSWER_AND_LOGGING
โ // FastAPI ํธ์ถ๋ก ์ ์ค๋ต ํ๋จ ๋ฐ ํด์ค ํฌํจ
โ โ WAITING_CONCEPT_RATING
โ // ํด์ค์ ๋ํ ์ดํด๋ ํ๊ฐ ์์ฒญ
โ โโ 4~5์ โ WAITING_NEXT_ACTION_AFTER_LEARNING
โ โ // ๋ค์ ํ๋ ์ ํ (1. ๋ค์ ๋ฌธ์ / 2. ๊ธฐ๋ฅ ์ ํ)
โ โ โโ 1. ๋ค์ ๋ฌธ์ โ โก GENERATING_ADDITIONAL_QUESTION_WITH_RAG
โ โ โ โ โก EVALUATING_ANSWER_AND_LOGGING โ ...
โ โ โโ 2. ๊ธฐ๋ฅ ์ ํ โ WAITING_USER_SELECT_FEATURE
โ โโ 1~3์ โ WAITING_REASON_FOR_LOW_RATING
โ // ๋ฎ์ ์ ์ ์ด์ ์์ฒญ
โ โ โก REEXPLAINING_CONCEPT
โ // FastAPI ํธ์ถ๋ก ๋ณด์ถฉ ์ค๋ช
โ โ WAITING_CONCEPT_RATING (๋ฐ๋ณต)
โโ 2. ํ์ด์ง ์ฐพ๊ธฐ
โ โ WAITING_KEYWORD_FOR_PAGE_SEARCH
โ // ํค์๋ ์
๋ ฅ ๋๊ธฐ
โ โ โก PROCESSING_PAGE_SEARCH_RESULT
โ // FastAPI ํธ์ถ๋ก ํ์ด์ง/์ฑํฐ ์ถ์ฒ
โ โ WAITING_USER_SELECT_FEATURE (๋ฃจํ)
โโ 3. ๊ฐ๋
์ค๋ช
โ WAITING_CONCEPT_INPUT
// ๊ฐ๋
์
๋ ฅ ๋๊ธฐ
โ โก PRESENTING_CONCEPT_EXPLANATION
// FastAPI ํธ์ถ๋ก ๊ฐ๋
์ค๋ช
โ WAITING_CONCEPT_RATING
// ์ค๋ช
์ ๋ํ ํ๊ฐ
โโ 4~5์ โ WAITING_NEXT_ACTION_AFTER_LEARNING โ (์ ํ์ ๋ฐ๋ผ ๋ฃจํ)
โโ 1~3์ โ WAITING_REASON_FOR_LOW_RATING โ โก REEXPLAINING_CONCEPT โ WAITING_CONCEPT_RATING (๋ฐ๋ณต)
๐ฆKDT_BE12_Toy_Project4/
โโ ๐ application-server/ # Spring Boot ์ ํ๋ฆฌ์ผ์ด์
โ โโ ๐ application/ # ํต์ฌ ์๋ฒ ์ ํ๋ฆฌ์ผ์ด์
๋ชจ๋
โ โโ ๐ src/ # Java ์์ค ์ฝ๋
โ โโ ๐ build.gradle # Gradle ๋น๋ ์คํฌ๋ฆฝํธ
โ โโ ๐ Dockerfile # Spring Boot Dockerfile
โ โโ ...
โ
โโ ๐ langchain-server/ # FastAPI + LangChain ๊ธฐ๋ฐ AI ์๋ฒ
โ โโ ๐ app/ # FastAPI ๋ผ์ฐํฐ ๋ฐ ์๋น์ค ์ฝ๋
โ โโ ๐ tests/ # ํ
์คํธ ์ฝ๋
โ โโ ๐ Dockerfile # FastAPI Dockerfile
โ โโ ๐ Dockerfile.elasticsearch # Elasticsearch ํฌํจ ๋น๋์ฉ Dockerfile
โ โโ ๐ pyproject.toml # Python ํ๋ก์ ํธ ์ค์
โ
โโ ๐ docker-compose.yml # ์ ์ฒด ๋ฉํฐ ์ปจํ
์ด๋ ๊ตฌ์ฑ ํ์ผ
โโ ๐ .env.dev # ๊ฐ๋ฐ์ฉ ํ๊ฒฝ ๋ณ์
โโ ๐ .env.prod # ์ด์์ฉ ๋ฏผ๊ฐ ์ ๋ณด (Git ์ ์ธ ๊ถ์ฅ)
โโ ๐ README.md
โโ ...
| ๊ตฌ์ฑ ์์ | ์ค๋ช | ํธ์คํธ ํฌํธ โ ์ปจํ ์ด๋ ํฌํธ |
|---|---|---|
Spring Boot |
์ฌ์ฉ์ API / View ๋ ๋๋ง | 8080:8080 |
MySQL |
๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค | 3307:3306 |
FastAPI (LangChain) |
AI ๊ธฐ๋ฐ ์๋ต ์ฒ๋ฆฌ | 8000:8000 |
Elasticsearch |
๊ฒ์ ๊ธฐ๋ฐ ์์คํ | 9200:9200 |
- ๋ชจ๋ ์ปจํ
์ด๋๋ Docker Compose์
backend๋คํธ์ํฌ๋ก ์ฐ๊ฒฐ - ๋ด๋ถ DNS ์ด๋ฆ (
mysql,langchain,elasticsearch)์ผ๋ก ์๋ก ์ ๊ทผ
| ํ์ผ๋ช | ๋ชฉ์ | ๋น๊ณ |
|---|---|---|
.env.dev |
๊ฐ๋ฐ ํ๊ฒฝ์ฉ ์ค์ (DB ํฌํธ, ์๋น์ค ์ด๋ฆ ๋ฑ) | ๋ก์ปฌ ๊ฐ๋ฐ์๋ค์ด ๊ณตํต์ผ๋ก ์ฌ์ฉํ ์ ์๋๋ก Git์ ํฌํจ |
.env.prod |
์ด์ ๋๋ ๋ฐฐํฌ์ฉ ๋ฏผ๊ฐ ์ ๋ณด (API ํค, ์ํฌ๋ฆฟ ๋ฑ) | ๋ณด์์ Git์ ํฌํจ โ, ๋ก์ปฌ ๋๋ ์๋ฒ์์ ๊ฐ๋ณ ๊ด๋ฆฌ ํ์ |
OPENAI_API_KEY=sk-xxxxxxxxxxxx
OPENAI_MODEL_NAME=gpt-4
GEMINI_API_KEY=xxxxxxxxxxxx
GOOGLE_SEARCH_API_KEY=xxxxxxxxxxxx
GOOGLE_CSE_ID=xxxxxxxxxxxx- ํ์ฌ API ํค ๋ง๋ฃ ์ํ(langchain-server์ ํ
์คํธ๋ฅผ ์งํํ์ง ๋ชปํจ)
- API ํค ๋ง๋ฃ๋ก PDF ์๋ฒ ๋ฉ์ด ๋์ง ์์
BookEmbeddingService.java์์ PDF ์๋ฒ ๋ฉ ์์ฒญ ๋ก์ง ์์ ํ์- ์ด ์ธ์๋ langchain-server์ ํ ์คํธ ํ์
- ...

