| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | |
| 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
| 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 28 | 29 | 30 |
- API MARKETPLACE
- APIMARKETPLACE
- 가상화
- naver
- k8s
- 홈서버
- 홈랩
- AI
- opnsense
- prometheus-stack
- GPU 엔지니어링
- proxmox
- 대외활동
- N100
- homelab
- 모니터링
- 서포터즈
- slf4j
- 2022
- 네이버
- spring boot
- NAS
- 방화벽
- jenkins
- LOG
- log4j2
- Elk
- Docker
- 젠킨스
- GPU
- Today
- Total
G 스토리
[Side Project] 단일 AI의 한계를 넘어: LangGraph와 Streamlit으로 구축한 나만의 다중 에이전트 시스템(MAS) 개발기 본문
[Side Project] 단일 AI의 한계를 넘어: LangGraph와 Streamlit으로 구축한 나만의 다중 에이전트 시스템(MAS) 개발기
Jiione 2026. 4. 22. 23:04들어가며 ...
왜 다중 에이전트(Multi-Agent)인가?
'다중 에이전트 시스템(Multi-Agent System, MAS)'을 설계했습니다.
이 글에서는 LangGraph 프레임워크를 기반으로 AI-native 검색 엔진인 Tavily, 그리고 Streamlit 웹 인터페이스를 결합하여 어떻게 이 시스템을 밑바닥부터 구축했는지 상세한 과정을 공유하고자 합니다.
시스템 아키텍처 및 핵심 도구
- Planner (계획 수립자): 사용자의 요청을 분석하고 구체적인 실행 계획을 세웁니다.
- Executor (실행자): 계획을 바탕으로 실제 코드 작성, 파일 시스템 접근, 검색 등의 도구를 사용해 작업을 수행합니다.
- Skeptic (회의론자): Executor와 병렬로 실행되며, Executor의 결과물이 아닌 Planner의 계획 자체를 보고 독립적인 위협 모델과 검토 기준을 세웁니다.
- Executive (관리자): 실행 로그와 리뷰 코멘트를 취합하여 최종 판단(승인, 수정, 거절)을 내립니다.
- Human-in-the-Loop (사람): 최종 실행 전 개입하여 승인하거나 수정 지시를 내립니다.
- 오케스트레이션: LangGraph (에이전트 간의 상태와 흐름 제어)
- 웹 인터페이스: Streamlit (기존 디스코드 봇의 메시지 제한 한계를 극복하기 위한 세련된 UI)
- 검색 엔진: Tavily API (AI 에이전트에 최적화된 정보 검색 및 추출)
- 코딩 보조 및 자동화: Claude Code CLI (터미널 기반의 에이전틱 코딩 도구로 전체 스캐폴딩 및 테스트 자동화 수행)
단계별 구축 프로세스 및 핵심 구현 로직
프로젝트는 복잡한 시스템을 한 번에 뭉뚱그려 짜는 대신, 총 9개의 페이즈(Phase)로 나누어 점증적으로 구축하고 검증하는 방식을 택했습니다
Phase 1 & 2: 기초 스캐폴딩과 상태(State) 설계

class AgentState(TypedDict):
# 누적 필드: 병렬 노드가 동시에 쓰더라도 덮어쓰지 않고 리스트에 추가됨
messages: Annotated[list[BaseMessage], operator.add]
review_comments: Annotated[list[str], operator.add]
execution_logs: Annotated[list[str], operator.add]
# 단일값 필드: 마지막으로 쓴 노드의 값이 최종값
task: str
current_agent: str
executive_verdict: str
위 코드처럼 Annotated[list[str], operator.add]를 사용해 리스트가 안전하게 누적(Append)되도록 설계했습니다. 이 리듀서(Reducer) 기능이 없었다면 Skeptic의 비판적 리뷰가 Executor의 로그에 조용히 덮어써져 사라지는 문제를 겪었을 수도 있습니다.

Phase 3 & 4: 병렬 팬아웃(Fan-out) 설계
Planner의 계획이 수립된 후, Executor와 Skeptic 노드는 직렬이 아닌 병렬(Parallel)로 실행되도록 add_edge를 구성했습니다.

Phase 5: 무한 루프 방지와 Executive 피드백 루프
if has_error:
if revision_count >= MAX_REVISIONS: # 안전장치: 상한선 도달 시 강제 종료
verdict = "reject"
else:
verdict = "revise"
revision_count = revision_count + 1

Phase 6: Docker 기반의 안전한 코드 실행 샌드박스

Phase 7: 권한의 물리적 분리와 Tavily 지능형 검색
- Executor 툴: read_file, write_file, run_code_in_sandbox, web_search
- Skeptic 툴: grep_logs (읽기 전용), web_search

Phase 8: Streamlit을 활용한 Human-in-the-Loop (인간 개입)


프로젝트 회고 및 개선점(희망 사항)
1. 사람의 개입에서 완전한 A2A 시스템으로
이번 시스템에서 의도적으로 사람의 개입을 넣은 이유는 두 가지 이유가 있었습니다.
- AI의 추론 과정에서 제 의견을 주입하여 방향을 틀 수 있고, 완벽하다면 입력창을 비워 둔채 통과시켜 유연하게 저의 개입을 정하려고 했습니다.
- 가장 큰 이유는 Claude API 가격이 너무 많이 나올까봐 였습니다... Executor(실행자)와 Skeptic(검토자) 사이에서 무한 루프를 돌며 API 토큰 비용을 기하급수적으로 소모할 수 있기 때문에 제어가 필요하다고 생각했습니다.
하지만 저의 기존 목표는 완전 자율형 A2A 였기 때문에 향후, 에이전트의 자체 검증 로직을 좀 더 고도화하여 사람의 개입이 없이 문제를 해결하는 아키텍처를 만들고자 합니다.
2. 에이전트 프레임워크 다원화 와 멀티 모델
이번 프로젝트에서는 에이전트 간의 '상태(State)'와 '제어 흐름(Control Flow)'을 명시적인 그래프 구조로 정밀하게 제어하기 위해 LangGraph를 채택했고 시스템의 모든 에이전트는 Claude 단일 모델을 사용하였습니다.
그래서 첫 번째로는 정확히 동일한 조건과 목표(과제)를 부여한 상태에서 CrewAI와 AutoGen(AG2) 같은 다른 에이전트 프레임워크를 사용해 시스템을 재구축해
LangGraph와 비교했을 때 개발자 경험(DX), 토큰 소모량, 결과물의 품질 면에서 어떤 차이를 보이는지 직접 벤치마킹 해보고 싶습니다.
두 번째는 Gemini 3.1 pro나 다른 오픈소스 모델 등 AI 모델들의 각기 다른 특화된 강점을 살려 멀티 모델 시스템을 구축할 예정입니다.
3. 홈 서버와 결합
현재는 로컬 환경에서 가동하여, 집에 있는 데스크탑에서만 사용이 가능하지만, 조금 더 고도화를 한 이후에 웹 페이지와 에이전트 시스템 전체를 제 홈 서버의 Proxmox VM에 배포하여 상시 가동을 하며, 외부에서도 핸드폰이나 노트북으로 사용할 수 있게 만들 예정입니다.
4. Claude Code와 NotebookLM을 통한 '프롬프트 엔지니어링'의 재발견
번 프로젝트의 뼈대를 세우고 문서화하는 과정에서 터미널 기반의 Claude Code와 구글의 NotebookLM을 처음으로 적극 활용해 보았습니다. 이 도구들이 프로젝트 스캐폴딩과 코드 실행을 자동화해주어 개발 속도가 비약적으로 상승했습니다.
또한, 프롬프트의 미세한 차이가 전체 시스템의 결과물에 얼마나 영향을 미치는가 를 느꼈습니다. 단순히 "~ 해 줘"라고 묻는 것을 넘어서 에 이전트의 페르소나, 사용 가능한 도구의 제약 조건 등을 어떻게 걸어두냐에 따라서 결과물이 많이 달랐습니다.
이후에도 계속해서 프롬프트 엔지니어링에 대해서 공부하고 제 방향에 맞는 프롬프트를 찾아볼 예정입니다.