feat(retrieval): 청크 검색 기본 켬(+62.5%p recall@1) + 확신도 전역화 (v2.2.218)
P1 — 섹션 청크 검색 기본 활성화: - 골든셋 24질의 A/B 측정: 파일 단위 → 섹션 청크에서 recall@1 12.5%→75.0% · recall@3 33.3%→83.3% · recall@5 37.5%→87.5% · MRR 0.217→0.802. 18질의 개선·악화 0건. - Phase 1-가 구현은 완성돼 있었으나 chunkLevelRetrieval 기본값이 false 라 실전 채팅이 열등한 파일 모드로 동작 — package.json·config 기본값 true 로. - tests/retrievalEvalCompare.test.ts: 환경변수(ASTRA_EVAL_BRAIN) 게이트형 A/B 회귀 측정 도구 (평소 skip — CI/패키징 무영향). P2 — 확신도 전역화 (/meet 원칙을 모든 대화로): - memoryContext 에 [GROUNDING] 블록 — 두뇌 근거 강도(강/보통/약)를 점수로 평가해 답변 정책 주입: 약함 → "⚠️ 두뇌 근거 약함" 표기+단정 금지, 강함 → 근거 문서 제목 인용, 보통 → 사실/추론 구분 서술. P3 — 회의 용어집 자동화 + 출력 위생: - /meet 실행마다 담당자 이름·사용자 메타데이터 용어를 .astra/meet_glossary.json 에 누적, 다음 실행 때 자동 주입 (STT 보정 용어집 — 반복 회의 표기 일관성). - selfIdentity 블록에 한·영 혼합 깨진 표기 금지 규칙 (전 대화, 무비용). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -251,3 +251,38 @@ export function renderPendingQuestion(p: PendingFile): string {
|
||||
export function logMeetRegistration(event: string, data: Record<string, unknown>): void {
|
||||
logInfo(`/meet 등록 게이트: ${event}`, data);
|
||||
}
|
||||
|
||||
// ── 회의 용어집 (반복 회의의 STT 보정 정확도용) ─────────────────────────────
|
||||
// meetPrompt 는 메타데이터를 "용어집 역할"로 쓴다 — 매번 수동 입력하는 대신,
|
||||
// 이전 /meet 실행에서 나온 인명(담당)·사용자 입력 메타데이터 용어를 워크스페이스에
|
||||
// 누적하고 다음 실행 때 자동 주입한다. (.astra/meet_glossary.json)
|
||||
const GLOSSARY_REL = 'meet_glossary.json';
|
||||
const GLOSSARY_MAX = 120;
|
||||
type Glossary = { terms: string[]; updatedAt: string };
|
||||
|
||||
export function loadGlossaryTerms(): string[] {
|
||||
return (readJson<Glossary>(GLOSSARY_REL)?.terms || []).filter(t => typeof t === 'string' && t.trim());
|
||||
}
|
||||
|
||||
/** 담당자 이름·메타데이터에서 뽑은 용어를 용어집에 누적 (중복 제거, 상한 유지). */
|
||||
export function updateGlossary(newTerms: string[]): void {
|
||||
const cleaned = newTerms
|
||||
.map(t => (t || '').trim())
|
||||
.filter(t => t.length >= 2 && t.length <= 30 && !/미지정|없음|확인|불명/.test(t));
|
||||
if (!cleaned.length) return;
|
||||
const cur = loadGlossaryTerms();
|
||||
const set = new Set(cur);
|
||||
for (const t of cleaned) set.add(t);
|
||||
// 상한 초과 시 오래된 것부터 제거 (Set 삽입 순서 = 누적 순서)
|
||||
const all = [...set];
|
||||
const terms = all.length > GLOSSARY_MAX ? all.slice(all.length - GLOSSARY_MAX) : all;
|
||||
writeJson(GLOSSARY_REL, { terms, updatedAt: new Date().toISOString() } satisfies Glossary);
|
||||
}
|
||||
|
||||
/** 사용자 메타데이터 입력에서 용어 후보 추출 — 쉼표/슬래시/공백 구분 토큰 중 고유명사형. */
|
||||
export function extractGlossaryCandidates(metadata: string): string[] {
|
||||
return (metadata || '')
|
||||
.split(/[,,/·;\n]+/)
|
||||
.map(t => t.replace(/^[\s::\-–·]+|[\s::\-–·]+$/g, ''))
|
||||
.filter(t => t.length >= 2 && t.length <= 30 && !/^\d+$/.test(t));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user