사줘
경력근거: 고객이 상품 URL만 입력하면 AI가 상품 정보를 자동 분석하고 배송비, 관세, 수수료까지 한 번에 계산
※ 실제 산출물이 아닌 AI 예측 시안입니다.
사줘는 한국·일본·미국 세 나라를 잇는 크로스보더 커머스라 같은 상품이라도 도착 국가에 따라 관세 기준과 면세 한도, 통화 환산이 달라지고, 일본우편이 제1투자자로 참여한 물류 구조 위에서 중량 구간별 배송비가 결정됩니다. 상품 페이지 양식이 나라마다 제각각인 상태에서 최종 결제금액을 한 번에 확정해야 하는 문제는 사줘의 3개국 서비스 맥락에서 실제로 나옵니다. 이 포트폴리오는 비정형 페이지를 스키마로 강제해 뽑고 금액을 규칙으로 계산하며 실패를 폴백으로 메우는 기술을 보여주며, 관세 실무나 국제물류 요율 협상 같은 도메인 전문성은 주장하지 않습니다. 모르는 깊이는 면접에서 모른다고 말하는 편이 낫습니다.
상품 주소만 넣으면 상품 정보가 자동으로 분석되고 배송비·관세·수수료까지 한 번에 계산되는 흐름이 제품의 핵심입니다.
평가 셋과 구조화 출력, 폴백 설계로 제품 품질을 평가하고 개선해 본 경험을 우대사항으로 명시합니다.
프론트엔드부터 백엔드까지 하나의 기능을 끝까지 구현하고 배포하는 완결 경험을 요구합니다.
사줘가 한국·일본·미국을 잇는 크로스보더 커머스에서 상품 주소 하나로 구매를 끝내는 경험을 만드는 맥락에서, 해외 상품 페이지 원문을 받아 상품명·가격·통화·중량·카테고리를 구조화 필드로 뽑고 배송비·관세·수수료를 규칙으로 계산해 최종 결제금액과 항목별 근거를 보여주는 관리자 페이지입니다. 상품 페이지와 요율표는 실 데이터 대신 더미를 가정합니다.
해외 상품 주소를 받을 때마다 상품 정보를 눈으로 옮겨 적고 배송비와 관세를 따로 계산기로 두드리다 통화 단위나 중량 표기에서 자꾸 틀리던 크로스보더 커머스 담당자가, 주소 하나를 넣으면 최종 결제금액과 그 근거를 한 화면에서 받아보고 싶은 사람입니다.
상품 페이지에서 뽑아야 할 필드를 스키마로 강제하고 배송비·관세·수수료를 요율 규칙으로 두면, 페이지 양식이 제각각이어도 최종 결제금액과 항목별 근거를 일관되게 낼 수 있다는 가정입니다.
해외 상품 페이지 더미를 넣으면 상품명·가격·통화·중량·카테고리를 구조화 필드로 뽑고, 중량 구간 배송비와 카테고리별 관세율, 수수료를 규칙으로 계산해 최종 결제금액과 항목별 근거를 보여주는 화면이 도는 완결품입니다. 추출이 실패하거나 값이 비면 부피중량 추정과 기본 세율 같은 폴백을 쓰고 그 사실을 화면에 표시합니다.
1주차 추출 결과 위에 정답을 붙인 평가 셋을 얹어 필드별 정확도와 폴백 발동률을 재고, 어긋난 페이지 유형을 모아 추출 프롬프트와 폴백 규칙을 고친 근거를 보여줍니다.
2주차 평가 셋 위에 일본·미국 도착 국가별 관세 기준과 면세 한도, 통화 환산 규칙을 갈아끼워, 같은 상품 페이지가 국가별로 다른 최종 결제금액을 내는 비교 화면을 완성합니다.
해외 상품 페이지 더미를 넣으면 상품 정보 추출부터 최종 결제금액과 항목별 근거까지 한 화면에 나오는 과정을 시연합니다.
금액 계산이 요율표대로 떨어지는지 항목별로 대조해 보여주되, 요율표와 정답을 작성자가 만든 합성 기준이라 성능 검증이 아니라 데모 조건 동작입니다.
중량 결측·통화 표기 흔들림·미등록 카테고리·가격 0원 같은 하드 케이스 30종을 넣어도 콘솔이 멈추지 않고 폴백을 표시하며 금액을 내는 강건성을 보여줍니다.
위 수치는 더미데이터 자가채점이며, 실제 추출 정확도와 금액 일치율은 사줘의 실 상품 페이지와 실 요율표, 실 운영 담당자가 있어야 측정 가능합니다. 이 포트폴리오는 그 검증을 바로 돌릴 수 있는 상태까지 만듭니다.
수치는 합성 데이터 자가채점이라 성능 증명이 아니므로, 면접에서는 데모 동작과 실검증 준비 상태로 솔직히 설명합니다.
정답을 작성자가 만들었으니 잘 맞는 게 당연하므로, 중량 결측·통화 표기 흔들림·미등록 카테고리·극단 가격 같은 경계 케이스를 더미에 일부러 섞어 쉬운 문제만 푸는 함정을 피합니다.
이 포트폴리오는 비정형 페이지를 스키마로 강제해 뽑고 금액을 규칙으로 계산하며 폴백을 남기는 기술을 보여주며, 관세 실무나 국제물류 요율 같은 도메인 전문성은 주장하지 않습니다. 금액은 규칙이 계산하고 LLM은 추출만 맡습니다.
실제 도입 때는 상품 페이지 양식과 국가별 관세 기준이 수시로 바뀌므로, 요율표 갱신과 페이지 양식 변화 감지를 도입 단계 과제로 둡니다.
① 인라인 샘플 · ② seed.json 다운로드 · ③ 증강 프롬프트. 세 층 모두 동일한 schema 에서 파생.
해외 상품 페이지에서 뽑은 원문 값으로, 중량 결측·통화 표기 흔들림·미등록 카테고리·가격 극단값 같은 하드 케이스를 일부러 섞어 추출과 폴백이 제대로 도는지 확인합니다.
| page_id | source_country | title_raw | price_raw | currency | weight_g | box_cm | category_raw | category_id |
|---|---|---|---|---|---|---|---|---|
| P-001 | JP | ミズノ ランニングシューズ WAVE-27 | 12,800円 | JPY | 620 | 32x20x12 | シューズ | SHOES |
| P-002 | US | Anker PowerCore 20000mAh | $49.99 | USD | 430 | 18x10x4 | Portable Charger | BATTERY |
| P-003 | JP | 資生堂 化粧水 200ml | 3,300円 | JPY | — | 8x8x18 | スキンケア | COSMETIC |
| P-004 | US | Sony WH-1000XM5 Headphones | 398.00 USD | USD | 250 | — | Headphones | ELECTRONICS |
| P-005 | JP | ユニクロ ダウンジャケット L | 9,900 | — | 780 | 40x30x15 | アウター | APPAREL |
다음 JSON Schema 에 맞는 해외 상품 페이지 행을 더 생성하세요: {"type":"object","properties":{"page_id":{"type":"string"},"source_country":{"type":"string","enum":["JP","US","KR"]},"title_raw":{"type":"string"},"price_raw":{"type":"string"},"currency":{"type":["string","null"],"enum":["JPY","USD","KRW",null]},"weight_g":{"type":["number","null"]},"box_cm":{"type":["string","null"]},"category_raw":{"type":"string"},"category_id":{"type":["string","null"]}},"required":["page_id","source_country","title_raw","price_raw","category_raw"]} 쉬운 데이터만 만들지 말 것. 다음 하드 케이스를 의도적으로 섞어라: weight_g 가 null 이라 부피중량 추정 폴백이 필요한 중량 결측, box_cm 도 null 이라 폴백조차 못 쓰는 이중 결측, currency 가 null 이거나 price_raw 에 통화 기호가 없어 통화를 추정해야 하는 경우, price_raw 가 숫자가 아닌 문구(가격은 장바구니에서 확인)인 추출 불가, weight_g 가 0 이거나 45000 처럼 극단인 경계값, price_raw 가 0 원인 극단 최소값, category_id 가 null 이라 관세율 테이블에 매핑 안 된 미등록 카테고리, title_raw 가 같은 상품의 표기 흔들림(WAVE-27 을 WAVE27 로)이라 정규화가 필요한 경우. 국가와 카테고리를 골고루 섞고, 형식 깨뜨리기 시도(스키마 타입 위반) 3건은 데이터가 아니라 별도 목록으로 표시하세요.{"type":"object","properties":{"page_id":{"type":"string"},"source_country":{"type":"string","enum":["JP","US","KR"]},"title_raw":{"type":"string"},"price_raw":{"type":"string"},"currency":{"type":["string","null"],"enum":["JPY","USD","KRW",null]},"weight_g":{"type":["number","null"]},"box_cm":{"type":["string","null"]},"category_raw":{"type":"string"},"category_id":{"type":["string","null"]}},"required":["page_id","source_country","title_raw","price_raw","category_raw"]}| TypeScript | 추출 스키마와 요율 규칙, 화면을 하나의 타입 정의로 묶어 필드 이름이 어긋나지 않게 합니다. |
| React | 상품 정보와 금액 항목, 폴백 표시를 한 화면에서 확인하는 견적 콘솔을 구현합니다. |
| NestJS | 상품 페이지 추출과 금액 계산을 나눈 견적 API를 구현하고 기본 배포로 바로 돌게 합니다. |
| LLM API(Claude) | 비정형 상품 페이지에서 상품명·가격·통화·중량·카테고리를 구조화 필드로 뽑고, 금액 계산은 규칙이 합니다. |
| JSON Schema | 추출 결과와 견적 결과의 모양을 강제해 필드 누락을 막고 더미 증강에 씁니다. |
| 구조화 출력·폴백 설계 | 추출 실패와 결측을 부피중량 추정·기본 세율 폴백으로 메우고 그 사실을 결과에 남깁니다. |
| 평가 셋 | 정답을 붙인 상품 페이지 표본으로 필드별 추출 정확도와 폴백 발동률을 잽니다. |
✓ pass → 그대로 멈춰도 완결입니다. 더 키우려면 2주차에서 정답을 붙인 평가 셋으로 추출 정확도를 잽니다.
✓ pass → 여기서 멈춰도 검증된 완결입니다. 더 키우려면 3주차에서 도착 국가별 요율을 갈아끼워 같은 엔진이 도는지 봅니다.
상품 페이지 한 건을 받아 최종 결제금액과 항목별 근거, 폴백 사용 여부를 함께 내보내, 근거 없는 금액이 그대로 결제로 넘어가지 않게 합니다.
{"type":"object","properties":{"page_id":{"type":"string"},"total_krw":{"type":["number","null"]},"breakdown":{"type":"array","items":{"type":"object","properties":{"item":{"type":"string","enum":["product","shipping","duty","fee"]},"amount_krw":{"type":["number","null"]},"basis":{"type":"string"}},"required":["item","amount_krw","basis"]}},"fallbacks":{"type":"array","items":{"type":"string","enum":["volumetric_weight","default_duty_rate","currency_guess","price_unparsed"]}},"hedge":{"type":["string","null"]}},"required":["page_id","total_krw","breakdown","fallbacks"]}[
{
"page_id": "P-001",
"total_krw": 148600,
"breakdown": [
{
"item": "product",
"amount_krw": 118400,
"basis": "12,800엔을 환율 9.25로 환산했습니다."
},
{
"item": "shipping",
"amount_krw": 12000,
"basis": "실중량 620g이 500~1000g 구간이라 12,000원입니다."
},
{
"item": "duty",
"amount_krw": 15400,
"basis": "SHOES 카테고리 관세율 13%를 상품가에 적용했습니다."
},
{
"item": "fee",
"amount_krw": 2800,
"basis": "수수료 규칙 정액 2,800원입니다."
}
],
"fallbacks": [],
"hedge": null
},
{
"page_id": "P-003",
"total_krw": 42300,
"breakdown": [
{
"item": "product",
"amount_krw": 30525,
"basis": "3,300엔을 환율 9.25로 환산했습니다."
},
{
"item": "shipping",
"amount_krw": 9000,
"basis": "실중량이 비어 박스 8x8x18에서 부피중량 288g을 추정해 0~500g 구간을 적용했습니다."
},
{
"item": "duty",
"amount_krw": 0,
"basis": "COSMETIC 카테고리가 면세 한도 아래라 관세가 0원입니다."
},
{
"item": "fee",
"amount_krw": 2800,
"basis": "수수료 규칙 정액 2,800원입니다."
}
],
"fallbacks": [
"volumetric_weight"
],
"hedge": "중량이 비어 부피중량으로 배송비를 추정했으므로 실제 계근 결과와 달라질 수 있습니다(합성 기준 추정)."
},
{
"page_id": "P-006",
"total_krw": 36800,
"breakdown": [
{
"item": "product",
"amount_krw": 28900,
"basis": "21.50달러를 환율 1344로 환산했습니다."
},
{
"item": "shipping",
"amount_krw": 9000,
"basis": "실중량 310g이 0~500g 구간이라 9,000원입니다."
},
{
"item": "duty",
"amount_krw": 0,
"basis": "카테고리가 매핑되지 않아 기본 세율 0%를 적용했습니다."
},
{
"item": "fee",
"amount_krw": 2800,
"basis": "수수료 규칙 정액 2,800원입니다."
}
],
"fallbacks": [
"default_duty_rate"
],
"hedge": "Supplement 표기가 관세율 테이블에 없어 기본 세율로 계산했으므로 실제 통관 세율과 다를 수 있습니다(합성 기준 추정)."
},
{
"page_id": "P-011",
"total_krw": null,
"breakdown": [
{
"item": "product",
"amount_krw": null,
"basis": "가격이 숫자가 아닌 문구라 금액을 뽑지 못했습니다."
},
{
"item": "shipping",
"amount_krw": 9000,
"basis": "실중량 90g이 0~500g 구간이라 9,000원입니다."
},
{
"item": "duty",
"amount_krw": null,
"basis": "상품가가 없어 관세를 계산하지 못했습니다."
},
{
"item": "fee",
"amount_krw": 2800,
"basis": "수수료 규칙 정액 2,800원입니다."
}
],
"fallbacks": [
"price_unparsed"
],
"hedge": "상품가를 뽑지 못해 최종 금액을 비워 두고 사람 확인이 필요하다고 표시했습니다."
}
][자동 검증] 1. breakdown 의 각 amount_krw 가 요율표대로 계산되는지 대조합니다. 배송비는 중량 구간표, 관세는 카테고리별 세율, 수수료는 정액 규칙과 맞아야 합니다. 2. total_krw 가 breakdown 합계와 같은지 확인하고, 항목 중 하나라도 null 이면 total_krw 도 null 인지 확인해 빈 금액이 0원으로 둔갑하지 않게 합니다. 3. basis 문장에 실제 입력 값(중량·통화·카테고리)이 인용됐는지 확인해, 근거 없는 금액을 거릅니다. 4. weight_g 가 null 인데 fallbacks 에 volumetric_weight 가 없으면 폴백 누락으로 표시합니다. [수동 검증] 1. 카테고리별 관세율과 면세 한도가 실제 통관 기준과 맞는지 운영 담당자가 확인합니다. 2. 중량과 부피중량 중 무엇을 적용할지 겹치는 구간의 우선순위를 담당자가 정합니다.
포트폴리오가 “무엇을 만들지”라면, 시나리오 테스트는 “현장에서 어떻게 판단·소통할지” 입니다. 실제 이 채용공고 맥락의 대본을 읽고 무엇을 물어야 할지 직접 써봅니다.