← quant-agent design·DOC 02

서브에이전트 구성 설계

정량 필터가 넘긴 후보 15종목을 추천 3–5종목 + 매매 계획으로 바꾸는 에이전트 파이프라인. 핵심 설계 원칙은 독립성(분석가끼리 서로 못 봄), 구조화 출력(전부 JSON 스키마 강제), 측정 가능성(에이전트별 정확도를 사후에 채점)입니다.

결론 요약
에이전트
10종 (스크리너 1 + 분석가 5 + 매크로 1 + 비평 1 + 결정 1 + 리스크 1) + 리포트 라이터 1
종목 분석
정량 분석 15종목 선정 → 에이전트 스크리닝 6종목 선정 → 에이전트 병렬 분석 → 비평 → 결정
1회 실행
55 API 콜 · 35–45분 소요 (07:00 → 07:50)

1전체 구조

STAGE 0 · 정량 TIER-1 스크리닝 TIER-2 병렬 분석 (독립 실행) 종합 · 검증 발행 리스크 게이트 반려 → 재결정 (최대 1회) 정량 후보 15 DOC 01 · 코드 Tier-1 스크리너 경량 모델 · 15콜 → 상위 6 선별 테크니컬 (Vision) 고성능 비전 모델 · 차트 3장 펀더멘탈 표준 모델 · 재무·밸류 뉴스 · 공시 표준 모델 · web search 수급 (Flow) 표준 모델 · 외국인·기관 섹터 · 피어 표준 모델 · 상대강도 매크로 · 시장국면 고성능 모델 · 1일 1회 종목 무관 · 결정 단계에만 주입 비평 (Red Team) 고성능 모델 · 6콜 반증 · 근거 검증 결정 (PM) 고성능 모델 · 1콜 종목·가격·비중 확정 리스크 게이트 표준 모델 + 룰 포트폴리오 한도 리포트 라이터 표준 모델 · 1콜 HTML / JSON
왜 분석가들이 서로를 못 보게 하는가 에이전트가 다른 에이전트의 결론을 먼저 읽으면 그 결론에 앵커링됩니다. "뉴스 에이전트가 강력 호재라고 했다" → 테크니컬 에이전트가 하락 패턴을 상승 신호로 해석합니다. 5명이 독립적으로 판단해야 의견 불일치가 정보가 됩니다. 4명 찬성 1명 반대와 5명 찬성은 다른 상황이고, 그 차이를 결정 에이전트가 봐야 합니다. 매크로도 같은 이유로 분석가에게 주입하지 않고 결정 단계에서만 씁니다.

2에이전트별 명세

TIER-1 · SCREENER

스크리너

입력 정량 지표 요약표, 최근 5일 가격/거래량, 최근 7일 뉴스 헤드라인 10개, 공시 제목

출력 proceed: bool, interest: 0–10, one_line_thesis, disqualifier

판단 "이 종목에 심층 분석 비용을 쓸 가치가 있나?" 만. 매수 여부는 판단하지 않음.

왜 필요한가 15종목 전부에 5개 에이전트를 돌리면 콜이 75 → 30으로 줄이는 게 이 단계의 유일한 목적. 상위 6개는 interest 내림차순.

ANALYST 1 · TECHNICAL

테크니컬 (이미지 분석)

입력 차트 이미지 3장 + 계산된 지표값 표 (숫자는 코드가 계산해서 텍스트로 전달)

출력 추세국면, 패턴, 지지/저항, 진입트리거, 손절, 목표가 2단, R:R

판단 차트 구조. 상세 규격은 DOC 03.

비고 고성능 비전 모델 필요. 이미지에서 패턴을 읽는 건 이 파이프라인에서 가장 어려운 작업입니다.

ANALYST 2 · FUNDAMENTAL

펀더멘탈

입력 최근 8분기 재무제표(매출·영업이익·순이익·영업CF·부채), 밸류에이션 지표와 3년 밴드 내 위치, 동일 섹터 피어 비교표, 최근 실적발표 요약

출력 실적 방향성, 밸류에이션 판정(저평가/적정/고평가 + 근거), 이익의 질, 재무 리스크

판단 "이 가격이 이 실적에 정당한가", "실적 추세가 개선 중인가". 단기 시계라도 펀더멘탈은 손절선의 신뢰도를 결정합니다 — 실적이 좋은 종목의 급락은 되돌림 가능성이 높습니다.

ANALYST 3 · NEWS & DISCLOSURE

뉴스 · 공시 거부권

입력 최근 14일 뉴스 본문(뉴스API 국제 정세, 주요 이벤트), DART 공시 전문, 애널리스트 리포트 제목·목표가 변경

출력 재료 요약, 재료 신선도(이미 주가에 반영됐나), 감정 점수, hard_veto: bool

거부권 발동 유상증자·전환사채 공시, 횡령·배임, 감사의견 비적정, 대주주 대량 매도, 임상 실패, 규제 제재, 실적 하향 경고. 다른 에이전트 점수와 무관하게 종목 탈락.

주의 web_search 서버 툴 사용. 유료 기사 본문 접근 불가 구간이 있어 헤드라인만으로 판단하는 경우가 생깁니다 — 출력에 source_quality를 같이 받아 신뢰도를 감쇄시킵니다.

ANALYST 4 · FLOW

수급

입력 20일 외국인·기관·개인 일별 순매수(금액·수량), 프로그램 매매, 공매도 잔고 추이, 대차잔고, 시가총액 대비 순매수 비율

출력 주도 주체, 수급 방향 전환 여부, 매집/분산 판정, 공매도 압력

왜 별도 에이전트인가 한국 시장에서 외국인·기관 수급은 단기 주가의 가장 강한 단일 설명변수에 가깝습니다. 테크니컬 에이전트의 부속으로 두면 차트 판정에 묻힙니다. 독립 투표권을 줘야 합니다.

주의 공매도 잔고는 T+2 지연 데이터. 프롬프트에 지연 사실을 명시해 최신 정보처럼 쓰지 않게 합니다.

ANALYST 5 · SECTOR & PEER

섹터 · 피어

입력 소속 섹터 지수의 1M/3M 수익률과 KOSPI 대비 상대강도, 동일 섹터 상위 5종목의 최근 수익률·밸류에이션, 섹터 관련 정책·업황 뉴스

출력 섹터 국면, 종목의 섹터 내 위치(주도주/후발주/소외주), 순환매 단계 판정

판단 "섹터가 오르는데 이 종목만 안 오른 건가(기회), 섹터가 이미 다 오른 뒤인가(위험)". 정량 필터가 섹터 중립화로 지운 정보를 여기서 되살립니다.

MACRO · 1× PER DAY

매크로 · 시장 국면

입력 전일 미국 3대 지수·반도체 지수, VIX, 미 10년물 금리, DXY, USD/KRW, 유가, 야간 선물, 전일 KOSPI 외국인 수급, 당일·주간 이벤트 캘린더(FOMC·CPI·옵션만기·실적발표)

출력 regime: risk_on | neutral | risk_off, KOSPI 예상 밴드, 시나리오 3개 + 확률, 주도 예상 섹터, exposure_cap: 0–100%

핵심 역할 exposure_cap. risk_off 국면에서는 아무리 좋은 종목이 나와도 총 노출을 30%로 묶습니다. 개별 종목 분석이 잘 되면 잘 될수록 이 브레이크가 필요합니다.

CRITIC · RED TEAM

비평 반증 임무

입력 해당 종목에 대한 5개 분석가의 출력 전문 + 원본 데이터

출력 factual_errors[], logical_gaps[], bear_case, confidence_adjustment: -3..0, kill: bool

프롬프트 방향 "이 종목을 사면 안 되는 이유를 찾아라"로 단방향 지시. 균형 잡힌 평가를 요구하면 그냥 요약을 합니다. 특히 세 가지를 검증시킵니다 — (1) 분석가가 인용한 숫자가 원본 데이터와 일치하는가(할루시네이션 검출), (2) 5명의 결론이 서로 모순되지 않는가, (3) 이미 주가에 반영된 재료를 새 재료로 착각하지 않았는가.

왜 종목별 1콜인가 전체를 한 번에 비평하면 종목 간 비교로 흐르고, 개별 논거 검증이 얕아집니다.

DECISION · PORTFOLIO MANAGER

결정

입력 6종목 × (분석가 5 + 비평 1) 전문, 매크로 출력, 현재 보유 포지션, 계좌 잔고, 최근 10일 성과 요약

출력 추천 3–5종목 각각의 action, entry_type(시가/지정가/조건부), entry_price, stop_loss, target_1, target_2, weight_pct, holding_days, conviction: 1–10, thesis, invalidation(이 논거가 깨지는 조건), 그리고 보유 종목에 대한 hold/trim/exit 판단

중요 이 에이전트만 전체 맥락을 봅니다. 그리고 "오늘은 살 게 없다"는 출력이 허용되어야 합니다. 매일 3종목을 반드시 뽑게 강제하면 나쁜 날에도 억지로 사게 됩니다. 프롬프트에 명시적으로 recommendations: []가 정당한 답이라고 씁니다.

RISK GATE · 룰 + LLM

리스크 게이트

기계적 룰 (LLM 없이 코드로 먼저)

  • 1종목 비중 ≤ 15% · 1섹터 ≤ 35% · 총 주식노출 ≤ 매크로 exposure_cap
  • 손절 폭 × 비중 = 1종목 최대손실 ≤ 계좌의 1.5%
  • 동시 보유 ≤ 8종목 · 신규 진입 ≤ 1일 3종목
  • R:R < 2.0 → 반려 · 손절선이 진입가에서 12% 초과 이격 → 반려
  • 계좌 누적 손실이 고점 대비 −10% → 신규 진입 전면 중단

LLM 파트 룰은 통과하지만 "추천 5종목이 사실상 같은 AI 인프라 테마" 같은 숨은 상관을 잡아내는 역할.

반려 시 사유를 붙여 결정 에이전트에 1회 반송. 2회차에도 실패하면 해당 종목만 드롭하고 진행.

3출력 스키마 — 전부 강제

모든 분석가는 동일한 공통 스키마를 반환합니다. 그래야 결정 에이전트가 기계적으로 집계할 수 있고, 무엇보다 사후에 에이전트별 정확도를 채점할 수 있습니다. LLM API의 Structured Outputs 기능 또는 strict: true 툴 정의로 스키마를 강제합니다.

{
  "agent":        "technical" | "fundamental" | "news" | "flow" | "sector",
  "ticker":       "005930",
  "score":        -2.0 ~ +2.0,      // 방향성 점수. 0 = 중립
  "confidence":   0.0 ~ 1.0,        // 이 판단에 대한 자기 확신도
  "horizon_days": 1 ~ 20,          // 이 판단이 유효한 기간
  "evidence": [                     // 최대 4개. 근거 없는 주장 방지
    { "claim": "...", "data_point": "...", "source": "..." }
  ],
  "risks":       ["...", "..."],    // 최대 3개
  "veto":        false,             // news 에이전트만 true 가능
  "source_quality": "high" | "partial" | "thin",
  "notes":       "자유 서술 (리포트에 인용됨)"
}
evidence에 data_point를 필수로 만든 이유 "실적 개선세가 뚜렷하다"만 쓰게 하면 LLM은 근거 없이 씁니다. data_point를 필수 필드로 두면 "2Q 영업이익 4,120억, YoY +38%"처럼 원본 데이터를 인용해야 하고, 비평 에이전트가 그 숫자를 원본과 대조해 할루시네이션을 기계적으로 잡아낼 수 있습니다. 이 필드 하나가 전체 파이프라인의 신뢰도를 가장 크게 올립니다.

집계는 이중 트랙으로

A · 기계적 컨센서스 (코드)

consensus = Σ(w_agent × score × confidence)
          / Σ(w_agent × confidence)

w = { technical: 1.0, fundamental: 0.8,
      news: 1.0, flow: 1.2, sector: 0.7 }
      # 초기값. 실적 데이터가 쌓이면 재조정

해석 가능하고 재현 가능합니다. 하지만 뉘앙스를 못 읽습니다.

B · LLM 결정 (결정 에이전트)

전체 맥락을 읽고 판단. 예: "펀더멘탈 점수는 낮지만 그 이유가 일회성 대손충당금이고 뉴스 에이전트가 이를 해소된 이슈로 보고 있다" 같은 가중 평균으로 표현 불가능한 판단을 합니다.

둘 다 기록합니다 매일 A와 B를 같이 저장하고, 3개월 뒤 어느 쪽 수익률이 높은지 비교합니다. B가 A를 못 이기면 결정 에이전트는 비용만 쓰는 셈이고, 구조를 단순화해야 합니다. 이건 취향 문제가 아니라 측정할 수 있는 문제입니다.

4모델 등급 배정 및 토큰 사용량

에이전트모델 등급 (미정) 입력
(K tok)
출력
(K tok)
배정 이유
Tier-1 스크리너Standard / Fast15101.5단순 선별. 판단 난도 낮음
테크니컬 (Vision)Flagship (Vision)6152.5이미지 패턴 판독. 가장 어려운 작업
펀더멘탈Standard6202.0구조화된 표 해석
뉴스 · 공시Standard6302.0긴 텍스트 요약. 웹검색 토큰 큼
수급Standard6121.5시계열 표 판독
섹터 · 피어Standard6151.5상대 비교
매크로Flagship / Reasoning1405.0전체 노출도를 결정. 틀리면 전부 틀림
비평Flagship / Reasoning6253.0반증 추론. 약한 모델은 그냥 동의함
결정 (PM)Flagship / Reasoning1808.0최종 판단. 고성능 모델 필요
리스크 게이트Standard1202.0대부분 코드 룰. LLM은 보조
리포트 라이터Standard16012.0글쓰기. 출력 토큰이 큼
아침 리포트 합계551회 실행 (약 55콜)
장마감 리뷰 (4에이전트)Standard + Flagship~10DOC 05
1일 합계 / 월(거래일 20일)~65월 약 1,300콜 실행 예정
토큰 수 및 호출 횟수는 추정치이며, 모델 최종 선정 후 단가에 따라 실제 비용이 산정됩니다.
비용을 절감하는 핵심 설계 — 프롬프트 캐싱 각 에이전트의 시스템 프롬프트(역할 정의 + 출력 스키마 + 판단 기준, 약 3–5K 토큰)는 매일 동일합니다. 그리고 같은 날 6종목에 같은 에이전트를 6번 호출하므로 캐시 히트가 5번 발생합니다. 시스템 프롬프트 끝에 캐시 설정을 걸고, 종목별 데이터는 그 뒤에 배치하여 전체 입력 토큰 비용을 최대 40% 이상 절감할 수 있습니다.

API 호출 구성 예시 (설계안)

# 판단형 에이전트 (테크니컬 · 비평 · 결정 · 매크로)
model         = "MODEL_FLAGSHIP_TIER"          # 플래그십/추론 모델 적용 예정
thinking      = {"type": "adaptive"}          # 또는 reasoning_effort: "high"
output_config = {"effort": "high", "format": {...스키마...}}
max_tokens    = 16000

# 수집·정리형 에이전트 (펀더멘탈 · 뉴스 · 수급 · 섹터 · 스크리너 · 라이터)
model         = "MODEL_STANDARD_TIER"          # 표준/경량 모델 적용 예정
thinking      = {"type": "adaptive"}
output_config = {"effort": "medium", "format": {...스키마...}}

# 뉴스 에이전트만 웹 검색 툴 추가
tools = [{"type": "web_search", "name": "web_search", "max_uses": 8}]

5실패 처리와 타임아웃

상황처리
분석가 1명 실패 (타임아웃 · 5xx)2회 재시도(지수 백오프) → 실패 시 해당 에이전트를 null로 두고 진행. 컨센서스 계산에서 가중치 재정규화
분석가 3명 이상 실패해당 종목을 후보에서 제외. 3명 미만의 근거로 매매 결정을 내리지 않음
매크로 에이전트 실패전체 중단. exposure_cap 없이 진행하면 리스크 통제가 사라짐. 재시도 후에도 실패하면 "매크로 판단 불가로 금일 신규 진입 없음" 리포트 발행
결정 에이전트 실패3회 재시도. 최종 실패 시 기계적 컨센서스(트랙 A) 상위 3종목을 관망 등급으로만 리포트에 표기. 자동 주문 없음
스키마 검증 실패Structured Outputs가 대부분 막지만, 실패 시 에러 메시지를 붙여 1회 재요청
전체 파이프라인이 08:30 미완부분 완료분으로 리포트 발행 + incomplete: true 플래그. 자동 주문은 집행하지 않음
stop_reason == "refusal"서버측 폴백(Fallback) 설정을 활성화해 자동 대체. 금융 데이터 분석에서 흔하진 않지만 핸들링은 필요

6장마감 리뷰 파이프라인

아침과 별개의 4-에이전트 구성입니다. 대부분의 채점은 코드가 하고, LLM은 왜 그랬는지를 씁니다.

1 · 채점

성과 채점

코드가 계산: 추천 종목 수익률, 목표/손절 도달, 지수 예측 오차, 에이전트별 방향 적중. LLM은 결과 서술만.

2 · 리서치

장중 이슈

웹검색으로 09:00–15:30 사이 시장을 움직인 뉴스를 시간순 타임라인화.

3 · 귀인

원인 분석

아침 판단과 실제 결과의 차이가 운인가 실력인가. 놓친 급등주도 함께 분석.

4 · 교훈

개선 제안

누적 30일 데이터를 보고 팩터 가중치·에이전트 가중치·프롬프트 수정안 제시. 자동 적용은 안 함 — 사람이 승인.

교훈 에이전트가 스스로 프롬프트를 고치게 하면 안 되는 이유 자기 개선 루프를 자동화하면 최근 며칠의 노이즈에 과적합됩니다. 3일 연속 반도체가 빠지면 "반도체 비중을 줄이라"는 제안이 나오고, 그게 자동 적용되면 반등 구간을 놓칩니다. 제안은 DB에 쌓아두고 월 1회 사람이 리뷰해서 반영합니다.

7미결정 사항 — 판단이 필요한 부분

Q1 · 비평 에이전트를 2개(강세론자 / 약세론자)로 나눌 것인가

현재 설계는 약세 단일 방향입니다. 강세 옹호자를 붙이면 균형은 잡히지만 콜이 6개 늘고, 결정 에이전트가 이미 강세 근거(분석가 5명)를 충분히 받습니다. 제안: 단일 약세 비평 유지. 시스템이 "너무 조심스러워서 아무것도 안 사는" 문제를 보이면 그때 추가.

Q2 · 테크니컬 에이전트를 3개(단기/중기/패턴)로 쪼갤 것인가

시간프레임별로 판단이 갈리는 경우가 많습니다(일봉은 조정, 주봉은 상승추세). 제안: 쪼개지 않고, 한 에이전트가 시간프레임별로 각각 답하게 스키마를 확장. DOC 03에 그 형태로 설계했습니다.

Q3 · 사람 승인 게이트를 넣을 것인가

현재 설계는 08:00 리포트 발행 후 09:00 자동 주문입니다. 그 사이 사람 확인이 없습니다. 제안: 모의투자 단계에서는 완전 자동(개입하면 시스템 성능을 측정할 수 없음). 실계좌 전환 시 "리포트 확인 후 승인 버튼" 게이트를 웹 화면에 추가. DOC 06에 버튼 자리를 잡아뒀습니다.

Q4 · 에이전트 가중치의 초기값 근거가 없다

위의 w = {flow: 1.2, technical: 1.0, ...}은 제 직관입니다. 데이터가 없습니다. 제안: 첫 30 거래일은 전부 1.0 균등으로 운영하고, 에이전트별 방향 적중률이 쌓인 뒤 조정. 근거 없는 가중치는 근거 없는 확신을 만듭니다.

토큰 수·콜 수는 추정치