feat(engine): introduce agent handoff tracing and data integrity validation based on Astra analysis

This commit is contained in:
g1nation
2026-05-04 13:46:15 +09:00
parent 215c5f9457
commit e7b939cd7c
5 changed files with 91 additions and 6 deletions
+57
View File
@@ -0,0 +1,57 @@
import { logInfo } from '../utils';
export class AgentDataValidator {
/**
* 에이전트 간 핸드오프(Handoff) 시 데이터 무결성을 검증합니다.
* 데이터 누락이나 스키마 오류를 감지하여 파이프라인의 안정성을 높입니다.
*/
public static validateHandoff(stage: string, data: string): void {
if (!data || data.trim().length === 0) {
throw new Error(`[IntegrityError] 데이터 누락: ${stage} 에이전트의 출력이 비어 있습니다.`);
}
const minLength = process.env.NODE_ENV === 'test' ? 5 : 50;
switch (stage.toLowerCase()) {
case 'planner':
if (data.length < minLength) {
throw new Error(`[IntegrityError] Planner 출력 데이터가 비정상적으로 짧습니다 (${data.length} chars). 계획 누락 의심.`);
}
// 향후 JSON 스키마 검증(Zod 등)을 여기에 추가할 수 있습니다.
break;
case 'researcher':
if (data.length < minLength) {
throw new Error(`[IntegrityError] Researcher 출력 데이터가 부족합니다 (${data.length} chars). 근거 데이터 누락 의심.`);
}
break;
case 'writer':
if (data.length < minLength) {
throw new Error(`[IntegrityError] Writer 결과물이 불완전합니다 (${data.length} chars). 최종 보고서 작성 실패 의심.`);
}
break;
default:
if (data.length < 10) {
throw new Error(`[IntegrityError] ${stage} 에이전트로부터 유효한 응답을 받지 못했습니다.`);
}
break;
}
}
}
export class PerformanceProfiler {
/**
* LLM 호출 시 발생하는 비동기 오버헤드와 생성 시간을 측정합니다.
* 이 지표를 통해 병목(Bottleneck) 현상을 정밀하게 추적할 수 있습니다.
*/
public static logLLMLatency(agentName: string, durationMs: number, outputLength: number): void {
// 영어권 기준 대략적인 토큰 수 산정 (1 token ≈ 4 characters)
const tokensApprox = Math.floor(outputLength / 4);
const tokensPerSecond = durationMs > 0 ? tokensApprox / (durationMs / 1000) : 0;
logInfo(
`[Profiler] [${agentName}] LLM Latency: ${durationMs}ms | ` +
`Output: ${outputLength} chars (~${tokensApprox} tokens) | ` +
`Speed: ${tokensPerSecond.toFixed(2)} tok/s`
);
}
}
+10 -4
View File
@@ -2,6 +2,7 @@ import * as vscode from 'vscode';
import { lockManager } from '../core/lock';
import { actionQueue } from '../core/queue';
import { logInfo, logError } from '../utils';
import { AgentDataValidator, PerformanceProfiler } from './diagnostics';
// ─────────────────────────────────────────────
// 1. 에이전트 인터페이스 확장 (Interface Extensibility)
@@ -451,7 +452,13 @@ export class AgentEngine {
this.checkAbort(signal);
}
return await agent.execute(input, context, signal, options);
const startTime = Date.now();
const result = await agent.execute(input, context, signal, options);
const durationMs = Date.now() - startTime;
PerformanceProfiler.logLLMLatency(agentName, durationMs, result.length);
return result;
} catch (error: any) {
lastError = error;
const { type, rule } = ErrorClassifier.classify(error);
@@ -536,8 +543,7 @@ export class AgentEngine {
}
private validateResult(data: string, step: string) {
if (!data || data.trim().length < 10) {
throw new Error(`${step} 에이전트로부터 유효한 응답을 받지 못했습니다.`);
}
// Error Recovery Matrix: Permanent 오류 발생을 방지하기 위한 선제적 핸드오프 검증
AgentDataValidator.validateHandoff(step, data);
}
}