perf(scoring): optimized retrieval engine with caching and IDF smoothing v2.69.0
This commit is contained in:
Generated
+2
-2
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "g1nation",
|
"name": "g1nation",
|
||||||
"version": "2.68.0",
|
"version": "2.69.0",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "g1nation",
|
"name": "g1nation",
|
||||||
"version": "2.68.0",
|
"version": "2.69.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"marked": "^18.0.2"
|
"marked": "^18.0.2"
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
"name": "astra",
|
"name": "astra",
|
||||||
"displayName": "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.",
|
"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.68.0",
|
"version": "2.69.0",
|
||||||
"publisher": "g1nation",
|
"publisher": "g1nation",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"icon": "assets/icon.png",
|
"icon": "assets/icon.png",
|
||||||
|
|||||||
@@ -28,16 +28,43 @@ const STOP_WORDS_KO = new Set([
|
|||||||
'대한', '대해', '통해', '따라', '위해', '대로', '만큼'
|
'대한', '대해', '통해', '따라', '위해', '대로', '만큼'
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
// ─── Internal Cache for Tokenization ───
|
||||||
|
const TOKEN_CACHE = new Map<string, string[]>();
|
||||||
|
const MAX_CACHE_SIZE = 1000;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 한국어/영어 혼합 텍스트를 토큰으로 분리합니다.
|
* 한국어/영어 혼합 텍스트를 정규화하고 토큰으로 분리합니다.
|
||||||
|
* (Performance Optimization: 내부 캐시 적용)
|
||||||
*/
|
*/
|
||||||
export function tokenize(text: string): string[] {
|
export function tokenize(text: string): string[] {
|
||||||
return text
|
if (!text) return [];
|
||||||
|
|
||||||
|
// 캐시 확인
|
||||||
|
if (TOKEN_CACHE.has(text)) {
|
||||||
|
return TOKEN_CACHE.get(text)!;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1. Pre-normalization: 특수문자 정제 및 표준화
|
||||||
|
const normalized = text
|
||||||
.toLowerCase()
|
.toLowerCase()
|
||||||
|
.replace(/[\u200B-\u200D\uFEFF]/g, '') // Zero-width spaces 제거
|
||||||
|
.replace(/[^\w\s가-힣_.-]/g, ' ') // 허용된 문자 외에는 공백 처리
|
||||||
|
.trim();
|
||||||
|
|
||||||
|
// 2. Tokenization: 정제된 텍스트 분리
|
||||||
|
const tokens = normalized
|
||||||
.split(/[^a-z0-9가-힣_.-]+/g)
|
.split(/[^a-z0-9가-힣_.-]+/g)
|
||||||
.map((t) => t.trim())
|
.map((t) => t.trim())
|
||||||
.filter((t) => t.length >= 2)
|
.filter((t) => t.length >= 2)
|
||||||
.filter((t) => !STOP_WORDS_EN.has(t) && !STOP_WORDS_KO.has(t));
|
.filter((t) => !STOP_WORDS_EN.has(t) && !STOP_WORDS_KO.has(t));
|
||||||
|
|
||||||
|
// 캐시 저장 (메모리 관리: 임계값 초과 시 비우기)
|
||||||
|
if (TOKEN_CACHE.size >= MAX_CACHE_SIZE) {
|
||||||
|
TOKEN_CACHE.clear();
|
||||||
|
}
|
||||||
|
TOKEN_CACHE.set(text, tokens);
|
||||||
|
|
||||||
|
return tokens;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -90,13 +117,24 @@ function termFrequency(term: string, documentTokens: string[]): number {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* IDF (Inverse Document Frequency): 전체 문서 대비 희소도
|
* IDF (Inverse Document Frequency): 전체 문서 대비 희소도
|
||||||
|
* (Stability Enhancement: Smoothing 적용 및 최소 문서 수 대응)
|
||||||
*/
|
*/
|
||||||
function inverseDocumentFrequency(
|
function inverseDocumentFrequency(
|
||||||
term: string,
|
term: string,
|
||||||
allDocumentTokenSets: Array<Set<string>>
|
allDocumentTokenSets: Array<Set<string>>
|
||||||
): number {
|
): number {
|
||||||
|
const N = allDocumentTokenSets.length;
|
||||||
|
if (N === 0) return 1.0;
|
||||||
|
|
||||||
const containing = allDocumentTokenSets.filter((doc) => doc.has(term)).length;
|
const containing = allDocumentTokenSets.filter((doc) => doc.has(term)).length;
|
||||||
return Math.log((allDocumentTokenSets.length + 1) / (containing + 1)) + 1;
|
|
||||||
|
// N이 매우 작을 때(예: 5개 이하) 스코어 편향 방지를 위한 최소 분모 보정
|
||||||
|
const smoothN = N < 5 ? N + 5 : N;
|
||||||
|
const smoothContaining = containing;
|
||||||
|
|
||||||
|
// Standard Smooth IDF: log((N+1) / (containing+1)) + 1
|
||||||
|
// containing이 0일 경우에도 안전하게 동작하도록 설계
|
||||||
|
return Math.log((smoothN + 1) / (smoothContaining + 1)) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ScoredDocument {
|
export interface ScoredDocument {
|
||||||
|
|||||||
Reference in New Issue
Block a user