From ca9fbf125a1e74ddda0c00e8d2e2fe6f7bfb96af Mon Sep 17 00:00:00 2001 From: g1nation Date: Tue, 5 May 2026 11:03:06 +0900 Subject: [PATCH] feat(scoring): integrated conflict detection and info density metrics v2.71.0 --- package-lock.json | 4 ++-- package.json | 2 +- src/retrieval/scoring.ts | 24 +++++++++++++++++++----- 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index f9b50ed..e02c4ab 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "g1nation", - "version": "2.70.0", + "version": "2.71.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "g1nation", - "version": "2.70.0", + "version": "2.71.0", "license": "MIT", "dependencies": { "marked": "^18.0.2" diff --git a/package.json b/package.json index 376cb62..6a529c4 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "astra", "displayName": "Astra", "description": "The personal intelligence layer for Antigravity and VS Code. A private cognitive partner for deep project context, memory, and proactive strategic decision-making.", - "version": "2.70.0", + "version": "2.71.0", "publisher": "g1nation", "license": "MIT", "icon": "assets/icon.png", diff --git a/src/retrieval/scoring.ts b/src/retrieval/scoring.ts index 860e21e..cb410dc 100644 --- a/src/retrieval/scoring.ts +++ b/src/retrieval/scoring.ts @@ -51,7 +51,11 @@ const SCORING_CONFIG = { ] as [string, string[]][], DENSITY_THRESHOLD: 0.15, // 발췌문 추출 시 최소 키워드 밀도 TITLE_MULTIPLIER: 3.0, // 제목 일치 가중치 - GLOBAL_CACHE_LIMIT: 2000 + GLOBAL_CACHE_LIMIT: 2000, + CONFLICT_INDICATORS: new Set([ + '반대', '충돌', '오류', '논란', '반박', '차이', '대조', + 'conflict', 'contradict', 'dispute', 'controversy', 'error', 'mismatch', 'vs' + ]) }; // ─── Global Search State & Cache ─── @@ -168,6 +172,8 @@ export interface ScoredDocument { titleBoost: number; recencyBoost: number; matchedTerms: string[]; + conflictDetected: boolean; + informationDensity: number; } /** @@ -208,6 +214,9 @@ export function scoreTfIdf( let score = 0; const matchedTerms: string[] = []; + // Conflict Detection: 문서 내 상충 지표 확인 + const conflictDetected = docTokens.some(t => SCORING_CONFIG.CONFLICT_INDICATORS.has(t)); + for (const term of expandedQuery) { const tf = termFrequency(term, docTokens); const idf = idfCache.get(term) || 1; @@ -217,12 +226,15 @@ export function scoreTfIdf( matchedTerms.push(term); } - // Title match bonus (3x) - const titleMultiplier = titleTokens.has(term) ? 3.0 : 1.0; + // Title match bonus + const titleMultiplier = titleTokens.has(term) ? SCORING_CONFIG.TITLE_MULTIPLIER : 1.0; score += tfidf * titleMultiplier; } - // Recency boost: documents modified recently get a boost + // Information Density: 쿼리 관련 토큰의 밀도 측정 + const informationDensity = docTokens.length > 0 ? matchedTerms.length / docTokens.length : 0; + + // Recency boost let recencyBoost = 0; if (doc.lastModified) { const daysAgo = (now - doc.lastModified) / (1000 * 60 * 60 * 24); @@ -239,7 +251,9 @@ export function scoreTfIdf( score: score + recencyBoost + titleBoost, titleBoost, recencyBoost, - matchedTerms: [...new Set(matchedTerms)] + matchedTerms: [...new Set(matchedTerms)], + conflictDetected, + informationDensity }; }); }