o2o-site-ontology/src/serving/serving.module.ts
hbyang f7485aab32 매칭을 속성별 다중 질의 + 가중 RRF + 사실 기반 필터로 재구성
프로필을 통짜로 한 벡터에 넣으면 속성이 희석된다.
실측: 통짜는 점수 폭 0.0076, 속성별로 쪼개면 0.0624 (8배).

- src/serving/match.rules.ts — 레인 빌더, 권역 판정, 수용 인원/시설 필터,
  시설 통제 어휘 정규화
- src/serving/match.service.ts — 레인별 검색 → 가중 RRF 융합 → 필터 →
  레인별 그룹(byLane) 출력. 근거(어느 레인 몇 위)를 함께 반환
- POST /v1/match 에 mode=fusion(기본) / single(기존 통짜, 비교용)
- 데모 페이지: 모드 토글, 레인 카드, 융합/레인별/배제됨 탭

레인 설계에서 실측으로 고친 것
- 브랜드 레인 제거 — 상호는 사전에 없어 generic '군산 펜션 ~예약'만 끌어왔다
- 권역/인근 레인 병합 — '신흥동' 토큰이 겹쳐 위치 키워드가 상위를 쓸어갔다
- RRF 상수 60 → 20 — 60은 1위/40위 기여도 차이가 1.6배뿐이라 generic이 유리했다

사실 기반 필터는 벡터가 못 거르는 모순을 배제한다.
스테이머뭄(최대 4인, 원도심) 기준 61건 배제.
미확인 시설은 배제하지 않고 '보류'로 표시한다 — 없음이 아니라 모름이므로.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-09 16:00:00 +09:00

15 lines
565 B
TypeScript

import { Module } from '@nestjs/common';
import { KeywordsModule } from '../keywords/keywords.module';
import { MerchantsModule } from '../merchants/merchants.module';
import { DemoController } from './demo.controller';
import { MatchService } from './match.service';
import { ServingController } from './serving.controller';
import { ServingService } from './serving.service';
@Module({
imports: [MerchantsModule, KeywordsModule],
controllers: [ServingController, DemoController],
providers: [ServingService, MatchService],
})
export class ServingModule {}