쇼핑몰 리뷰, 누가 답해야 할지 자동으로 나누기 — n8n에서 Jev 노드로 점수 매기고 분기하는 6단계
이 글과 연결된 글 보기
드래그로 이동 · 휠/두 손가락으로 확대 · 방향키로 글 선택 · 0으로 맞춤. 실선: 본문 링크, 점선: 시리즈·주제의 대표 연결.표시된 글 24편 목록
리뷰가 하루 몇 개일 때는 직접 읽고 "이건 배송팀, 이건 제품팀" 하고 넘기면 됩니다. 그런데 이 일은 매번 같은 기준으로 고르는 일이라, 사람이 할 때는 지치고 일반 AI에게 맡기면 답이 문장으로 나와서 다시 해석해야 합니다.
이 글은 n8n에 TypeSafe AI 커뮤니티 노드를 붙여서, 리뷰마다 만족도 점수와 판매자 답변이 필요한 확률을 매기고, 그 리뷰를 칭찬·배송 문제·품질 문제 담당자에게 바로 나눠 보내는 워크플로우를 만드는 과정입니다. 2026년 10월 21일에 셀프호스팅 n8n 2.44.4에서 실제로 만들고 돌려 본 설정과 결과만 담았습니다.

이 글은 이런 분께 필요합니다
- 이런 분: 스마트스토어나 쇼핑몰 리뷰·문의를 사람이 읽고 담당자에게 넘기고 있는 분. n8n에서 노드 몇 개를 연결해 본 적은 있는 분.
- 필요한 것: 커뮤니티 노드를 설치할 수 있는 n8n(이 글은 셀프호스팅 2.44.4 기준), TypeSafe 콘솔에서 발급한 API 키.
- 필요한 시간: 30분 정도. 아래 JSON을 가져오면 크리덴셜 연결만 하고 바로 실행할 수 있습니다.
- 이 글에서 하지 않는 것: 리뷰를 실제로 수집하거나, Slack·메일로 보내는 부분은 넣지 않았습니다. 분류 정확도 검증도 하지 않았습니다. 리뷰 4건은 직접 쓴 예시 리뷰입니다.
Jev가 어떤 모델인지 처음이라면 TypeSafe Jev 입문을 먼저 보시면 좋습니다. 한 줄로 줄이면, 글을 써 주는 대신 내가 정한 선택지 중 하나를 고르거나 확률·점수를 돌려주는 모델입니다. 그래서 결과를 n8n 분기에 바로 꽂을 수 있습니다.
완성하면 이렇게 동작합니다
| 단계 | 노드 | 하는 일 |
|---|---|---|
| 1 | 실행 버튼 (Manual Trigger) | 손으로 실행 |
| 2 | 샘플 리뷰 4건 (Code) | 예시 리뷰 4개를 만듦 |
| 3 | Jev 평가 (TypeSafe AI · Evaluate) | 리뷰마다 만족도 점수(Score)와 답변 필요 확률(Noul)을 붙임 |
| 4 | Jev 라우팅 (TypeSafe AI · Route) | 칭찬 / 배송 문제 / 품질 문제 중 하나로 보내고, 확신이 낮으면 Fallback으로 보냄 |
| 5 | 분기별 Set 4개 | 갈래마다 "다음 할 일"과 "담당"을 붙임 |
워크플로우 파일은 여기서 받을 수 있습니다: jev-review-routing.json. 크리덴셜 정보는 빼 두었으니, 가져온 뒤 Step 2의 크리덴셜만 연결하면 됩니다.
Step 1. TypeSafe AI 커뮤니티 노드를 설치합니다
TypeSafe AI 노드는 n8n 기본 노드가 아니라 npm으로 배포되는 커뮤니티 노드입니다. 셀프호스팅 n8n에서는 서버에 접속하지 않고 화면에서 설치할 수 있습니다.
- 왼쪽 아래 Settings를 열고 Community nodes로 들어갑니다.
- Install a community node를 누릅니다.
- 패키지 이름에
@typesafe-ai/n8n-nodes-typesafe-ai를 넣습니다. - I understand the risks of installing unverified code에 체크해야 Install 버튼이 켜집니다. 누르면 20초 남짓 걸립니다.
설치가 끝나면 노드 패널에서 "TypeSafe"로 검색했을 때 TypeSafe AI가 나오고, 동작은 Evaluate와 Route 두 가지입니다. 이 글을 쓸 때 설치된 버전은 0.9.0입니다.
Step 2. TypeSafe AI 크리덴셜을 연결합니다
- TypeSafe 콘솔(console.typesafe.ai)에서 API 키를 발급받습니다.
- 캔버스에 TypeSafe AI 노드를 하나 올리고 Credential 칸에서 새 크리덴셜을 만듭니다. 종류는 TypeSafe AI API입니다.
- API Key를 붙여 넣고 저장합니다.
크리덴셜이 연결되기 전에는 Model 목록이 비어 있습니다. 연결되면 jev-latest를 고를 수 있고, 이번 실행에서 실제로 응답한 모델은 jev-1.13.0이었습니다.
Step 3. 리뷰 데이터를 준비합니다
연습용으로 Code 노드에서 리뷰 4개를 만듭니다. 실제로 쓸 때는 이 노드 자리에 리뷰를 가져오는 노드(구글시트, 웹훅, 스마트스토어 API 등)를 넣으면 됩니다. 뒤 노드가 쓰는 필드는 product와 review 두 개뿐입니다.
// 스마트스토어 리뷰 샘플 4건 (실제 운영에선 리뷰 수집 노드로 교체)
return [
{ review_id: "R-001", product: "NFC 성경 키링", review: "키링 디자인 너무 예뻐요! 선물했는데 친구가 엄청 좋아했어요. 재구매 의사 있습니다." },
{ review_id: "R-002", product: "3D 프린팅 피규어", review: "주문한 지 일주일이 넘었는데 아직도 배송 준비중이에요. 언제 받을 수 있나요?" },
{ review_id: "R-003", product: "NFC 성경 키링", review: "NFC 태그가 폰에 인식이 안 돼요. 몇 번을 대봐도 반응이 없네요. 불량인 것 같아요." },
{ review_id: "R-004", product: "3D 프린팅 피규어", review: "그냥 그래요. 사진이랑 색이 좀 다른 것 같기도 하고요." }
].map(json => ({ json }));
네 번째 리뷰는 일부러 애매하게 썼습니다. 불만인지 아닌지, 품질 문제인지 아닌지 사람도 잠깐 고민하게 되는 리뷰입니다.
Step 4. Evaluate로 만족도와 답변 필요 여부를 매깁니다
TypeSafe AI 노드를 하나 더 올리고 아래처럼 설정합니다.
| 설정 | 값 |
|---|---|
| Operation | Evaluate |
| Model | From list → jev-latest |
| State Format | Text |
| State | 상품: {{ $json.product }} 줄바꿈 리뷰: {{ $json.review }} (Expression) |
| Questions Format | Using Fields Below |
State는 Jev가 읽을 내용입니다. Input Item을 고르면 들어온 JSON 전체를 보내는데, 리뷰 ID처럼 판단에 필요 없는 값까지 들어가서 여기서는 Text로 필요한 두 줄만 보냈습니다.
Add Question으로 질문 두 개를 넣습니다.
| 질문 ID | Question Type | Instructions | 추가 설정 |
|---|---|---|---|
satisfaction | Score | 이 리뷰를 쓴 고객은 얼마나 만족했나요? | Levels 5개: 매우 불만족 / 불만족 / 보통 / 만족 / 매우 만족 |
needs_reply | Noul (Yes/No) | 판매자가 이 리뷰에 직접 답변하거나 조치해야 하나요? | True Means: 판매자 답변/조치 필요 · False Means: 감사 인사 정도면 충분 |

결과는 리뷰 항목마다 answers 아래에 질문 ID로 붙습니다. Score는 Levels를 위에서부터 0, 1, 2, 3, 4로 본 점수에 확신도(confidence)가 함께 오고, Noul은 "예"일 확률 하나가 옵니다.
"answers": {
"satisfaction": { "score": 0.8, "confidence": 0.83 },
"needs_reply": { "noul": 0.93 }
}
위 값은 배송 지연 리뷰(R-002)의 실제 결과입니다. 점수는 정수만 나오는 게 아니라 0.8, 1.49처럼 레벨 사이 값도 나옵니다.
Step 5. Route로 담당자별로 나눕니다
세 번째 TypeSafe AI 노드는 Route로 바꿉니다. Route는 질문 하나에 대한 답으로 출력 자체를 여러 갈래로 나누는 동작이라, 뒤에 IF나 Switch 노드를 따로 둘 필요가 없습니다.
| 설정 | 값 |
|---|---|
| Operation | Route |
| Model | jev-latest |
| State Format / State | Step 4와 같음 (상품·리뷰 두 줄) |
| Question Type | Choice |
| Instructions | 이 리뷰를 어느 담당자에게 보내야 하나요? |
| Routes | praise: 칭찬·만족 리뷰. 감사 답글만 달면 됨 / shipping_issue: 배송 지연·누락·파손 등 배송 문제 / quality_issue: 제품 불량·작동 안 됨·사진과 다름 등 품질 문제 |
| Confidence Handling | Route to Separate Fallback Output |
| Confidence Threshold | 0.7 |
Routes에 적은 Name이 그대로 노드의 출력 이름이 되고, Description은 Jev가 고를 때 보는 기준입니다. Confidence Handling을 Route to Separate Fallback Output으로 바꾸면 맨 아래에 Fallback 출력이 하나 더 생기고, 확신도가 기준값(여기서는 0.7)보다 낮은 리뷰는 그쪽으로 갑니다. 기본값인 Always Route는 확신이 낮아도 가장 가능성 높은 갈래로 보냅니다.

Options의 Include Other Input Fields는 켜진 상태가 기본이라, Step 4에서 붙인 answers가 Route를 지나도 그대로 남습니다. 그래서 분기 뒤에서도 만족도 점수와 답변 필요 확률을 같이 쓸 수 있습니다.
Step 6. 갈래마다 할 일을 붙이고 실행합니다
Route의 출력 4개(praise, shipping_issue, quality_issue, Fallback)에 Set 노드를 하나씩 연결하고, next_action과 owner 필드를 넣었습니다.
| 출력 | Set 노드 이름 | next_action | owner |
|---|---|---|---|
| praise | 칭찬 → 감사 답글 | 감사 답글 작성 | 마케팅 |
| shipping_issue | 배송 문제 → CS | 배송 조회 후 고객 안내 | CS |
| quality_issue | 품질 문제 → 제품팀 | 교환/환불 및 불량 원인 확인 | 제품팀 |
| Fallback | 애매함 → 사람 검토 | 확신도 낮음: 사람이 직접 읽고 분류 | 대표 |
실제로 쓸 때는 이 Set 노드 자리에 Slack 메시지, 구글시트 행 추가, 답글 초안 작성 같은 노드를 붙이면 됩니다.
실행은 캔버스 아래쪽 주황색 Execute 버튼으로 합니다.
실행 결과
2026년 10월 21일 실행 기록(#1283) 그대로입니다. 실행 기록을 노드 순서대로 다시 재생한 영상부터 보면 흐름이 한눈에 들어옵니다.
| 리뷰 | 만족도 점수 (0~4) | 답변 필요 확률 | 간 곳 (확신도) |
|---|---|---|---|
| R-001 키링 예뻐요, 재구매 의사 | 4 (확신도 1) | 0.20 | praise (1) |
| R-002 일주일째 배송 준비중 | 0.8 (0.83) | 0.93 | shipping_issue (1) |
| R-003 NFC 인식 안 됨, 불량 같음 | 0.28 (0.77) | 0.88 | quality_issue (1) |
| R-004 그냥 그래요, 색이 좀 다름 | 1.49 (0.59) | 0.47 | quality_issue (1) |
| 노드 | 걸린 시간 |
|---|---|
| Jev 평가 (리뷰 4건, 질문 2개) | 1,218ms |
| Jev 라우팅 (리뷰 4건) | 1,050ms |
| 워크플로우 전체 | 약 5.2초 |
결과에서 볼 만한 점이 두 가지 있습니다.
- 애매한 리뷰는 Evaluate 쪽 숫자에서 드러났습니다. R-004는 만족도 확신도가 0.59로 네 리뷰 중 가장 낮았고, 답변 필요 확률도 0.47로 딱 중간이었습니다.
- 그런데 Route 확신도는 1이었습니다. "사진이랑 색이 다름"을 Routes 설명의 "사진과 다름"에 그대로 맞췄기 때문으로 보입니다. 그래서 이번 실행에서 Fallback으로 간 리뷰는 0건이었습니다. Fallback만 믿기보다, Evaluate의 확신도나 답변 필요 확률이 애매한 구간(예: 0.4~0.6)인 리뷰를 한 번 더 사람이 보게 하는 조건을 두는 편이 안전합니다.
전체 5.2초 중 2.8초는 예시 리뷰를 만드는 Code 노드였습니다. 이 서버는 Code 노드를 별도 runner 컨테이너에서 실행해서, 그 시작 시간이 들어간 것으로 보입니다. Jev 호출 두 번은 합쳐서 2.3초 정도였습니다.
자주 막히는 곳
| 증상 | 원인 | 해결 |
|---|---|---|
| Model 목록이 비어 있음 | 크리덴셜이 연결되지 않음 | Step 2대로 TypeSafe AI API 크리덴셜을 먼저 연결 |
실행하면 At least 1 field is required | Evaluate 노드의 Questions가 비어 있음. 에디터에 JSON을 붙여 넣어 가져왔을 때 질문 목록이 빈 채로 들어온 적이 있었습니다 | 노드를 열어 Questions가 들어 있는지 확인하고, 비어 있으면 Add Question으로 다시 채우기 |
| 실행했는데 첫 노드만 초록색 | 트리거 노드 위에 뜨는 실행 버튼을 누르면 그 노드까지만 실행됨 | 캔버스 아래쪽 주황색 Execute 버튼으로 전체 실행 |
| Choice 질문인데 Noul 결과가 나옴 | Add Question의 기본 Question Type이 Noul (Yes/No) | 질문을 추가한 뒤 Question Type을 Choice나 Score로 바꾸기 |
| Fallback으로 아무것도 안 감 | Route 확신도가 기준값보다 높음 (이번 실행은 4건 모두 1) | Confidence Threshold를 올리거나, Evaluate 확신도로 사람 검토 조건을 따로 두기 |
한계
- 리뷰 4건은 직접 쓴 예시라서, 이 결과로 분류 정확도를 말할 수는 없습니다. 실제 카페 리뷰 50건을 정답과 비교해 본 결과는 댓글·카페 리뷰·채용공고·실종자 후보 220건 실험에 따로 정리했습니다.
- 커뮤니티 노드 설치는 셀프호스팅 n8n에서 확인했습니다. n8n Cloud에서 같은 패키지를 설치할 수 있는지는 이 글에서 확인하지 않았습니다.
- TypeSafe AI 노드는 n8n이 검증한(Verified) 노드가 아닙니다. 설치할 때 n8n이 경고하는 것도 이 때문이니, 여러 사람이 같이 쓰는 인스턴스라면 관리자와 먼저 상의하세요.
다음 단계
- Step 3의 Code 노드를 실제 리뷰가 쌓이는 곳(구글시트, 웹훅)으로 바꿔 보세요.
- Set 노드 대신 Slack이나 메일 노드를 붙이면, 담당자에게 바로 알림이 갑니다.
- Jev를 어떤 일에 쓰면 좋고 어떤 일에는 안 맞는지는 Jev 활용 사례 37개에 정리해 두었습니다.
