/** * 기능 개념 지도 — vscode 의존 없는 순수 모듈 (테스트 용이). * * 두 소비처: * 1. featureInventory.ts — "ASTRA 기능 인벤토리" 마크다운 생성 (LLM 프롬프트 주입용) * 2. postAnswerHooks inventory-cross-check — 답변이 *이미 구현된 기능*을 신규 * 제안하는지 결정론적으로 검사해 정정 푸터를 붙임 * * 2번이 존재하는 이유: 인벤토리를 프롬프트에 주입해도 작은 로컬 모델은 mid-prompt * 컨텍스트를 무시하고 일반론으로 "X를 도입하라"고 제안하는 실패가 반복 재현됐다. * 프롬프트 주입은 1차 방어선일 뿐 — 모델이 무시해도 사용자에게 정정이 보이는 * 결정론적 안전망(LLM 콜 0)이 최종 방어선이다. */ export interface ConceptEntry { /** 학술/일반 명칭 (마크다운 표기용). */ concept: string; /** ASTRA 구현 내역 한 줄. */ impl: string; /** 답변 본문에서 이 개념을 식별하는 키워드 (소문자 비교, 한·영). */ keywords: string[]; } export const CONCEPT_ENTRIES: ConceptEntry[] = [ { concept: 'CoVe / Chain-of-Verification / Self-Critique', impl: '구현됨 — coveEnabled(답변 전 그라운딩 체크리스트) + critic-loop 훅(문제 신호 턴 LLM 검수) + citationTrace(출처 역추적)', keywords: ['cove', 'chain-of-verification', 'self-critique', 'selfcritique', 'self-correction', '자기 검증', '자기검증', '자기 수정', '크리틱 에이전트', '비판적 사고 루프', '스스로 검토하는 단계'], }, { concept: '지식 노후 점검 자동화 / Automated Decay Audit', impl: '구현됨 — 주간 성장 사이클이 매주 자동 실행 (decay-report.md) + "Astra: 지식 노후 점검" 수동 명령', keywords: ['노후화', '노후 점검', 'decay', '지식 신선도'], }, { concept: '지식 충돌 감지/해결 / Conflict Resolver', impl: '구현됨 — 검색 시점 [CONFLICT WARNING] + 일일 충돌 스캔 + 신뢰도(trust·confidence·최신성) 비교 우선 권고. 최종 결정만 사람', keywords: ['충돌 감지', '충돌 해결', 'conflict resolver', '상충되는 정보 발견'], }, { concept: '피드백 태깅 / 오류 분류 / Feedback Tagging', impl: '구현됨 — Correction Loop가 사용자 정정을 자동 분류(사실오류/근거누락/맥락누락/추론오류/지시불이행/형식오류)해 레슨+회귀 케이스로 저장', keywords: ['피드백 태깅', '피드백 루프 자동화', '오류 분류', '교훈으로 자동', '자동으로 \'교훈\'', '교훈을 자동', 'feedback tagging'], }, { concept: '멀티스텝 플래닝 / Multi-Step Planning / CoT 강제', impl: '구현됨 — multiAgentEnabled(Planner→Researcher→Writer, 기본 OFF) + 1인 기업 모드 디스패처', keywords: ['멀티스텝 플래닝', 'multi-step planning', 'cot 강제', 'reasoning chain', '추론 체인', 'chain of thought', '생각 단계(thought)', '생각의 단계'], }, { concept: '골든셋 자동 평가 / Regression Test', impl: '구현됨 — 주간 사이클 자동 평가 + 직전 대비 회귀 경보(regression-alert.md) + 정정 회귀 재검사', keywords: ['골든셋', '회귀 테스트', 'regression test'], }, { concept: 'Sleep-time / 유휴 시간 학습', impl: '구현됨 — 일일 지식 사전 소화 (Digests/)', keywords: ['sleep-time', '유휴 시간 학습', '유휴시간 학습'], }, { concept: '확신도 게이팅 / 환각 방지 표명', impl: '구현됨 — [GROUNDING] 강함/보통/약함 + 약함 시 표명 강제 + 학습큐 자동 등록', keywords: ['확신도 게이팅', '환각 방지', '확신 편향'], }, { concept: 'Reflection Layer / 자기 성찰 / 메타 학습 루프 / Self-Reflection', impl: '구현됨 — Self-Reflector Phase A(답변 자가 점검 블록, opt-in) + Phase B(외부 검증 LLM + 자동 재시도) + Phase C(생성 파일 syntax 검증) + Hollow Code Check(빈 깡통 감지 + 자동 재작업) + 약점 프로필→자기검토 블록(최근 정정 통계가 다음 턴 행동을 직접 변경)', keywords: ['reflection layer', 'self-reflection', '자기 성찰', '성찰 계층', '성찰 단계', '성찰(reflection)', '메타 학습'], }, { concept: '질문 전 자가 조사 / Self-Research / 경험 기반 제약 주입', impl: '구현됨 — Intent Alignment 자가 조사(질문을 사용자에게 노출하기 전 두뇌 검색으로 선해결) + 사용자 답변 두뇌 자동 저장(Alignment Knowledge 학습 루프) + 레슨 체크리스트 truncation 보호 구역 주입', keywords: ['자가 조사', 'self-research', '경험 기반 제약'], }, ]; /** * 신규 도입/추가/구축을 제안하는 문장인지 (또는 부재를 단정하는 문장). * '합' 포함 — "추가합니다/구축합니다" 활용형 미매치 갭 (회귀 테스트로 발견). * '강화' 동사 + "도입:" 명사형(소제목 스타일) 추가 — 12B 답변의 * "Reasoning Chain 도입: ..." 패턴 미매치 갭 (회귀 테스트로 발견). */ const PROPOSAL_RE = /(도입|추가|구축|신설|개발|보강|강화|만들)(하|해|할|합|을|를)|(도입|추가|구축|신설)\s*[::]|필요합니다|제안합니다|추천합니다|부족합니다|부재|없습니다|미흡/; /** 같은 문장에서 이미 구현 사실을 인지하고 있으면 정정 불필요. */ const ACKNOWLEDGED_RE = /(이미|기)\s*(구현|존재|있)|구현돼|구현되어|작동\s*중/; export interface ReimplementationHit { concept: string; impl: string; /** 감지된 문장 (검증/디버그용, 120자 cap). */ sentence: string; } /** * 답변이 이미 구현된 기능을 "도입하라/없다"고 제안·단정하는 문장을 결정론적으로 * 감지. LLM 콜 0 — 문장 단위 키워드 + 제안 동사 공기(co-occurrence) 검사. * 보수적 설계: 같은 문장에 "이미 구현/존재" 인지가 있으면 제외 (정정 노이즈 방지). */ export function detectReimplementedProposals(answer: string): ReimplementationHit[] { if (!answer || !answer.trim()) return []; // 문장 분리 — 마침표/줄바꿈/콜론 기준의 느슨한 분할이면 충분. const sentences = answer.split(/(?<=[.!?다요음됨])\s+|\n+/); const hits: ReimplementationHit[] = []; const seen = new Set(); for (const sentence of sentences) { const lower = sentence.toLowerCase(); if (!PROPOSAL_RE.test(sentence)) continue; if (ACKNOWLEDGED_RE.test(sentence)) continue; for (const entry of CONCEPT_ENTRIES) { if (seen.has(entry.concept)) continue; if (entry.keywords.some((k) => lower.includes(k.toLowerCase()))) { seen.add(entry.concept); hits.push({ concept: entry.concept, impl: entry.impl, sentence: sentence.trim().slice(0, 120), }); } } } return hits; } /** 정정 푸터 마크다운 — 빈 hits 면 ''. */ export function formatReimplementationFooter(hits: ReimplementationHit[]): string { if (hits.length === 0) return ''; const lines: string[] = []; lines.push('\n\n---'); lines.push('⚠️ **기능 인벤토리 자동 대조** (결정론적 검사 — LLM 아님): 위 답변이 신규 도입을 제안한 항목 중 다음은 **이미 구현되어 있습니다**.'); for (const h of hits) { lines.push(`- **${h.concept}** → ${h.impl}`); } lines.push(''); lines.push('_위 제안을 채택하기 전에 기존 구현을 먼저 확인하세요. (두뇌의 "ASTRA 기능 인벤토리.md" 참조)_'); return lines.join('\n'); }