LINE ๋ํ๋ก ์ฐพ๋ ์ํ, AI๋ก ์ด์ด์ง๋ ์ผํ ๊ฒฝํ
LINE ๋ฉ์์ง์ AI ์ํ ์ถ์ฒ์ ์ฐ๊ฒฐํ๋ ์ผํ ์๋น์ค ๋ฐฑ์๋์
๋๋ค.
ํ๋ก์ ํธ ์๊ฐ ยท ์ฃผ์ ๊ธฐ๋ฅ ยท ํ์ ยท ๊ธฐ์ ์คํ ยท ์ํคํ ์ฒ
Capstone BE๋ ์ํยท์ฃผ๋ฌธ ๊ด๋ฆฌ API์ LINE ์ฑ๋ด์ ํจ๊ป ์ ๊ณตํ๋ ์บก์คํค ํ๋ก์ ํธ์ ๋๋ค.
์ฌ์ฉ์๊ฐ LINE์ผ๋ก ๋ฉ์์ง๋ฅผ ๋ณด๋ด๋ฉด, ์๋ฒ๋ ๋ฉ์์ง๋ฅผ ์๋ฒ ๋ฉ์ผ๋ก ๋ณํํ๊ณ ์ ์ฅ๋ ๋ฌธ์ ๋ถ๋ฅ์ ๋น๊ตํฉ๋๋ค. ์ํ ์ถ์ฒ ์์ฒญ์๋ ์ ์ฌํ ์ํ์ ์ฐพ์ ์ด๋ฏธ์งยท๊ฐ๊ฒฉยท์์ธ ํ์ด์ง ๋งํฌ๊ฐ ๋ด๊ธด ์นด๋๋ฅผ ์ ์กํ๊ณ , ๋ฐฐ์กยทํ๋ถ ๋ฌธ์์๋ ๊ด๋ จ ํ์ด์ง์ ์๋ด์ ์ฐ๊ฒฐ ๋ฒํผ์ ์๋ดํฉ๋๋ค.
์ผํ ์๋น์ค์์๋ ์ํ๊ณผ ๋งค์ฅ์ ๋ฑ๋กํ๊ณ , ์ฌ์ฉ์ยท๋ฐฐ์ก์งยท์ฃผ๋ฌธ ์ ๋ณด๋ฅผ ๊ด๋ฆฌํ ์ ์์ต๋๋ค. ์ํ ๋ฑ๋ก ์์๋ ์ํ ์ด๋ฆ์ ์๋ฒ ๋ฉ์ ํจ๊ป ์ ์ฅํด ์ดํ ์ถ์ฒ์ ํ์ฉํฉ๋๋ค.
| ๊ธฐ๋ฅ | ์ค๋ช |
|---|---|
| AI ์ํ ์ถ์ฒ | ์ฌ์ฉ์ ๋ฉ์์ง์ ์ํ ์๋ฒ ๋ฉ์ ๊ฑฐ๋ฆฌ๋ฅผ ๋น๊ตํด ๊ฐ๊น์ด ์ํ ์ต๋ 5๊ฐ ์กฐํ |
| LINE ๋ํ ์ฐ๋ | ์นํ ์ผ๋ก ๋ฉ์์ง๋ฅผ ์์ ํ๊ณ ํ ์คํธยท๋ฒํผยท์ํ ์นด๋ ๋ฉ์์ง ์ ์ก |
| ๋ฌธ์ ์ ํ๋ณ ์๋ด | ์ถ์ฒยท๋ฐฐ์กยทํ๋ถ ๋ถ๋ฅ์ ๋ฐ๋ผ ์ํ ์นด๋ ๋๋ ์๋ด ๋ฒํผ ์ ๊ณต |
| ์ํ ๊ด๋ฆฌ | ์ํ ๋ฑ๋กยท๋ชฉ๋ก ๋ฐ ๋จ๊ฑด ์กฐํยท์์ ยท์ญ์ API, ๋ธ๋๋ยท๊ฐ๊ฒฉยทํ๋งค ์ํยทํ ์ธ ์ ๋ณด ๊ด๋ฆฌ |
| ์ํ ์ด๋ฏธ์ง ์ ๋ก๋ | ์ ํ์ ์ผ๋ก ์ฒจ๋ถํ ์ด๋ฏธ์ง๋ฅผ FTP ์๋ฒ์ ๋น๋๊ธฐ๋ก ์ ๋ก๋ํ๊ณ ์ํ์ ์ด๋ฏธ์ง URL ์ ์ฅ |
| ์ฃผ๋ฌธ ๊ด๋ฆฌ | ์ฃผ๋ฌธ ์์ฑยท๋ชฉ๋ก ๋ฐ ๋จ๊ฑด ์กฐํยท์์ ยท์ญ์ API |
| ์ฌ์ฉ์ยท๋ฐฐ์ก์ง ๊ด๋ฆฌ | ์ฌ์ฉ์ ๋ฑ๋กยท์กฐํยท์ญ์ ๋ฐ ์ฌ์ฉ์๋ณ ๋ฐฐ์ก์ง ๋ฑ๋กยท์กฐํ |
| ๋งค์ฅ ๊ด๋ฆฌ | ๋งค์ฅ ๋ฑ๋กยท์กฐํ ๋ฐ ์ํ๊ณผ ๋งค์ฅ ์ฐ๊ฒฐ |
์ด ๋ฐฑ์๋ ์ ์ฅ์์ ์ปค๋ฐ ๊ธฐ์ฌ์์ ๋๋ค.
| KimRPG | Kim-Min-Hyeok | SoominYoo |
|---|---|---|
| @KimRPG | @Kim-Min-Hyeok | @SoominYoo |
| ๊ตฌ๋ถ | ๊ธฐ์ | ์ฌ์ฉ ๋ชฉ์ |
|---|---|---|
| Language | Java 17 | ์๋ฒ ์ ํ๋ฆฌ์ผ์ด์ ๊ฐ๋ฐ |
| Framework | Spring Boot 3.3.4, Spring Web | REST API ๋ฐ LINE ์นํ ์ฒ๋ฆฌ |
| Persistence | Spring Data JPA, JdbcTemplate | ๋๋ฉ์ธ ๋ฐ์ดํฐ ์ ์ฅยท์กฐํ ๋ฐ ๋ฒกํฐ ๊ฒ์ SQL ์คํ |
| AI | Spring AI 1.0.0-M3, OpenAI ์ฐ๋ | ํ ์คํธ ์๋ฒ ๋ฉ ์์ฑ ๋ฐ ๋ณ๋ AI ๋ต๋ณ API |
| Messaging | LINE Bot SDK 2.1.0, Reactor | LINE ๋ฉ์์ง ์์ ยท๋ฐ์ก ๋ฐ ๋น๋๊ธฐ ์๋ต ์ฒ๋ฆฌ |
| API Docs | springdoc-openapi 2.2.0 | OpenAPI ๋ฐ Swagger UI ์ค์ |
| Build | Gradle Wrapper 8.5 | ์์กด์ฑ ๊ด๋ฆฌ ๋ฐ ๋น๋ |
| ๊ตฌ๋ถ | ๊ธฐ์ | ์ฌ์ฉ ๋ชฉ์ |
|---|---|---|
| Database | PostgreSQL, pgvector | ์ผํ ๋ฐ์ดํฐ์ 1,536์ฐจ์ ์๋ฒ ๋ฉ ์ ์ฅ, ๋ฒกํฐ ๊ฑฐ๋ฆฌ ๊ธฐ๋ฐ ๊ฒ์ |
| File Storage | FTP, Apache Commons Net 3.9.0 | ์ํ ์ด๋ฏธ์ง ์ ๋ก๋ |
| Messaging Platform | LINE Messaging API | ์ฌ์ฉ์ ๋ํ ์ฑ๋ ๋ฐ ์ํ ์นด๋ ์ ๋ฌ |
| AI Provider | OpenAI API | Spring AI๋ฅผ ํตํ ๋ชจ๋ธ ํธ์ถ |
๊ธฐ์ ๋ฐ ๋ฒ์ ์ build.gradle๊ณผ ํ์ฌ ์์ค ์ฝ๋๋ฅผ ๊ธฐ์ค์ผ๋ก ์ ๋ฆฌํ์ต๋๋ค. S3 ์ค์ ยท์ ๋ก๋ ์๋น์ค๋ ๋จ์ ์์ง๋ง, ํ์ฌ ์ํ ๋ฑ๋ก ๊ฒฝ๋ก์์๋ FTP๋ฅผ ์ฌ์ฉํฉ๋๋ค.
flowchart LR
User[์ฌ์ฉ์] -->|๋ฉ์์ง ์
๋ ฅ| LINE[LINE]
LINE -->|Webhook| Webhook[LineWebhookController]
Webhook --> AI[AIService]
AI -->|์๋ฒ ๋ฉ ์์ฑ| OpenAI[OpenAI API]
AI -->|๋ฌธ์ ๋ถ๋ฅ ๊ฒ์| DB[(PostgreSQL / pgvector)]
DB --> Category{๋ฌธ์ ์ ํ}
Category -->|์ถ์ฒ| Search[์ ์ฌ ์ํ ์ต๋ 5๊ฐ ์กฐํ]
Search --> Cards[์ํ ์นด๋ ๊ตฌ์ฑ]
Category -->|๋ฐฐ์ก ยท ํ๋ถ ยท ๊ธฐํ| Guide[๊ด๋ จ ํ์ด์ง ยท ์๋ด์ ๋ฒํผ]
Cards --> API[LINE Messaging API]
Guide --> API
API -->|๋ฉ์์ง ์ ๋ฌ| User
flowchart TB
Client[์ผํ ํด๋ผ์ด์ธํธ] --> Controllers[์ํ ยท ์ฃผ๋ฌธ ยท ์ฌ์ฉ์ ยท ๋งค์ฅ Controller]
LINE[LINE Webhook] --> LineController[LineWebhookController]
subgraph Backend[Spring Boot Backend]
Controllers --> Services[๋๋ฉ์ธ Service]
Services --> Repos[Spring Data JPA Repository]
Services -->|์ํ ์ด๋ฆ ์๋ฒ ๋ฉ| AI[AIService]
Services -->|์ํ ์ด๋ฏธ์ง| FTP[FtpServer]
LineController --> AI
AI --> JDBC[AiJDBC]
LineController --> Message[๋ฉ์์ง ์์ฑ ยท ๋ฐ์ก]
end
Repos --> DB[(PostgreSQL / pgvector)]
JDBC --> DB
AI --> OpenAI[OpenAI API]
FTP --> Storage[FTP ํ์ผ ์๋ฒ]
Message --> Messaging[LINE Messaging API]
์ ๋ค์ด์ด๊ทธ๋จ์ ์ฝ๋์ ํธ์ถ ๊ด๊ณ๋ฅผ ๋ํ๋ ๋๋ค. ๋ฐฐํฌ ์๋ฒ ๊ตฌ์ฑ์ด๋ CI/CD ํ์ดํ๋ผ์ธ์ ์ด ์ ์ฅ์์ ์ ์๋์ด ์์ง ์์ต๋๋ค.
- ์ํ ๋ฑ๋ก โ ์ํ ์ด๋ฆ์ ์๋ฒ ๋ฉ์ผ๋ก ๋ณํํด
product.embedding์ ์ ์ฅํฉ๋๋ค. - ๋ฌธ์ ๋ถ๋ฅ โ ์ฌ์ฉ์ ๋ฉ์์ง์ ์๋ฒ ๋ฉ๊ณผ
recommendํ ์ด๋ธ์ ๋น๊ตํด ๊ฐ์ฅ ๊ฐ๊น์ด ๋ถ๋ฅ ํ๋๋ฅผ ์ ํํฉ๋๋ค. - ์ํ ๊ฒ์ โ ๋ถ๋ฅ๊ฐ
์ถ์ฒ์ด๋ฉด ๊ฐ์ ๋ฉ์์ง ์๋ฒ ๋ฉ์ผ๋ก ์ํ์ ๊ฒ์ํฉ๋๋ค. pgvector์<->๊ฑฐ๋ฆฌ ์ฐ์ฐ ๊ฒฐ๊ณผ๋ฅผ ์ค๋ฆ์ฐจ์์ผ๋ก ์ ๋ ฌํ๊ณ ์ต๋ 5๊ฐ๋ฅผ ๊ฐ์ ธ์ต๋๋ค. - ์นด๋ ์ ์ก โ ์กฐํํ ์ํ์ ์ด๋ฏธ์งยท์ด๋ฆยท์ค๋ช ยท๊ฐ๊ฒฉยท์์ธ ๋งํฌ๊ฐ ์๋ LINE ์ํ ์นด๋๋ก ๋ณํํด ์ ์กํฉ๋๋ค.
๊ตฌํ: AIService ยท AiJDBC ยท LineWebhookController
| ์์ญ | Method | Path | ๊ธฐ๋ฅ |
|---|---|---|---|
| ์ํ | POST ยท GET ยท PATCH ยท DELETE |
/product |
์ํ ๋ฑ๋กยท์กฐํยท์์ ยท์ญ์ |
| ์ฃผ๋ฌธ | POST ยท GET ยท PATCH ยท DELETE |
/order |
์ฃผ๋ฌธ ์์ฑยท์กฐํยท์์ ยท์ญ์ |
| ์ฌ์ฉ์ | POST ยท GET ยท DELETE |
/user |
์ฌ์ฉ์ ๋ฑ๋กยท์กฐํยท์ญ์ |
| ๋ฐฐ์ก์ง | POST ยท GET |
/user/address |
์ฌ์ฉ์๋ณ ๋ฐฐ์ก์ง ๋ฑ๋กยท์กฐํ |
| ๋งค์ฅ | POST ยท GET |
/store |
๋งค์ฅ ๋ฑ๋กยท์กฐํ |
| AI | GET |
/ai/answer |
AI ํ ์คํธ ๋ต๋ณ |
| AI | GET |
/ai/recommend |
๋ฌธ์ ์ ํ ๋ถ๋ฅ |
| AI | GET |
/ai/recommend/product |
์ ์ฌ ์ํ ์ถ์ฒ |
| LINE | POST |
/channel/line |
์นํ ์ด๋ฒคํธ ์์ |
| LINE | POST |
/channel/line/text |
ํ ์คํธ ๋ฉ์์ง ์ ์ก |
| LINE | POST |
/channel/line/question |
๋ฒํผ์ ํฌํจํ ๋ฉ์์ง ์ ์ก |
| LINE | POST |
/channel/line/product-card |
์ํ ์นด๋ ๋ฉ์์ง ์ ์ก |
์ํยท์ฃผ๋ฌธยท์ฌ์ฉ์ยท๋งค์ฅ ์กฐํ๋ id ์ฟผ๋ฆฌ ํ๋ผ๋ฏธํฐ ์ ๋ฌด์ ๋ฐ๋ผ ๋จ๊ฑด ๋๋ ๋ชฉ๋ก์ ๋ฐํํฉ๋๋ค. ๋ฐฐ์ก์ง๋ ๋ฑ๋ก ์ userId, ์กฐํ ์ id๋ก ์ฌ์ฉ์ ID๋ฅผ ์ ๋ฌํฉ๋๋ค. ํ์ฌ AI ์กฐํ API๋ GET ์์ฒญ์ JSON ๋ณธ๋ฌธ์ผ๋ก {"request":"๋ฉ์์ง"}๋ฅผ ๋ฐ์ต๋๋ค.
src/main/java/com/capstonexjapan/line_backend
โโโ ai # ์๋ฒ ๋ฉ ์์ฑ, ๋ฌธ์ ๋ถ๋ฅ, ์ํ ์ถ์ฒ
โโโ config # AI, LINE, CORS, S3, OpenAPI ์ค์
โโโ ftp # FTP ์
๋ก๋ ๋ฐ ํ์ผ ๋ณํ
โโโ global/exception # ๊ณตํต ์์ธ ์ฒ๋ฆฌ
โโโ line_message # LINE ์นํ
, ๋ฉ์์ง ์์ฑ ๋ฐ ๋ฐ์ก
โโโ shop
โโโ product # ์ํ ๋ฐ ์ด๋ฏธ์ง ๊ด๋ฆฌ
โโโ order # ์ฃผ๋ฌธ ๋ฐ ์ฃผ๋ฌธ ์ด๋ ฅ ๊ด๋ จ ์ฝ๋
โโโ user # ์ฌ์ฉ์ ๋ฐ ๋ฐฐ์ก์ง ๊ด๋ฆฌ
โโโ store # ๋งค์ฅ ๊ด๋ฆฌ
โโโ square # ๊ฒฐ์ ์ฐ๋์ฉ ๊ธฐ๋ณธ ๊ตฌ์กฐ
์คํ์๋ JDK 17, pgvector๋ฅผ ์ฌ์ฉํ ์ ์๋ PostgreSQL, OpenAI ๋ฐ LINE ์ฐ๊ฒฐ ์ ๋ณด, FTP ์๋ฒ ์ค์ ์ด ํ์ํฉ๋๋ค. ๋ก์ปฌ ์ค์ ํ์ผ(*.yml, *.properties)์ Git ๊ด๋ฆฌ ๋์์์ ์ ์ธ๋์ด ์์ต๋๋ค.
| ์ค์ ์์ญ | ์ค๋นํ ํญ๋ชฉ |
|---|---|
| ๋ฐ์ดํฐ๋ฒ ์ด์ค | Spring datasource ์ฐ๊ฒฐ ์ ๋ณด, vector ํ์ฅ ๋ฐ ์๋ฒ ๋ฉ ์ปฌ๋ผ ๊ตฌ์ฑ |
| AI | Spring AI OpenAI ์ธ์ฆยท๋ชจ๋ธ ์ค์ , ์ ์ฅ๋ ์๋ฒ ๋ฉ๊ณผ ๋์ผํ ๋ชจ๋ธ ๋ฐ 1,536์ฐจ์ ์ถ๋ ฅ |
| ๋ฌธ์ ๋ถ๋ฅ | recommend ํ
์ด๋ธ์ ๋ฌธ์ ์ ํ๊ณผ ํด๋น ์๋ฒ ๋ฉ ์ฌ์ ์ ์ฅ |
| LINE | line.channel.token, ๊ณต๊ฐ ์นํ
์ฃผ์ /channel/line |
| FTP | ftp.server, ftp.username, ftp.password ๋ฐ ์
๋ก๋ ๋๋ ํฐ๋ฆฌ /A |
| ์์กด S3 ์ค์ | cloud.aws.credentials.access-key, cloud.aws.credentials.secret-key, cloud.aws.region.static, cloud.aws.s3.bucket |
ํ์ฌ ์ฝ๋ ๊ธฐ์ค ์คํ ์ ํ์ธ ์ฌํญ
- LINE ํด๋ผ์ด์ธํธ ์ค์ ์
@Value(".${line.channel.token}")์๋ ํ ํฐ ์์ ๋ง์นจํ๊ฐ ๋ถ์ต๋๋ค. ์ค์ ์ฐ๋ ์ ํ ํฐ ์ฃผ์ ์์ ํ์ธํด์ผ ํฉ๋๋ค. - CORS ํ์ฉ ์ฃผ์, ์ํ ์์ธยท๋ฐฐ์กยท์ฃผ๋ฌธ ํ์ด์ง ๋งํฌ์ ์ด๋ฏธ์ง ๊ธฐ๋ณธ URL์ ์์ฐ ํ๊ฒฝ ๊ฐ์ด ์ฝ๋์ ์ง์ ๋์ด ์์ด ์คํ ํ๊ฒฝ์ ๋ง๊ฒ ์กฐ์ ํด์ผ ํฉ๋๋ค.
- S3๋ ํ์ฌ ์ํ ์ ๋ก๋ ๊ฒฝ๋ก์์ ์ฌ์ฉํ์ง ์์ง๋ง ์ค์ ๋น์ด ๋จ์ ์์ผ๋ฏ๋ก ๊ด๋ จ ์ค์ ์ ์ ๊ณตํ๊ฑฐ๋ ๋น ๊ตฌ์ฑ์ ์ ๋ฆฌํด์ผ ํฉ๋๋ค.
- ๋ฌธ์ ๋ถ๋ฅ ๋ฐ์ดํฐ์ ์๋ ์ด๊ธฐํ ์ ์ฐจ๋ ํฌํจ๋์ด ์์ง ์์ผ๋ฉฐ,
/ai/embedding๋งคํ๋ ์ฃผ์ ์ฒ๋ฆฌ๋์ด ์์ต๋๋ค. shop/square์ ๊ฒฐ์ ํด๋์ค๋ ๊ธฐ๋ณธ ๊ตฌ์กฐ๋ง ๋จ์ ์์ต๋๋ค. ์ฃผ๋ฌธ ์ด๋ ฅ ์ ์ฅ ์๋น์ค๋ ํ์ฌ ์ฃผ๋ฌธ ์์ฑ ํ๋ฆ์์๋ ํธ์ถ๋์ง ์์ต๋๋ค.
์ด ๋ฌธ์๋ ์์ค ์ฝ๋๋ฅผ ๊ธฐ์ค์ผ๋ก ์์ฑํ์ผ๋ฉฐ, ์ธ๋ถ ์๋น์ค ์ฐ๊ฒฐ์ ํฌํจํ ์คํ ๊ฒ์ฆ ๊ฒฐ๊ณผ๋ฅผ ์๋ฏธํ์ง ์์ต๋๋ค.