
CrewAI를 활용한 6개 에이전트 투자 조사 파이프라인 구축
요약
CrewAI를 활용하여 6개의 전문 에이전트로 구성된 주식 조사 멀티 에이전트 시스템 아키텍처를 소개합니다. 단일 에이전트의 환각 문제를 해결하기 위해 역할을 분리하고, LLM은 추론을, 도구는 계산을 담당하도록 설계하는 원칙을 제시합니다.
핵심 포인트
- 단일 에이전트의 한계인 환각 및 맥락 결여 문제 해결
- 6개의 전문 에이전트(분석가, 전략가, 비판가 등)로 역할 분담
- LLM은 추론에 집중하고, 수치 계산은 도구(Tool)가 수행하도록 설계
- 비판적 검토(Critic) 단계를 포함하여 의사결정의 객관성 확보
제가 어떻게 주식 조사를 6개의 전문 에이전트로 나누었는지, 그리고 포트폴리오를 환각(Hallucination) 속으로 빠뜨리지 않게 만든 두 가지 설계 규칙에 대해 설명합니다.
저는 주식 포트폴리오를 조사하는 멀티 에이전트 시스템(Multi-agent system)인 ProspectAI를 구축했습니다. 이것은 기술 데모이며 투자 도구가 아닙니다. 흥미로운 부분은 종목 추천이 아니라 아키텍처(Architecture)입니다. 이 포스트는 파이프라인이 어떻게 구성되었는지와 이를 작동하게 만든 두 가지 규칙에 관한 것입니다.
하나의 거대한 에이전트가 가진 문제점
이것을 구축하는 가장 명백한 방법은 단일 에이전트를 사용하는 것입니다: "여기 주식이 있으니, 분석해서 매수할지 알려줘." 하나의 프롬프트(Prompt), 하나의 호출(Call), 하나의 답변.
데모에서는 작동하지만 실제로는 무너집니다. 그 단일 프롬프트는 거시적 맥락(Macro context), 기술적 신호(Technical signals), 펀더멘털(Fundamentals), 그리고 최종 결정을 한꺼번에 담고 있어야 합니다. 출력이 틀렸을 때 어느 부분이 실패했는지 알 수 없습니다. 모델이 숫자를 환각(Hallucinate)할 때 이를 잡아낼 수 있는 것이 없습니다. 그리고 루프(Loop) 내에 반대 의견을 낼 사람이 없기 때문에, 모델은 스스로를 설득하여 결론에 도달하는 경향이 있습니다.
그래서 저는 작업을 나누었습니다. 에이전트가 많아서가 아니라, 명확한 경계(Boundaries)가 있기 때문입니다.
파이프라인, 위에서 아래까지
6개의 에이전트가 파이프라인(Pipeline)으로 실행됩니다. 각 에이전트는 좁은 범위의 업무를 수행하며 다음 에이전트에게 구조화된 결과(Structured result)를 전달합니다.
Market Analyst -> macro & sector context
│
┌──────────┴──────────┐
...
Market Analyst가 가장 먼저 실행되어 거시(Macro) 및 섹터(Sector) 맥락을 설정합니다. 그 맥락은 Technical Analyst와 Fundamental Analyst에게 전달되어 각자의 견해를 생성합니다. Draft Strategist는 모든 것을 진입가, 손절가, 목표가가 포함된 후보 포트폴리오로 변환합니다. Critic은 이를 무너뜨리려 시도합니다. Final Strategist는 비판(Critique)을 바탕으로 이를 다시 작성합니다.
이것이 구조입니다. 아래의 두 가지 규칙이 이 구조를 실제로 유지하게 만듭니다.
규칙 1: LLM은 추론하고, 도구는 계산한다
만약 단 하나의 규칙만 유지해야 한다면, 제가 선택할 규칙은 바로 이것입니다.
포트폴리오에 포함되는 그 어떤 숫자도 언어 모델 (Language Model)에 의해 생성되지 않습니다. 종합 점수(composite score), 포지션 규모(position size), 손절매(stop-loss), 손익비(risk/reward ratio) 그 무엇도 마찬가지입니다. 모든 수치는 결정론적인 (deterministic) Python 도구에 의해 계산됩니다. LLM은 어떤 신호가 중요한지, 그리고 왜 중요한지를 결정합니다. 수학 계산은 LLM의 역할이 아닙니다.
의사 코드 (pseudocode)로 표현하면, 그 구분은 다음과 같습니다.
# 잘못된 방식: 모델이 숫자를 지어냄
score = llm("분석을 바탕으로 이 주식의 점수를 0에서 100 사이로 매겨주세요")
...
이유는 간단합니다. 주식 투자 논거 (stock thesis)를 환각 (hallucinate)할 수 있는 모델은 성과 지표 (performance metric) 또한 환각할 수 있습니다. 그리고 두 번째 상황은 훨씬 더 위험합니다. 왜냐하면 그 지표는 첫 번째 논거가 유효했는지를 판단하기 위해 우리가 신뢰하는 숫자이기 때문입니다. 모델을 산술 연산으로부터 격리시키면, 조용히 발생하는 오류(silent errors)의 한 범주가 통째로 사라집니다.
규칙 2: 에이전트 간의 타입화된 계약 (typed contracts)
두 번째 규칙은 에이전트 사이의 경계를 무엇이 통과하느냐에 관한 것입니다.
초기에는 에이전트들이 서로에게 산문 (prose) 형태의 텍스트를 전달했습니다. 기술적 분석가 (Technical Analyst)가 한 단락을 작성하면, 초안 전략가 (Draft Strategist)가 이를 읽고 해석하는 방식이었습니다. 이는 조용하고 짜증 나는 방식으로 시스템을 망가뜨립니다. 하류 (downstream) 에이전트가 서사를 다시 읽으면서, 상류 (upstream) 에이전트가 의도했던 바를 미묘하게 재발명해 버리기 때문입니다.
해결책은 텍스트가 아닌 타입화된 객체 (typed objects)를 전달하는 것입니다. 각 에이전트는 스키마 (schema)를 반환하며, 이는 다음 단계로 넘어가기 전에 검증됩니다.
class TechnicalView(BaseModel):
trend: Literal["up", "down", "sideways"]
momentum_score: float
...
스키마에 포함되어 있지 않다면, 데이터는 전달되지 않습니다. 하류 에이전트는 산문에서 추론한 '느낌 (vibe)'에 따라 행동할 수 없습니다. 오직 정의된 필드 (fields)만을 전달받기 때문입니다. 이 한 가지 변화만으로 제가 겪었던 대부분의 핸드오프 (hand-off) 버그가 사라졌습니다.
오직 공격만을 위해 존재하는 에이전트
비판가 (Critic)는 제가 가장 좋아하는 부분이며, 이 에이전트는 분석을 전혀 수행하지 않습니다.
이 에이전트는 새로운 컨텍스트(context)와 단 하나의 지시사항을 받습니다: 초안을 공격하십시오. 누락된 촉매제, 모순되는 신호, 그리고 리스크가 보상을 정당화하지 못하는 상황을 찾아내십시오. 이 에이전트는 포트폴리오를 재구축하지 않습니다. 대신 구조화된 수정 지침(revision directives)을 생성하며, 최종 전략가(Final Strategist)가 이를 적용합니다.
draft = draft_strategist(analyst_views)
critique = critic(draft) # 새로운 컨텍스트, 적대적 역할
final = final_strategist(draft, critique)
왜 하나의 에이전트에게 "자신의 작업을 재검토하라"고 요청하는 대신 별도의 에이전트를 사용했을까요? 동일한 컨텍스트 내에서 자신의 출력을 검토하는 모델은 스스로의 의견에 동조하는 경향이 있기 때문입니다. 새로운 컨텍스트와 적대적인 지시사항을 가진 별도의 역할은 실제로 반론을 제기합니다. 한 번의 실행에서 비판가(Critic)는 초안을 여러 번 반려했으며, 결과적으로 제가 직접 만든 평가기(evaluator)의 점수를 상당히 개선했습니다.
스택 (The stack)
특별한 것은 없습니다. 에이전트 오케스트레이션(orchestration)을 위한 CrewAI, 설정에 따른 에이전트별 모델 선택(분석가에게는 더 저렴한 모델을, 전략가와 비판가에게는 더 강력한 모델을 사용), 모든 계산을 위한 결정론적(deterministic) Python 도구, 백엔드를 위한 Modal, 프론트엔드를 위한 Cloudflare Pages를 사용했습니다. 결과는 SSE를 통해 브라우저로 스트리밍됩니다.
이 패턴은 금융에 국한된 것이 아닙니다
티커(tickers)를 제외하면, 이 방식은 거의 모든 LLM 파이프라인에 일반화될 수 있습니다.
모델이 추론하게 하고, 정답이 하나뿐인 모든 작업은 결정론적 코드(deterministic code)가 수행하게 하십시오. 단계 사이에는 자유 형식의 텍스트가 아닌 타입이 지정된 객체(typed objects)를 전달하십시오. 하나의 구성 요소에는 다른 구성 요소들과 의견을 달리하는 명시적인 임무를 부여하십시오. 그리고 샘플로 뒷받침할 수 없는 결과는 보고하기를 거부하십시오.
이 중 어느 것도 금융 아이디어가 아닙니다. 이것들은 멀티 에이전트 시스템(multi-agent system)이 무엇을 수행하든 간에, 그 시스템이 정직함을 유지하도록 만드는 요소들입니다.
실행되는 모습을 보고 싶다면 라이브 파이프라인은 여기에 있으며, Python 패키지는 PyPI에 있습니다. 비판가 패턴(critic pattern)에 대한 피드백을 받고 싶으니, 유사한 것을 구축해 보셨다면 무엇이 효과적이었는지 알려주세요.
ProspectAI는 멀티 에이전트 AI 시스템의 기술적 데모이며, 공개 데이터를 활용한 모의 투자(paper-traded)를 수행합니다. 이는 명시적으로 투자 조언이 아닙니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기