23 KiB
23 KiB
Level 2: 파라미터 자동 조정 시스템 설계
작성일: 2026-02-05 상태: 설계 단계 기반: Level 1 Auto-Retry 로그 분석
1. 개요
1.1 Level 1 vs Level 2
| 항목 | Level 1 (Auto-Retry) | Level 2 (Parameter Tuning) |
|---|---|---|
| 목표 | 일시적 실패 자동 복구 | 최적 파라미터 자동 발견 |
| 입력 | 개별 실행 결과 (성공/실패) | 누적 로그 패턴 |
| 출력 | 재시도 또는 최종 실패 | 설정 조정 제안 + 자동 적용 |
| 시간 | 실시간 (밀리초) | 주기적 (일/주/월) |
| Loop | ✅ Closed (즉시) | ✅ Closed (지연) |
| 사람 개입 | 불필요 | 최소한 (승인만) |
1.2 핵심 원칙
Level 1의 성공 패턴 계승:
- ✅ Closed Loop: 분석 → 제안 → 적용 → 검증 → 롤백/커밋
- ✅ Objective Metrics: 객관적 데이터 기반 (재시도율, 평균 응답 시간)
- ✅ Immediate Verification: 적용 후 즉시 검증
- ✅ Goodhart's Law 회피: 실제 성능만 인정, 점수 게임 불가
V4.0의 실패 회피:
- ❌ Open Loop (제안만 하고 끝)
- ❌ 주관적 판단 (AI가 "좋다/나쁘다" 평가)
- ❌ 검증 지연 (주간/월간 검토)
2. 현재 상태 분석 (2026-02-05)
2.1 Level 1 Auto-Retry 실행 통계
데이터 기간: 2026-02-05 04:38 ~ 07:50 (약 3.2시간)
| Cron | 실행 횟수 | 성공률 | 평균 시도 | 재시도 발생 |
|---|---|---|---|---|
| TQQQ 15분 모니터링 | 8회 | 100% | 1.0 | 0회 |
| GitHub 감시 | 3회 | 100% | 1.0 | 0회 |
| 일일 주식 브리핑 | 1회 | 100% | 1.0 | 0회 |
| 실제 cron 합계 | 12회 | 100% | 1.0 | 0회 |
| 테스트/시뮬레이션 | 6회 | 50% | 2.17 | 3회 |
핵심 발견:
- ✅ 실제 cron은 재시도 필요 없음 (100% 첫 시도 성공)
- ⚠️ 테스트에서는 16.7% 재시도 필요 (HTTP 429, ETIMEDOUT)
- ✅ 현재 설정(
maxRetries=3)은 충분히 안전
2.2 성능 데이터
TQQQ 15분 모니터링 (Yahoo Finance API):
- 평균: 1,658ms
- 범위: 1,437ms ~ 2,300ms
- 목표: < 15,000ms (timeout)
- 여유율: 87% (13초 여유)
GitHub 감시 (GitHub API):
- 평균: 673ms
- 범위: 370ms ~ 1,203ms
- 목표: < 15,000ms
- 여유율: 96% (14.3초 여유)
일일 주식 브리핑 (복합):
- TQQQ: 2,380ms
- SOXL: 1,436ms
- NVDA: 1,409ms
- Hot Scanner: 3,622ms
- Rumor Scanner: 5,800ms
- 총합: ~14.6초
- 병렬 실행 시 예상: ~6초 (가장 느린 작업 기준)
결론:
- ✅ 모든 작업이 timeout 내 완료
- ✅ 여유가 충분함 → timeout 조정 불필요
2.3 현재 설정 적정성
{
maxRetries: 3, // ✅ 적정 (실패 시 충분한 재시도)
backoff: 'exponential', // ✅ 적정 (1s, 2s, 4s)
timeout: 15000, // ✅ 적정 (87~96% 여유)
maxBuffer: 10MB // ✅ 적정 (출력 크기 문제 없음)
}
Level 2 제안: 현재 설정 유지 (조정 불필요)
3. Level 2 시스템 아키텍처
3.1 전체 구조
┌─────────────────────────────────────────────────────────┐
│ Level 2 Parameter Tuner │
└─────────────────────────────────────────────────────────┘
│
↓
┌─────────────────────────────────────────────────────────┐
│ 1. Log Analyzer │
│ ──────────────── │
│ - ~/openclaw/logs/auto-retry.jsonl 분석 │
│ - 패턴 감지: 반복 실패, 성능 저하, 트렌드 변화 │
│ - 통계 생성: 평균 시도 횟수, 실패율, 응답 시간 │
└─────────────────────────────────────────────────────────┘
│
↓
┌─────────────────────────────────────────────────────────┐
│ 2. Parameter Optimizer │
│ ───────────────────── │
│ - 패턴 기반 최적값 계산 │
│ - 안전 범위 검증 (min/max 제약) │
│ - 개선 예상치 산출 │
└─────────────────────────────────────────────────────────┘
│
↓
┌─────────────────────────────────────────────────────────┐
│ 3. Change Applicator (with A/B Testing) │
│ ─────────────────────────────────── │
│ - 설정 파일 수정 (config.json, wrapper scripts) │
│ - A/B 테스트: 50% 트래픽만 새 설정 적용 │
│ - 롤백 포인트 생성 │
└─────────────────────────────────────────────────────────┘
│
↓
┌─────────────────────────────────────────────────────────┐
│ 4. Verification Engine │
│ ───────────────────── │
│ - Before/After 메트릭 비교 │
│ - 통계적 유의성 검정 (t-test, χ² test) │
│ - 개선 확인 → 커밋 / 악화 확인 → 롤백 │
└─────────────────────────────────────────────────────────┘
│
↓
┌─────────────────────────────────────────────────────────┐
│ 5. Notification & Logging │
│ ──────────────────────── │
│ - Discord 알림 (조정 성공/실패) │
│ - 변경 히스토리 기록 │
│ - 월간 리포트 생성 │
└─────────────────────────────────────────────────────────┘
3.2 Closed Loop 구현
// Level 2 메인 루프
async function level2MainLoop() {
while (true) {
// 1. 로그 분석
const patterns = await analyzeLog();
// 2. 조정 필요 여부 판단
if (!patterns.needsTuning) {
await sleep(7 * 24 * 3600 * 1000); // 1주일 대기
continue;
}
// 3. 최적 파라미터 계산
const optimizedParams = calculateOptimal(patterns);
// 4. 안전성 검증
if (!isSafeToApply(optimizedParams)) {
notify('⚠️ 조정 제안이 안전 범위 벗어남, 수동 검토 필요');
continue;
}
// 5. A/B 테스트 적용
const rollbackPoint = createRollbackPoint();
await applyWithABTest(optimizedParams);
// 6. 검증 (24시간 모니터링)
await sleep(24 * 3600 * 1000);
const metrics = await compareMetrics(rollbackPoint);
// 7. 커밋 또는 롤백
if (metrics.improved) {
commit(optimizedParams);
notify('✅ 파라미터 조정 성공', metrics);
} else {
rollback(rollbackPoint);
notify('❌ 조정 효과 없음, 롤백', metrics);
}
// 8. 다음 주기 대기
await sleep(7 * 24 * 3600 * 1000);
}
}
4. 조정 가능한 파라미터
4.1 파라미터 카탈로그
| 파라미터 | 현재값 | 조정 범위 | 안전 범위 | 트리거 조건 |
|---|---|---|---|---|
maxRetries |
3 | 1~10 | 2~5 | 재시도율 > 10% |
timeout |
15000ms | 5000~60000 | 10000~30000 | 평균 응답 시간 > timeout * 0.8 |
backoff |
exponential | linear/exponential/fixed | exponential | 재시도 패턴 분석 |
backoffBase |
1000ms | 500~5000 | 1000~3000 | Rate limit 빈도 |
4.2 조정 규칙
규칙 1: maxRetries 증가
// 조건
if (retry_rate > 0.10 && final_failure_rate > 0.01) {
// 10% 이상 재시도 필요 & 1% 이상 최종 실패
// 조정
maxRetries = current + 1; // 3 → 4
// 예상 효과
// 최종 실패율 1% → 0.1% (90% 감소)
}
규칙 2: timeout 증가
// 조건
if (avg_response_time > timeout * 0.8) {
// 평균 응답 시간이 timeout의 80% 초과
// 조정
timeout = avg_response_time * 1.5; // 여유 50% 확보
// 예상 효과
// timeout 에러 감소
}
규칙 3: backoff 조정
// 조건
if (http_429_count > 0) {
// Rate limit 발생
// 조정
backoffBase = current * 2; // 1000ms → 2000ms
// 예상 효과
// Rate limit 회피
}
4.3 안전 제약
절대 하지 말아야 할 것:
- ❌
maxRetries< 2 (너무 적음) - ❌
maxRetries> 5 (너무 많음, 느림) - ❌
timeout< 5000 (너무 짧음) - ❌
timeout> 60000 (너무 김, cron 충돌 위험)
자동 적용 vs 수동 검토:
// 자동 적용 가능
- maxRetries: 3 → 4 (안전 범위 내)
- timeout: 15s → 20s (안전 범위 내)
- backoffBase: 1s → 2s (안전 범위 내)
// 수동 검토 필요
- maxRetries: 3 → 10 (안전 범위 벗어남)
- timeout: 15s → 5s (감소는 위험)
- 근본 원인 수정 (코드 변경)
5. 구현 계획
5.1 Phase 1: 로그 분석기 (Week 1-2)
파일: ~/openclaw/lib/log-analyzer.js
const fs = require('fs');
const readline = require('readline');
class LogAnalyzer {
async analyze(logPath) {
const stats = {
total: 0,
success: 0,
failure: 0,
retries: 0,
byTontextCron: {}
};
const fileStream = fs.createReadStream(logPath);
const rl = readline.createInterface({
input: fileStream,
crlfDelay: Infinity
});
for await (const line of rl) {
const entry = JSON.parse(line);
// Skip tests
if (!entry.context?.cron) continue;
const cron = entry.context.cron;
if (!stats.byCron[cron]) {
stats.byCron[cron] = {
total: 0,
success: 0,
retries: 0,
avgDuration: 0,
durations: []
};
}
stats.total++;
stats.byCron[cron].total++;
if (entry.type === 'success') {
stats.success++;
stats.byCron[cron].success++;
} else {
stats.failure++;
}
const attempts = entry.attempts.length;
if (attempts > 1) {
stats.retries++;
stats.byCron[cron].retries++;
}
const duration = entry.totalDuration;
stats.byCron[cron].durations.push(duration);
}
// Calculate averages
for (const [cron, data] of Object.entries(stats.byCron)) {
data.avgDuration = data.durations.reduce((a, b) => a + b, 0) / data.durations.length;
data.retryRate = data.retries / data.total;
}
return stats;
}
detectPatterns(stats) {
const patterns = [];
for (const [cron, data] of Object.entries(stats.byCron)) {
// Pattern 1: High retry rate
if (data.retryRate > 0.10) {
patterns.push({
type: 'high_retry_rate',
cron,
value: data.retryRate,
suggestion: 'increase maxRetries'
});
}
// Pattern 2: Slow response
if (data.avgDuration > 12000) { // 80% of 15s
patterns.push({
type: 'slow_response',
cron,
value: data.avgDuration,
suggestion: 'increase timeout'
});
}
}
return patterns;
}
}
module.exports = { LogAnalyzer };
5.2 Phase 2: 파라미터 최적화기 (Week 3-4)
파일: ~/openclaw/lib/parameter-optimizer.js
class ParameterOptimizer {
calculateOptimal(patterns) {
const recommendations = [];
for (const pattern of patterns) {
if (pattern.type === 'high_retry_rate') {
recommendations.push({
param: 'maxRetries',
current: 3,
proposed: 4,
reason: `Retry rate ${(pattern.value * 100).toFixed(1)}% > 10%`,
expectedImprovement: 'Final failure rate -90%',
safe: true
});
}
if (pattern.type === 'slow_response') {
const newTimeout = Math.ceil(pattern.value * 1.5);
recommendations.push({
param: 'timeout',
current: 15000,
proposed: newTimeout,
reason: `Avg response ${pattern.value}ms > 80% of timeout`,
expectedImprovement: 'Timeout errors -100%',
safe: newTimeout <= 30000
});
}
}
return recommendations;
}
isSafeToApply(recommendation) {
const safetyRules = {
maxRetries: { min: 2, max: 5 },
timeout: { min: 10000, max: 30000 },
backoffBase: { min: 1000, max: 5000 }
};
const rule = safetyRules[recommendation.param];
if (!rule) return false;
return recommendation.proposed >= rule.min &&
recommendation.proposed <= rule.max;
}
}
module.exports = { ParameterOptimizer };
5.3 Phase 3: 변경 적용기 (Week 5-6)
파일: ~/openclaw/lib/change-applicator.js
const fs = require('fs');
class ChangeApplicator {
async apply(recommendation, cron) {
// 1. Create rollback point
const rollback = this.createRollbackPoint(cron);
// 2. Update wrapper script
const wrapperPath = this.getWrapperPath(cron);
const content = fs.readFileSync(wrapperPath, 'utf8');
const updated = content.replace(
new RegExp(`${recommendation.param}: \\d+`),
`${recommendation.param}: ${recommendation.proposed}`
);
fs.writeFileSync(wrapperPath, updated);
// 3. Log change
this.logChange({
timestamp: new Date().toISOString(),
cron,
param: recommendation.param,
from: recommendation.current,
to: recommendation.proposed,
reason: recommendation.reason,
rollbackPoint: rollback
});
return rollback;
}
createRollbackPoint(cron) {
const timestamp = Date.now();
const wrapperPath = this.getWrapperPath(cron);
const backupPath = `${wrapperPath}.${timestamp}.bak`;
fs.copyFileSync(wrapperPath, backupPath);
return {
timestamp,
backupPath,
wrapperPath
};
}
rollback(rollbackPoint) {
fs.copyFileSync(rollbackPoint.backupPath, rollbackPoint.wrapperPath);
fs.unlinkSync(rollbackPoint.backupPath);
}
}
module.exports = { ChangeApplicator };
5.4 Phase 4: 검증 엔진 (Week 7-8)
파일: ~/openclaw/lib/verification-engine.js
class VerificationEngine {
async verify(rollbackPoint, duration = 24 * 3600 * 1000) {
// 1. Get baseline metrics (before change)
const before = await this.getMetricsAtTimestamp(
rollbackPoint.timestamp - duration
);
// 2. Wait for new data
await new Promise(resolve => setTimeout(resolve, duration));
// 3. Get current metrics (after change)
const after = await this.getCurrentMetrics();
// 4. Compare
const comparison = {
retryRate: {
before: before.retryRate,
after: after.retryRate,
change: ((after.retryRate - before.retryRate) / before.retryRate) * 100
},
avgDuration: {
before: before.avgDuration,
after: after.avgDuration,
change: ((after.avgDuration - before.avgDuration) / before.avgDuration) * 100
},
failureRate: {
before: before.failureRate,
after: after.failureRate,
change: ((after.failureRate - before.failureRate) / before.failureRate) * 100
}
};
// 5. Determine if improved
const improved =
comparison.retryRate.change < 0 || // Less retries
comparison.failureRate.change < 0 || // Less failures
(comparison.avgDuration.change < 5 && comparison.failureRate.change <= 0); // Not slower & not worse
return { improved, comparison };
}
async getMetricsAtTimestamp(timestamp) {
// Read logs from timestamp onwards
// Calculate metrics
// Return stats
}
}
module.exports = { VerificationEngine };
6. 실행 스케줄
6.1 주간 분석 (매주 일요일 23:00)
# ~/openclaw/scripts/level2-weekly-analysis.js
const { LogAnalyzer } = require('../lib/log-analyzer');
const { ParameterOptimizer } = require('../lib/parameter-optimizer');
async function weeklyAnalysis() {
console.log('📊 Level 2: 주간 로그 분석\n');
// 1. Analyze logs
const analyzer = new LogAnalyzer();
const stats = await analyzer.analyze('~/openclaw/logs/auto-retry.jsonl');
console.log('통계:');
console.log(`- 총 실행: ${stats.total}회`);
console.log(`- 성공률: ${(stats.success / stats.total * 100).toFixed(1)}%`);
console.log(`- 재시도율: ${(stats.retries / stats.total * 100).toFixed(1)}%`);
// 2. Detect patterns
const patterns = analyzer.detectPatterns(stats);
if (patterns.length === 0) {
console.log('✅ 조정 불필요 (모든 지표 정상)');
return;
}
console.log(`\n⚠️ ${patterns.length}개 패턴 발견:`);
patterns.forEach(p => console.log(`- ${p.type}: ${p.cron}`));
// 3. Generate recommendations
const optimizer = new ParameterOptimizer();
const recommendations = optimizer.calculateOptimal(patterns);
console.log('\n💡 조정 제안:');
recommendations.forEach(r => {
console.log(`- ${r.param}: ${r.current} → ${r.proposed}`);
console.log(` 이유: ${r.reason}`);
console.log(` 예상 효과: ${r.expectedImprovement}`);
console.log(` 안전: ${r.safe ? '✅' : '❌'}`);
});
// 4. Auto-apply if safe
const safeRecs = recommendations.filter(r => r.safe);
if (safeRecs.length > 0) {
console.log(`\n✅ ${safeRecs.length}개 자동 적용 예정 (24시간 후 검증)`);
// Apply changes...
} else {
console.log('\n⚠️ 수동 검토 필요 (안전 범위 벗어남)');
}
}
weeklyAnalysis();
6.2 Cron 설정
{
"name": "Level 2 주간 분석",
"schedule": "0 23 * * 0",
"payload": {
"message": "node ~/openclaw/scripts/level2-weekly-analysis.js",
"to": "channel:1468751194284621967"
}
}
7. 성공 지표
7.1 Level 2 자체의 성공 기준
| 지표 | 목표 | 측정 방법 |
|---|---|---|
| 자동 조정 정확도 | > 90% | 조정 후 롤백 비율 < 10% |
| 개선 효과 | > 0% | Before/After 메트릭 비교 |
| 사람 개입 비율 | < 10% | 수동 검토 필요 건수 / 전체 조정 |
| 안전성 | 100% | 안전 범위 벗어난 조정 0건 |
7.2 측정 가능한 개선
Before Level 2:
- maxRetries 수동 설정 → 과하거나 부족할 수 있음
- timeout 수동 설정 → 실제 성능과 불일치
- 설정 변경 시 사람이 판단 → 지연, 실수 가능
After Level 2:
- maxRetries 자동 최적화 → 데이터 기반 정확한 값
- timeout 자동 조정 → 실제 응답 시간 * 1.5 여유
- 설정 변경 자동화 → 즉시 적용, 검증, 롤백
예상 효과:
- 최종 실패율: -50% (더 많은 재시도로 복구)
- 응답 시간: ±5% (timeout 최적화)
- 운영 부담: -80% (자동화)
8. Level 3로의 전환 조건
Level 2에서 Level 3 (코드 자동 수정)으로 넘어가는 조건:
조건 1: 반복 패턴 감지
// 예시
if (same_error_count > 10 && same_fix_count > 5) {
// 같은 에러가 10번 이상 발생
// 같은 수동 수정이 5번 이상 발생
// → AI가 패턴 학습 가능
suggest_code_fix();
}
조건 2: 근본 원인 명확
// 예시
if (timeout_on_same_api > 5) {
// 특정 API에서 반복적으로 timeout
// 근본 원인: API 자체가 느림
// 해결책: timeout 증가 (설정 변경) OR 캐싱 추가 (코드 변경)
if (parameter_tuning_not_enough) {
suggest_code_change();
}
}
조건 3: 안전한 코드 패턴
// 자동 수정 가능한 패턴
- timeout 값 증가
- retry 로직 추가
- 캐싱 레이어 추가
// 수동 검토 필요한 패턴
- 로직 변경
- API 엔드포인트 변경
- 데이터 구조 변경
9. 다음 단계
9.1 즉시 (2026-02-05 ~ 02-12)
- Level 2 설계 문서 작성 (이 문서)
- 로그 분석기 구현 (
log-analyzer.js) - 테스트 데이터로 검증
9.2 2주차 (2026-02-12 ~ 02-19)
- 파라미터 최적화기 구현
- 변경 적용기 구현
- 단위 테스트 작성
9.3 3주차 (2026-02-19 ~ 02-26)
- 검증 엔진 구현
- 주간 분석 스크립트 작성
- Cron 등록
9.4 4주차 (2026-02-26 ~ 03-05)
- 프로덕션 배포
- 첫 자동 조정 실행
- 효과 측정 및 리포트
10. 부록
10.1 참고 문서
~/openclaw/docs/auto-retry-integration.md(Level 1 설계)~/openclaw/docs/level1-rollout-summary.md(Level 1 배포 결과)~/openclaw/MEMORY.md(자가개선 원칙)
10.2 관련 파일
~/openclaw/
├── lib/
│ ├── auto-retry.js (Level 1)
│ ├── log-analyzer.js (Level 2 - 구현 예정)
│ ├── parameter-optimizer.js (Level 2 - 구현 예정)
│ ├── change-applicator.js (Level 2 - 구현 예정)
│ └── verification-engine.js (Level 2 - 구현 예정)
├── scripts/
│ ├── tqqq-monitor-with-retry.js (Level 1)
│ └── level2-weekly-analysis.js (Level 2 - 구현 예정)
├── logs/
│ └── auto-retry.jsonl (Level 1 & 2 공용)
└── docs/
├── level1-rollout-summary.md (Level 1)
└── level2-parameter-tuning-design.md (이 문서)
작성: Claude Opus 4.5 날짜: 2026-02-05 상태: ✅ 설계 완료, 구현 대기