| name | ipzitalk-retail-proximity |
| description | 주소 또는 단지명을 입력받아 가장 가까운 백화점·대형마트(대형슈퍼 포함)까지의 직선거리를 기준으로 쇼세권 신호 배지(🟢상권 인접/🟡근접/🟠다소 이격/⬜이격)를 카드 + 지도로 생성한다. "쇼세권", "백화점 가까워", "대형마트 근처", "쇼핑 상권", "마트 가까워?", "생활 인프라 좋아?", "스타필드 가까워", "더현대 근처" 등의 표현이 있을 때 이 스킬을 사용한다. 사용자가 특정 주소/단지의 백화점·대형마트 상권 접근성을 물으면 즉시 트리거한다.
|
| version | 1.0.5 |
| license | proprietary |
쇼세권 진단
주소/단지명 하나로 최근접 백화점·대형마트까지 직선거리를 재서 쇼세권 신호 배지 + 지도를 만든다.
※ 직선거리 기준. 영업 여부·매장 규모는 미반영. 복합몰(스타필드·더현대)은 명칭 근사(내부 대형마트/백화점으로 포착).
입력
| 파라미터 | 필수 | 기본 | 설명 |
|---|
address 또는 complex_query | ✅(택1) | - | 주소 또는 단지명 |
radius_m | ✕ | 2000 | 상권 검색 반경 |
필수 도구
| 도구 | 용도 |
|---|
get_geocode / get_address | 좌표 확보(주거시설 우선) |
search_by_nearby_keyword | 백화점: query="백화점" (본체만 남기도록 필터) |
search_by_nearby_category | 대형마트: categories=['mart_large'](MT1) |
get_static_map / get_map_embed_url | 지도 |
워크플로우 (조합 검색 · 검증됨)
- 좌표 확보 (address→geocode / 단지명→get_address 주거시설 우선).
- 백화점:
search_by_nearby_keyword(center, radius_m=2000, query="백화점", grid=true, category_filter={include_contains:["백화점"]})
→ category_name이 "백화점"인 본체만 남김(입점매장·ATM 노이즈 제거).
🚨 grid=true 없이 부르면 입점 매장이 45건 캡을 다 먹어 본체가 0건으로 사라진다(아래 gotcha, 실측).
0건이면 truncated 를 확인한다. truncated:true = "없음"이 아니라 "확인 불가".
- 대형마트:
search_by_nearby_category(center, radius_m=2000, categories=['mart_large']).
→ 결과에는 대형마트(홈플러스 등)와 대형슈퍼/SSM(이마트에브리데이·롯데슈퍼프레시 등)이 섞여 나온다.
- 2·3 결과를 합쳐 주소 dedupe → 최근접 1건 + 반경 내 개수.
- 배지 판정(아래) → 지도 생성.
밴드(직선거리 m): ≤1000 🟢 상권 인접 / 1000–2000 🟡 근접 / 2000–3000 🟠 다소 이격 / >3000 ⬜ 이격
SSM(대형슈퍼) 인정 규칙 (사용자 확정)
- 반경 내 백화점·진짜 대형마트가 멀면(또는 없으면) 대형슈퍼(SSM)도 생활 상권으로 인정한다.
- 단, 이때 hedge에 **"백화점 없음 · 진짜 대형마트는 N km · 근린은 대형슈퍼 위주"**를 반드시 명시한다.
- 최근접이 SSM이면 stat 라벨을
최근접(대형슈퍼)로 구분 표기, POI 명에 (대형슈퍼)/(대형마트)를 병기.
검증된 사항 (방배롯데캐슬아르떼 · 방배동 424-28 · 2026-07-08)
- 백화점:
query="백화점" radius 2000 → 0건 (방배동 인근 백화점 없음).
- 대형마트(
mart_large, radius 2000): 이마트에브리데이 이수점 320m(대형슈퍼) · 사당동점 736m · 롯데슈퍼프레시 873m · 홈플러스익스프레스 1009m · 홈플러스 남현점 1318m(진짜 대형마트) · 이마트에브리데이 방배그랑자이 1624m.
- 판정: 백화점 0 + 대형마트 1.3km지만 SSM 최근접 320m → 🟢 상권 인접. hedge에 "백화점 없음 · 홈플러스 1.3km · 근린 대형슈퍼 위주" 명시.
출력 = 카드 템플릿
templates/result.html 구조의 ipzi-data JSON을 채운다(self-contained, SVG only, CDN·이모지 금지). 값:
iconId:"i-shopping", badgeTitle:"쇼세권 진단", axisMax:2000, radiusDefault:1000
signal:{label:"상권 인접(생활밀착)",cls:"g"} (밴드 결과에 맞춰)
bands:[{max:1000,cls:"g",label:"≤1000 상권 인접"},{max:2000,cls:"a",label:"1000–2000 근접"},{max:3000,cls:"o",label:"2000–3000 다소 이격"},{max:Infinity,cls:"x",label:">3000 이격"}]
stat:[{n:"320m",l:"최근접(대형슈퍼)",cls:"g"},{n:"__COUNT__",l:"1km 내 마트"},{dot:"g",l:"신호 등급"}]
pois: 마트 리스트에 (대형슈퍼)/(대형마트) 라벨 병기, d=직선거리(m)
hedge.verify: null (배정교 개념 없음)
필수 단서 · 금지 표현
- 필수: 직선거리 기준 · 영업/규모 미확인 · 복합몰 명칭 근사 · (SSM 인정 시) 백화점/대형마트 이격 명시
- 금지: "상권 최고" 등 근거 없는 우열 단정, 값 지어내기
엣지
- 지오코딩 실패/
AMBIGUOUS → 재입력/후보 제시
- 백화점·대형마트·대형슈퍼 전부 0건 → ⬜ 데이터 부족(반경 넓혀 재시도 제안)
Gotcha
mart_large(MT1) 카테고리는 대형마트뿐 아니라 대형슈퍼/SSM(이마트에브리데이·롯데슈퍼프레시·홈플러스익스프레스)도 함께 반환한다. 최근접이 SSM일 수 있으니 라벨을 반드시 구분하고, "진짜 대형마트"까지의 거리를 별도로 확인·명시할 것.
mart_large 단독으로는 백화점·복합몰이 누락될 수 있음 → 백화점은 query="백화점" 키워드로 별도 검색.
"백화점" 키워드 단독은 입점매장·ATM 노이즈가 섞임 → category_name "백화점" 본체만 남김.
섹션마다 출처를 작게 단다
데이터 블록 하단에 .src 한 줄. 도구·API 이름은 쓰지 않는다. 사용자가 아는 기관명만.
| 블록 | 출처 표기 |
|---|
| 단지 개요·세대수·준공·주차·연차 | 공동주택관리정보시스템(K-apt) |
| 매매·전세·평당가·거래량 | 국토교통부 실거래가 |
| 학교·교통·생활·상권 등 장소 | 카카오맵 |
| 분양공고·분양가·주택형·입주월 | 청약홈 |
| 지도 (장소 마커) | 네이버 지도 · 카카오맵 |
| 지도 (분양공고 마커) | 네이버 지도 · 청약홈 |
- 🚨 출처 문자열은
ipzi-data JSON으로 받지 않고 템플릿 마크업에 직접 박는다.
어느 블록이 어디서 왔는지는 실행마다 달라지지 않는다. 데이터로 받으면 채우는 걸 잊거나 틀리게 쓸 여지만 생긴다.
- 🚨 한 블록에 두 출처가 섞이면 병기한다. 예:
세대수·주차 — 공동주택관리정보시스템(K-apt) · 위치 — 카카오맵.
하나로 뭉뚱그리면 어느 숫자가 어디서 왔는지 사용자가 알 수 없다.
- 🚨 쓰지 않은 기관을 출처로 적지 않는다. 우리가 부르는 곳은 위 다섯 곳뿐이다.
- 히어로·유의사항·푸터에는 달지 않는다. 데이터 블록에만.
디자인 정본
스킬 폴더 밖 문서에 의존하지 않도록 규칙을 여기 인라인으로 둔다.
- CDN·외부 폰트·이모지 금지. 아이콘은
<symbol> 인라인 + <use> 참조로 self-contained.
- 라이트/다크 양쪽.
prefers-color-scheme + :root[data-theme] 모두 대응.
- 토큰만 사용:
--g/--y/--o/--r/--x/--brand/--up/--down/--zebra (+ -s 배경 변형).
- 예외 상태:
null은 "정보없음"(0 아님) · 표본 부족은 판정 유보 · 45건 캡 도달은 "목록 불완전" 표기.
★·☆는 활자 기호이며 이모지가 아니다. 등급 표기에 사용 가능.
- 지도 카드 CSS:
.map{overflow-x:auto; overflow-y:hidden} + .map iframe{display:block; min-width:720px}.
overflow:hidden만 주면 iframe이 카드 폭에 짓눌려 지도가 최소 줌(한반도)으로 떨어진다.
- 🚨 지도 링크는 발급 후 7일 만료. 산출물 지도 캡션에 유효기간·재발급 필요를 반드시 적는다.
만료 시 iframe이 빈 화면이 되는데, 원인 표기가 없으면 리포트가 고장난 것처럼 보인다.
- 🚨 반경 눈금 마커를 넣지 않는다. 예전엔
fitBounds가 반경 원을 무시해 원이 잘리는 걸 막으려고
정북·남·동·서에 회색 더미 마커 4개를 심었다. 사용자에게는 정체를 알 수 없는 점으로 보여 혼란만 준다.
원이 잘리더라도 마커는 실제 장소만 찍는다. (근본 해결은 render.ts가 원을 bounds에 포함하도록 고치는 것 — 발견사항 6번)
🚨 상권 시설을 3층으로 구분한다 (실측 2026-07-09)
같은 '상권'이라도 급이 다르다. 하나로 뭉치면 대형슈퍼가 백화점으로 둔갑한다.
| 층 | 예 (위례 실측) |
|---|
| 대형슈퍼(SSM) | GS더프레시 송파위례점 132m · 롯데슈퍼프레시 · 노브랜드 |
| 복합쇼핑몰·대형마트 | 스타필드시티 위례 673m(트레이더스·이마트 포함) · 롯데마트 |
| 백화점 | NC백화점 송파점 1.4km — 아울렛형. 롯데·신세계·현대 같은 정통 백화점은 반경 3km 내 부재 |
- 최근접 라벨에 시설 종류를 병기한다(예:
최근접(대형슈퍼) 132m).
- 🚨 대형슈퍼 132m 를 근거로 "상권 우수"라고 쓰지 않는다. hedge 에 급 차이를 명시한다.
- 정통 백화점이 없으면 없다고 쓴다.
🚨 생활잡화(다이소)는 목록에만 — 판정 제외 (2026-07-10 결정)
다이소를 찾아서 보여주되, 신호 등급과 개수 산정에는 넣지 않는다.
검색
search_by_nearby_keyword(center, radius_m=2000, query="다이소")
- 카테고리가 깔끔하다:
가정,생활 > 생활용품점 > 다이소
- 위례 실측 2km 내 8곳.
시설 4층 구분
| 층 | 판정 | 예 (위례 실측) |
|---|
| 백화점 | ✅ | NC백화점 송파점 1.4km (아울렛형) |
| 복합쇼핑몰·대형마트 | ✅ | 스타필드시티 위례 673m · 이마트 가든파이브점 |
| 대형슈퍼(SSM) | ✅ | GS더프레시 송파위례점 132m · 롯데슈퍼프레시 |
| 생활잡화 | ❌ 참고만 | 다이소 위례본점 598m |
왜 판정에서 빼나
밴드가 ≤1000m → 상권 인접(초록)이다. 다이소를 그대로 넣으면 다이소 하나만 있는 동네도 초록이 된다.
다이소는 생필품 잡화점이지 식료품·대형 상권이 아니다.
구현
ipzi-data.pois 에 aux: true 로 넣는다.
{n:"다이소 위례본점 (생활잡화)", d:598, aux:true}
템플릿이 aux 항목을 이렇게 처리한다.
- 목록·지도에는 보인다.
참고 배지 + 회색 핀.
1km 내 상권시설 개수에서 제외. 밴드 색도 회색 고정.
- 최근접 판정(
stat[0])에도 쓰지 않는다.
위례 검증: 다이소 8곳을 넣어도 1km 내 상권시설 = 4, 신호 상권 인접(생활밀착) 불변.
복합몰 안의 다이소
다이소 스타필드위례점 683m(스타필드시티 위례 673m 내), 다이소 현대시티몰가든파이브점 1,497m(NC백화점 내)처럼
몰 안에 있는 지점도 그대로 표시한다. 거리가 거의 같아 같은 건물임이 드러난다. 별도 제외 처리 없음.
🚨 화면 문구는 일반인 언어로 (2026-07-10 결정)
진단 시리즈(초품아·역세권·병세권·쇼세권·숲세권)의 독자는 부동산 전문가가 아니다.
내부 용어를 그대로 화면에 쓰지 않는다. 임계값·색(cls)은 그대로 두고 라벨만 바꾼다.
| 쓰지 않는 말 | 대신 |
|---|
| 최근접 · (최근접·판정 기준) | 제일 가까운 곳 · (제일 가까움) |
| 판정 밴드 · 판정 기준 | 등급 기준 |
| 신호 등급 | 등급 |
| 인접 / 근접 | 아주 가까움 / 가까움 |
| 다소 이격 | 조금 먼 편 |
| 이격 · 역 이격 | 먼 편 · 역이 먼 편 |
| 보도권 | 가까움 |
| 판정 유보 | 자료 부족 |
| 판정창 | 기준 범위 |
| 참고 신호(진단 아님) | 참고용이며 확정 판단이 아닙니다 |
| 1km 내 · 슬라이더 반경 내 | 1km 안 · 선택한 반경 안 |
| 미확인 | 확인되지 않음 |
| 판정에서 제외 | 등급에서 제외 |
거리도 읽기 쉽게: 1313m → 1.3km.
문장도 사람 말로
✕ SITE(파랑) · 반경 3km 원 · 판정 기준 경찰병원(주황, 2.3km) · 서울세계로병원(회색)은 등급에 미반영
✓ 파란 점이 우리 집, 주황 점이 등급 기준이 된 경찰병원(2.3km)입니다.
회색 서울세계로병원(645m)은 종합병원이 아니라 등급에 넣지 않았습니다.
- 🚨 부드럽게 쓰되 사실은 그대로. "가까움"이 "좋음"이 되면 안 된다. 등급은 거리 밴드가 정한다.
- 🚨 숫자는 화면 전체에서 일치해야 한다.
aux 항목을 개수에서 뺐으면 본문 문장의 개수도 함께 고친다.
실제로 목록은 5곳인데 본문이 6곳이라고 적힌 적이 있다.
- 익숙한 말은 남긴다:
역세권·준역세권·초품아·상권.
🚨 운영 상태는 장소명 문자열에만 있다 — 폐점·오픈예정 (2026-07-10)
카카오는 운영 상태 필드를 주지 않는다. 상태를 장소명에 괄호로 붙인다.
학교 "서울반포초등학교 (휴교)", 역 "위례호수공원역 (2026년12월예정)" 이 실측으로 확인됐다.
- 장소명에
폐점·폐업·휴업·임시휴업·오픈예정·개점예정·(20NN년 이 있으면
신호 등급·최근접·개수에서 제외하고, 목록에만 꼬리표를 단다.
- 재개장 시점·연도를 지어내지 말 것. 장소명에 있는 문자열만 화면에 쓴다.
- ✅ 상업시설에서도 관측 확정 (잠실 실측 2026-07-10). 더 이상 예방 규칙이 아니다.
categories:['mart_large'] r2500 응답에 그대로 섞여 나왔다.
홈플러스 잠실점 (폐점) 774m 가정,생활 > 대형마트 > 홈플러스
롯데마트 월드타워점 799m 가정,생활 > 대형마트 > 롯데마트 ← 운영 중 최근접
25m 차이로 문 닫은 점포가 최근접 대형마트를 가로챈다. category_name·거리 모두 정상 시설과 같아
응답만 보고는 구분할 수 없다. 같은 실측에서 공공기관(풍납2동주민센터 (2027년 예정))에서도 관측됐다.
🚨 query="백화점" 은 입점 매장이 45건 캡을 다 먹는다 (실측 2026-07-10)
카카오는 백화점 입점 매장 장소명에 지점명을 붙인다. 거리순 정렬이라 본체보다 매장이 먼저 온다.
반포래미안아이파크 · radius_m=4000 · query="백화점"
→ 45건 전부 입점 매장. 백화점 본체 0건. truncated: true
신세계 본사 736m 서비스,산업 > 기업 ← 최근접
르메르 신세계백화점 강남점 757m 가정,생활 > 패션 > 여성의류
미가훠궈 신세계백화점 강남점 778m 음식점 > 중식
룰루레몬 · 커피스니퍼 · 노스페이스키즈 · 키친툴 …
category_name == "백화점" 인 본체만 남기는 후처리는 이 경우 0건을 반환한다.
"백화점 없음"이 아니라 캡에 잘려 안 보이는 것이다. park 카테고리가 죽은 것과 같은 구조다.
해결 검색식 (실측 검증 2026-07-10)
search_by_nearby_keyword(center, radius_m=2000, query="백화점",
grid=true, category_filter={include_contains:["백화점"]})
→ total_found 68 → after_filter 2 → after_dedupe 1 · truncated: false
신세계백화점 강남점 888m 가정,생활 > 백화점 > 신세계백화점 ← 본체 복구
- 🚨
grid=true 와 include_contains:["백화점"] 을 함께 준다. 하나만으로는 안 된다.
include 필터는 서버 후처리라 캡 이후에 걸린다 → grid 로 캡을 우회해야 본체가 필터에 도달한다.
- 반경을 넓히면 오히려 나빠진다. grid 없이 4km = 본체 0건 / grid로 2km = 본체 1건.
입점 매장이 거리순 상위를 채우기 때문이다. 넓은 반경이 필요하면 반드시
grid.
- 🚨
0건 이라고 쓰기 전에 truncated 를 본다. truncated:true 면 "백화점 없음"이 아니라 "확인 불가".
- ⚠️ 아래 방배 검증(2026-07-08)의
백화점 0건 은 이 규칙 이전 결과다 → 재검증 필요.
MCP 도구 네임스페이스와 출처
ipzitalk MCP 도구의 네임스페이스는 실행 환경(Codex, Claude Code, Hermes, claude.ai 커넥터 등)에 따라 다르다.
이 문서에 적힌 도구 이름(search_announcement_info, get_geocode, get_map_embed_url 등)은 접두사 없는 기본 도구명(base tool name) 이다.
- 먼저 연결된 도구 목록에서 같은 기본 도구명을 찾는다.
- 그중
ipzitalk-remote 플러그인의 ipzitalk 서버 provenance가 확인되는 도구만 우선 사용한다. Codex에서는 실제 도구 호출 이벤트의 server: ipzitalk과 기본 도구명을 기준으로 확인한다.
presale-mcp 또는 다른 로컬 MCP provenance의 동명 도구는 Remote Skill의 대체 수단으로 사용하지 않는다.
- provenance를 확인할 수 없거나 같은 기본 도구명이 여러 서버에 있어 모호하면 임의 선택하지 말고 중단하여 필요한 Remote 도구명을 안내한다.
클라이언트가 연결 도구 목록에 plugin/server provenance를 구조적으로 제공하지 않을 때만 다음 명시적 fallback을 사용한다.
mcp__plugin_ipzitalk-remote_ipzitalk__<도구명>
mcp__ipzitalk_mcp__<도구명>
mcp__ipzitalk__<도구명>
mcp__claude_ai_ipzitalk__<도구명>
fallback으로도 Remote 출처를 유일하게 확인할 수 없으면 값을 추정하지 말고, 사용자에게 ipzitalk Remote MCP 연결 상태를 확인하도록 안내한 뒤 중단한다.