콘텐츠로 이동

에이전트 프레임워크 v2

작성: 2026-05-15 v1 대비 변경: 종합 판정을 코드(synthesize.py)로 이관. LLM은 도메인 해석만 담당.


핵심 아키텍처

원자 에이전트 (LLM)          synthesize.py (코드)        서술 에이전트 (LLM)
 도메인 해석 + 점수화    →    결정론적 종합 판정     →    사람이 읽을 리포트
 잘하는 것: 해석             잘하는 것: 일관성           잘하는 것: 글쓰기
 못하는 것: 일관된 종합       못하는 것: 해석             못하는 것: 없음

규칙: LLM이 GO/WAIT/PASS를 결정하지 않는다. 코드가 결정한다. LLM은 (1) 도메인별 verdict+score를 생성하고 (2) 코드의 판정을 리포트로 변환한다.


1. 원자 에이전트 표준 출력 스키마

모든 도메인 에이전트는 이 스키마로 JSON을 출력:

{
  "domain": "chart | flow | material | fundamentals | environment",
  "code": "042700",
  "name": "한미반도체",
  "as_of": "2026-05-15T16:30:00+09:00",

  "verdict": "긍정 | 중립 | 부정",
  "score": 8,
  "confidence": 0.85,

  "key_evidence": "3주 베이스 돌파, MARUBOZU 92%, VP POC 380K 위",
  "risk_factor": "52주 신고가 근접 저항",

  "data_frame": {
    "primary_metric": "close",
    "value": 420000,
    "change_1d": 5.5,
    "change_5d": 12.3,
    "change_20d": 18.3,
    "streak": 3,
    "direction": "accelerating"
  },

  "domain_specific": {}
}

필드 규칙

필드 타입 규칙
verdict enum 긍정/중립/부정. 3값만 허용.
score int 0~10. 도메인 내부 기준으로 산출.
confidence float 0.0~1.0. 데이터 충분성/신뢰도.
key_evidence string 1~2문장. 판정 근거. 수치 포함 필수.
risk_factor string 1문장. 주요 리스크. null 허용.
data_frame object 핵심 지표의 변화+누적 프레임.
domain_specific object 도메인별 추가 필드 (아래 정의).

도메인별 domain_specific 필드

chart:

{
  "trend": "상승 | 횡보 | 하락",
  "sl": 390000,
  "tp": 480000,
  "rr_ratio": 2.0,
  "sl_basis": "VP HVN 385K + MA20 392K",
  "at_peak_signal": false,
  "peak_evidence": null,
  "structure": "base_breakout | pullback | channel | range"
}

flow:

{
  "pattern": "매집 | 추격 | 차익실현 | 전환 | 혼조 | 폭탄",
  "dual_buy": true,
  "foreign_5d_cum": 850000,
  "inst_5d_cum": 120000,
  "foreign_20d_cum": -1800000,
  "positioning_extreme": false,
  "subject_dynamics": "외인 매집 3일째, 기관 동조"
}

material:

{
  "catalyst_grade": "S | A | B | C | D",
  "structural_grade": "structural | semi_structural | temporary",
  "freshness": "Fresh | Aging | Stale",
  "freshness_days": 2,
  "priced_in": "no | partial | yes",
  "propagation": "NVIDIA 매출↑ → HBM 수요↑ → 한미반도체 패키징",
  "theme": "AI반도체/HBM"
}

fundamentals:

{
  "op_yoy_trend": "가속 | 유지 | 감속 | 적자전환",
  "op_yoy_quarters": [32, 45],
  "valuation_grade": "저평가 | 적정 | 고평가 | 극단",
  "red_flag": false,
  "red_flag_detail": null,
  "dart_confirmed": true
}

environment:

{
  "theme_lifecycle": "EMERGING | ACCELERATING | LEADING | COOLING | RE_ACCELERATING",
  "macro_regime": "risk_on_growth | risk_on_rotation | neutral | risk_off",
  "bond_equity_conflict": "none | mild | severe",
  "crowding": "low | moderate | high",
  "sector_rs_rank": 5
}


2. synthesize.py 규칙표

거부권 (Veto) — 무조건 적용, 예외 없음

규칙 조건 결과
VETO_CHART chart.verdict == "부정" PASS
VETO_RR chart.rr_ratio < 1.5 PASS
VETO_RED_FLAG fundamentals.red_flag == true 최대 WAIT

교차검증 (X1~X7) — 모순 감지

# 검증 입력 차단 조건
X1 채권 vs 주식 env.bond_equity_conflict severe → GO 불가
X2 컨센서스 과밀 env.crowding (단독 비차단)
X3 촉매 선반영 material.priced_in yes → GO 불가
X4 차트 vs 수급 괴리 chart.verdict ↔ flow.verdict (기록만, 비차단)
X5 재료 vs 실적 불일치 material.verdict 긍정 + fund.verdict 부정 contradiction → GO 불가
X6 포지셔닝 극단 flow.positioning_extreme true → 사이즈 50%
X7 과밀+선반영 동시 X2 high + X3 yes → GO 불가

GO 4조건 — 전부 충족 시 GO

# 조건 입력
G1 고점 신호 부재 chart.at_peak_signal == false
G2 SL 확보 (R:R ≥ 1.5) chart.rr_ratio >= 1.5
G3 재료 뒷받침 material.structural_grade ∈ {structural, semi_structural}
G4 수급 확인 flow.dual_buy == true 또는 flow.pattern == "매집"

최종 판정 매트릭스

거부권 발동?
  → YES → PASS 또는 WAIT (규칙에 따라)
  → NO ↓

교차검증 차단?
  → YES → WAIT (차단 사유 명시)
  → NO ↓

GO 4조건 전부 충족 + 가중점수 ≥ 1.2?
  → YES → GO (사이즈: X6에 따라 full 또는 half)
  → NO ↓

GO 3/4 충족 + 가중점수 ≥ 1.0?
  → YES → WAIT (미충족 조건 명시)
  → NO ↓

가중점수 ≥ 0.8?
  → YES → WAIT
  → NO → PASS

가중 점수

weighted_score = Σ (domain.score × domain.confidence × domain.weight)

가중치: chart=0.25, flow=0.25, material=0.20, fundamentals=0.15, environment=0.15
score: 0~10 스케일 (각 도메인 에이전트가 산출)
confidence: 0.0~1.0 (데이터 충분성)

3. Claude CLI 워크플로우

종목 분석 시

스킬 (rs_evening.md 또는 candidate-pipeline):

  1. candidate_from_theme.py → 종목 풀 확보

  2. 종목별 5개 에이전트 호출 (병렬 가능):
     Agent(subagent_type="domain/chart-analyst", prompt="종목 042700 분석...")
       → data/agent_results/YYYYMMDD/042700_chart.json
     Agent(subagent_type="domain/flow-analyst", prompt="종목 042700 수급...")
       → data/agent_results/YYYYMMDD/042700_flow.json
     Agent(subagent_type="domain/material-analyst", prompt="종목 042700 재료...")
       → data/agent_results/YYYYMMDD/042700_material.json
     Agent(subagent_type="domain/fundamentals-analyst", prompt="종목 042700 실적...")
       → data/agent_results/YYYYMMDD/042700_fundamentals.json
     Agent(subagent_type="domain/environment-analyst", prompt="종목 042700 환경...")
       → data/agent_results/YYYYMMDD/042700_environment.json

  3. synthesize.py 실행 (코드 판정):
     scripts/synthesize.py --dir data/agent_results/YYYYMMDD/ --code 042700
       → data/agent_results/YYYYMMDD/verdicts.json

  4. 서술 에이전트 호출 (리포트 작성):
     Agent(subagent_type="narrator", prompt="verdicts.json을 읽고 리포트 작성...")
       → 리포트 마크다운

시장 전체 분석 시 (장전/장마감/저녁)

스킬 (rs_morning_open.md):

  1. 데이터 수집 스크립트 (병렬):
     fetch_global_assets.py → data/routine_data/global_assets.json
     fetch_market_top.py → data/market_top/YYYYMMDD.json
     ...

  2. 시장 에이전트 호출 (순차 — 앞 결과가 뒤 입력):
     Agent: global-asset-scanner → data/outputs/YYYYMMDD/mo1_global.json
     Agent: sector-transfer-mapper → data/outputs/YYYYMMDD/mo2_sector.json
       (mo1 결과를 입력으로 받음)
     Agent: overnight-material-grader → data/outputs/YYYYMMDD/mo3_material.json
     Agent: signal-synthesizer → data/outputs/YYYYMMDD/mo5_signals.json
       (mo1~mo3 전체를 입력으로 받음)

  3. morning_view.json 조립 (코드 — 스크립트):
     assemble_morning_view.py → data/outputs/YYYYMMDD/morning_view.json

  4. 리포트 작성 (에이전트):
     Agent: morning-reporter → docs/morning_open/YYYYMMDD_morning_open.md

4. 에이전트 목록 (재구성)

도메인 분석 에이전트 (종목별, 5개)

에이전트 질문 내부 복잡도 산출물
chart-analyst "이 차트 구조가 진입에 유리한가?" C1~C10 통합, mtf_chart_profiler, VP+VSA+구조 {code}_chart.json
flow-analyst "스마트머니가 사고 있는가, 빠지고 있는가?" SEN-1~5 통합, 5d/20d 누적, 패턴 분류 {code}_flow.json
material-analyst "카탈리스트가 구조적인가, 실제 매출에 닿는가?" NC-3+NC-6+material-validator 통합, 4Q binary {code}_material.json
fundamentals-analyst "이익이 개선되고 있는가?" FA-M1~M7 통합, DART 3~4분기 IS, OP YoY {code}_fundamentals.json
environment-analyst "테마·매크로·섹터가 우호적인가?" M1+S1+S2 통합, lifecycle, RS, regime {code}_environment.json

각 에이전트는 내부적으로 복잡하지만 (기존 원자 에이전트 여러 개의 역할을 통합), 출력은 표준 스키마 하나로 고정됨.

시장 분석 에이전트 (전체 시장, 단계별)

단계 에이전트 질문
장전 global-asset-scanner 밤사이 글로벌 자산 변화와 한국 영향?
장전 sector-transfer-mapper 미장 섹터 → 한국 테마 전이?
장전 overnight-material-grader 밤사이 재료 중 오늘 장에 영향 줄 것?
장전 signal-synthesizer 오늘 시그널은 무엇이고 종목 연결은?
장마감 signal-scorecard 아침 시그널이 맞았나 틀렸나?
장마감 theme-strength-ranker 오늘 실제 강했던 테마와 생명주기?
장마감 discovery-detector 오늘 새로 등장한 이상 움직임?
저녁 macro-4axis 금리/원자재/환율/유동성 4축 환경?
저녁 material-validator 각 재료가 구조적인가 일시적인가?
저녁 theme-scenario-builder 내일 유력 테마와 시나리오?

조립/서술 에이전트 (판정 후)

에이전트 역할
morning-reporter morning_view.json → 장전 마크다운 리포트
postmarket-reporter post_market_view.json → 장마감 마크다운 리포트
evening-reporter evening_view.json → 저녁 마크다운 리포트

5. 역할 분리 요약

역할 누가
도메인 해석 LLM (에이전트) 차트 패턴 읽기, 수급 패턴 분류 등은 LLM이 잘함
점수 산출 LLM (에이전트) 도메인 내부 기준으로 0~10 채점은 LLM이 할 수 있음
종합 판정 코드 (synthesize.py) 5개 점수를 합산하여 GO/WAIT/PASS — 일관성 필요
교차 모순 검출 코드 (synthesize.py) X1~X7 규칙 — 결정론적이어야 함
리포트 작성 LLM (서술 에이전트) 코드 판정을 사람이 읽을 형태로 — LLM이 잘함
PM 최종 결정 PM GO여도 PM이 실행 여부 결정
---

## 6. 일관성 보장 메커니즘

### 입력 검증
- synthesize.py가 5개 JSON 파일의 필수 필드를 검증
- 누락 → INCOMPLETE 반환 (판정 자체를 하지 않음)
- 잘못된 enum → INVALID 반환

### 출력 재현성
- 같은 5개 JSON이 들어오면 항상 같은 verdict
- 가중치, 임계값, 거부권 규칙이 코드에 고정
- 규칙 변경은 synthesize.py 수정 → git 추적 가능

### 피드백 루프
synthesize.py verdict
↓ (다음날)
signal_scorecard에서 HIT/MISS 판정
↓ (주간)
accuracy_log.jsonl 집계
↓ (월간)
가중치/임계값 조정 검토 (PM 승인 후 synthesize.py 수정)
```