위홈
경력근거: 자연어 질문을 실제 숙소, 가격, 지역과 예약 가능 데이터에 연결합니다.
※ 실제 산출물이 아닌 AI 예측 시안입니다.
위홈은 이 자리에 게스트를 위한 AI Travel Agent 를 맡기며 자연어 질문을 실제 숙소, 가격, 지역과 예약 가능 데이터에 연결하라고 적었고, 같은 공고에서 잘못된 도구 실행을 줄이는 Guardrail 과 사람의 승인이 들어가는 Human-in-the-Loop 를 요구합니다. 공고가 Agent 가 다룰 데이터로 숙소·예약 옆에 정책을 꼽았듯, 위홈의 추천은 날짜와 가격이 맞아도 그 게스트가 그 숙소를 이용할 수 있어야 예약이 됩니다. 이 포트폴리오는 Agent 추천을 예약 달력과 숙소 정보로 되짚는 판정 규칙과, 그 규칙을 Agent 가 추천 전에 부르는 MCP 도구로 옮기는 구성을 보여줍니다. 공유숙박 법령 해석이나 숙박업 허가 실무 전문성은 주장하지 않습니다.
공고는 AI Travel Agent 가 여행 목적·일정·인원·예산을 이해해 숙소를 추천하고, 그 질문을 실제 숙소·가격·예약 가능 데이터에 연결하라고 적었습니다. Agent 가 내놓은 추천을 예약 달력과 숙소 정보로 되짚어 날짜·정원·가격이 맞는지 보는 화면은 그 연결이 맞게 됐는지를 사람이 확인하는 자리입니다.
같은 공고가 잘못된 도구 실행을 줄이는 Guardrail 과 중요한 업무에 사람의 승인이 들어가는 Human-in-the-Loop 를 요구합니다. 추천을 게스트에게 내보내기 전에 판정 규칙을 한 번 더 통과시키고, 3주차 정정 안내 초안은 CS 담당자가 승인해야 복사되게 하는 구성이 여기에 닿습니다.
숙소·예약·정책 데이터를 Agent 가 안전하게 쓰도록 연결하는 일과 Tool Calling·MCP 이해를 자격요건으로 둡니다. 1주차 판정 함수를 2주차에 MCP 도구로 감싸, 시험용 Agent 가 추천을 내기 전에 그 도구를 불러 걸린 숙소를 빼고 다시 고르게 하는 단계가 여기에 닿습니다.
위홈은 내국인과 외국인 게스트가 서울·부산 공유숙박을 예약하는 플랫폼이고, AI Travel Agent 는 게스트의 자연어 문의를 받아 숙소를 추천합니다. 이 화면은 Agent 가 내놓은 추천 한 건마다 그 대화의 인원과 내·외국인 구분, 숙소의 정원과 내국인 숙박 허가 여부, 숙박일별 달력 상태와 가격을 겹쳐 다섯 판정 중 하나를 붙입니다. 체크인부터 체크아웃 전날까지 숙박일을 펼쳐 예약됨·막힘인 날을 찾고, 그 날들의 가격을 더해 Agent 가 안내한 총액과 견줍니다. CS 담당자는 걸린 추천을 받은 게스트에게 정정 연락을 하고, 운영 담당자는 같은 숙소가 되풀이해 걸리면 그 숙소 정보를 바로잡습니다.
위홈 앱에서 AI Travel Agent 의 추천을 받고 예약하다 막힌 게스트의 문의를 받는 위홈 CS 담당자와, 숙소·허가 정보를 관리하는 위홈 운영 담당자. 같은 관리자 화면을 보고 CS 는 이미 안내받은 게스트에게 정정 연락을, 운영 담당자는 정보가 틀린 숙소 정리를 맡는다
Agent 는 대화 속 요청에 맞는 숙소를 고르지만, 그 숙소가 그날 비어 있는지, 인원이 정원 안인지, 안내한 금액이 달력 가격 합계와 같은지는 추천을 낸 뒤 따로 맞춰 보지 않으면 모릅니다. 지금은 게스트가 결제 단계에서 막혀 문의를 남긴 뒤에야 CS 담당자가 대화를 거슬러 올라가 무엇이 틀렸는지 찾습니다. 하루치 추천 기록을 예약 달력·숙소 정보·게스트 요청과 겹쳐 보면, 게스트가 결제에 닿기 전에 틀린 추천을 사유별로 골라냅니다.
CS 담당자가 Agent 추천 기록·게스트 요청·숙소 정보·예약 달력 네 CSV 를 올리면, 추천 한 건마다 다섯 판정 중 하나와 막힌 날짜, 인원과 정원, 안내 금액과 달력 합계, 게스트 구분과 숙소의 내국인 허가가 서는 관리자 화면입니다. 숙박일 펼치기와 가격 합산, 판정 차례를 담은 규칙은 TypeScript 로 짜고 단위 테스트로 고정합니다. Agent 는 아직 붙이지 않고, 대화 로그에서 숙소 번호·날짜·안내 금액만 뽑아낸 모양으로 하루치 추천 기록을 지어 씁니다.
판정 함수를 MCP 서버의 도구 check_bookability 로 감싸고, Claude 로 만든 시험용 Travel Agent 가 숙소를 고른 뒤 이 도구를 불러 걸린 숙소를 빼고 다시 고르게 합니다. 같은 게스트 문의 120개의 첫 추천을 도구 없이 한 번, 도구를 붙여 한 번 받아 판정별 걸린 추천 수를 대조 탭에 나란히 세우고, 추천마다 Agent 가 부른 도구와 판정 결과를 trace 로 남깁니다.
CS 담당자가 걸린 추천을 고르면, 같은 날짜·인원·게스트 구분으로 다섯 판정을 모두 통과하는 대체 숙소를 규칙이 두세 곳 고르고 Claude 가 그 사유와 대체 숙소를 담은 정정 안내 초안을 게스트가 쓴 언어로 씁니다. 초안의 숙소 번호·금액·날짜가 판정 결과와 같은지 규칙으로 다시 보고, CS 담당자가 승인해야 복사되며 발송은 하지 않습니다. 운영 담당자 탭에는 같은 숙소가 걸린 횟수를 사유별로 모아 정보를 바로잡을 숙소부터 세웁니다.
CS 담당자가 10월 4일 하루치 추천을 올리면 망원동 루프탑 하우스가 10-12 예약됨으로 이미 예약된 숙소 묶음에, 해운대 오션뷰 투룸이 요청 6명·정원 4명으로 정원 묶음에, 연남동 한옥 스테이가 안내 248,000원·달력 두 밤 296,000원으로 가격 묶음에, 성수 로프트가 내국인 게스트에게 추천돼 내국인 불가 묶음에 서는 과정을 시연합니다.
CS 담당자가 을지로 복층 스튜디오 추천을 펼치면 11-28 이 막힘이라 이미 예약된 숙소로 서 있고 다섯 명 요청이 정원 3명을 넘는 사실도 함께 걸린 판정으로 보여, 게스트에게 날짜와 인원을 한 번에 정정합니다.
인원을 말하지 않은 대화, 인원이 정원과 똑같은 대화, 체크아웃 날에만 다른 예약이 잡힌 숙소, 안내 금액이 달력 합계보다 정확히 1천 원 많은 추천을 하루치에 섞어도 추천마다 판정 하나가 정해집니다. 호스트가 달력 가격을 「148,000원」처럼 글자째 올린 날이 섞이면 그 숙박일만 합계에서 빠졌다고 펼침 칸에 적고, 그 추천은 가격 판정만 보류합니다.
2주차 도구 전후 대조 탭은 같은 게스트 문의 120개의 첫 추천을 도구 없이 받은 열과 도구를 붙여 받은 열로 나란히 세우고, 이미 예약된 숙소와 내국인 불가 숙소가 도구 뒤에 몇 건 남는지 판정별로 보여줍니다.
위 수치는 더미데이터 자가채점이며, 틀린 추천이 실제로 줄고 결제 단계 이탈과 CS 문의가 줄어드는지는 위홈 AI Travel Agent 의 실제 추천 기록과 예약 달력, 결제 이탈 기록이 있어야 측정됩니다. 위홈 Agent 대화 로그에서 추천 숙소·날짜·안내 금액을 뽑을 수 있으면 그 하루치를 올리는 것만으로 이 추천 표가 다시 찹니다.
120개 문의와 그 정답 판정을 모두 제가 지었으므로, 대조 탭에서 맞는 추천이 늘어도 실제 게스트 문의에서 Agent 가 얼마나 자주 틀리는지는 모릅니다. 이 화면이 지금 말할 수 있는 것은 인원을 말하지 않은 C-55246 은 정원 판정을 건너뛰고, 체크아웃 날만 예약된 광안리 숙소는 예약 가능으로 남는다는 규칙의 동작뿐입니다.
체크아웃 날을 숙박일에 넣는 실수는 광안리 R-1004-0007 을 이미 예약됨으로 바꾸고, 가격 문턱을 '1천 원 이상'으로 쓰는 실수는 이태원 R-1004-0006 을 가격 다름으로 바꿉니다. 호스트가 막아 둔 날을 예약됨과 따로 다루면 을지로 R-1004-0010 이 정원 초과로 내려가, 하루치 11건 가운데 이 세 추천이 날짜 계산의 실수를 드러내는 자리입니다.
내국인 숙박 허가 여부는 숙소 정보의 domestic_allowed 값을 그대로 믿습니다. 이 조건은 공고에 없고, 위홈이 과기정통부 공유숙박 임시허가를 받은 숙소에서만 내국인을 받는다는 사실은 회사 공개 자료에서 가져왔습니다. 어느 숙소가 허가 대상인지 정하는 일은 운영 담당자 몫이고, 이 화면은 그 값과 게스트 구분이 어긋나는 추천만 보여줍니다.
가격 대조는 달력의 1박 가격 합계와 Agent 안내 총액만 견주고 청소비·인원 추가 요금·할인은 넣지 않습니다. 위홈 결제 화면이 이런 항목을 더하면 달력 합계와 결제 금액이 달라져 가격 다름이 실제보다 많이 나올 수 있어, 실제 결제 금액 구성을 본 뒤 계산식에 넣을지 정할 도입 과제로 둡니다.
게스트 구분은 대화가 아니라 가입 때 확인한 국적에서 온 값으로 둡니다. 외국인 게스트가 한국어로, 내국인 게스트가 영어로 문의하는 일이 흔해 대화 언어로 구분을 추정하면 허가 판정이 엉뚱하게 걸립니다.
① 인라인 샘플 · ② seed.json 다운로드 · ③ 증강 프롬프트. 세 층 모두 동일한 schema 에서 파생.
AI Travel Agent 가 대화마다 게스트에게 내놓은 숙소 추천 기록입니다. quoted_total 은 Agent 가 대화에서 안내한 숙박 총액이고, Agent 가 가격을 말하지 않은 추천은 null 입니다. 한 대화에 추천이 둘 이상일 수 있습니다. 값은 작성자가 만든 더미입니다.
| rec_id | conversation_id | listing_id | checkin | checkout | quoted_total | recommended_at |
|---|---|---|---|---|---|---|
| R-1004-0001 | C-55102 | L-1021 | 2026-10-11 | 2026-10-13 | 330,000 | 2026-10-04T09:12:00+09:00 |
| R-1004-0002 | C-55102 | L-1075 | 2026-10-11 | 2026-10-13 | 420,000 | 2026-10-04T09:12:00+09:00 |
| R-1004-0003 | C-55139 | L-2047 | 2026-10-17 | 2026-10-18 | 189,000 | 2026-10-04T10:03:00+09:00 |
| R-1004-0004 | C-55188 | L-1088 | 2026-10-09 | 2026-10-11 | 248,000 | 2026-10-04T11:27:00+09:00 |
| R-1004-0005 | C-55201 | L-1102 | 2026-10-10 | 2026-10-11 | 132,000 | 2026-10-04T12:40:00+09:00 |
아래 JSON Schema 에 맞는 AI Travel Agent 추천 기록 행을 더 만들어 주세요. {"type":"object","properties":{"rec_id":{"type":"string","description":"AI Travel Agent 가 내놓은 추천 한 건의 번호입니다."},"conversation_id":{"type":"string","description":"그 추천이 나온 게스트 대화 번호입니다."},"listing_id":{"type":"string","description":"추천한 숙소 번호입니다."},"checkin":{"type":"string","format":"date","description":"Agent 가 안내한 체크인 날짜입니다."},"checkout":{"type":"string","format":"date","description":"Agent 가 안내한 체크아웃 날짜입니다. 이 날은 숙박일에 들지 않습니다."},"quoted_total":{"type":["integer","null"],"minimum":0,"description":"Agent 가 대화에서 안내한 숙박 총액(원)입니다. 가격을 말하지 않은 추천은 null 입니다."},"recommended_at":{"type":"string","format":"date-time","description":"Agent 가 추천을 내놓은 시각입니다."}},"required":["rec_id","conversation_id","listing_id","checkin","checkout","quoted_total","recommended_at"]} 하루 동안 대화 30~80건에서 대화마다 추천 1~3건을 만들고, 숙박은 1~4박, 체크인은 추천일로부터 1~60일 뒤로 둡니다. 쉬운 데이터만 만들지 말 것 — 다음 하드 케이스를 의도적으로 섞어라: (1) quoted_total 이 null 인 추천, (2) 1박 가격을 총액처럼 안내한 추천, (3) 안내 금액이 달력 합계와 정확히 1천 원 차이 나는 추천, (4) 같은 대화에서 같은 날짜로 두 숙소를 추천한 경우. 생성한 행은 위 스키마를 통과해야 하며, 형식을 깨뜨리는 시도는 별도로 3건만 표시해 두세요.{"type":"object","properties":{"rec_id":{"type":"string","description":"AI Travel Agent 가 내놓은 추천 한 건의 번호입니다."},"conversation_id":{"type":"string","description":"그 추천이 나온 게스트 대화 번호입니다."},"listing_id":{"type":"string","description":"추천한 숙소 번호입니다."},"checkin":{"type":"string","format":"date","description":"Agent 가 안내한 체크인 날짜입니다."},"checkout":{"type":"string","format":"date","description":"Agent 가 안내한 체크아웃 날짜입니다. 이 날은 숙박일에 들지 않습니다."},"quoted_total":{"type":["integer","null"],"minimum":0,"description":"Agent 가 대화에서 안내한 숙박 총액(원)입니다. 가격을 말하지 않은 추천은 null 입니다."},"recommended_at":{"type":"string","format":"date-time","description":"Agent 가 추천을 내놓은 시각입니다."}},"required":["rec_id","conversation_id","listing_id","checkin","checkout","quoted_total","recommended_at"]}Agent 대화마다 게스트 계정의 내·외국인 구분과 대화에서 밝힌 인원입니다. guest_type 은 대화 언어가 아니라 가입 때 확인한 국적에서 오고, 인원을 말하지 않은 대화는 guests 가 null 입니다. first_message 는 게스트의 첫 요청 원문이라 한국어와 영어가 섞여 있습니다. 값은 작성자가 만든 더미입니다.
| conversation_id | guest_type | guests | first_message |
|---|---|---|---|
| C-55102 | 내국인 | 4 | 10월 11일부터 2박, 친구 넷이서 망원동 근처 루프탑 있는 집 찾아요 |
| C-55139 | 내국인 | 6 | 해운대 바다 보이는 숙소요. 어른 여섯 명이고 10월 17일 하루만 자요 |
| C-55188 | 외국인 | 2 | Two nights in Yeonnam-dong from Oct 9,… |
| C-55201 | 내국인 | 2 | 성수동 근처 감성 숙소, 둘이서 10월 10일 하루 |
| C-55217 | 외국인 | 2 | Itaewon place with a terrace for 2, Oc… |
아래 JSON Schema 에 맞는 게스트 요청 행을 더 만들어 주세요. {"type":"object","properties":{"conversation_id":{"type":"string","description":"게스트 대화 번호입니다."},"guest_type":{"type":"string","enum":["내국인","외국인"],"description":"가입 때 확인한 국적으로 정한 게스트 구분입니다. 대화 언어로 정하지 않습니다."},"guests":{"type":["integer","null"],"minimum":1,"description":"게스트가 대화에서 밝힌 숙박 인원입니다. 인원을 말하지 않았으면 null 입니다."},"first_message":{"type":"string","description":"게스트가 Agent 에 처음 보낸 요청 원문입니다."}},"required":["conversation_id","guest_type","guests","first_message"]} 서울·부산 숙소를 찾는 대화를 만들고 first_message 는 날짜·인원·동네·분위기를 섞은 한두 문장으로 씁니다. 쉬운 데이터만 만들지 말 것 — 다음 하드 케이스를 의도적으로 섞어라: (1) 인원을 말하지 않아 guests 가 null 인 대화, (2) 한국어로 문의한 외국인과 영어로 문의한 내국인, (3) 「어른 둘 아이 하나」처럼 인원을 나눠 말한 대화. 생성한 행은 위 스키마를 통과해야 하며, 형식을 깨뜨리는 시도는 별도로 3건만 표시해 두세요.{"type":"object","properties":{"conversation_id":{"type":"string","description":"게스트 대화 번호입니다."},"guest_type":{"type":"string","enum":["내국인","외국인"],"description":"가입 때 확인한 국적으로 정한 게스트 구분입니다. 대화 언어로 정하지 않습니다."},"guests":{"type":["integer","null"],"minimum":1,"description":"게스트가 대화에서 밝힌 숙박 인원입니다. 인원을 말하지 않았으면 null 입니다."},"first_message":{"type":"string","description":"게스트가 Agent 에 처음 보낸 요청 원문입니다."}},"required":["conversation_id","guest_type","guests","first_message"]}위홈에 등록된 숙소 정보입니다. domestic_allowed 는 그 숙소가 내국인 숙박을 받을 수 있는지이고, 외국인관광도시민박으로만 등록된 숙소는 false 입니다. 이 조건은 공고가 아니라 위홈 공개 자료에서 가져왔고 출처는 output_schema 의 검증 메모에 적었습니다. 값은 작성자가 만든 더미입니다.
| listing_id | title | region | max_guests | domestic_allowed |
|---|---|---|---|---|
| L-1021 | 망원동 루프탑 하우스 | 서울 마포구 | 4 | true |
| L-2047 | 해운대 오션뷰 투룸 | 부산 해운대구 | 4 | true |
| L-1088 | 연남동 한옥 스테이 | 서울 마포구 | 3 | true |
| L-1102 | 성수 로프트 | 서울 성동구 | 2 | false |
| L-1130 | 이태원 테라스 원룸 | 서울 용산구 | 2 | false |
아래 JSON Schema 에 맞는 위홈 숙소 행을 더 만들어 주세요. {"type":"object","properties":{"listing_id":{"type":"string","description":"위홈 숙소 번호입니다."},"title":{"type":"string","description":"숙소 이름입니다."},"region":{"type":"string","description":"숙소가 있는 시·구입니다."},"max_guests":{"type":"integer","minimum":1,"description":"호스트가 등록한 최대 숙박 인원입니다."},"domestic_allowed":{"type":"boolean","description":"내국인 숙박을 받을 수 있는 숙소인지입니다. 외국인관광도시민박으로만 등록된 숙소는 false 입니다."}},"required":["listing_id","title","region","max_guests","domestic_allowed"]} 서울 마포·용산·종로·성동·중구와 부산 해운대·수영·부산진구 숙소를 섞고 정원은 2~8명으로 둡니다. 쉬운 데이터만 만들지 말 것 — 다음 하드 케이스를 의도적으로 섞어라: (1) domestic_allowed 가 false 인 숙소를 전체의 30% 쯤, (2) 같은 동네에 이름이 비슷한 숙소 두 곳, (3) 정원이 2명인 원룸. 생성한 행은 위 스키마를 통과해야 하며, 형식을 깨뜨리는 시도는 별도로 3건만 표시해 두세요.{"type":"object","properties":{"listing_id":{"type":"string","description":"위홈 숙소 번호입니다."},"title":{"type":"string","description":"숙소 이름입니다."},"region":{"type":"string","description":"숙소가 있는 시·구입니다."},"max_guests":{"type":"integer","minimum":1,"description":"호스트가 등록한 최대 숙박 인원입니다."},"domestic_allowed":{"type":"boolean","description":"내국인 숙박을 받을 수 있는 숙소인지입니다. 외국인관광도시민박으로만 등록된 숙소는 false 입니다."}},"required":["listing_id","title","region","max_guests","domestic_allowed"]}숙소마다 날짜별 예약 달력입니다. 하루 한 줄이고 price 는 그날 1박 가격입니다. 인라인 샘플은 추천된 숙박일과, 판정에 들지 않는 체크아웃 날 한 줄만 싣습니다. 체크아웃 날에만 다른 예약이 잡힌 숙소와 호스트가 막아 둔 날을 일부러 담았습니다. 값은 작성자가 만든 더미입니다.
| listing_id | date | status | price |
|---|---|---|---|
| L-1021 | 2026-10-11 | 예약 가능 | 165,000 |
| L-1021 | 2026-10-12 | 예약됨 | 165,000 |
| L-1075 | 2026-10-11 | 예약 가능 | 210,000 |
| L-1075 | 2026-10-12 | 예약 가능 | 210,000 |
| L-2047 | 2026-10-17 | 예약 가능 | 189,000 |
아래 JSON Schema 에 맞는 숙소 예약 달력 행을 더 만들어 주세요. {"type":"object","properties":{"listing_id":{"type":"string","description":"숙소 번호입니다."},"date":{"type":"string","format":"date","description":"숙박일입니다. 하루 한 줄입니다."},"status":{"type":"string","enum":["예약 가능","예약됨","막힘"],"description":"그날의 달력 상태입니다. 막힘은 호스트가 직접 닫아 둔 날입니다."},"price":{"type":"integer","minimum":0,"description":"그날 1박 가격(원)입니다."}},"required":["listing_id","date","status","price"]} 숙소마다 60일치를 만들고 주말 가격을 평일보다 15~30% 높게 둡니다. 쉬운 데이터만 만들지 말 것 — 다음 하드 케이스를 의도적으로 섞어라: (1) 숙박 기간 가운데 하루만 예약됨인 경우, (2) 체크아웃 날에만 예약됨인 경우, (3) 호스트가 막아 둔 막힘, (4) 하루 사이에 가격이 바뀌는 날. 생성한 행은 위 스키마를 통과해야 하며, 형식을 깨뜨리는 시도는 별도로 3건만 표시해 두세요.{"type":"object","properties":{"listing_id":{"type":"string","description":"숙소 번호입니다."},"date":{"type":"string","format":"date","description":"숙박일입니다. 하루 한 줄입니다."},"status":{"type":"string","enum":["예약 가능","예약됨","막힘"],"description":"그날의 달력 상태입니다. 막힘은 호스트가 직접 닫아 둔 날입니다."},"price":{"type":"integer","minimum":0,"description":"그날 1박 가격(원)입니다."}},"required":["listing_id","date","status","price"]}| TypeScript | 숙박일 펼치기, 가격 합산, 정원·허가 비교, 판정 차례를 담은 규칙 엔진과 관리자 화면 코드의 언어입니다. |
| Backend API | 네 표를 받아 추천마다 판정을 내주는 API 입니다. 2주차 MCP 도구가 같은 함수를 그대로 부릅니다. |
| Database | PostgreSQL 에 네 입력 표와 날짜별 판정 결과, 3주차 CS 승인 기록을 담습니다. |
| MCP | 2주차에 판정 함수를 check_bookability 도구로 내보내 Agent 가 추천 전에 부르게 합니다. |
| Tool Calling | 시험용 Travel Agent 가 숙소 검색 도구와 check_bookability 를 차례로 부르고, 걸린 숙소는 빼고 다시 고릅니다. |
| LLM API | Claude API 로 2주차 시험용 Travel Agent 와 3주차 정정 안내 초안을 돌립니다. |
| Guardrail | Agent 추천을 게스트에게 보여주기 전에 판정 규칙을 한 번 더 통과시키는 마지막 관문입니다. |
| Human-in-the-Loop | 3주차 정정 안내 초안은 CS 담당자가 승인해야 복사되고, 승인·수정 기록이 남습니다. |
| AI Evaluation | 2주차에 같은 문의 120개를 도구 전후로 돌려 도구 뒤에 남은 걸린 추천 수를 판정별로 냅니다. |
| Observability | 추천 한 건마다 Agent 가 부른 도구와 그 판정 결과를 trace 로 남겨, 걸린 추천이 어느 호출 뒤에 나왔는지 따라갑니다. |
| Claude Code | 규칙 엔진·MCP 서버·화면 작업을 나눠 맡기고, 판정 단위 테스트를 통과한 코드만 합칩니다. |
✗ fail → 체크인이 사흘 안인 추천이 표 아래쪽에 묻혀 있으면, 판정 묶음 안을 체크인 날짜 순으로 다시 세워 연락이 급한 게스트를 위로 올립니다.
✓ pass → check_bookability 도구를 MCP 서버에 올리는 2주차로 갑니다.
✗ fail → 다시 고르기를 세 번 넘게 되풀이하는 문의는 trace 에서 도구 응답의 사유가 Agent 지시문에 실제로 넘어가는지 봅니다.
✓ pass → 3주차 대체 숙소와 정정 안내 초안으로 넘어갑니다.
위 예측 UI 는 3주차까지 완주했을 때의 화면입니다. 1주차에 실제로 만드는 것은 아래 표시된 화면 하나입니다.
verdict사유 라벨 · rec_id + 한 줄 요약(근거 수치 포함)화면·코드·면접에서 이 단어를 그대로 씁니다. 키는 출력 스키마의 enum 과 같습니다.
예약 가능한 추천예약 가능그 날짜에 이미 예약된 숙소이미 예약됨인원이 숙소 정원을 넘음정원 초과안내한 가격이 실제와 다름가격 다름내국인이 예약할 수 없는 숙소내국인 불가Agent 추천 한 건이 숙박일 펼치기, 달력 상태 확인, 정원 비교, 가격 합산, 내국인 허가 비교를 거쳐 어떤 판정을 받는지 남기는 형식입니다. 판정은 규칙과 차례가 정하고, 3주차 정정 안내 초안만 모델이 씁니다.
{"type":"object","properties":{"rec_id":{"type":"string"},"conversation_id":{"type":"string"},"listing_id":{"type":"string"},"checkin":{"type":"string","format":"date"},"checkout":{"type":"string","format":"date"},"nights":{"type":"integer","minimum":1,"description":"checkout − checkin 을 일로 센 숙박일 수입니다."},"verdict":{"type":"string","enum":["예약 가능한 추천","그 날짜에 이미 예약된 숙소","인원이 숙소 정원을 넘음","안내한 가격이 실제와 다름","내국인이 예약할 수 없는 숙소"]},"also_flagged":{"type":"array","items":{"type":"string","enum":["그 날짜에 이미 예약된 숙소","인원이 숙소 정원을 넘음","안내한 가격이 실제와 다름","내국인이 예약할 수 없는 숙소"]},"description":"판정 차례에서 밀려 verdict 에 오르지 못한 나머지 판정입니다."},"guest_type":{"type":"string","enum":["내국인","외국인"]},"domestic_allowed":{"type":"boolean"},"guests":{"type":["integer","null"],"minimum":1},"max_guests":{"type":"integer","minimum":1},"blocked_dates":{"type":"array","items":{"type":"string","format":"date"},"description":"checkin 부터 checkout 전날까지 booking_calendar.status 가 예약됨·막힘인 날짜입니다."},"quoted_total":{"type":["integer","null"],"minimum":0},"calendar_total":{"type":"integer","minimum":0,"description":"checkin 부터 checkout 전날까지 booking_calendar.price 의 합입니다."},"price_gap":{"type":["integer","null"],"description":"quoted_total − calendar_total 입니다. quoted_total 이 null 이면 null 입니다."},"evidence":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"agg":{"type":["string","null"],"enum":["count","sum","avg","min","max",null]},"value":{}},"required":["field","value"]}},"summary":{"type":"string"},"hedge":{"type":["string","null"]}},"required":["rec_id","conversation_id","listing_id","checkin","checkout","nights","verdict","also_flagged","guest_type","domestic_allowed","guests","max_guests","blocked_dates","quoted_total","calendar_total","price_gap","evidence","summary"]}[
{
"rec_id": "R-1004-0001",
"conversation_id": "C-55102",
"listing_id": "L-1021",
"checkin": "2026-10-11",
"checkout": "2026-10-13",
"nights": 2,
"verdict": "그 날짜에 이미 예약된 숙소",
"also_flagged": [],
"guest_type": "내국인",
"domestic_allowed": true,
"guests": 4,
"max_guests": 4,
"blocked_dates": [
"2026-10-12"
],
"quoted_total": 330000,
"calendar_total": 330000,
"price_gap": 0,
"evidence": [
{
"field": "date",
"value": "2026-10-12"
},
{
"field": "status",
"value": "예약됨"
},
{
"field": "quoted_total",
"value": 330000
},
{
"field": "price",
"agg": "sum",
"value": 330000
}
],
"summary": "망원동 루프탑 하우스는 10-11~10-13 두 밤 가운데 10-12 가 이미 예약돼 있어, 게스트가 결제 화면에서 막힙니다.",
"hedge": "인원 4명은 정원 4명과 같아 정원 판정에는 걸리지 않았습니다. 같은 대화에서 함께 추천된 홍대 3층 단독주택(R-1004-0002)은 예약 가능하므로 정정 안내에 그쪽을 먼저 적습니다."
},
{
"rec_id": "R-1004-0003",
"conversation_id": "C-55139",
"listing_id": "L-2047",
"checkin": "2026-10-17",
"checkout": "2026-10-18",
"nights": 1,
"verdict": "인원이 숙소 정원을 넘음",
"also_flagged": [],
"guest_type": "내국인",
"domestic_allowed": true,
"guests": 6,
"max_guests": 4,
"blocked_dates": [],
"quoted_total": 189000,
"calendar_total": 189000,
"price_gap": 0,
"evidence": [
{
"field": "guests",
"value": 6
},
{
"field": "max_guests",
"value": 4
},
{
"field": "quoted_total",
"value": 189000
},
{
"field": "price",
"value": 189000
}
],
"summary": "해운대 오션뷰 투룸은 정원이 4명인데 게스트는 어른 6명을 요청해, 이 인원으로는 예약할 수 없습니다.",
"hedge": null
},
{
"rec_id": "R-1004-0004",
"conversation_id": "C-55188",
"listing_id": "L-1088",
"checkin": "2026-10-09",
"checkout": "2026-10-11",
"nights": 2,
"verdict": "안내한 가격이 실제와 다름",
"also_flagged": [],
"guest_type": "외국인",
"domestic_allowed": true,
"guests": 2,
"max_guests": 3,
"blocked_dates": [],
"quoted_total": 248000,
"calendar_total": 296000,
"price_gap": -48000,
"evidence": [
{
"field": "quoted_total",
"value": 248000
},
{
"field": "price",
"agg": "sum",
"value": 296000
},
{
"field": "price",
"value": 148000
}
],
"summary": "연남동 한옥 스테이는 Agent 가 248,000원이라고 안내했지만 달력의 두 밤 가격은 148,000원씩 296,000원이라 48,000원 차이가 납니다.",
"hedge": "1박 가격을 두 밤 총액처럼 안내했거나 다른 날짜 가격을 읽었을 수 있습니다. 게스트가 영어로 문의했으므로 정정 안내도 영어로 씁니다."
},
{
"rec_id": "R-1004-0005",
"conversation_id": "C-55201",
"listing_id": "L-1102",
"checkin": "2026-10-10",
"checkout": "2026-10-11",
"nights": 1,
"verdict": "내국인이 예약할 수 없는 숙소",
"also_flagged": [],
"guest_type": "내국인",
"domestic_allowed": false,
"guests": 2,
"max_guests": 2,
"blocked_dates": [],
"quoted_total": 132000,
"calendar_total": 132000,
"price_gap": 0,
"evidence": [
{
"field": "guest_type",
"value": "내국인"
},
{
"field": "domestic_allowed",
"value": false
},
{
"field": "quoted_total",
"value": 132000
},
{
"field": "price",
"value": 132000
}
],
"summary": "성수 로프트는 외국인관광도시민박으로만 등록돼 내국인 숙박을 받을 수 없는데, Agent 가 내국인 게스트에게 추천했습니다.",
"hedge": "날짜와 인원, 가격은 모두 맞아 결제 직전까지 문제가 드러나지 않는 추천입니다."
},
{
"rec_id": "R-1004-0010",
"conversation_id": "C-55263",
"listing_id": "L-1159",
"checkin": "2026-11-28",
"checkout": "2026-11-29",
"nights": 1,
"verdict": "그 날짜에 이미 예약된 숙소",
"also_flagged": [
"인원이 숙소 정원을 넘음"
],
"guest_type": "내국인",
"domestic_allowed": true,
"guests": 5,
"max_guests": 3,
"blocked_dates": [
"2026-11-28"
],
"quoted_total": 125000,
"calendar_total": 125000,
"price_gap": 0,
"evidence": [
{
"field": "date",
"value": "2026-11-28"
},
{
"field": "status",
"value": "막힘"
},
{
"field": "guests",
"value": 5
},
{
"field": "max_guests",
"value": 3
},
{
"field": "quoted_total",
"value": 125000
},
{
"field": "price",
"value": 125000
}
],
"summary": "을지로 복층 스튜디오는 호스트가 11-28 을 막아 두어 예약할 수 없습니다.",
"hedge": "다섯 명 요청이 정원 3명을 넘어 인원이 숙소 정원을 넘음도 함께 걸렸습니다. 날짜만 바꿔 안내하면 다시 막히므로 정정 안내에 두 사유를 같이 적습니다."
},
{
"rec_id": "R-1004-0006",
"conversation_id": "C-55217",
"listing_id": "L-1130",
"checkin": "2026-10-12",
"checkout": "2026-10-14",
"nights": 2,
"verdict": "예약 가능한 추천",
"also_flagged": [],
"guest_type": "외국인",
"domestic_allowed": false,
"guests": 2,
"max_guests": 2,
"blocked_dates": [],
"quoted_total": 197000,
"calendar_total": 196000,
"price_gap": 1000,
"evidence": [
{
"field": "quoted_total",
"value": 197000
},
{
"field": "price",
"agg": "sum",
"value": 196000
},
{
"field": "guest_type",
"value": "외국인"
},
{
"field": "domestic_allowed",
"value": false
}
],
"summary": "이태원 테라스 원룸은 외국인 게스트에게 추천됐고, 안내 금액 197,000원과 달력 합계 196,000원의 차이가 1,000원이라 예약 가능한 추천입니다.",
"hedge": "차이가 정확히 1,000원이라 '1천 원을 넘으면' 기준에 걸리지 않았습니다. 숙소는 내국인을 받지 않지만 게스트가 외국인이라 허가 판정에도 걸리지 않습니다."
},
{
"rec_id": "R-1004-0007",
"conversation_id": "C-55230",
"listing_id": "L-2051",
"checkin": "2026-10-18",
"checkout": "2026-10-20",
"nights": 2,
"verdict": "예약 가능한 추천",
"also_flagged": [],
"guest_type": "내국인",
"domestic_allowed": true,
"guests": 3,
"max_guests": 3,
"blocked_dates": [],
"quoted_total": 250000,
"calendar_total": 250000,
"price_gap": 0,
"evidence": [
{
"field": "guests",
"value": 3
},
{
"field": "max_guests",
"value": 3
},
{
"field": "date",
"value": "2026-10-20"
},
{
"field": "quoted_total",
"value": 250000
},
{
"field": "price",
"agg": "sum",
"value": 250000
}
],
"summary": "광안리 바다 앞 스튜디오는 10-18·10-19 두 밤이 비어 있고 인원 3명이 정원 3명 안이라 예약 가능한 추천입니다.",
"hedge": "10-20 은 예약됨이지만 체크아웃 날이라 숙박일에 들지 않습니다."
},
{
"rec_id": "R-1004-0008",
"conversation_id": "C-55246",
"listing_id": "L-1075",
"checkin": "2026-10-25",
"checkout": "2026-10-26",
"nights": 1,
"verdict": "예약 가능한 추천",
"also_flagged": [],
"guest_type": "내국인",
"domestic_allowed": true,
"guests": null,
"max_guests": 6,
"blocked_dates": [],
"quoted_total": 240000,
"calendar_total": 240000,
"price_gap": 0,
"evidence": [
{
"field": "guests",
"value": null
},
{
"field": "max_guests",
"value": 6
},
{
"field": "quoted_total",
"value": 240000
},
{
"field": "price",
"value": 240000
}
],
"summary": "홍대 3층 단독주택은 10-25 하루가 비어 있고 안내 금액 240,000원이 달력 가격과 같아 예약 가능한 추천입니다.",
"hedge": "게스트가 인원을 말하지 않아 정원 판정은 하지 않았습니다. 「다 같이 모이려고요」라는 요청이라 정원 6명을 넘을 수 있어, CS 가 예약 전에 인원을 물어볼 대화로 표시합니다."
}
][자동 검증 · 코드가 판정합니다] 1. verdict 가 예약 가능한 추천·그 날짜에 이미 예약된 숙소·인원이 숙소 정원을 넘음·안내한 가격이 실제와 다름·내국인이 예약할 수 없는 숙소 다섯 값 중 하나이고, also_flagged 의 값이 같은 다섯 값 가운데 verdict 가 아닌 것인지 확인합니다. 2. rec_id·conversation_id·listing_id·checkin·checkout·nights·verdict·also_flagged·guest_type·domestic_allowed·guests·max_guests·blocked_dates·quoted_total·calendar_total·price_gap·evidence·summary 필드가 빠짐없이 있는지 확인합니다. 3. nights·max_guests 가 1 이상, guests 가 1 이상이거나 null, calendar_total 이 0 이상인지 확인합니다. 4. 두 근거 값의 차이를 다시 계산합니다. nights 는 checkout − checkin, calendar_total 은 checkin 부터 checkout 전날까지 booking_calendar.price 합, price_gap 은 quoted_total − calendar_total 입니다. blocked_dates 는 같은 숙박일 가운데 status 가 예약됨·막힘인 날짜입니다. 5. guest_type 이 내국인이고 domestic_allowed 가 false 이면 verdict 는 내국인이 예약할 수 없는 숙소입니다. 6. 앞 조건에 걸리지 않고 blocked_dates 가 하나 이상이면 verdict 는 그 날짜에 이미 예약된 숙소입니다. 7. 앞 두 조건에 걸리지 않고 guests 가 max_guests 보다 크면 verdict 는 인원이 숙소 정원을 넘음입니다. 8. 앞 세 조건에 걸리지 않고 price_gap 의 절댓값이 1000 을 넘으면 verdict 는 안내한 가격이 실제와 다름이고, 그렇지 않으면 예약 가능한 추천입니다. 9. evidence 의 field 이름이 agent_recommendations·guest_requests·listings·booking_calendar 에 있는 컬럼인지 대조합니다. 10. evidence 의 value 가 수록된 행의 원문 값과 같은지 확인합니다. 여러 숙박일 가격을 더한 수는 agg 를 sum 으로 적습니다. 11. summary 가 존댓말로 끝나는지 확인합니다. [판정 차례 · 위 규칙이 둘 이상 동시에 걸릴 때] 추천 한 건에는 판정을 하나만 남기고 나머지는 also_flagged 에 둡니다. ① 내국인이 예약할 수 없는 숙소 → ② 그 날짜에 이미 예약된 숙소 → ③ 인원이 숙소 정원을 넘음 → ④ 안내한 가격이 실제와 다름 → ⑤ 예약 가능한 추천. 날짜나 인원을 바꿔도 풀리지 않는 허가 조건을 맨 앞에 두고, 숙소를 바꿔야 하는 날짜·정원을 금액만 고쳐 안내하면 되는 가격보다 앞에 둡니다. [판정 근거 · 내국인 숙박 허가 조건의 출처] 이 판정값은 공고에서 오지 않았습니다. 공고는 Agent 가 정책 데이터를 안전하게 다뤄야 한다고만 적고, 내국인 숙박 조건은 위홈 회사 브리프(2026-10-04 조사)에서 가져왔습니다. 브리프에는 위홈이 받은 「과기정통부 공유숙박 임시허가 2026-3호」와 「ICT 규제샌드박스 실증특례(2019-11 지정, 2020-07 서비스 시작, 2023-10 부산 확대)」가 있고, 위홈 자기소개는 이 지정으로 내외국인 모두에게 합법적인 공유숙박을 제공한다고 적습니다. 브리프가 근거로 든 위홈 게스트 안내(https://www.wehome.me/trust/ko/wehomeguestinfo/)는 내국인 공유숙박이 위홈 실증특례·임시허가 숙소에서만 합법이라고 설명하고, 외국인관광도시민박업으로만 등록된 숙소는 외국인만 받습니다. listings 의 domestic_allowed 가 이 조건을 담고, 이 화면은 허가 여부를 스스로 판단하지 않고 그 값을 게스트 구분과 견주기만 합니다. [하드 케이스 · 판정이 갈리는 이유] C-55246 은 guests 가 null 인 결측이라 정원 판정을 하지 않고, 나머지 조건으로 R-1004-0008 을 예약 가능한 추천으로 둡니다. R-1004-0009 는 quoted_total 이 null 이라 price_gap 도 null 이고 가격 판정을 하지 않습니다. R-1004-0006 은 price_gap 이 정확히 1000 이라 '1천 원을 넘으면'에 걸리지 않습니다. R-1004-0007 은 guests 3 이 max_guests 3 과 같고, L-2051 의 10-20 예약됨은 체크아웃 날이라 blocked_dates 에 들지 않습니다. R-1004-0010 은 11-28 막힘과 정원 초과가 동시에 걸려, 차례대로 그 날짜에 이미 예약된 숙소를 verdict 로, 인원이 숙소 정원을 넘음을 also_flagged 로 둡니다. [평가 러너 · 2주차] 같은 게스트 문의 120개의 첫 추천을 MCP 도구 없이 한 번, 도구를 붙여 한 번 받아 제가 먼저 적어 둔 판정과 대조합니다. 도구 뒤에도 남은 걸린 추천은 trace 를 열어 Agent 가 도구를 부르지 않았는지, 부르고도 결과를 무시했는지로 나눠 셉니다. [수동 검증 · 사람이 봅니다] 1. 정정 연락을 누구에게 먼저 할지는 체크인이 가까운 순서와 게스트가 이미 결제를 시도했는지를 보고 CS 담당자가 정합니다. 2. 같은 숙소가 가격 다름으로 되풀이해 걸리면 Agent 가 읽는 숙소 정보가 틀린 것인지 호스트가 달력을 늦게 고친 것인지 운영 담당자가 확인합니다.