에이전트 피드백 루프 설계 패턴: Micro-Meso-Macro 3중 구조
멀티에이전트 시스템의 Micro-Meso-Macro 3중 피드백 루프 설계와 동적 가중치 조정
피드백 루프가 없는 에이전트는 학습하지 못한다
멀티에이전트 트레이딩 시스템은 데이터 수집, 분석, 토론, 합의, 실행이라는 정교한 의사결정 파이프라인을 갖추고 있다. 하지만 실행 결과가 다시 시스템으로 역전파되지 않는다면, 에이전트는 동일한 실수를 반복한다. FINSABER 벤치마크(20년+100종목 장기 백테스트)가 보여주듯, LLM 단독 전략은 상승장에서 과도하게 보수적이고 하락장에서 과도하게 공격적인 역설적 행동을 보인다. 이 편향을 교정하는 유일한 방법이 구조화된 피드백 루프다.
핵심은 "이겼다/졌다"가 아니라, 거래의 가정(뉴스 촉매 지속성, 변동성 가정, 유동성 가정)이 어디서 깨졌는지를 구조화해 다음 결정에 반영하는 것이다.
3중 피드백 루프 아키텍처
시간 규모(Time-scale)와 목적에 따라 세 가지 수준의 피드백 루프를 가동한다.
| 루프 | 시간 규모 | 대상 | 핵심 메커니즘 | 이론적 기반 |
|---|---|---|---|---|
| Micro | 초-분 | 단일 분석 출력 | Generator-Critic 반복 정제 | Self-Refine, Reflection Agents |
| Meso | 일 단위 | 개별 거래 성패 | PnL Attribution + 가중치 업데이트 | Reflexion, QuantAgents |
| Macro | 주-월 | 시스템 전체 성능 | ReST(Reinforced Self-Training) | ReST, 카나리 배포 |
Micro Loop: Generator-Critic 실시간 정제
개요
Micro Loop는 단일 의사결정 사이클 내에서 실행 전 발생하는 출력 정제 메커니즘이다. LLM Analyst가 분석 리포트를 생성하면, Critic 에이전트가 논리적 허점이나 계산 오류를 지적하고, Generator가 수정을 반복한다.
LangGraph 구현
LangGraph에서 Generator와 Critic을 두 개의 노드로 구성하고, Conditional Edge로 반복 여부를 제어한다.
def critic_node(state: PipelineState) -> PipelineState:
"""LLM 분석 결과를 비판적으로 검증."""
report = state["narrative_report"]
critique = llm.evaluate(f"""
다음 분석 리포트의 논리적 결함을 검토하세요:
{report}
검토 항목:
1. 근거 뉴스 ID가 실제로 존재하는가?
2. 감성 점수와 서술이 일관되는가?
3. 리스크 플래그가 누락되지 않았는가?
4. 확신도가 근거에 비해 과도하지 않은가?
결과: {{"pass": bool, "issues": [str], "severity": str}}
""")
if critique["pass"]:
state["critic_approved"] = True
else:
state["critic_issues"] = critique["issues"]
state["critic_iteration"] += 1
return state
# Conditional Edge: 통과 시 다음 단계, 실패 시 Generator로 회귀
graph.add_conditional_edges(
"critic",
lambda s: (
"debate" if s.get("critic_approved")
else "generator" if s.get("critic_iteration", 0) < 2
else "debate" # 최대 2회 반복 후 강제 진행
),
{"debate": "bull_bear_debate", "generator": "llm_analyst"},
)핵심 설계 원칙
| 원칙 | 설명 |
|---|---|
| 반복 제한 | 최대 2회 반복 후 강제 진행 (무한 루프 방지) |
| 비용 인식 | Critic은 Haiku 급 경량 모델로 실행 (비용 절감) |
| 구조화 출력 | Critic 결과는 JSON으로 구조화 (파싱 실패 방지) |
| 심각도 분류 | 경미한 오류는 통과, 치명적 오류만 재생성 요구 |
이 과정은 시스템이 본능적이고 반응적인 'System 1' 사고방식에서 벗어나, 보다 체계적이고 반성적인 'System 2' 수준의 행동을 보이도록 유도한다. 금융 거래와 같은 고위험 도메인에서는 응답의 질과 논리적 무결성이 지연 시간보다 중요하다.
Meso Loop: Post-Trade Reflection
개요
Meso Loop는 개별 거래가 청산된 후 가동되는 가장 중요한 피드백 루프다. 거래의 성패를 분석하고, 어떤 에이전트의 판단이 정확했는지를 추적하여 다음 의사결정의 가중치를 업데이트한다.
PnL Attribution: 원인 분해
손익의 원인을 세 가지 요소로 분해한다.
| 요소 | 설명 | 측정 방법 |
|---|---|---|
| Signal | 방향 판단의 정확성 | 에이전트 예측 vs 실제 가격 방향 |
| Execution | 실행 품질 | Implementation Shortfall(IS) bps |
| Regime | 거시 환경 영향 | 시장 베타 대비 초과/미달 수익 |
Reflection Memo 스키마
{
"reflection_id": "uuid",
"trade_id": "uuid",
"symbol": "005930",
"timestamp": "2026-02-21T15:30:00+09:00",
"trade_summary": {
"side": "BUY",
"entry_price": 72000,
"exit_price": 70500,
"pnl_pct": -2.08,
"hold_duration_hours": 4.5
},
"attribution": {
"signal_contribution_pct": -60,
"execution_contribution_pct": -15,
"regime_contribution_pct": -25
},
"failure_mode": "SIGNAL_ERROR",
"failure_detail": "Quant RSI 과매도 반등 예상했으나 하락 추세 지속",
"agent_scores": {
"quant_analyst": {
"predicted": "BUY",
"correct": false,
"confidence_was": 0.72
},
"llm_analyst": {
"predicted": "HOLD",
"correct": true,
"confidence_was": 0.55
},
"sector_rotation": {
"predicted": "NEUTRAL",
"correct": true,
"confidence_was": 0.60
}
},
"lessons": [
"RSI 과매도 신호만으로는 하락추세 중 반등 포착 불가",
"LLM의 보수적 HOLD 판단이 더 정확했음"
],
"policy_updates": [
{
"target": "ensemble_voter",
"action": "decrease_weight",
"agent": "quant_analyst",
"delta": -0.05
},
{
"target": "ensemble_voter",
"action": "increase_weight",
"agent": "llm_analyst",
"delta": 0.03
}
]
}실패 유형 분류 체계
| 실패 유형 | 코드 | 설명 | 가중치 조정 대상 |
|---|---|---|---|
| 신호 오류 | SIGNAL_ERROR | Quant/LLM의 방향 오판 | 해당 에이전트 가중치 감소 |
| 뉴스 오판 | NEWS_HALLUCINATION | 환각 또는 루머에 반응 | LLM Analyst 신뢰도 감쇠 |
| 실행 실패 | EXECUTION_FAILURE | 슬리피지, 미체결, 지연 | Executor 정책 조정 |
| 레짐 변화 | REGIME_SHIFT | 거시 환경 급변 | 전체 포지션 사이즈 축소 |
| 과신 편향 | OVERCONFIDENCE | 높은 확신도에도 불구하고 손실 | 확신도 캘리브레이션 |
동적 가중치 업데이트 수식
RRMSE 기반 가중치 조정
Ensemble Voter가 각 에이전트에 부여하는 가중치를 거래 결과에 기반하여 자동 조정한다. RRMSE(Relative Root Mean Square Error) 기반의 가중 투표 회귀 기법을 적용한다.
where:
- : 에이전트 의 최근 회 거래에 대한 RRMSE
- : 학습률 (기본값: 0.1)
제약 조건:
- (최소 5% 보장)
- (단일 에이전트 40% 상한)
가중치 설정표
| 에이전트 | 초기 가중치 | 범위 | 저장소 | 업데이트 트리거 |
|---|---|---|---|---|
| Quant Analyst | 0.25 | [0.05, 0.40] | Redis weights:{project_id} | 거래 청산 시 |
| LLM Analyst | 0.25 | [0.05, 0.40] | Redis weights:{project_id} | 거래 청산 시 |
| Sector Rotation | 0.15 | [0.05, 0.30] | Redis weights:{project_id} | 거래 청산 시 |
| BullBear Debate | 0.20 | [0.05, 0.35] | Redis weights:{project_id} | 거래 청산 시 |
| Memory Penalty/Bonus | 0.15 | [0.00, 0.25] | Redis weights:{project_id} | Reflection 시 |
합성 알고리즘
Ensemble Voter의 최종 점수 산출 공식:
where:
- : 레짐별 에이전트 가중치 (Redis에서 로드)
- : 데이터 품질/신뢰도 감쇠 계수
- : 에이전트가 보고한 확신도
- : 방향성 ()
| 조건 | 결정 | 비고 |
|---|---|---|
| AND | MARKET -- 즉시 진입 | 강한 합의 |
| AND | LIMIT -- 가격 확인 후 | 보통 합의 |
| CONDITIONAL -- 추가 확인 대기 | 약한 합의 | |
| OR | NO-TRADE -- 관망 | 불확실 |
가중치 업데이트 시나리오 예시
거래가 손실(-2.08%)로 청산된 경우:
Before (초기 가중치):
| 에이전트 | 가중치 |
|---|---|
| quant_analyst | 0.25 |
| llm_analyst | 0.25 |
| sector_rotation | 0.15 |
| debate | 0.20 |
| memory | 0.15 |
Reflection 결과:
| 에이전트 | 예측 | 실제 | |
|---|---|---|---|
| quant_analyst | BUY | DOWN | 1.0 |
| llm_analyst | HOLD | DOWN | 0.0 (정확) |
| sector_rotation | NEUTRAL | — | 0.2 |
Update ():
After (정규화 + 클리핑):
| 에이전트 | 가중치 | 변화 |
|---|---|---|
| quant_analyst | 0.22 | 감소 |
| llm_analyst | 0.28 | 증가 |
| sector_rotation | 0.15 | 유지 |
| debate | 0.20 | 유지 |
| memory | 0.15 | 유지 |
이 메커니즘을 통해 시스템 구조를 변경하지 않고도 다음 거래부터 즉각적으로 적응도가 높아진다.
Macro Loop: ReST 기반 강화 자가 훈련
개요
Macro Loop는 주간/월간 단위로 실행되는 거시적 시스템 개선 루프다. LLM 기반 에이전트의 지속적 개선을 위해 ReST(Reinforced Self-Training) 패러다임을 적용한다.
성장(Grow) 단계
지난 기간의 거래 로그에서 시장 대비 초과 수익을 달성한 거래의 추론 과정을 추출한다.
class MacroLoopGrow:
"""성공 거래의 최적 추론 패턴 추출."""
async def extract_winning_patterns(
self,
period_start: date,
period_end: date,
) -> list[ReasoningPattern]:
# 1. 기간 내 모든 거래 조회
trades = await db.get_trades(period_start, period_end)
# 2. 시장 대비 초과 수익 거래 필터링
winners = [
t for t in trades
if t.excess_return_vs_benchmark > 0.02 # 2%p 초과
]
# 3. 각 성공 거래의 의사결정 추적
patterns = []
for trade in winners:
trace = await db.get_decision_trace(trade.correlation_id)
# 어떤 에이전트 조합이 정확했는가
# 토론에서 어떤 논거가 승리했는가
# 리스크 조정이 어떻게 이루어졌는가
pattern = self.analyze_trace(trace)
patterns.append(pattern)
return patterns개선(Improve) 단계
추출된 패턴을 바탕으로 다음을 업데이트한다.
| 업데이트 대상 | 방법 | 예시 |
|---|---|---|
| 시스템 프롬프트 | 성공 사례의 추론 패턴 반영 | "하락 추세에서 RSI 과매도는 반등이 아닌 추세 지속을 의미할 수 있음" |
| 토론 규칙 | 쟁점 템플릿 업데이트 | 새로운 반증 조건 추가 |
| 리스크 정책 | 소프트룰 기준값 조정 | 변동성 타겟 조정, 섹터 집중도 한도 변경 |
| 가중치 범위 | w_min/w_max 재설정 | 지속적으로 부정확한 에이전트의 상한 축소 |
내부 vs 외부 결함 구분
Macro Loop에서 중요한 것은 내부적 결함과 외부 환경 변동을 구분하는 것이다.
| 유형 | 원인 | 대응 |
|---|---|---|
| 내부 결함 | 추론 오류, 환각, 프롬프트 드리프트 | 훈련 루프로 피드백 -> 모델/프롬프트 교정 |
| 외부 변동 | 금리 변경, 규제 발표, 시장 레짐 전환 | 컨텍스트 버퍼에 지식 업데이트 (핵심 로직 불변) |
카나리 배포: 안전한 전략 변경
왜 카나리 배포가 필요한가
Macro Loop의 결과물(프롬프트 변경, 규칙 업데이트)을 전체 시스템에 즉시 적용하는 것은 위험하다. Google SRE의 카나리 릴리스 원칙을 트레이딩에 적용한다.
카나리 배포 프로토콜
카나리 모니터링 기준
| 지표 | 기준 | 위반 시 |
|---|---|---|
| Sharpe Ratio | 기존 대비 -0.5 이내 | 경고 |
| Maximum Drawdown | 기존 DD의 1.5배 이내 | 즉시 롤백 |
| 승률 | 기존 대비 -5%p 이내 | 경고 |
| API 비용 | 기존 대비 2배 이내 | 경고 |
| 평균 지연 | 기존 대비 1.5배 이내 | 경고 |
전체 피드백 루프 통합 아키텍처
루프 간 상호작용
세 루프는 독립적이지 않고 계층적으로 상호작용한다.
운영 스케줄
| 루프 | 실행 주기 | 트리거 | 인프라 |
|---|---|---|---|
| Micro | 매 파이프라인 실행 시 | LLM Analyst 출력 생성 | LangGraph Conditional Edge |
| Meso | 거래 청산 시 + 매일 06:00 | Kafka pipeline.trades 토픽 | Celery Worker |
| Macro | 매주 토요일 09:00 | Celery Beat | Celery Worker + 수동 승인 |
Celery Beat 스케줄
beat_schedule = {
"daily-reflection": {
"task": "tasks.run_reflection",
"schedule": crontab(hour=6, minute=0),
},
"weekly-macro": {
"task": "tasks.run_macro_loop",
"schedule": crontab(hour=9, minute=0, day_of_week=6),
},
}QuantAgents의 이중 피드백
실거래 + 시뮬레이션 이중 검증
QuantAgents는 Meso Loop를 확장하여 이중 피드백 구조를 제안한다.
| 피드백 채널 | 입력 | 출력 | 장점 |
|---|---|---|---|
| 실거래 성과 | 실제 PnL, 슬리피지, IS | 에이전트 정확도 평가 | 현실적 (실제 비용 포함) |
| 시뮬레이션 | 페이퍼 트레이딩 예측 정확도 | 장기 추세 예측 검증 | 데이터 풍부 (비용 없이 다수 시뮬레이션) |
실서비스에서 전면 시뮬레이션이 부담일 수 있으나, 최소한 다음은 구현 가능하다.
- 주간 백테스트: 지난 주의 의사결정을 "만약 반대로 결정했다면?" 시뮬레이션
- LangGraph Time Travel: 체크포인트를 이용해 특정 시점으로 되돌아가 다른 경로 탐색
- Shadow Mode: 실제 거래는 하지 않되, 시그널만 기록하여 정확도를 측정
합성 전략 비교
피드백 루프와 밀접하게 연관된 합성(Ensemble) 전략의 비교:
| 전략 | 핵심 아이디어 | 장점 | 단점 | 권장 단계 |
|---|---|---|---|---|
| 규칙 기반 가중합 | 레짐별 가중치 + 신뢰도 감쇠 + 임계값 | 구현 단순, 설명가능, 감사 친화 | 수동 튜닝, 비선형 한계 | 초기 상용화 |
| 스태킹 메타모델 | 에이전트 출력을 피처로 학습 | 비선형 결합 학습 | 과적합, 레짐 변화 취약 | 데이터 축적 후 |
| 레짐-게이팅 MoE | 레짐에 따라 전문가 가중치 갱신 | 레짐 전환 대응 | 구현 복잡 | 섹터/거시 영향 큰 전략 |
| 베이지안 모델 평균 | 모델별 예측 분포 결합 | 신뢰구간 기반 의사결정 | 분포 추정 필요 | 정교한 리스크 기반 |
초기에는 규칙 기반 가중합으로 시작하고, Meso Loop를 통해 가중치를 동적으로 조정하다가, 충분한 데이터가 축적되면 스태킹이나 MoE로 전환하는 것이 현실적인 로드맵이다.
메모리 아키텍처
계층적 메모리 구조
피드백 루프의 산출물은 계층적 메모리에 저장된다.
| 메모리 계층 | 저장소 | TTL | 내용 |
|---|---|---|---|
| Working Memory | LangGraph State | 파이프라인 실행 동안 | 현재 실행의 중간 결과 |
| Short-term Memory | Redis | 7일 | 최근 가중치, 포지션 현황, 최근 Reflection |
| Long-term Memory | PostgreSQL | 영구 | 전체 Reflection Memo, 거래 이력, 가중치 스냅샷 |
Redis 가중치 캐시 구조
# 에이전트 가중치 (Meso Loop에서 갱신)
weights:{project_id} -> {
"quant_analyst": 0.22,
"llm_analyst": 0.28,
"sector_rotation": 0.15,
"debate": 0.20,
"memory": 0.15,
"updated_at": "2026-02-21T06:00:00+09:00",
"version": 47
}
TTL: 없음 (명시적 갱신)
# 최근 Reflection 요약 (Ensemble Voter 참조용)
reflection_summary:{project_id} -> {
"recent_failures": ["SIGNAL_ERROR", "NEWS_HALLUCINATION"],
"avoid_patterns": ["RSI oversold in downtrend"],
"preferred_agents": ["llm_analyst"],
"updated_at": "2026-02-21T06:00:00+09:00"
}
TTL: 7일피드백 루프 설계 시 주의사항
과적합 방지
| 위험 | 완화책 |
|---|---|
| 최근 거래에 과잉 적응 | 이동 평균(N=20~50 거래) 기반 가중치 조정 |
| 단일 대형 손실에 과반응 | 가중치 변동 폭 제한 (delta max 0.05/회) |
| 시장 레짐 변화를 패턴으로 오인 | 레짐 감지 에이전트(Sector Rotation) 독립 운영 |
| Macro Loop 프롬프트 오염 | 카나리 배포 + 자동 롤백 |
비용 관리
Micro Loop의 Generator-Critic 반복은 LLM API 호출 비용을 증가시킨다.
| 전략 | 효과 |
|---|---|
| Critic에 경량 모델(Haiku) 사용 | 비용 80% 절감 |
| 확신도 높은 출력은 Critic 생략 | 호출 횟수 50% 감소 |
| Meso Loop는 Celery 비동기 처리 | 메인 파이프라인 지연 영향 없음 |
| Macro Loop는 주 1회 제한 | 고비용 분석을 일괄 처리 |
참고 자료
- Reflexion: Language Agents with Verbal Reinforcement Learning (arxiv:2303.11366)
- Self-Refine: Iterative Refinement with Self-Feedback (arxiv:2303.17651)
- QuantAgents: Towards Multi-agent Financial System via Simulated Trading (arxiv:2510.04643)
- TradingAgents: Multi-Agents LLM Financial Trading Framework (arxiv:2412.20138)
- RRMSE-enhanced weighted voting regressor for improved prediction
- LangGraph Reflection Agents: https://www.blog.langchain.com/reflection-agents/
- Google SRE: Canarying Releases