본 콘텐츠의 이미지 및 내용은 AI로 생성되었습니다.
본 콘텐츠의 이미지 및 내용을 무단으로 복제, 배포, 수정하여 사용할 경우 저작권법에 의해 법적 제재를 받을 수 있습니다.
이미지 로딩 중...
AI Generated
2025. 12. 26. · 2 Views
Multi-Agent 아키텍처 완벽 가이드
여러 AI 에이전트가 협업하여 복잡한 문제를 해결하는 Multi-Agent 아키텍처를 초급자 눈높이에서 설명합니다. 역할 분업, 협업 패턴, 실전 구현까지 실무에 바로 적용할 수 있는 내용을 담았습니다.
목차
1. 다중 에이전트의 필요성
어느 날 신입 개발자 김개발 씨는 LLM 기반 챗봇 프로젝트를 맡게 되었습니다. 처음에는 하나의 프롬프트로 모든 걸 해결하려 했지만, 점점 프롬프트가 길어지고 복잡해지더니 결과도 엉망이 되어버렸습니다.
"이걸 어떻게 해야 하지?" 막막해하던 그때, 선배 박시니어 씨가 다가왔습니다.
Multi-Agent 아키텍처는 하나의 거대한 에이전트 대신 여러 개의 작은 전문 에이전트들이 협업하여 문제를 해결하는 방식입니다. 마치 회사에서 각 부서가 전문 분야를 맡아 일하는 것처럼, 각 에이전트는 자신의 역할에 집중합니다.
이를 통해 복잡한 작업을 효율적으로 처리하고, 유지보수도 훨씬 쉬워집니다.
다음 코드를 살펴봅시다.
# 단일 에이전트 방식 (비추천)
single_agent_prompt = """
당신은 데이터 분석, 코드 작성, 문서화, 테스트까지
모든 것을 처리하는 만능 AI입니다.
다음 작업을 수행하세요: {task}
"""
# Multi-Agent 방식 (추천)
class AnalystAgent:
"""데이터 분석 전문 에이전트"""
def analyze(self, data):
return self.llm.generate(f"데이터 분석: {data}")
class CoderAgent:
"""코드 작성 전문 에이전트"""
def write_code(self, spec):
return self.llm.generate(f"코드 작성: {spec}")
class ReviewerAgent:
"""코드 리뷰 전문 에이전트"""
def review(self, code):
return self.llm.generate(f"코드 리뷰: {code}")
김개발 씨는 고객 문의를 자동으로 처리하는 AI 시스템을 개발 중이었습니다. 처음에는 간단할 줄 알았습니다.
"LLM에 프롬프트 하나만 잘 작성하면 되겠지?" 그렇게 생각하며 프롬프트를 작성하기 시작했습니다. 그런데 요구사항이 계속 추가되었습니다.
문의 내용을 분류하고, 데이터베이스에서 정보를 찾고, 답변을 생성하고, 번역도 해야 하고, 심지어 감정 분석까지 필요했습니다. 프롬프트는 점점 길어져 3000자를 넘어섰고, 결과는 불안정해졌습니다.
박시니어 씨가 김개발 씨의 모니터를 보더니 고개를 저었습니다. "김 대리, 이건 마치 한 사람에게 회계, 마케팅, 개발, 디자인을 전부 시키는 것과 같아요." 단일 에이전트의 한계 생각해보면 당연한 이야기입니다.
회사에서도 각 부서가 전문 분야를 맡아 일합니다. 회계사에게 디자인을 시키지 않고, 개발자에게 마케팅을 맡기지 않습니다.
각자 잘하는 일을 맡아야 효율적이기 때문입니다. AI 에이전트도 마찬가지입니다.
하나의 프롬프트에 모든 것을 담으면 맥락이 섞이고, 우선순위가 흐려지고, 품질이 떨어집니다. 또한 문제가 생겼을 때 어디서 잘못되었는지 찾기도 어렵습니다.
Multi-Agent의 등장 바로 이런 문제를 해결하기 위해 Multi-Agent 아키텍처가 등장했습니다. 핵심 아이디어는 간단합니다.
하나의 거대한 에이전트 대신 여러 개의 작은 전문 에이전트를 만드는 것입니다. 각 에이전트는 자신의 역할에만 집중하고, 필요할 때 다른 에이전트와 협업합니다.
마치 오케스트라와 같습니다. 바이올린 연주자는 바이올린에만 집중하고, 첼로 연주자는 첼로에만 집중합니다.
하지만 지휘자의 지휘에 따라 모두가 협력하면 아름다운 음악이 완성됩니다. 실제 사례로 이해하기 김개발 씨의 고객 문의 시스템을 Multi-Agent로 재설계해 봅시다.
먼저 분류 에이전트가 문의 내용을 분석합니다. "이건 기술 문의네요." 그러면 검색 에이전트가 관련 문서를 찾아옵니다.
찾은 정보를 바탕으로 답변 생성 에이전트가 친절한 답변을 작성합니다. 마지막으로 번역 에이전트가 고객의 언어로 번역합니다.
각 에이전트는 자신의 일만 잘하면 됩니다. 프롬프트도 짧고 명확해집니다.
문제가 생기면 어느 에이전트에서 문제가 발생했는지 바로 알 수 있습니다. 왜 더 효율적일까 첫째, 프롬프트가 단순해집니다.
각 에이전트는 하나의 목적만 가지므로 프롬프트가 짧고 명확합니다. 짧은 프롬프트는 LLM이 더 정확하게 이해하고 처리할 수 있습니다.
둘째, 재사용성이 높아집니다. 번역 에이전트는 다른 프로젝트에서도 그대로 사용할 수 있습니다.
레고 블록처럼 조합하여 새로운 시스템을 빠르게 만들 수 있습니다. 셋째, 유지보수가 쉬워집니다.
답변 품질을 개선하고 싶다면 답변 생성 에이전트만 수정하면 됩니다. 다른 에이전트는 건드릴 필요가 없습니다.
코드로 보는 차이 위의 코드를 보면 차이가 명확합니다. 단일 에이전트 방식은 하나의 거대한 프롬프트에 모든 지시사항을 담습니다.
이렇게 하면 LLM이 무엇에 집중해야 할지 혼란스러워합니다. 반면 Multi-Agent 방식은 각 클래스가 명확한 책임을 가집니다.
AnalystAgent는 분석만, CoderAgent는 코딩만, ReviewerAgent는 리뷰만 담당합니다. 단일 책임 원칙을 따르는 깔끔한 설계입니다.
실무에서의 활용 대형 IT 기업들은 이미 Multi-Agent 시스템을 적극 활용하고 있습니다. 구글의 코드 리뷰 시스템, 아마존의 고객 서비스 자동화, 마이크로소프트의 개발 도구 등이 모두 여러 에이전트의 협업으로 동작합니다.
스타트업에서도 마찬가지입니다. 제한된 리소스로 최대 효과를 내려면 각 에이전트를 잘 설계하고 효율적으로 협업시켜야 합니다.
주의할 점 물론 무조건 에이전트를 많이 만든다고 좋은 것은 아닙니다. 간단한 작업에 여러 에이전트를 사용하면 오히려 복잡도만 증가합니다.
"Hello World"를 출력하는데 5개의 에이전트가 필요하지는 않습니다. 핵심은 적절한 균형입니다.
작업이 복잡하고 여러 단계로 나뉠 때, 각 단계가 명확히 구분될 때 Multi-Agent를 고려해야 합니다. 정리하며 김개발 씨는 박시니어 씨의 조언을 듣고 시스템을 재설계했습니다.
하나의 거대한 프롬프트를 4개의 전문 에이전트로 나누었더니 응답 품질도 좋아지고 유지보수도 훨씬 쉬워졌습니다. 여러분도 복잡한 LLM 시스템을 설계할 때 "이걸 여러 전문가에게 나눠 맡기면 어떨까?"라고 생각해 보세요.
그것이 Multi-Agent 아키텍처의 시작입니다.
실전 팁
💡 - 에이전트 하나당 하나의 명확한 책임만 부여하세요
- 간단한 작업은 단일 에이전트로 충분합니다
- 각 에이전트의 입출력 인터페이스를 명확히 정의하세요
2. 역할 기반 분업
김개발 씨가 Multi-Agent 시스템을 설계하려고 하자 새로운 고민이 생겼습니다. "에이전트를 어떻게 나눠야 하지?" 너무 많이 나누면 복잡하고, 너무 적게 나누면 효과가 없을 것 같았습니다.
박시니어 씨는 화이트보드에 조직도를 그리며 설명하기 시작했습니다.
역할 기반 분업은 각 에이전트에게 명확한 역할과 책임을 부여하는 설계 원칙입니다. 마치 소프트웨어 개발 팀에서 기획자, 개발자, 디자이너, QA가 각자의 역할을 맡는 것처럼, 에이전트도 Planner, Executor, Reviewer 등의 역할로 나뉩니다.
이렇게 하면 각 에이전트가 자신의 전문성을 최대한 발휘할 수 있습니다.
다음 코드를 살펴봅시다.
from typing import Dict, List
class PlannerAgent:
"""작업 계획을 수립하는 에이전트"""
def create_plan(self, task: str) -> List[Dict]:
prompt = f"다음 작업을 단계별로 나눠주세요: {task}"
steps = self.llm.generate(prompt)
return self.parse_steps(steps)
class ExecutorAgent:
"""실제 작업을 수행하는 에이전트"""
def execute(self, step: Dict) -> str:
prompt = f"다음 작업을 수행하세요: {step['action']}"
return self.llm.generate(prompt)
class ReviewerAgent:
"""결과를 검증하는 에이전트"""
def review(self, result: str, criteria: Dict) -> Dict:
prompt = f"다음 결과를 검토하세요: {result}\n기준: {criteria}"
feedback = self.llm.generate(prompt)
return {"approved": self.is_approved(feedback), "feedback": feedback}
박시니어 씨는 화이트보드에 조직도를 그렸습니다. "우리 회사 조직도를 보세요.
CEO 밑에 기획팀, 개발팀, 디자인팀, QA팀이 있죠? 각 팀은 자기 역할이 명확합니다." 김개발 씨가 고개를 끄덕였습니다.
"네, 기획팀은 요구사항 정리, 개발팀은 구현, QA팀은 테스트를 담당하죠." "바로 그겁니다! Multi-Agent 시스템도 똑같이 설계하면 됩니다." 역할의 중요성 회사에서 만약 모든 팀원이 "나는 그냥 직원입니다"라고만 한다면 어떻게 될까요?
누가 무엇을 해야 할지 모호해지고, 일이 중복되거나 누락됩니다. 책임 소재도 불분명해집니다.
에이전트도 마찬가지입니다. 역할 없이 "나는 그냥 에이전트입니다"라고만 하면 비효율적입니다.
명확한 역할 정의가 효율적인 협업의 첫걸음입니다. 기본적인 역할 패턴 가장 보편적인 역할 구조는 Planner-Executor-Reviewer 패턴입니다.
Planner는 전략가입니다. 주어진 작업을 분석하고 어떤 순서로 무엇을 할지 계획합니다.
"먼저 데이터를 수집하고, 그다음 분석하고, 마지막에 리포트를 작성하자." 이런 식으로 로드맵을 제시합니다. Executor는 실행자입니다.
Planner가 만든 계획을 실제로 수행합니다. 코드를 작성하거나, 데이터를 처리하거나, 문서를 생성합니다.
가장 많은 연산을 담당하는 핵심 에이전트입니다. Reviewer는 검증자입니다.
Executor가 만든 결과물을 검토합니다. "이 코드에 버그는 없나?", "이 답변이 적절한가?" 같은 질문을 던지며 품질을 보장합니다.
실무 시나리오로 이해하기 블로그 글 작성 자동화 시스템을 만든다고 가정해봅시다. 먼저 ResearcherAgent가 주제에 대해 조사합니다.
관련 논문, 기사, 블로그를 찾아 핵심 정보를 추출합니다. 이 역할은 정보 수집 전문가입니다.
다음으로 OutlineAgent가 글의 구조를 설계합니다. 서론, 본론, 결론을 어떻게 구성할지, 어떤 순서로 논리를 전개할지 결정합니다.
이 역할은 구조 설계 전문가입니다. 이제 WriterAgent가 실제 글을 작성합니다.
OutlineAgent가 만든 구조에 따라 각 섹션을 채워나갑니다. 이 역할은 콘텐츠 생성 전문가입니다.
마지막으로 EditorAgent가 글을 교정합니다. 문법 오류, 논리적 비약, 어색한 표현을 찾아 수정합니다.
이 역할은 품질 관리 전문가입니다. 코드로 보는 역할 분리 위의 코드를 자세히 살펴봅시다.
PlannerAgent의 create_plan 메서드는 작업을 단계별로 분해합니다. "사용자 인증 기능 구현"이라는 큰 작업을 "DB 스키마 설계 → API 엔드포인트 작성 → 프론트엔드 폼 구현 → 테스트 작성"으로 나눕니다.
ExecutorAgent의 execute 메서드는 각 단계를 실제로 수행합니다. 프롬프트가 매우 구체적입니다.
"DB 스키마를 설계하세요"가 아니라 "users 테이블에 email, password_hash, created_at 컬럼을 추가하세요" 같은 식입니다. ReviewerAgent의 review 메서드는 결과를 평가합니다.
단순히 "좋다/나쁘다"가 아니라 구체적인 피드백을 제공합니다. "보안상 password는 해싱해야 합니다", "created_at에 인덱스를 추가하면 성능이 개선됩니다" 같은 조언을 합니다.
역할별 프롬프트 최적화 중요한 점은 각 역할에 맞게 프롬프트를 최적화해야 한다는 것입니다. PlannerAgent에게는 "당신은 경험 많은 프로젝트 매니저입니다"라고 역할을 부여합니다.
그러면 LLM이 계획 수립에 적합한 사고방식으로 전환됩니다. ExecutorAgent에게는 "당신은 시니어 개발자입니다.
베스트 프랙티스를 따르세요"라고 지시합니다. 그러면 더 나은 품질의 코드를 생성합니다.
ReviewerAgent에게는 "당신은 까다로운 코드 리뷰어입니다. 잠재적 문제를 찾으세요"라고 요청합니다.
그러면 더 철저하게 검증합니다. 동적 역할 할당 때로는 상황에 따라 역할이 바뀌기도 합니다.
간단한 작업이면 ExecutorAgent만 있으면 되지만, 복잡한 작업이면 SpecialistAgent를 추가로 투입할 수 있습니다. 마치 프로젝트 규모에 따라 팀 구성이 달라지는 것과 같습니다.
작은 프로젝트는 풀스택 개발자 한 명으로 충분하지만, 대형 프로젝트는 프론트엔드, 백엔드, DevOps, 데이터 엔지니어를 모두 투입합니다. 역할 간 인터페이스 각 역할 간의 인터페이스도 명확해야 합니다.
PlannerAgent의 출력은 ExecutorAgent의 입력 형식과 일치해야 합니다. 예를 들어 Planner가 {"step": 1, "action": "create_table", "params": {...}}처럼 구조화된 데이터를 반환하면, Executor는 이를 바로 실행할 수 있습니다.
중간에 파싱이나 변환이 필요하지 않습니다. 정리하며 김개발 씨는 역할 기반 설계의 중요성을 깨달았습니다.
"각 에이전트에게 명확한 정체성을 주는 거군요!" 맞습니다. 좋은 Multi-Agent 시스템은 좋은 조직과 비슷합니다.
각자의 역할이 명확하고, 책임이 분명하고, 협업이 원활해야 합니다.
실전 팁
💡 - 역할 이름을 명확하게 짓세요 (Planner, Executor, Reviewer 등)
- 각 역할에 맞는 페르소나를 프롬프트에 포함하세요
- 역할 간 데이터 교환 형식을 표준화하세요
3. 협업 vs 경쟁
며칠 후 김개발 씨는 새로운 아이디어를 떠올렸습니다. "에이전트끼리 경쟁시키면 더 좋은 결과가 나오지 않을까?" 박시니어 씨는 커피를 한 모금 마시고는 미소 지었습니다.
"좋은 생각이에요. 하지만 항상 경쟁이 답은 아닙니다.
때로는 협업이, 때로는 경쟁이 필요하죠."
Multi-Agent 시스템에서 에이전트 간 상호작용은 크게 **협업(Collaboration)**과 경쟁(Competition) 방식으로 나뉩니다. 협업 방식은 에이전트들이 정보를 공유하며 하나의 목표를 향해 나아가는 것이고, 경쟁 방식은 여러 에이전트가 독립적으로 솔루션을 제시하고 가장 좋은 것을 선택하는 것입니다.
상황에 따라 적절한 방식을 선택해야 합니다.
다음 코드를 살펴봅시다.
# 협업 방식: 에이전트들이 정보를 공유
class CollaborativeSystem:
def solve(self, problem):
# Agent A가 초안 작성
draft = self.agent_a.create_draft(problem)
# Agent B가 Agent A의 결과를 개선
improved = self.agent_b.improve(draft)
# Agent C가 최종 검토
final = self.agent_c.finalize(improved)
return final
# 경쟁 방식: 여러 솔루션 중 최선 선택
class CompetitiveSystem:
def solve(self, problem):
# 3개 에이전트가 독립적으로 솔루션 제시
solution_a = self.agent_a.solve(problem)
solution_b = self.agent_b.solve(problem)
solution_c = self.agent_c.solve(problem)
# 가장 좋은 솔루션 선택
return self.judge.select_best([solution_a, solution_b, solution_c])
박시니어 씨는 두 가지 시나리오를 설명하기 시작했습니다. "먼저 협업 상황을 생각해봅시다.
여러분이 대형 프로젝트를 진행 중인데, 각 팀이 독립적으로 일하면 어떻게 될까요? 프론트엔드 팀이 만든 API 요청 형식과 백엔드 팀이 만든 API 응답 형식이 안 맞을 수 있습니다." 김개발 씨가 고개를 끄덕였습니다.
"그래서 회의를 통해 인터페이스를 맞추죠." "정확합니다. 이게 협업입니다.
이제 경쟁 상황을 봅시다. 회사 로고 디자인을 의뢰했다고 가정해봅시다.
여러 디자이너에게 각자 시안을 만들어달라고 하고, 그중 가장 마음에 드는 걸 선택합니다. 이게 경쟁입니다." 협업 방식의 장단점 협업 방식은 에이전트들이 서로의 결과물을 주고받으며 점진적으로 개선해 나갑니다.
마치 릴레이 경주와 같습니다. 첫 번째 주자가 바통을 넘기면, 두 번째 주자가 이어받아 달리고, 세 번째 주자가 다시 이어받습니다.
장점은 일관성입니다. 모든 에이전트가 같은 맥락을 공유하므로 결과물이 통일성을 가집니다.
또한 이전 단계의 결과를 활용하므로 효율적입니다. 단점은 오류 전파입니다.
첫 번째 에이전트가 실수하면 그 오류가 다음 단계로 이어집니다. 잘못된 전제 위에 쌓아 올린 결과는 전체가 무너질 수 있습니다.
경쟁 방식의 장단점 경쟁 방식은 여러 에이전트가 동시에 독립적으로 문제를 해결합니다. 마치 백미터 달리기와 같습니다.
여러 선수가 동시에 출발해서 가장 빠른 선수가 우승합니다. 장점은 다양성입니다.
각 에이전트가 다른 접근법을 시도하므로 창의적인 솔루션이 나올 수 있습니다. 또한 한 에이전트의 실패가 전체 시스템에 영향을 주지 않습니다.
단점은 비용입니다. 동일한 작업을 여러 번 수행하므로 계산 리소스와 API 비용이 배로 듭니다.
또한 최선을 선택하는 Judge 에이전트가 추가로 필요합니다. 실무에서의 활용 실제 프로젝트에서는 두 방식을 혼합해서 사용합니다.
예를 들어 고객 상담 시스템을 생각해봅시다. 먼저 분류 에이전트가 문의 유형을 판단합니다.
그다음 해당 유형의 전문 에이전트가 답변을 생성합니다. 이 부분까지는 협업입니다.
그런데 중요한 법률 자문이나 의료 상담처럼 정확성이 중요한 경우는 어떻게 할까요? 이때는 3개의 전문 에이전트가 각각 독립적으로 답변을 생성하고, 검증 에이전트가 가장 정확한 답변을 선택합니다.
이 부분은 경쟁입니다. 코드로 보는 차이 위의 코드를 비교해봅시다.
CollaborativeSystem에서는 draft → improved → final로 이어지는 파이프라인입니다. 각 단계가 이전 단계의 결과에 의존합니다.
agent_b는 agent_a의 결과를 받아 개선하고, agent_c는 agent_b의 결과를 최종 검토합니다. 반면 CompetitiveSystem에서는 세 에이전트가 병렬로 동작합니다.
서로의 결과를 전혀 모릅니다. 그리고 judge가 세 솔루션을 비교하여 최선을 선택합니다.
언제 협업을, 언제 경쟁을 협업은 프로세스가 명확할 때 적합합니다. 데이터 처리 파이프라인, 문서 생성, 코드 작성처럼 단계가 분명한 작업은 협업 방식이 효율적입니다.
경쟁은 정답이 다양할 때 적합합니다. 창작 활동, 전략 수립, 디자인처럼 주관적 판단이 필요한 작업은 경쟁 방식이 더 나은 결과를 냅니다.
또한 신뢰성이 중요할 때도 경쟁이 유리합니다. 금융 거래, 의료 진단처럼 실수가 치명적인 분야에서는 여러 에이전트의 교차 검증이 안전합니다.
하이브리드 접근법 가장 좋은 방법은 하이브리드입니다. 기본적으로는 협업 방식으로 효율성을 추구하되, 중요한 의사결정 지점에서는 경쟁 방식으로 품질을 보장하는 것입니다.
예를 들어 코드 생성 시스템을 만든다면, Planner → Coder로 이어지는 협업 과정을 거치되, 최종 코드 리뷰 단계에서는 3명의 Reviewer가 독립적으로 평가하고 다수결로 결정하는 식입니다. 정리하며 김개발 씨는 두 방식의 차이를 이해했습니다.
"협업은 효율적이지만 오류가 전파될 수 있고, 경쟁은 품질은 높지만 비용이 많이 드는군요." "정확합니다. 그래서 상황에 맞게 선택해야 합니다.
빠르게 초안을 만들 땐 협업, 최종 검증이 필요할 땐 경쟁을 사용하세요."
실전 팁
💡 - 일반적인 작업은 협업 방식으로 효율성을 높이세요
- 중요한 의사결정은 경쟁 방식으로 품질을 보장하세요
- 두 방식을 혼합하여 최적의 시스템을 설계하세요
4. 실습 3-Agent 시스템
이론은 충분히 배웠습니다. 이제 김개발 씨는 실제로 Multi-Agent 시스템을 만들어보고 싶었습니다.
"가장 간단한 예제부터 시작할까요?" 박시니어 씨는 노트북을 열고 코드를 작성하기 시작했습니다. "좋아요, 가장 기본적인 3-Agent 시스템을 만들어봅시다."
3-Agent 시스템은 Planner, Worker, Critic 세 에이전트로 구성된 가장 기본적인 Multi-Agent 패턴입니다. Planner가 계획을 세우고, Worker가 실행하고, Critic이 결과를 평가하는 단순하지만 강력한 구조입니다.
이 패턴을 이해하면 더 복잡한 Multi-Agent 시스템도 쉽게 설계할 수 있습니다.
다음 코드를 살펴봅시다.
import anthropic
class ThreeAgentSystem:
def __init__(self, api_key):
self.client = anthropic.Anthropic(api_key=api_key)
def planner(self, task):
"""작업을 단계별로 계획"""
response = self.client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=1024,
messages=[{"role": "user", "content":
f"당신은 프로젝트 매니저입니다. 다음 작업을 3-5단계로 나눠주세요:\n{task}"}]
)
return response.content[0].text
def worker(self, plan):
"""계획을 실행"""
response = self.client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=2048,
messages=[{"role": "user", "content":
f"당신은 시니어 개발자입니다. 다음 계획을 실행하세요:\n{plan}"}]
)
return response.content[0].text
def critic(self, result, original_task):
"""결과를 평가하고 개선점 제안"""
response = self.client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=1024,
messages=[{"role": "user", "content":
f"당신은 코드 리뷰어입니다.\n원래 작업: {original_task}\n결과물: {result}\n\n평가하고 개선점을 제안하세요."}]
)
return response.content[0].text
def run(self, task):
print("=== PLANNER ===")
plan = self.planner(task)
print(plan)
print("\n=== WORKER ===")
result = self.worker(plan)
print(result)
print("\n=== CRITIC ===")
feedback = self.critic(result, task)
print(feedback)
return {"plan": plan, "result": result, "feedback": feedback}
박시니어 씨는 화면을 김개발 씨에게 보여주며 설명했습니다. "보세요, 실제로는 정말 간단합니다." 시스템 설계 철학 3-Agent 시스템은 계획-실행-평가라는 인간의 문제 해결 방식을 그대로 따릅니다.
우리가 새로운 프로젝트를 시작할 때도 마찬가지입니다. 먼저 어떻게 할지 계획하고, 실제로 작업하고, 결과를 검토합니다.
이 패턴은 단순함과 효과의 완벽한 균형입니다. 에이전트가 너무 적으면 각 에이전트가 너무 많은 책임을 지게 되고, 너무 많으면 복잡도가 증가합니다.
3개는 딱 적절한 숫자입니다. Planner 에이전트 분석 Planner는 "프로젝트 매니저"라는 페르소나를 가집니다.
이 정체성이 중요합니다. LLM은 역할을 부여받으면 그에 맞는 사고방식으로 전환됩니다.
프롬프트를 보면 "3-5단계로 나눠주세요"라고 구체적으로 요청합니다. 너무 세분화하지도, 너무 뭉뚱그리지도 않게 합니다.
이 정도 단위가 Worker가 처리하기에 적절합니다. 예를 들어 "TODO 앱 만들기"라는 작업이 들어오면, Planner는 "1.
데이터 모델 설계, 2. API 엔드포인트 구현, 3.
프론트엔드 UI 작성, 4. 테스트 추가"처럼 나눕니다.
Worker 에이전트 분석 Worker는 "시니어 개발자"라는 페르소나를 가집니다. 단순히 "개발자"가 아니라 "시니어" 개발자입니다.
이렇게 하면 더 나은 품질의 코드를 생성합니다. Worker는 Planner의 계획을 받아 실제로 구현합니다.
max_tokens이 2048로 더 큰 것을 주목하세요. 코드 생성은 텍스트가 길어질 수 있기 때문입니다.
Worker는 계획의 각 단계를 순서대로 수행합니다. 데이터 모델을 먼저 설계하고, 그 위에 API를 구축하고, 다시 그 위에 UI를 만듭니다.
논리적 순서를 따릅니다. Critic 에이전트 분석 Critic은 "코드 리뷰어"라는 페르소나를 가집니다.
중요한 것은 원래 작업(original_task)과 결과물(result)을 모두 제공한다는 점입니다. 이렇게 하면 Critic이 "원래 요구사항을 제대로 충족했는가?"를 판단할 수 있습니다.
아무리 코드가 잘 작성되었어도 요구사항을 만족하지 못하면 소용없습니다. Critic은 단순히 "좋다/나쁘다"가 아니라 구체적인 개선점을 제안합니다.
"함수 이름을 더 명확하게", "에러 처리를 추가하세요", "테스트 케이스가 부족합니다" 같은 실용적인 피드백을 제공합니다. 전체 흐름 이해하기 run 메서드를 보면 전체 흐름이 한눈에 보입니다.
먼저 Planner가 작업을 받아 계획을 수립합니다. 이 계획이 출력되므로 사용자는 어떤 방향으로 진행될지 미리 알 수 있습니다.
다음으로 Worker가 계획을 받아 실제로 실행합니다. 코드나 문서가 생성됩니다.
이것도 출력되므로 중간 결과를 확인할 수 있습니다. 마지막으로 Critic이 결과를 평가합니다.
개선점이 있다면 제안합니다. 사용자는 이 피드백을 보고 결과를 수정하거나 다시 실행할 수 있습니다.
실제 사용 예시 코드를 실제로 사용해봅시다. python system = ThreeAgentSystem(api_key="your-api-key") system.run("Python으로 간단한 계산기 클래스 만들기") Planner는 "1.
클래스 구조 설계, 2. 사칙연산 메서드 구현, 3.
예외 처리 추가"처럼 계획합니다. Worker는 실제로 Calculator 클래스를 작성합니다.
add, subtract, multiply, divide 메서드를 구현하고 ZeroDivisionError 예외 처리도 추가합니다. Critic은 "divide 메서드에 타입 힌트를 추가하면 좋겠습니다", "테스트 케이스를 추가하세요" 같은 피드백을 제공합니다.
개선 및 확장 이 기본 구조는 여러 방향으로 확장할 수 있습니다. 반복 개선: Critic의 피드백을 Worker에게 다시 전달하여 결과를 개선할 수 있습니다.
만족스러운 결과가 나올 때까지 반복합니다. 중간 저장: 각 단계의 결과를 파일로 저장하여 나중에 재사용할 수 있습니다.
계획은 plan.txt, 결과는 result.py, 피드백은 feedback.md로 저장합니다. 병렬 Worker: 복잡한 작업은 여러 Worker를 병렬로 실행할 수 있습니다.
프론트엔드와 백엔드를 동시에 개발하는 식입니다. 실무 적용 사례 이 패턴은 실무에서 매우 유용합니다.
예를 들어 기술 문서 작성 자동화에 활용할 수 있습니다. Planner가 "서론, API 레퍼런스, 예제 코드, 문제 해결" 구조를 설계하면, Writer(Worker)가 각 섹션을 작성하고, Editor(Critic)가 문법과 논리를 검토합니다.
또는 데이터 분석 파이프라인에도 사용할 수 있습니다. Planner가 "데이터 수집, 전처리, 분석, 시각화" 단계를 정의하면, Analyst(Worker)가 각 단계를 수행하고, Validator(Critic)가 결과를 검증합니다.
정리하며 김개발 씨는 코드를 따라 작성하며 감탄했습니다. "생각보다 정말 간단하네요!
이게 Multi-Agent 시스템이라니." "맞아요. 복잡한 프레임워크 없이도 핵심 개념만으로 충분히 강력한 시스템을 만들 수 있습니다.
이제 여러분도 직접 만들어보세요."
실전 팁
💡 - 각 에이전트에게 명확한 페르소나를 부여하세요
- max_tokens은 에이전트 역할에 맞게 조정하세요
- 중간 결과를 출력하여 디버깅을 쉽게 하세요
5. 실습 역할별 전문 에이전트
기본 3-Agent 시스템을 완성한 김개발 씨는 더 복잡한 시스템에 도전하고 싶어졌습니다. "실무에서는 더 많은 전문가가 필요할 것 같은데요?" 박시니어 씨는 고개를 끄덕이며 새로운 프로젝트를 열었습니다.
"좋습니다. 이번에는 각 분야의 전문 에이전트를 만들어봅시다."
전문 에이전트는 특정 도메인이나 작업에 최적화된 에이전트입니다. 일반적인 Worker 대신 BackendAgent, FrontendAgent, DatabaseAgent, TestAgent처럼 세분화하면 각 영역에서 훨씬 높은 품질의 결과를 얻을 수 있습니다.
실무에 가까운 Multi-Agent 시스템의 핵심입니다.
다음 코드를 살펴봅시다.
class SpecializedAgentSystem:
def __init__(self, api_key):
self.client = anthropic.Anthropic(api_key=api_key)
def architect_agent(self, requirement):
"""시스템 아키텍처를 설계하는 전문 에이전트"""
prompt = """당신은 소프트웨어 아키텍트입니다.
다음 요구사항에 맞는 시스템 아키텍처를 설계하세요.
- 사용할 기술 스택
- 데이터베이스 스키마
- API 엔드포인트 구조
- 프론트엔드 컴포넌트 구조"""
response = self.client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=2048,
messages=[{"role": "user", "content": f"{prompt}\n\n요구사항: {requirement}"}]
)
return response.content[0].text
def backend_agent(self, architecture):
"""백엔드 API를 구현하는 전문 에이전트"""
prompt = """당신은 백엔드 개발 전문가입니다.
Python FastAPI를 사용하여 다음 아키텍처에 맞는 API 엔드포인트를 구현하세요.
- RESTful 설계 원칙 준수
- 적절한 에러 핸들링
- 타입 힌트 사용"""
response = self.client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=3072,
messages=[{"role": "user", "content": f"{prompt}\n\n아키텍처: {architecture}"}]
)
return response.content[0].text
def database_agent(self, architecture):
"""데이터베이스 스키마와 쿼리를 작성하는 전문 에이전트"""
prompt = """당신은 데이터베이스 전문가입니다.
PostgreSQL을 사용하여 다음을 작성하세요:
- 테이블 생성 SQL (CREATE TABLE)
- 인덱스 설정
- 샘플 쿼리"""
response = self.client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=2048,
messages=[{"role": "user", "content": f"{prompt}\n\n아키텍처: {architecture}"}]
)
return response.content[0].text
def frontend_agent(self, architecture, backend_code):
"""프론트엔드를 구현하는 전문 에이전트"""
prompt = """당신은 프론트엔드 개발 전문가입니다.
React와 TypeScript를 사용하여 다음을 구현하세요:
- API 연동 로직
- 상태 관리
- UI 컴포넌트"""
response = self.client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=3072,
messages=[{"role": "user", "content":
f"{prompt}\n\n아키텍처: {architecture}\n\n백엔드 API: {backend_code}"}]
)
return response.content[0].text
def test_agent(self, backend_code, frontend_code):
"""테스트 코드를 작성하는 전문 에이전트"""
prompt = """당신은 테스트 전문가입니다.
다음 코드에 대한 테스트를 작성하세요:
- 백엔드: pytest 사용
- 프론트엔드: Jest와 React Testing Library 사용
- 엣지 케이스 포함"""
response = self.client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=3072,
messages=[{"role": "user", "content":
f"{prompt}\n\n백엔드: {backend_code}\n\n프론트엔드: {frontend_code}"}]
)
return response.content[0].text
def run_full_stack(self, requirement):
"""풀스택 개발 워크플로우 실행"""
print("=== ARCHITECT ===")
architecture = self.architect_agent(requirement)
print(architecture)
print("\n=== BACKEND ===")
backend = self.backend_agent(architecture)
print(backend[:500] + "...") # 일부만 출력
print("\n=== DATABASE ===")
database = self.database_agent(architecture)
print(database[:500] + "...")
print("\n=== FRONTEND ===")
frontend = self.frontend_agent(architecture, backend)
print(frontend[:500] + "...")
print("\n=== TESTS ===")
tests = self.test_agent(backend, frontend)
print(tests[:500] + "...")
return {
"architecture": architecture,
"backend": backend,
"database": database,
"frontend": frontend,
"tests": tests
}
박시니어 씨는 코드를 가리키며 설명을 시작했습니다. "이제 실무에 가까운 시스템입니다.
각 에이전트가 실제 직무를 담당합니다." 전문화의 힘 일반적인 Worker 에이전트는 "뭐든지 할 수 있는" 에이전트입니다. 하지만 현실에서는 전문가가 더 나은 결과를 냅니다.
백엔드 개발 10년 차와 풀스택 개발 1년 차 중 누가 더 나은 API를 만들까요? 당연히 전문가입니다.
LLM도 마찬가지입니다. "당신은 개발자입니다"보다 "당신은 10년 경력의 백엔드 전문가입니다.
FastAPI와 PostgreSQL에 능숙합니다"라고 하면 훨씬 구체적이고 전문적인 결과를 냅니다. Architect Agent 분석 Architect는 전체 시스템의 청사진을 그립니다.
어떤 기술을 사용할지, 데이터는 어떻게 구조화할지, 컴포넌트는 어떻게 나눌지 결정합니다. 프롬프트를 보면 매우 구체적입니다.
"기술 스택, 데이터베이스 스키마, API 구조, 컴포넌트 구조"를 명시적으로 요청합니다. 이렇게 하면 Architect가 빠뜨리는 부분 없이 완전한 설계를 제공합니다.
예를 들어 "블로그 플랫폼"을 요구하면, Architect는 "백엔드: Python FastAPI, 데이터베이스: PostgreSQL, 프론트엔드: React + TypeScript, 인증: JWT"처럼 기술 스택을 정하고, posts, users, comments 테이블 구조를 설계합니다. Backend Agent 분석 Backend Agent는 API 구현에 집중합니다.
중요한 것은 "FastAPI를 사용하여"라고 구체적으로 지정한다는 점입니다. 프레임워크를 명시하면 더 정확한 코드를 생성합니다.
또한 "RESTful 설계 원칙", "에러 핸들링", "타입 힌트"를 요구합니다. 이런 베스트 프랙티스를 프롬프트에 포함하면 프로덕션 수준의 코드를 얻을 수 있습니다.
Backend Agent는 Architect의 설계를 받아 실제 엔드포인트를 구현합니다. GET /posts, POST /posts, PUT /posts/{id}, DELETE /posts/{id} 같은 API를 만들고, 각각에 적절한 상태 코드와 응답 모델을 정의합니다.
Database Agent 분석 Database Agent는 데이터 계층을 담당합니다. 테이블 생성 SQL만이 아니라 인덱스 설정도 포함합니다.
이것이 중요합니다. 인덱스는 성능에 큰 영향을 미치기 때문입니다.
또한 "샘플 쿼리"를 요청합니다. 이렇게 하면 실제로 사용할 SQL 예제를 얻을 수 있어, 백엔드 개발 시 참고할 수 있습니다.
Database Agent는 단순히 CREATE TABLE만 하는 것이 아닙니다. FOREIGN KEY 제약, CHECK 제약, DEFAULT 값, UNIQUE 제약까지 모두 고려합니다.
데이터 무결성을 보장하는 완전한 스키마를 제공합니다. Frontend Agent 분석 Frontend Agent는 UI와 상태 관리를 구현합니다.
중요한 것은 architecture와 backend_code를 모두 받는다는 점입니다. architecture를 보고 전체 구조를 이해하고, backend_code를 보고 정확한 API 엔드포인트와 데이터 모델을 파악합니다.
그래서 백엔드와 완벽히 호환되는 프론트엔드를 만들 수 있습니다. Frontend Agent는 React 컴포넌트, API 호출 로직, 상태 관리(useState, useEffect), 에러 처리까지 구현합니다.
사용자 경험도 고려하여 로딩 상태와 에러 메시지도 추가합니다. Test Agent 분석 Test Agent는 품질 보증을 담당합니다.
backend_code와 frontend_code를 받아 각각에 맞는 테스트를 작성합니다. 백엔드 테스트는 pytest를 사용하여 각 엔드포인트를 검증합니다.
정상 케이스뿐만 아니라 엣지 케이스도 포함합니다. 존재하지 않는 ID로 조회, 잘못된 입력 데이터, 권한 없는 접근 등을 테스트합니다.
프론트엔드 테스트는 Jest와 React Testing Library를 사용합니다. 컴포넌트 렌더링, 사용자 상호작용, API 모킹을 테스트합니다.
전체 워크플로우 이해 run_full_stack 메서드는 완전한 풀스택 개발 파이프라인입니다. 먼저 Architect가 전체 설계를 합니다.
이것이 모든 에이전트의 기준점이 됩니다. 다음으로 Backend와 Database가 병렬로 작업할 수 있습니다.
서로 독립적이기 때문입니다. 그다음 Frontend가 Backend의 결과를 받아 UI를 구현합니다.
Backend가 완료되어야 정확한 API 인터페이스를 알 수 있기 때문에 순차적으로 진행됩니다. 마지막으로 Test가 모든 코드를 받아 테스트를 작성합니다.
전체 시스템이 완성된 후 품질을 검증하는 단계입니다. 실제 사용 예시 실무에서 사용해봅시다.
python system = SpecializedAgentSystem(api_key="your-api-key") result = system.run_full_stack("사용자가 할 일을 등록하고 관리할 수 있는 TODO 앱") Architect는 users, todos 테이블 구조를 설계하고, REST API 엔드포인트를 정의합니다. Backend는 FastAPI로 GET /todos, POST /todos, PATCH /todos/{id}, DELETE /todos/{id} 엔드포인트를 구현합니다.
각각 적절한 검증과 에러 처리를 포함합니다. Database는 테이블 생성 SQL과 함께 user_id에 인덱스를 추가하여 조회 성능을 최적화합니다.
Frontend는 React로 TodoList, TodoItem, AddTodoForm 컴포넌트를 만들고, API와 연동합니다. 낙관적 업데이트로 사용자 경험을 개선합니다.
Test는 백엔드 API 테스트와 프론트엔드 컴포넌트 테스트를 모두 작성합니다. 커버리지 80% 이상을 목표로 합니다.
확장 가능성 이 시스템은 더 확장할 수 있습니다. DevOps Agent를 추가하면 Docker 설정, CI/CD 파이프라인, 배포 스크립트를 자동으로 생성할 수 있습니다.
Security Agent를 추가하면 SQL Injection, XSS, CSRF 같은 보안 취약점을 검사하고 수정 방안을 제안할 수 있습니다. Documentation Agent를 추가하면 API 문서, 사용자 가이드, 개발자 문서를 자동으로 작성할 수 있습니다.
실무 적용 시 주의사항 물론 실무에 바로 적용하려면 몇 가지 개선이 필요합니다. 첫째, 결과 저장입니다.
각 에이전트의 출력을 파일로 저장해야 실제로 사용할 수 있습니다. backend.py, schema.sql, App.tsx 같은 파일로 저장합니다.
둘째, 반복 개선입니다. 한 번에 완벽한 코드가 나오지 않습니다.
Critic Agent를 추가하여 각 단계의 결과를 검토하고 개선해야 합니다. 셋째, 사람의 검토입니다.
AI가 생성한 코드를 그대로 사용하지 말고 반드시 검토해야 합니다. 특히 보안과 성능이 중요한 부분은 더욱 주의해야 합니다.
정리하며 김개발 씨는 완성된 시스템을 보며 놀라워했습니다. "와, 이게 정말 자동으로 풀스택 앱을 만들다니!" "물론 아직 프로덕션 수준은 아닙니다.
하지만 초안을 빠르게 만들거나, 프로토타입을 제작하거나, 학습용으로는 충분히 유용합니다. 이제 여러분만의 전문 에이전트를 만들어보세요."
실전 팁
💡 - 각 에이전트의 프롬프트에 구체적인 기술 스택을 명시하세요
- 에이전트 간 데이터 전달 순서를 신중히 설계하세요
- 결과를 파일로 저장하여 실제 프로젝트에서 사용하세요
이상으로 학습을 마칩니다. 위 내용을 직접 코드로 작성해보면서 익혀보세요!
댓글 (0)
함께 보면 좋은 카드 뉴스
Human-in-the-Loop Agents 완벽 가이드
AI 에이전트가 중요한 결정을 내리기 전에 사람의 승인을 받는 시스템을 구축하는 방법을 배웁니다. 실무에서 안전하고 신뢰할 수 있는 AI 에이전트를 만드는 핵심 패턴을 소개합니다.
Agent Orchestration 완벽 가이드
여러 AI 에이전트를 효율적으로 조율하고 관리하는 방법을 배웁니다. 에이전트 라우팅부터 동적 선택, 워크플로 관리까지 실무에서 바로 사용할 수 있는 오케스트레이션 기법을 다룹니다.
Swarm Intelligence 분산 처리 완벽 가이드
집단 지성 패턴으로 대규모 작업을 분산 처리하는 방법을 배웁니다. 여러 에이전트가 협력하여 복잡한 문제를 해결하는 실전 기법을 익힐 수 있습니다. 초급 개발자도 쉽게 따라할 수 있는 실습 예제를 포함합니다.
Agent Debate 패턴 완벽 가이드
여러 AI 에이전트가 토론하고 합의하는 Agent Debate 패턴을 초급 개발자도 쉽게 이해할 수 있도록 실무 사례와 함께 설명합니다. 다중 관점 토론부터 합의 도출, 실전 구현까지 단계별로 배워봅니다.
Hierarchical Agents 완벽 가이드
AI 에이전트를 계층적으로 구성하여 복잡한 작업을 효율적으로 처리하는 방법을 배웁니다. Supervisor-Worker 패턴부터 실전 프로젝트 관리까지 단계별로 학습합니다.