- scripts/ingest-nationwide.ts — 지역 계층 66개 노드 선행 등록 후 적재
source='nationwide' 로 군산 상세 데이터셋(dataset)과 공존
태그는 지역 중립이므로 region_id NULL
- 광역 롤업 키를 ASCII 로 (ltree 라벨은 한글 불가: rollup.경기 → kr.gyeonggi)
- MATCH_SOURCES 에 nationwide 추가
데이터 오류 수정: '산간'이라고 스키장이 있는 건 아니다.
가평·양평·강화에 '스키 펜션'이 생성돼 있었다. regions.json 에 ski 플래그를 두고
실제 스키장 보유 5개 지역(평창·정선·홍천·태백·무주)에만 전개한다.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
기획 변경: 군산 단일 지역 → 전국 지역별.
- data/regions.json — 전국 54개 펜션 수요 지역 마스터
시도/지역/지역키/성격(해변·산간·호수·강변·도심·섬·계곡)/대표 관광지 202곳
복합 지명은 별칭으로 분리 (보령·대천 → 대천 + 별칭 보령)
- scripts/build-nationwide-dataset.mjs — 지역 성격에 맞는 시설·시즌만 전개
평창·무주 오션뷰 0건, 태안·거제 산뷰 0건으로 검증
- scripts/export-xlsx.py — 4개 시트 엑셀 (키워드/지역마스터/지역별요약/사용가이드)
- npm run dataset:nationwide
7,138건 / 지역당 평균 110건.
군산 974건을 54개 지역에 곱하면 5만 건이 되지만, 단일 지역 검증에서
저장분의 89%가 미사용이었으므로 티어를 매겨 눌렀다.
검색량·경쟁도 열은 비워 두었다 — 키워드도구로 채운 뒤 월 10 미만을 걷어내야 한다.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
② 사전 보강 — 실측으로 찾은 어휘 공백을 메움
- 인원: 2인·3인 추가 (4/6/10/20인만 있어 기준 2인 업체가 노릴 키워드가 없었다)
- 단독 명사형: 군산 독채 / 스테이 / 풀빌라 (조합형만 있어 단독 검색을 놓쳤다)
- 분위기 11종(감성·조용한·사진찍기 좋은·인생샷 …), 여행형태 9종(뚜벅이·1박2일 …)
- scripts/import-related.ts — 검색광고 키워드도구 내려받기 병합 (파일 임포터)
③ 사전 오염 정리
- source='llm' 27건 삭제 (강남 미용실·해운대 한식당이 군산 펜션 사전에 있었다)
- 매칭 후보를 업체 업종으로 한정 + source IN ('dataset','manual') 만 조회
- 적재 시 데이터셋에서 빠진 행 삭제 — upsert 만 하면 재빌드마다 누적된다 (974 → 1072)
④ 고객 언어 레인 (w=0.9)
- hashtags + reviewSignals(원문 아닌 빈도 집계) 를 별도 레인으로
- 사업자 표현보다 검색어에 가까우므로 유형 다음으로 높게 잡음
- 스테이머뭄 데이터는 아직 없음 — 인스타는 로그인 월이라 스크래퍼가 채워야 함
⑤ 레인 토큰 중복 제거
- '신흥동' 과 '신흥동 일본식가옥' 이 별개 원소라 같은 낱말이 두 번 실렸다
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
정책 변경: 주기 수집 없이 고정 데이터셋을 1회 적재한다.
- data/gunsan-pension-keywords.json — "군산 펜션" 키워드·태그 1,000건
실제 군산 지명·관광지·숙박 시설 어휘 × 로컬 검색 패턴으로 작성
- 임베딩을 LlmProvider 에서 EmbeddingProvider 로 분리
(mock | local:multilingual-e5-small | openai), e5 의 query/passage 비대칭 반영
- vector(1536) → vector(384) 마이그레이션, keyword 에 source/kind/category 추가
- scripts/ingest-dataset.ts — 어휘 중복만 자동 병합, 벡터 근접쌍은 검토 목록만 출력
- POST /v1/match — 업체명(띄어쓰기 무관) 또는 문장 → 사전에서 매칭
업체는 프로필 전체를 질의문으로 조립해 임베딩
- GET /demo — 매칭 콘솔 (public/demo.html)
실측으로 코사인 자동 병합 임계값을 0.92 → 0.99 로 정정.
짧은 한글 키워드는 같은 도메인이면 0.93+ 가 기본이라 0.92 는 오병합을 부른다.
적재 결과: 1,000건 → 어휘 중복 27 병합, 금칙어 2 차단 → 971건.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
발행된 사이트에 업체별 SEO/AEO 키워드를 제공하는 서비스.
- PostgreSQL 16 + pgvector/ltree/pg_trgm 단일 스토어
(정확·의미·계층 조회를 한 엔진에서 처리)
- 키워드는 전역 사전 + merchant_keyword 연결 테이블 구조
- 4단계 계단식 중복제거: 금칙어 → normalized 완전일치 →
pg_trgm → 코사인 유사도, 걸린 표기는 aliases[] 로 흡수
- BullMQ 생성 큐 (발행 즉시 / 일 1회 크론 / 성과 기반)
- OpenAI Structured Outputs + mock provider
(API 키 없이 로컬 전 구간 동작)
- 서빙 API: /v1/sites/:id/seo, /aeo, /performance, /keywords/search
- docs/architecture.html 설계 도식
JSON-LD 조립과 o2o-site-AEO 연동은 후속 작업.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>