정책 변경: 주기 수집 없이 고정 데이터셋을 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>
23 lines
1.2 KiB
SQL
23 lines
1.2 KiB
SQL
-- 임베딩 모델 전환: 로컬 multilingual-e5-small (384차원)
|
|
-- mock/openai 도 384 로 통일한다 (openai 는 dimensions 파라미터로 축소 요청).
|
|
DO $$
|
|
BEGIN
|
|
IF (SELECT format_type(atttypid, atttypmod) FROM pg_attribute
|
|
WHERE attrelid = 'keyword'::regclass AND attname = 'embedding') <> 'vector(384)' THEN
|
|
DROP INDEX IF EXISTS keyword_embedding_hnsw;
|
|
ALTER TABLE keyword ALTER COLUMN embedding TYPE vector(384) USING NULL::vector(384);
|
|
CREATE INDEX keyword_embedding_hnsw ON keyword USING hnsw (embedding vector_cosine_ops);
|
|
END IF;
|
|
|
|
IF (SELECT format_type(atttypid, atttypmod) FROM pg_attribute
|
|
WHERE attrelid = 'qa_pair'::regclass AND attname = 'embedding') <> 'vector(384)' THEN
|
|
ALTER TABLE qa_pair ALTER COLUMN embedding TYPE vector(384) USING NULL::vector(384);
|
|
END IF;
|
|
END $$;
|
|
|
|
-- 데이터셋 출처 추적 (수작업 큐레이션 / LLM 생성 구분)
|
|
ALTER TABLE keyword ADD COLUMN IF NOT EXISTS source text NOT NULL DEFAULT 'llm';
|
|
ALTER TABLE keyword ADD COLUMN IF NOT EXISTS kind text NOT NULL DEFAULT 'keyword';
|
|
ALTER TABLE keyword ADD COLUMN IF NOT EXISTS category text;
|
|
CREATE INDEX IF NOT EXISTS keyword_kind_idx ON keyword (kind, category);
|