feat: v2.2.173-193 — 4인 팀 운영 슬래시 13개 + ASTRA 검증 엔진 6종
4인 팀 운영 슬래시 (v2.2.173~189):
- 일과 리듬: /morning, /evening, /weekly, /standup
- 트래커 (event-sourced .astra/*.jsonl): /runway, /customers, /hire
- 작업·결정: /task, /blocked, /onesie, /decisions
- 외부 출력: /draft, /feedback
- 분석: /cohort (MoM 추세)
ASTRA 추론·검색 엔진 (v2.2.183~192):
- v2.2.183 Conflict Surface — scoring.conflictSeverity 를 [CONFLICT WARNINGS] 블록으로
서피스 + 교차-문서 발산(Jaccard) 감지
- v2.2.184 Chain-of-Verification — [VERIFICATION CHECKLIST] 답변 작성 전 그라운딩 자기 점검
(instructional, strictMode 옵션)
- v2.2.185 Actionability Scoring — 최근 슬래시 명령 + 열린 파일 신호로 검색 결과 재가중
- v2.2.186 Temporal Markers + Distillation Loop — LongTerm/Episodic 만료 필터 +
30일+ stale episode → LongTerm 'episode-digest' 승급 (수동 /memory distill + 세션 종료 자동)
- v2.2.187 Hierarchical Context Window + LLM Semantic Re-rank — 3-level 추상도 매칭
+ 토큰 예산 통과 후 LLM 1회로 의도-부합 재정렬 (opt-in)
- v2.2.190 Intent Clarification + Citation Trace — 모호 차원 감지 시 역질문 우선
+ 답변 끝 사용 출처 한 줄 정리
- v2.2.191 Post-hoc Self-Check — 답변 완료 후 별도 LLM 호출 1회로 답함/그라운딩/모순 평가,
footer 한 줄로 표시 (opt-in, semantic re-rank 와 같은 안전 fallback 패턴)
- v2.2.192 Terminology Dictionary — .astra/glossary.md 사용자 편집 파일 + Term Check
지침 통합 + /glossary init/path/reload
- v2.2.193 /help — 카테고리별 명령 목록 + 6종 verification 블록 현재 on/off
신규 모듈:
- src/retrieval/{conflictBlock,coveBlock,actionabilityScoring,hierarchicalLevel,
semanticRerank,intentClarification,citationTrace,terminologyBlock}.ts
- src/memory/distillation.ts + types.ts 에 expiresAt/promoted/episode-digest 추가
- src/agent/postHocSelfCheck.ts
- src/features/{customers,feedback,hire,runway}/*.ts (event-sourced stores)
ASTRA 검증 5종 자동 주입 (buildAstraModeSystemPrompt, casual 모드 제외):
[INTENT CLARIFICATION GUIDANCE] (답변 시작 전) → [TERMINOLOGY DICTIONARY] +
[CONFLICT WARNINGS] + [VERIFICATION CHECKLIST] (작성 중) → [CITATION TRACE] (끝)
+ 6번째: Post-hoc Self-Check footer (답변 완료 후, opt-in)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
+132
@@ -60,6 +60,113 @@ export interface IAgentConfig {
|
||||
* Default 0.5 = equal weight, a reasonable starting point.
|
||||
*/
|
||||
embeddingBlendAlpha: number;
|
||||
/**
|
||||
* Conflict Surface — 검색된 출처의 conflictSeverity 신호를 [CONFLICT WARNINGS] 블록
|
||||
* 으로 시스템 프롬프트에 노출. v4 정책 텍스트(buildAstraModeSystemPrompt) 가 이미
|
||||
* "[CONFLICT WARNING] 플래그" 를 참조하지만, 데이터를 LLM 에 전달하지 않아 무용했음.
|
||||
* true(기본) → 충돌 감지 시 블록 주입, false → 비활성.
|
||||
*/
|
||||
conflictHighlightingEnabled: boolean;
|
||||
/**
|
||||
* Conflict 자기-신호 surface 시 최소 severity 임계.
|
||||
* 'low' → LOW 이상 (가장 민감, 노이즈 가능)
|
||||
* 'medium' → MEDIUM 이상 (기본, 균형)
|
||||
* 'high' → HIGH 만 (가장 보수적, 강한 충돌만)
|
||||
*/
|
||||
conflictSeverityThreshold: 'low' | 'medium' | 'high';
|
||||
/**
|
||||
* 교차-문서 발산 감지 (같은 주제 ≥2 chunks, 본문 Jaccard < 0.30 인 잠재 모순 쌍).
|
||||
* 자기-신호와 합쳐 [CONFLICT WARNINGS] 블록에 표시.
|
||||
*/
|
||||
conflictCrossDocEnabled: boolean;
|
||||
/**
|
||||
* CoVe (Chain-of-Verification) — 답변 *작성 전* 그라운딩 체크리스트를 시스템 프롬프트에
|
||||
* 주입해 모델이 self-verify 하도록. 할루시네이션 방지 + 그라운딩 명확화.
|
||||
* true(기본) → 검색된 출처 있을 때 [VERIFICATION CHECKLIST] 블록 주입.
|
||||
*/
|
||||
coveEnabled: boolean;
|
||||
/** CoVe 체크리스트에 나열할 상위 출처 개수. 기본 5. */
|
||||
coveTopSourcesCount: number;
|
||||
/**
|
||||
* CoVe Strict 모드 — 모든 사실 주장 뒤에 출처 ID([S1] 등) inline 인용 강제.
|
||||
* 답변이 좀 더 학술적·verbose 해질 수 있어 기본 off.
|
||||
*/
|
||||
coveStrictMode: boolean;
|
||||
/**
|
||||
* Actionability — "현재 작업 상태" 신호(최근 슬래시 명령 + 열린 파일) 로 검색 결과
|
||||
* 재가중. TF-IDF 매치 점수에 actionability boost 추가해 "지금 작업 중인 컨텍스트" 와
|
||||
* 직접 연결된 문서를 우선. 기본 true.
|
||||
*/
|
||||
actionabilityEnabled: boolean;
|
||||
/**
|
||||
* Memory Lifecycle — Distillation Loop: stale Episodic Memory 를 LongTerm 'episode-digest'
|
||||
* 로 승급. 누적 epimemory 가 검색 노이즈가 되는 것 방지.
|
||||
* true(기본) → /memory distill + 세션 종료 시 자동 트리거 (interval 기준).
|
||||
*/
|
||||
distillationEnabled: boolean;
|
||||
/** 며칠 이상 지난 episode 를 distill 대상으로. 기본 30. */
|
||||
distillationAgeThresholdDays: number;
|
||||
/** 자동 distillation 의 최소 간격 (일). 너무 자주 안 돌도록. 기본 7. */
|
||||
distillationIntervalDays: number;
|
||||
/**
|
||||
* Archive 모드:
|
||||
* - 'mark-promoted' (기본): promoted=true 마킹만, 파일 보존
|
||||
* - 'archive-file': promoted 마킹 + 파일을 memory/episodes/archive/ 로 이동
|
||||
*/
|
||||
distillationArchiveMode: 'mark-promoted' | 'archive-file';
|
||||
/**
|
||||
* Hierarchical Context Window — 질의·문서 추상도(concrete/operational/strategic) 매칭으로
|
||||
* 검색 결과 재가중. 같은 레벨 boost (× 1.15), 양 끝 mismatch penalty (× 0.7). LLM 호출 없음.
|
||||
*/
|
||||
hierarchicalReweightEnabled: boolean;
|
||||
/**
|
||||
* Semantic Re-ranking — 토큰 예산 통과한 selectedChunks 의 *순서* 를 LLM 한 번 호출로
|
||||
* 재정렬. 의도 매치를 키워드 매치보다 우선. 매 turn 1회 추가 LLM 호출 (latency 비용).
|
||||
* 기본 OFF — 명시적으로 on 해야 함.
|
||||
*/
|
||||
semanticRerankEnabled: boolean;
|
||||
/** 재정렬 전용 모델 ID. 비면 defaultModel 사용. 빠른 작은 모델 권장. */
|
||||
semanticRerankModel: string;
|
||||
/** Re-rank 대상 상위 후보 개수. 기본 15. */
|
||||
semanticRerankCandidateK: number;
|
||||
/** Re-rank LLM 호출 타임아웃 (초). 기본 8. */
|
||||
semanticRerankTimeoutSec: number;
|
||||
/**
|
||||
* Intent Clarification — 모호 질의에서 *추측 답변 대신 역질문* 지시.
|
||||
* 휴리스틱 차원(환경/대상/범위/포맷/마감) 별 trigger + specifier 매치. 기본 true.
|
||||
*/
|
||||
intentClarificationEnabled: boolean;
|
||||
/**
|
||||
* 모호 판정 임계:
|
||||
* - 'low': 2개 이상 missing dimension 일 때만 ambiguous (가장 덜 묻기)
|
||||
* - 'medium' (기본): 1개 이상 missing → ambiguous
|
||||
* - 'high': 1개 이상 missing OR 짧은 prompt(<20자)+trigger 있으면 ambiguous (가장 자주 묻기)
|
||||
*/
|
||||
intentClarificationStrictness: 'low' | 'medium' | 'high';
|
||||
/**
|
||||
* Citation Trace — 답변 끝에 "출처:" 한 줄 정리 지시. CoVe Strict 의 가벼운 형제.
|
||||
* 검색 결과 있을 때만 동작. 기본 true.
|
||||
*/
|
||||
citationTraceEnabled: boolean;
|
||||
/**
|
||||
* Post-hoc Self-Check — 답변 *완료 후* LLM 1회 호출로 검증 (답변 직접도 / 그라운딩 /
|
||||
* 논리 모순). 매 turn 추가 LLM 호출 (latency 비용). 기본 OFF — 명시적 opt-in.
|
||||
* 결과는 답변 아래 footer 한 줄로 표시.
|
||||
*/
|
||||
selfCheckEnabled: boolean;
|
||||
/** Self-check 전용 모델 ID. 비면 defaultModel. 빠른 작은 모델 권장. */
|
||||
selfCheckModel: string;
|
||||
/** Self-check LLM 호출 타임아웃 (초). 기본 6. */
|
||||
selfCheckTimeoutSec: number;
|
||||
/**
|
||||
* Terminology Dictionary — 사용자 편집 글로서리 파일을 시스템 프롬프트에 주입,
|
||||
* 표준 표기 강제 + 답변 직전 자기 점검(Term Check). 기본 true. 파일 없으면 자동 no-op.
|
||||
*/
|
||||
glossaryEnabled: boolean;
|
||||
/** Glossary 파일 상대 경로 (workspace root 기준). 기본 '.astra/glossary.md'. */
|
||||
glossaryPath: string;
|
||||
/** Glossary 본문 시스템 프롬프트 cap (chars). 너무 크면 토큰 비용↑. 기본 4000. */
|
||||
glossaryMaxBodyLength: number;
|
||||
/**
|
||||
* Global Knowledge Mix weight (0–100). Controls how much the assistant leans on
|
||||
* Second Brain evidence vs. model general knowledge when answering.
|
||||
@@ -307,6 +414,31 @@ export function getConfig(): IAgentConfig {
|
||||
finalOnlyRetryOnThoughtLeak: cfg.get<boolean>('finalOnlyRetryOnThoughtLeak', true),
|
||||
embeddingModel: (cfg.get<string>('embeddingModel', '') || '').trim(),
|
||||
embeddingBlendAlpha: Math.max(0, Math.min(1, cfg.get<number>('embeddingBlendAlpha', 0.5))),
|
||||
conflictHighlightingEnabled: cfg.get<boolean>('conflictHighlightingEnabled', true),
|
||||
conflictSeverityThreshold: (cfg.get<string>('conflictSeverityThreshold', 'medium') as 'low' | 'medium' | 'high') || 'medium',
|
||||
conflictCrossDocEnabled: cfg.get<boolean>('conflictCrossDocEnabled', true),
|
||||
coveEnabled: cfg.get<boolean>('coveEnabled', true),
|
||||
coveTopSourcesCount: Math.max(1, Math.min(15, cfg.get<number>('coveTopSourcesCount', 5))),
|
||||
coveStrictMode: cfg.get<boolean>('coveStrictMode', false),
|
||||
actionabilityEnabled: cfg.get<boolean>('actionabilityEnabled', true),
|
||||
distillationEnabled: cfg.get<boolean>('distillationEnabled', true),
|
||||
distillationAgeThresholdDays: Math.max(1, Math.min(365, cfg.get<number>('distillationAgeThresholdDays', 30))),
|
||||
distillationIntervalDays: Math.max(1, Math.min(90, cfg.get<number>('distillationIntervalDays', 7))),
|
||||
distillationArchiveMode: (cfg.get<string>('distillationArchiveMode', 'mark-promoted') as 'mark-promoted' | 'archive-file') || 'mark-promoted',
|
||||
hierarchicalReweightEnabled: cfg.get<boolean>('hierarchicalReweightEnabled', true),
|
||||
semanticRerankEnabled: cfg.get<boolean>('semanticRerankEnabled', false),
|
||||
semanticRerankModel: cfg.get<string>('semanticRerankModel', '') || '',
|
||||
semanticRerankCandidateK: Math.max(2, Math.min(30, cfg.get<number>('semanticRerankCandidateK', 15))),
|
||||
semanticRerankTimeoutSec: Math.max(1, Math.min(60, cfg.get<number>('semanticRerankTimeoutSec', 8))),
|
||||
intentClarificationEnabled: cfg.get<boolean>('intentClarificationEnabled', true),
|
||||
intentClarificationStrictness: (cfg.get<string>('intentClarificationStrictness', 'medium') as 'low' | 'medium' | 'high') || 'medium',
|
||||
citationTraceEnabled: cfg.get<boolean>('citationTraceEnabled', true),
|
||||
selfCheckEnabled: cfg.get<boolean>('selfCheckEnabled', false),
|
||||
selfCheckModel: cfg.get<string>('selfCheckModel', '') || '',
|
||||
selfCheckTimeoutSec: Math.max(1, Math.min(60, cfg.get<number>('selfCheckTimeoutSec', 6))),
|
||||
glossaryEnabled: cfg.get<boolean>('glossaryEnabled', true),
|
||||
glossaryPath: cfg.get<string>('glossaryPath', '.astra/glossary.md') || '.astra/glossary.md',
|
||||
glossaryMaxBodyLength: Math.max(500, Math.min(20000, cfg.get<number>('glossaryMaxBodyLength', 4000))),
|
||||
knowledgeMixSecondBrainWeight: Math.max(0, Math.min(100, Math.round(
|
||||
cfg.get<number>('knowledgeMix.secondBrainWeight', 50)
|
||||
))),
|
||||
|
||||
Reference in New Issue
Block a user