์ฌ์ฉ์๊ฐ ์์ฑํ ๊ฒ์๊ธ์ ์ด์์ ์ฑ
๋ฃฐ ๊ธฐ๋ฐ์ผ๋ก ์๋ ๊ฒ์ํ๊ณ , ์คํธ/์ฌ๊ธฐ/์ด๋ทฐ์ง ์ํ๋๋ฅผ ๊ณ์ฐํด ALLOW, REVIEW, BLOCK ์ค ํ๋๋ก ํ์ ํฉ๋๋ค.
| ALLOW | BLOCK | REVIEW |
|---|---|---|
![]() |
![]() |
![]() |
์ด์ํ์ ๋งค์ผ ๋ง์ ๊ฒ์๊ธ์ ๊ฒ์ํด์ผ ํ๊ณ , ๋ฐ๋ณต์ ์ธ ์ ์ฑ ์๋ฐ ํค์๋ ํ์ง์ ์ํ๋ ํ๋จ์ ์์์ ์ผ๋ก ์ฒ๋ฆฌํ๋ฉด ์๋์ ์ผ๊ด์ฑ์ด ๋จ์ด์ง๋๋ค.
ํนํ ๋ค์๊ณผ ๊ฐ์ ํจํด์ ๋น ๋ฅด๊ฒ ๊ฐ์งํด ์ด์์๊ฐ ์ฐ์ ์์๋ฅผ ์ก์ ์ ์์ด์ผ ํฉ๋๋ค.
- ์ ์ ๊ธ ์๊ตฌ
- ์ธ๋ถ ์ฐ๋ฝ ์ ๋
- ๊ณ์ข/์ก๊ธ ์ ๋
- ๋ถ๋ฒ ๊ฑฐ๋ ํค์๋
- ์คํธ์ฑ ํํ
์์์ ๊ฒ์๋ง์ผ๋ก ์ฒ๋ฆฌํ ๊ฒฝ์ฐ ๋ค์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค.
| ๋ฌธ์ | ์ค๋ช |
|---|---|
| ์ฒ๋ฆฌ ์ง์ฐ | ๊ฒ์๊ธ์ด ๋ง์์ง์๋ก ๊ฒ์ ๋๊ธฐ ์๊ฐ์ด ์ฆ๊ฐ |
| ํ๋จ ์ผ๊ด์ฑ ๋ถ์กฑ | ์ด์์๋ง๋ค ์ ์ฑ ์๋ฐ ํ๋จ ๊ธฐ์ค์ด ๋ฌ๋ผ์ง ์ ์์ |
| ๋ฐ๋ณต ์ ๋ฌด ์ฆ๊ฐ | ๋จ์ ํค์๋ ๊ฒ์์๋ ์ด์ ๋ฆฌ์์ค๊ฐ ์๋ชจ๋จ |
| ์ฌํ ๋์ ๊ฐ๋ฅ์ฑ | ์ํ ์ฝํ ์ธ ๊ฐ ์ฌ์ฉ์์๊ฒ ๋ ธ์ถ๋ ๋ค ์ฒ๋ฆฌ๋ ์ ์์ |
์ํ ํค์๋๊ฐ ํฌํจ๋ ํ ์คํธ ๊ฒ์๊ธ ์์ ์บก์ฒ๋ฅผ ๋ฃ๋ ์์ญ์ ๋๋ค.
๋ณธ ํ๋ก์ ํธ์์๋ ์ด์์ ์ฑ ๋ฃฐ์ ์ฝ๋์ ํ๋์ฝ๋ฉํ์ง ์๊ณ DB์ ์ ์ฅํ ๋ค, ํ์ฑํ๋ ๋ฃฐ๋ง ๊ฒ์์ ์ฌ์ฉํ๋๋ก ์ค๊ณํ์ต๋๋ค.
- ์ด์์ ์ฑ ๋ฃฐ์ PostgreSQL์ ์ ์ฅ
- ์ ๋ชฉ๊ณผ ๋ณธ๋ฌธ์์ ํค์๋ ๋งค์นญ
- ๋งค์นญ๋ ๋ฃฐ์ ์ ์๋ฅผ ํฉ์ฐํด ์ํ๋ ๊ณ์ฐ
- ์ ์ ๊ธฐ์ค์ ๋ฐ๋ผ
ALLOW,REVIEW,BLOCKํ์ - ๊ฒ์ ๊ฒฐ๊ณผ์ ๋งค์นญ๋ ๋ฃฐ์ PostgreSQL์ ๋ก๊ทธ๋ก ์ ์ฅ
- ๋์ผ ์ฝํ ์ธ ์ฌ๊ฒ์๋ Redis ์บ์๋ก ์๋ต
ํ์ ๊ธฐ์ค์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
| ์ ์ ๋ฒ์ | ํ์ | ์๋ฏธ |
|---|---|---|
| 0 ~ 39 | ALLOW | ์ ์ ๊ฒ์๊ธ |
| 40 ~ 79 | REVIEW | ์ด์์ ๊ฒํ ํ์ |
| 80 ์ด์ | BLOCK | ์ฐจ๋จ ๋์ |
| ๊ตฌ๋ถ | ๊ธฐ์ |
|---|---|
| Language | Python 3.11+ |
| Framework | FastAPI |
| Database | PostgreSQL |
| ORM | SQLAlchemy |
| Migration | Alembic |
| Validation | Pydantic |
| Cache | Redis |
| Infra | Docker Compose |
| Test | pytest |
| API Docs | FastAPI Swagger UI |
flowchart LR
Client[Client / ์ด์์] --> API[FastAPI Server]
API --> Redis[(Redis)]
API --> DB[(PostgreSQL)]
DB --> Rules[moderation_rules]
DB --> Logs[moderation_logs]
API --> Hash[Content Hash ์์ฑ]
Hash --> Redis
API --> RuleEngine[Rule Engine]
RuleEngine --> Decision[ALLOW / REVIEW / BLOCK]
Decision --> Logs
GitHub README์ Mermaid ๋ ๋๋ง ํ๋ฉด ๋๋ mermaid.live์์ PNG๋ก ๋ฝ์ ์ด๋ฏธ์ง๋ฅผ ๋ฃ๋ ์์ญ์ ๋๋ค.
- ํด๋ผ์ด์ธํธ๊ฐ
POST /api/moderations/check๋ก ์ฝํ ์ธ ๋ฅผ ์ ์กํฉ๋๋ค. - ์๋ฒ๊ฐ
title + content + price + category๋กcontentHash๋ฅผ ์์ฑํฉ๋๋ค. - Redis์์
moderation:content:{contentHash}key๋ฅผ ์กฐํํฉ๋๋ค. - cache hit์ด๋ฉด ๋ฃฐ ๊ณ์ฐ๊ณผ DB ์กฐํ ์์ด ์ฆ์ ์๋ตํฉ๋๋ค.
- cache miss์ด๋ฉด ํ์ฑํ๋ ๋ฃฐ์ DB์์ ์กฐํํฉ๋๋ค.
- ์ ๋ชฉ๊ณผ ๋ณธ๋ฌธ์์ ํค์๋๋ฅผ ๋งค์นญํฉ๋๋ค.
- ๋งค์นญ๋ ๋ฃฐ์ ์ ์๋ฅผ ํฉ์ฐํด ์ํ ์ ์๋ฅผ ๊ณ์ฐํฉ๋๋ค.
- ์ํ ์ ์ ๊ธฐ์ค์ผ๋ก
ALLOW,REVIEW,BLOCK์ ํ์ ํฉ๋๋ค. - ๊ฒ์ ๋ก๊ทธ๋ฅผ PostgreSQL์ ์ ์ฅํฉ๋๋ค.
- ๊ฒ์ ๊ฒฐ๊ณผ๋ฅผ Redis์ 5๋ถ TTL๋ก ์ ์ฅํฉ๋๋ค.
- ํด๋ผ์ด์ธํธ์๊ฒ ํ์ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํฉ๋๋ค.
sequenceDiagram
participant Client as Client
participant API as FastAPI Server
participant Redis as Redis
participant DB as PostgreSQL
Client->>API: POST /api/moderations/check
API->>API: title + content + price + category๋ก contentHash ์์ฑ
API->>Redis: moderation:content:{contentHash} ์กฐํ
alt Cache Hit
Redis-->>API: ์บ์๋ ๊ฒ์ ๊ฒฐ๊ณผ ๋ฐํ
API-->>Client: decision, riskScore, matchedRules ๋ฐํ
else Cache Miss
API->>DB: enabled=true ์ด์์ ์ฑ
๋ฃฐ ์กฐํ
DB-->>API: ํ์ฑํ๋ rules ๋ฐํ
API->>API: ํค์๋ ๋งค์นญ
API->>API: riskScore ๊ณ์ฐ
API->>API: ALLOW / REVIEW / BLOCK ํ์
API->>DB: moderation_logs ์ ์ฅ
API->>Redis: ๊ฒ์ ๊ฒฐ๊ณผ ์บ์ฑ, TTL 5๋ถ
API-->>Client: decision, riskScore, matchedRules ๋ฐํ
end
ํฌํธํด๋ฆฌ์ค ๋ฌธ์์ ๋ฃ๊ธฐ ์ข์ ํต์ฌ ์บก์ฒ์ ๋๋ค.
erDiagram
MODERATION_RULES {
int id PK
string ruleName
string keyword
int score
string action
string category
boolean enabled
datetime createdAt
datetime updatedAt
}
MODERATION_LOGS {
int id PK
int userId
string title
string contentHash
int riskScore
string decision
string matchedRules
string reason
datetime createdAt
}
์ด์์ ์ฑ ๋ฃฐ์ ์ ์ฅํฉ๋๋ค.
| ํ๋ | ์ค๋ช |
|---|---|
| id | ๋ฃฐ ID |
| ruleName | ๋ฃฐ ์ด๋ฆ |
| keyword | ๊ฐ์ง ํค์๋ |
| score | ์ํ ์ ์ |
| action | ๊ธฐ๋ณธ ์ก์ ํํธ |
| category | ์ ์ฑ ์นดํ ๊ณ ๋ฆฌ |
| enabled | ๋ฃฐ ํ์ฑํ ์ฌ๋ถ |
| createdAt | ์์ฑ ์๊ฐ |
| updatedAt | ์์ ์๊ฐ |
๊ฒ์ ์์ฒญ์ ํ์ ๊ฒฐ๊ณผ๋ฅผ ์ ์ฅํฉ๋๋ค.
| ํ๋ | ์ค๋ช |
|---|---|
| id | ๋ก๊ทธ ID |
| userId | ์์ฑ์ ID |
| title | ๊ฒ์๊ธ ์ ๋ชฉ |
| contentHash | ์ฝํ ์ธ ํด์ |
| riskScore | ์ํ ์ ์ |
| decision | ์ต์ข ํ์ |
| matchedRules | ๋งค์นญ๋ ๋ฃฐ ์ด๋ฆ ๋ชฉ๋ก |
| reason | ํ์ ์ฌ์ |
| createdAt | ์์ฑ ์๊ฐ |
FastAPI ์๋ ๋ฌธ์๋ ์คํ ํ ์๋ ์ฃผ์์์ ํ์ธํ ์ ์์ต๋๋ค.
๊ฐ๋จํ ์ด์ ํ์ธ UI๋ ์คํ ํ http://localhost:8000/์์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
UI์ ๋ถํํ
์คํธ / ๊ด์ธก ์์ญ์์ ์์ฒญ ์, ๋์์ฑ, cached/unique ๋ชจ๋๋ฅผ ์ ํํด ๋ถํํ
์คํธ๋ฅผ ์คํํ ์ ์์ต๋๋ค. ์คํ ๊ฒฐ๊ณผ๋ก RPS, ํ๊ท ์ง์ฐ, p95 ์ง์ฐ, ์๋ฌ ์, RSS ๋ฉ๋ชจ๋ฆฌ, DB ์ปค๋ฅ์
ํ checked-out/overflow, Redis ping, ๋ณ๋ชฉ ํํธ๋ฅผ ํ์ธํ ์ ์์ต๋๋ค.
http://localhost:8000/docs
POST /api/moderations/check{
"userId": 1,
"title": "์์ดํฐ ์ธ๊ฒ ํ๋๋ค",
"content": "์ ์
๊ธํ๋ฉด ํ๋ฐฐ ๋ณด๋ด๋๋ ค์. ์นดํก ์ฃผ์ธ์.",
"price": 100000,
"category": "DIGITAL"
}{
"decision": "REVIEW",
"riskScore": 70,
"matchedRules": [
"PREPAYMENT_KEYWORD",
"EXTERNAL_CONTACT_KAKAO"
],
"reason": "์ด์์ ์ฑ
์ ๊ฒํ ๊ฐ ํ์ํ ํค์๋๊ฐ ๊ฐ์ง๋์์ต๋๋ค."
}| Method | Endpoint | ์ค๋ช |
|---|---|---|
| POST | /api/ops/rules |
์ด์์ ์ฑ ๋ฃฐ ๋ฑ๋ก |
| GET | /api/ops/rules |
์ด์์ ์ฑ ๋ฃฐ ๋ชฉ๋ก ์กฐํ |
| PATCH | /api/ops/rules/{id}/status |
์ด์์ ์ฑ ๋ฃฐ ํ์ฑํ/๋นํ์ฑํ |
GET /api/ops/moderation-logs?limit=50&offset=0๋์ผ ์ฝํ ์ธ ์ ๋ํ ๋ฐ๋ณต ๊ฒ์ ์์ฒญ์ Redis ์บ์๋ฅผ ํตํด DB ๋ฃฐ ์กฐํ์ ์ํ ์ ์ ๊ณ์ฐ์ ์๋ตํฉ๋๋ค.
| ํญ๋ชฉ | ๋ด์ฉ |
|---|---|
| Hash Source | title + content + price + category |
| Hash Algorithm | SHA-256 |
| Redis Key | moderation:content:{contentHash} |
| TTL | 5๋ถ |
| Cache Hit | ๋ฃฐ ๊ณ์ฐ๊ณผ DB ์กฐํ ์๋ต |
| Cache Miss | DB ๋ฃฐ ๊ธฐ๋ฐ ๊ฒ์ ํ Redis ์ ์ฅ |
moderation:content:3f1e9b3f2a2c9a...
Redis CLI ๋๋ RedisInsight์์ key๊ฐ ์ ์ฅ๋ ํ๋ฉด์ ์บก์ฒํฉ๋๋ค.
docker compose up --build์ฑ ์ปจํ ์ด๋ ์์ ์ Alembic migration์ ์ ์ฉํ๊ณ ์ด๊ธฐ seed rule์ ์ ์ฅํฉ๋๋ค.
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
pytestํ ์คํธ๋ SQLite์ fake Redis๋ฅผ ์ฌ์ฉํด ์ธ๋ถ ์๋น์ค ์์ด ์คํ๋ฉ๋๋ค.
| ํ ์คํธ | ๊ธฐ๋ ๊ฒฐ๊ณผ |
|---|---|
| ์ ์ ๊ฒ์๊ธ | ALLOW |
| ์ ์ ๊ธ ํฌํจ ๊ฒ์๊ธ | REVIEW |
| ์ ์ ๊ธ + ์นดํก + ๊ณ์ข ํฌํจ ๊ฒ์๊ธ | BLOCK ๋๋ ๊ธฐ์ค์ ๋ง๋ ๊ณ ์ํ ํ์ |
| ๋ถ๋ฒ ํค์๋ ํฌํจ ๊ฒ์๊ธ | BLOCK |
| ๋์ผ ์ฝํ ์ธ ์ฌ์์ฒญ | Redis ์บ์ ์ฌ์ฉ |
๊ฒ์ ๊ฒฐ๊ณผ๋ moderation_logs ํ
์ด๋ธ์ ์ ์ฅ๋ฉ๋๋ค.
์ด๋ฅผ ํตํด ์ด์์๋ ์ด๋ค ๊ฒ์๊ธ์ด ์ด๋ค ๋ฃฐ์ ์ํด ๊ฒ์๋์๋์ง ํ์ธํ ์ ์์ต๋๋ค.
์๋ ์์น๋ ์ค์ ์คํ ๊ฒฐ๊ณผ๋ฅผ ๋ฃ๋ ์์ญ์
๋๋ค.
์ค์ ์ธก์ ์ ์๋ ์์ ์์น๋ฅผ ๋ฃ์ง ์์ต๋๋ค.
| ๊ฒ์ฆ ํญ๋ชฉ | ๊ฒฐ๊ณผ |
|---|---|
| Docker Compose ์คํ | ์ฑ๊ณต |
| Swagger ์ ๊ทผ | ์ฑ๊ณต |
| ์ฝํ ์ธ ๊ฒ์ API | ์ฑ๊ณต |
| ์ด์์ ์ฑ ๋ฃฐ ๋ฑ๋ก/์กฐํ/์์ | ์ฑ๊ณต |
| ๊ฒ์ ๋ก๊ทธ ์ ์ฅ | ์ฑ๊ณต |
| Redis ์บ์ ์ ์ฅ | ์ฑ๊ณต |
| pytest ํต๊ณผ | ์ฑ๊ณต |
| ์บก์ฒ | ํ์ผ ๊ฒฝ๋ก |
|---|---|
| Swagger ๋ฌธ์ | docs/images/swagger-docs.png |
| ๊ฒ์ API ์๋ต | docs/images/moderation-check-response.png |
| ์ด์์ ์ฑ ๋ฃฐ ์กฐํ | docs/images/rules-list-response.png |
| ๊ฒ์ ๋ก๊ทธ API | docs/images/moderation-logs-response.png |
| PostgreSQL ๋ก๊ทธ ํ ์ด๋ธ | docs/images/moderation-logs-db.png |
| Redis ์บ์ ํค | docs/images/redis-cache-key.png |
| pytest ๊ฒฐ๊ณผ | docs/images/pytest-result.png |
| Docker ์คํ | docs/images/docker-compose-up.png |
| ๋น๊ทผ ์ด์๊ฐ๋ฐํ ์๊ตฌ | ํ๋ก์ ํธ ์ฐ๊ฒฐ |
|---|---|
| ์ด์ ์๋ํ | ์ด์์ ์ฑ ๋ฃฐ ๊ธฐ๋ฐ ์๋ ๊ฒ์ API |
| ์คํธ/์ฌ๊ธฐ/์ด๋ทฐ์ง ํ์ง | ์ํ ํค์๋ ๊ธฐ๋ฐ ์ ์ ๊ณ์ฐ |
| ๊ฑด๊ฐํ ์ฝํ ์ธ ๋๋ฌ | ALLOW, REVIEW, BLOCK ํ์ |
| ๋์ฉ๋ ํธ๋ํฝ ๊ณ ๋ ค | Redis ์บ์ฑ์ผ๋ก ๋์ผ ์ฝํ ์ธ ์ฌ๊ฒ์ ๋น์ฉ ๊ฐ์ |
| DB/์บ์ ์ดํด | PostgreSQL, Redis ํ์ฉ |
| AI ๊ด์ฌ ๋ฐ ํ์ฅ์ฑ | pgvector, AI ๋ณด์กฐ ํ๋จ ํ์ฅ ๊ตฌ์กฐ ์ ์ |
| ์ด์ ํ๋จ ๊ทผ๊ฑฐ | matchedRules, reason, moderation_logs ์ ์ฅ |
ํ์ฌ๋ ํค์๋ ๊ธฐ๋ฐ ๊ฒ์ ๋ฐฉ์์
๋๋ค.
์ถํ์๋ pgvector๋ฅผ ํ์ฉํด ๊ธฐ์กด ์ํ ๋ฌธ๊ตฌ์ ์ ์ฌํ ํํ๋ ํ์งํ ์ ์์ต๋๋ค.
์์:
| ๊ธฐ์กด ์ํ ๋ฌธ๊ตฌ | ์ฐํ ํํ |
|---|---|
| ์ ์ ๊ธํ๋ฉด ๋ณด๋ด๋๋ฆด๊ฒ์ | ๋จผ์ ๋ณด๋ด์ฃผ์๋ฉด ํ๋ฐฐ ์ ์ํ ๊ฒ์ |
| ์นดํก ์ฃผ์ธ์ | ใ ใ ์ฃผ์ธ์ |
| ๊ณ์ข๋ก ๋ณด๋ด์ฃผ์ธ์ | ใฑใ ๋ก ๋ณด๋ด์ฃผ์ธ์ |
๋ชจ๋ ๊ฒ์๊ธ์ AI๋ก ํ๋จํ๋ฉด ๋น์ฉ๊ณผ ์๋ต ์๊ฐ์ด ์ฆ๊ฐํ ์ ์์ต๋๋ค.
๋ฐ๋ผ์ REVIEW ํ์ ๊ฒ์๊ธ๋ง AI ๋ณด์กฐ ํ๋จ ๋์์ผ๋ก ๋๊ธฐ๋ ๋ฐฉ์์ผ๋ก ํ์ฅํ ์ ์์ต๋๋ค.
ALLOW โ ์ฆ์ ํต๊ณผ
REVIEW โ AI ๋ณด์กฐ ํ๋จ ๋๋ ์ด์์ ๊ฒ์
BLOCK โ ์ฐจ๋จ ๋๋ ๊ฐํ ๊ฒ์ ํ ๋ฑ๋ก
์ฌ์ฉ์ ์ ๊ณ ๊ฐ ๋ค์ด์ค๋ฉด ๊ธฐ์กด ๊ฒ์ ๋ก๊ทธ์ ์ฐ๊ฒฐํด ์ด์์ ๊ฒ์ ์ฐ์ ์์๋ฅผ ๋์ผ ์ ์์ต๋๋ค.
์ฌ์ฉ์ ์ ๊ณ
โ ๊ธฐ์กด moderation_log ์กฐํ
โ ์ํ ์ ์ ์ฌ๊ณ์ฐ
โ ์ด์์ ๊ฒ์ ํ ๋ฑ๋ก
๊ฒ์ API ์ฅ์ ๋ ๋น์ ์์ ์ธ BLOCK ๊ธ์ฆ ์ํฉ์ ์ด์ ์ฑ๋๋ก ์๋ฆด ์ ์์ต๋๋ค.
| ์กฐ๊ฑด | ์๋ฆผ |
|---|---|
| API ์คํจ์จ ์ฆ๊ฐ | ์ฅ์ ์๋ฆผ |
| p95 ์๋ต ์๊ฐ ์ฆ๊ฐ | ์ฑ๋ฅ ์ ํ ์๋ฆผ |
| BLOCK ํ์ ๊ธ์ฆ | ์ด์ ํจํด ์๋ฆผ |
์ด์์๊ฐ ์ง์ ๋ฃฐ์ ๋ฑ๋ก/์์ /๋นํ์ฑํํ ์ ์๋ ๊ด๋ฆฌ์ ํ๋ฉด์ผ๋ก ํ์ฅํ ์ ์์ต๋๋ค.
curl -X POST http://localhost:8000/api/moderations/check \
-H "Content-Type: application/json" \
-d '{
"userId": 1,
"title": "์์ดํฐ ์ธ๊ฒ ํ๋๋ค",
"content": "์ ์
๊ธํ๋ฉด ํ๋ฐฐ ๋ณด๋ด๋๋ ค์. ์นดํก ์ฃผ์ธ์.",
"price": 100000,
"category": "DIGITAL"
}'curl http://localhost:8000/api/ops/rulescurl -X POST http://localhost:8000/api/ops/rules \
-H "Content-Type: application/json" \
-d '{
"ruleName": "WIRE_TRANSFER_KEYWORD",
"keyword": "์ก๊ธ",
"score": 30,
"action": "REVIEW",
"category": "FRAUD",
"enabled": true
}'curl -X PATCH http://localhost:8000/api/ops/rules/1/status \
-H "Content-Type: application/json" \
-d '{"enabled": false}'curl "http://localhost:8000/api/ops/moderation-logs?limit=20&offset=0"์ด ํ๋ก์ ํธ๋ ๋จ์ํ ํค์๋ ํํฐ๋ง์ด ์๋๋ผ, ์ด์์ ์ฑ ์ ๋ฐ์ดํฐํํ๊ณ ์๋ํํ๋ ๋ฐฑ์๋ ๊ตฌ์กฐ๋ฅผ ๊ตฌํํ ํ๋ก์ ํธ์ ๋๋ค.
์ด์์๋ ๋ฃฐ์ ์ง์ ์ถ๊ฐํ๊ฑฐ๋ ๋นํ์ฑํํ ์ ์๊ณ , ๊ฒ์ ๊ฒฐ๊ณผ๋ ๋ก๊ทธ๋ก ์ ์ฅ๋์ด ์ฌํ ๋ถ์์ด ๊ฐ๋ฅํฉ๋๋ค. ๋ํ Redis ์บ์ฑ์ ํตํด ๋ฐ๋ณต ์์ฒญ ๋น์ฉ์ ์ค์์ผ๋ฉฐ, ์ถํ pgvector ๊ธฐ๋ฐ ์ ์ฌ ๋ฌธ๊ตฌ ํ์ง, AI ๋ณด์กฐ ํ๋จ, ์ ๊ณ ์์คํ , ์ฅ์ ์๋ฆผ์ผ๋ก ํ์ฅํ ์ ์์ต๋๋ค.















