- v2.2.299 아키텍처 수렴: coreChat 통일(엔진 휴리스틱 3벌 제거), 기업 모드 검색 오케스트레이터 승격, lib/execUtil(실행 래퍼 6곳·Python 탐지 3벌 단일화), lib/kstSchedule(워처 4개 nowInKst 통합), estimateTokens 통합, 설정 접근 규칙 명문화 - v2.2.300 채팅 화면 정리: LiveReasoningFilter(스트리밍 중 <think>/Harmony 추론 토큰 단위 차단), 확신도·검토요청 footer 기본 숨김(계산·Reflection 은 유지) - v2.2.301 문맥·의도 이해: [답변 전 이해 원칙] 상시 주입, 워크플로우 의도 브리핑, Report QA 루프(규칙 레지스트리+실측치+회귀 게이트, 블로그_v3 개념 이식) - v2.2.302 /benchmark 비즈니스 렌즈(가격·수익·운영)+빌드 프롬프트 모드+QA 연계 - v2.2.303 handoff 모드(측정치 무손실 인수인계 문서)+/claude(Claude Code 터미널 위임) - v2.2.304 이식성: 지식 경로 두뇌-상대 규약(pickWikiDir 상대 해석), 이사 체크리스트 - v2.2.305 Claude 구독 엔진: claude: 프로바이더(CLI 위임, 모델 드롭다운 자동 노출, coreChat 지원 — 워크플로우·QA도 구독 모델 가능) - v2.2.306 Tone Guard: AI 상투어 금지 레지스트리(상담사 화법 실사례 8종+대조 예시) - v2.2.307 /benchmark 레이아웃 골격(sectionRoles 결정론 분석, 롤링 배너 즉답), 파트별 실패 격리, 합성 타임아웃 120→300초 검증: tsc 무오류 + jest 888 통과 + esbuild 정상 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
110 lines
7.0 KiB
TypeScript
110 lines
7.0 KiB
TypeScript
import { buildToneGuardBlock } from '../../lib/contextBuilders/toneGuard';
|
|
import {
|
|
isProjectKnowledgeCreationRequest,
|
|
buildAstraStanceContext,
|
|
} from '../../lib/contextBuilders/localProjectIntent';
|
|
import { isThinkingPartnerRequest } from '../../lib/contextBuilders/promptDetection';
|
|
import { buildSelfIdentityBlock } from '../../lib/contextBuilders/selfIdentity';
|
|
import { buildKnowledgeMixPolicy } from '../../retrieval/knowledgeMix';
|
|
|
|
export interface BuildAstraModeSystemPromptInput {
|
|
prompt: string | null;
|
|
systemPrompt: string;
|
|
modeBridgeCtx: string;
|
|
/** [PRIOR TURN CONCLUSION] 블록 — 직전 assistant 답변의 첫 문장. follow-up 정정 대응용. */
|
|
priorConclusionCtx: string;
|
|
designerCtx: string;
|
|
projectArchitectureCtx: string;
|
|
secondBrainTraceCtx: string;
|
|
memoryCtx: string;
|
|
knowledgeContextForPrompt: string;
|
|
contextBlock: string;
|
|
negativeCtx: string;
|
|
isCasualConversation: boolean;
|
|
localPathContext: string;
|
|
/** From this._turnCtx.knowledgeMix — pass null when absent. */
|
|
knowledgeMix: any;
|
|
/**
|
|
* 동적 시스템 프롬프트 블록 Map (id → 본문). memoryContext 가 채움.
|
|
* 옛 named param 5개 (conflictWarningsCtx/coveChecklistCtx/intentClarificationCtx/
|
|
* citationTraceCtx/terminologyCtx) 를 통합. casual 모드는 자동 skip.
|
|
* 등록 순서대로 [CONTEXT] *밖* 에 join 되어 주입.
|
|
*/
|
|
dynamicBlocks?: Map<string, string>;
|
|
}
|
|
|
|
export function buildAstraModeSystemPrompt(input: BuildAstraModeSystemPromptInput): string {
|
|
const {
|
|
prompt,
|
|
systemPrompt,
|
|
modeBridgeCtx,
|
|
priorConclusionCtx,
|
|
designerCtx,
|
|
projectArchitectureCtx,
|
|
secondBrainTraceCtx,
|
|
memoryCtx,
|
|
knowledgeContextForPrompt,
|
|
contextBlock,
|
|
negativeCtx,
|
|
isCasualConversation,
|
|
localPathContext,
|
|
knowledgeMix,
|
|
dynamicBlocks,
|
|
} = input;
|
|
|
|
// 기존 Astra 모드 (에이전트 미선택)
|
|
const localProjectKnowledgeCtx = prompt && localPathContext && isProjectKnowledgeCreationRequest(prompt)
|
|
? `\n\n[LOCAL PROJECT KNOWLEDGE CREATION OVERRIDE]\nThe user gave an accessible local project path and asked to create project knowledge. Do not ask blocking scope questions. Use a sensible default MVP: create or propose a project overview note from the inspected tree and priority file previews. If writing is not explicitly safe, provide the concrete note draft and target path.`
|
|
: '';
|
|
const thinkingPartnerCtx = prompt && !isCasualConversation && isThinkingPartnerRequest(prompt)
|
|
? `\n\n[JARVIS THINKING PARTNER MODE]\nThe user is using this tool to clarify project direction, not just to receive generic advice. Give a clear opinionated verdict first. Then separate confirmed facts, inferences, concerns, decision forks, and the next small action. Do not merely say the direction is good. If evidence is thin, say exactly what is missing and what file or record should be checked next.`
|
|
: '';
|
|
const astraStanceCtx = prompt && !isCasualConversation
|
|
? `\n\n${buildAstraStanceContext(prompt, localPathContext)}`
|
|
: '';
|
|
// The v4 knowledge-management policy only matters when knowledge is actually in play —
|
|
// skip it for greetings/small talk so it doesn't dilute the [CASUAL CONVERSATION MODE] directive.
|
|
const v4PolicyCtx = isCasualConversation ? '' : [
|
|
"\n### 🏛️ 지식 관리 정책 v4.0 (Knowledge Management Policy Applied)",
|
|
"- [신뢰도] '의도적으로 작성된 글'은 Medium 이상의 신뢰도를 부여하여 최우선 근거로 활용할 것.",
|
|
"- [품질] 데이터의 양보다 '추론 기여 밀도'를 중시하여 핵심 위주로 깊이 있게 서술할 것.",
|
|
"- [충돌] 지식 간 충돌 발생 시 시스템이 독단적으로 판단하지 말고, 반드시 [CONFLICT WARNING] 플래그와 함께 상충되는 두 관점을 모두 명시하여 사용자에게 판단을 위임할 것."
|
|
].join('\n');
|
|
|
|
// [자기 지식 + 1인칭] Astra/Agent 양 모드 공용 블록 — 자기 오보고("frozen 모델")와
|
|
// 3인칭 화법("Astra는~") 방지. 본문은 selfIdentity.ts 참조.
|
|
const selfGrowthIdentityCtx = isCasualConversation ? '' : `\n${buildSelfIdentityBlock()}`;
|
|
|
|
// [CONTEXT] … [/CONTEXT] 사이만 컨텍스트 초과 시 trim 대상 — negative constraints 는 보호.
|
|
const casualCtx = isCasualConversation
|
|
? `\n\n[CASUAL CONVERSATION MODE]\nThe user sent a greeting, acknowledgement, or light conversational message. Reply naturally and briefly to the message itself. Do not use Second Brain, memory, project records, reports, references, or analysis unless the user explicitly asks for them.\n\n${buildToneGuardBlock()}`
|
|
: '';
|
|
// Knowledge Mix policy: tells the model how strongly to lean on Second Brain
|
|
// evidence vs. its own general knowledge for this turn. Suppressed for casual
|
|
// chat — pure greetings don't need to be told anything about RAG balance.
|
|
const knowledgeMixCtx = (!isCasualConversation && knowledgeMix)
|
|
? (() => {
|
|
const block = buildKnowledgeMixPolicy(knowledgeMix);
|
|
return block ? `\n\n${block}` : '';
|
|
})()
|
|
: '';
|
|
// memoryCtx(RAG/메모리/lessons)는 [CONTEXT] 안에 — 토큰이 빡빡하면 대화 기록보다 먼저 잘림.
|
|
// priorConclusionCtx 는 modeBridgeCtx 와 같은 위치 (base systemPrompt 직후) — 모델이
|
|
// 자기 직전 결론을 anchor 로 잡고 사용자의 follow-up 을 그 결론에 대한 정정으로 해석하게.
|
|
const priorConclusionBlock = priorConclusionCtx ? '\n\n' + priorConclusionCtx : '';
|
|
// 동적 블록 join — [CONTEXT] *밖* 에 주입돼 token-truncation 시 보호. Casual 모드면
|
|
// RAG context 자체를 안 쓰므로 동적 블록도 의미 없음 → 일괄 skip.
|
|
// 등록 순서대로 join (memoryContext 가 메모리 호출 순으로 set — 현재: intent →
|
|
// terminology → conflict → cove → citation). 빈 본문 entry 는 자동 제외.
|
|
let dynamicBlocksJoined = '';
|
|
if (!isCasualConversation && dynamicBlocks && dynamicBlocks.size > 0) {
|
|
for (const body of dynamicBlocks.values()) {
|
|
if (body && body.trim()) dynamicBlocksJoined += '\n\n' + body;
|
|
}
|
|
}
|
|
// [CONTEXT] 내부 순서 = 잘림 우선순위 (truncation 은 body *뒤*부터 자름):
|
|
// contextBlock(사용자가 지금 가리킨 실데이터 — URL 본문/열린 파일/일정)을 맨 앞에
|
|
// 둬 최후까지 보존, 배경 지식(brain RAG)과 memory 는 그보다 먼저 잘리게 한다.
|
|
return `${systemPrompt}${modeBridgeCtx ? '\n\n' + modeBridgeCtx : ''}${priorConclusionBlock}${designerCtx}${projectArchitectureCtx}${localProjectKnowledgeCtx}${thinkingPartnerCtx}${astraStanceCtx}${secondBrainTraceCtx}${v4PolicyCtx}${selfGrowthIdentityCtx}${knowledgeMixCtx}${casualCtx}${dynamicBlocksJoined}\n\n[CONTEXT]\n${contextBlock}\n${knowledgeContextForPrompt}\n${memoryCtx}\n[/CONTEXT]\n${negativeCtx}`;
|
|
}
|