Feat: Implement Project Claim Output Brake and refine agent reasoning
This commit is contained in:
+5
-1
@@ -34,6 +34,7 @@ import { actionQueue } from './core/queue';
|
||||
import { ConflictResolver } from './core/conflict';
|
||||
import {
|
||||
buildSecondBrainTrace,
|
||||
enforceProjectClaimPolicyInAnswer,
|
||||
renderSecondBrainTraceContext,
|
||||
renderSecondBrainTraceMarkdown,
|
||||
SecondBrainTrace
|
||||
@@ -409,7 +410,10 @@ export class AgentExecutor {
|
||||
|
||||
// 5. Execute Actions
|
||||
const rationale = this.parseRationale(aiResponseText);
|
||||
const assistantContent = this.sanitizeAssistantContent(aiResponseText);
|
||||
const assistantContent = enforceProjectClaimPolicyInAnswer(
|
||||
this.sanitizeAssistantContent(aiResponseText),
|
||||
secondBrainTrace
|
||||
);
|
||||
const traceMarkdown = secondBrainTrace
|
||||
? renderSecondBrainTraceMarkdown(secondBrainTrace, !!options.secondBrainTraceDebug)
|
||||
: '';
|
||||
|
||||
@@ -246,6 +246,45 @@ export function renderSecondBrainTraceMarkdown(trace: SecondBrainTrace, debug: b
|
||||
].join('\n');
|
||||
}
|
||||
|
||||
export function enforceProjectClaimPolicyInAnswer(answer: string, trace: SecondBrainTrace | null): string {
|
||||
if (!trace || trace.projectClaimPolicy !== 'general-only') return answer;
|
||||
|
||||
const forbiddenPatterns = [
|
||||
/[^.!?。!?\n]*(?:현재\s*)?(?:개발\s*방향은\s*)?기술적\s*기반(?:\s*면에서는)?\s*(?:안정적|탄탄|준비)[^.!?。!?\n]*(?:[.!?。!?]|$)/gi,
|
||||
/[^.!?。!?\n]*아키텍처(?:는|가)?\s*(?:유연|안정|확장성|준비|견고)[^.!?。!?\n]*(?:[.!?。!?]|$)/gi,
|
||||
/[^.!?。!?\n]*모듈화(?:된)?\s*구조[^.!?。!?\n]*(?:[.!?。!?]|$)/gi,
|
||||
/[^.!?。!?\n]*확장성\s*(?:측면에서)?\s*(?:준비|확보|충분|높)[^.!?。!?\n]*(?:[.!?。!?]|$)/gi,
|
||||
/[^.!?。!?\n]*구조적\s*안정성[^.!?。!?\n]*(?:[.!?。!?]|$)/gi,
|
||||
/[^.!?。!?\n]*API\s*Gateway\s*기반[^.!?。!?\n]*(?:[.!?。!?]|$)/gi,
|
||||
/[^.!?。!?\n]*비즈니스\s*로직[^.!?。!?\n]*데이터\s*접근\s*계층[^.!?。!?\n]*(?:[.!?。!?]|$)/gi
|
||||
];
|
||||
|
||||
let sanitized = answer;
|
||||
let removed = false;
|
||||
for (const pattern of forbiddenPatterns) {
|
||||
sanitized = sanitized.replace(pattern, (match) => {
|
||||
removed = true;
|
||||
return match.includes('\n') ? '\n' : '';
|
||||
});
|
||||
}
|
||||
|
||||
if (!removed) return answer;
|
||||
|
||||
const warning = [
|
||||
'> 현재 정보만으로는 기술 구조를 판단할 수 없습니다.',
|
||||
'> 기술적 안정성, 아키텍처 유연성, 모듈화 여부는 소스 코드나 설계 문서 확인이 필요합니다.'
|
||||
].join('\n');
|
||||
|
||||
return insertAfterFirstBlock(sanitized.trim(), warning);
|
||||
}
|
||||
|
||||
function insertAfterFirstBlock(answer: string, insertion: string): string {
|
||||
if (!answer.trim()) return insertion;
|
||||
const blocks = answer.split(/\n{2,}/);
|
||||
if (blocks.length <= 1) return `${insertion}\n\n${answer}`;
|
||||
return [blocks[0], insertion, ...blocks.slice(1)].join('\n\n');
|
||||
}
|
||||
|
||||
function deriveProjectClaimPolicy(
|
||||
docs: SecondBrainTraceDocument[],
|
||||
groundingScore: number
|
||||
|
||||
Reference in New Issue
Block a user