본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 05. 25. 04:50

에이전트 루프의 원인이 프롬프트가 아닌 관리 문제임을 깨달았을 때

요약

멀티 에이전트 시스템의 실패 원인은 프롬프트가 아닌 조직 설계(Org Design) 문제임을 지적합니다. 에이전트 간 무분별한 위임 대신, 명확한 책임과 계층 구조를 가진 코디네이터 중심의 설계가 운영 환경에서 더 효과적임을 강조합니다.

핵심 포인트

  • 에이전트 루프의 근본 원인은 프롬프트가 아닌 관리 구조의 부재임
  • 피어 투 피어 방식보다 '작업자 + 코디네이터' 계층 구조가 더 안정적임
  • 자율성보다는 명확한 권한과 책임 부여가 시스템 안정성에 필수적임
  • CrewAI, Anthropic 등 주요 프레임워크도 계층적 설계를 권장함

저는 대부분의 멀티 에이전트 (multi-agent) 실패 원인을 프롬프트 탓으로 돌리곤 했습니다. 만약 리서치 에이전트 (Research Agent)가 분석 에이전트 (Analyst Agent)에게 계속 작업을 되돌려 보내고, 분석 에이전트가 이를 라이터 에이전트 (Writer Agent)에게 넘기며, 라이터 에이전트가 리뷰어 에이전트 (Reviewer Agent)에게 승인을 요청한다면, 저는 해결책이 더 나은 지침 (instructions)이라고 가정했습니다. 하지만 대개 그렇지 않았습니다. 진짜 문제는 조직 설계 (org design)였습니다.

CrewAI, OpenAI Agents SDK, AutoGen, 그리고 OpenClaw가 실제로 위임 (delegation)을 어떻게 구조화하는지 살펴보기 시작하자 한 가지 패턴이 계속 나타났습니다. 워크플로우 (workflow)에 2개 이상의 위임 단계가 포함되면, '좁은 범위의 작업자 + 하나의 코디네이터 (coordinator)' 조합이 '피어 투 피어 (peer-to-peer) 에이전트 팀'보다 더 효과적이라는 점입니다. 이는 "자율적인 AI 팀"이라는 말보다 덜 흥미롭게 들릴 수 있습니다. 하지만 이것이 실제 운영 환경 (production)에서 살아남는 방식입니다. 실패 양상은 프롬프팅 (prompting) 문제처럼 보이지만, 실제로는 그렇지 않습니다.

전형적인 루프는 다음과 같습니다:

  • 리서치 에이전트가 부분적인 정보를 찾음
  • 분석 에이전트가 더 많은 컨텍스트 (context)를 요구함
  • 라이터 에이전트가 요약을 먼저 원함
  • 리뷰어 에이전트가 다른 출처를 요구함
  • 리서치 에이전트가 처음부터 다시 시작함

모두가 활동 중이지만, 아무도 결과물에 대한 책임을 지지 않습니다. 이것은 지능이 아닙니다. 그것은 위원회식 행동 (committee behavior)입니다. 저는 r/openclaw에서 누군가 명확하게 설명한 좋은 스레드를 발견했습니다. 에이전트들이 동료(peers)로 설계되면, 결과물을 명확하게 책임지는 사람이 아무도 없다는 것입니다. 이는 제가 실제 시스템에서 목격한 것과 일치합니다. 에이전트들은 프롬프트가 부족한 것이 아니라, 권한이 과도하게 부여된 (over-authorized) 것입니다.

지루한 답변: 대부분의 프레임워크가 이미 동의하고 있습니다
재미있는 점은 주요 프레임워크들이 대부분 같은 방향을 가리키고 있다는 것입니다.

Anthropic: 원하는 것보다 더 단순하게 시작하세요
에이전트에 대한 Anthropic의 가이드는 기본적으로 다음과 같습니다: 먼저 단순하고 결합 가능한 (composable) 패턴을 사용하세요. 곧바로 거대한 자율 시스템으로 뛰어들지 마세요. 이는 강력한 신호입니다. 자율성으로 마케팅되는 많은 것들은 그저 더 멋진 브랜딩을 입힌 아키텍처 부채 (architecture debt)일 뿐입니다.

CrewAI: 계층 구조 (hierarchy)가 명시적인 데에는 이유가 있습니다
CrewAI는 계층 구조를 우연히 만드는 것이 아니라 의도적인 선택으로 만듭니다. 사용자가 직접 선택해야 합니다:

from crewai import Crew, Process
crew = Crew(
agents = [researcher, analyst, writer],
process = Process.hierarchical,
manager_llm = "gpt-4"
)

이것이 중요합니다.

기본적으로 "모두가 모두에게 위임하는" 구조가 자동으로 만들어지지는 않습니다. 당신이 관리자(manager)를 선택해야 합니다. 계층 구조(hierarchy)를 선택해야 합니다. 권한(authority)을 명시적으로 만들어야 합니다. 프레임워크 제작자들은 모든 작업자(worker)가 프리랜서처럼 행동하기 시작할 때 어떤 일이 벌어지는지 알고 있습니다.

AutoGen: 그룹 채팅은 유연하며, 오케스트레이터(orchestrator)는 디버깅하기 더 쉽습니다. AutoGen에는 관리자가 공유 스레드에서 다음 발화자를 선택하는 그룹 채팅(Group Chat) 패턴이 있습니다. 이는 작동할 수 있습니다. 하지만 종료 조건(termination conditions)이 약하다면 심하게 표류할 수도 있습니다. AutoGen의 Mixture of Agents 패턴은 제가 프로덕션 환경에서 신뢰하는 방식에 더 가깝습니다: 작업자 에이전트(worker agents)는 범위가 지정된 작업(scoped jobs)을 수행하고, 하나의 오케스트레이터가 집계(aggregation)를 조정하며, 종료가 명시적(explicit termination)입니다. 덜 마법 같고, 더 유지보수하기 쉽습니다. 저는 언제나 그런 트레이드오프(trade-off)를 선택할 것입니다.

OpenAI Agents SDK: 핸드오프(handoffs)는 느낌(vibes)이 아니라 경계(boundaries)입니다. OpenAI의 Agents SDK는 중요한 점을 제대로 짚었습니다: 위임(delegation)이 명시적이라는 것입니다. 분류(triage) 에이전트는 무작위적인 동료 간의 잡담이 아니라, 전송 도구(transfer tools)를 통해 전문가에게 핸드오프를 수행합니다. 이는 상태 전환(transitions)을 추론할 수 있음을 의미합니다. 그리고 가드레일(guardrail) 모델은 대부분의 사람들이 깨닫는 것보다 훨씬 더 유용합니다: 입력 가드레일(input guardrails), 출력 가드레일(output guardrails), 도구 가드레일(tool guardrails). 만약 위임된 모든 단계에서 체크포인트(checkpoints)를 원한다면, 가장 중요한 것은 대개 도구 가드레일입니다. 그곳이 바로 작업이 경계를 넘나드는 지점이기 때문입니다.

OpenClaw: 범위가 지정된 상태(scoped state)가 집단 지성 메모리(hive-mind memory)보다 낫습니다. OpenClaw의 파일 시스템 레이아웃은 그 설계 철학에 대해 많은 것을 말해줍니다. 에이전트별 상태(Per-agent state)는 격리되어 있습니다:
~/.openclaw/agents/<agentId>/...
~/.openclaw/agents/<agentId>/sessions
~/.openclaw/agents/<agentId>/agent/auth-profiles.json

그리고 CLI는 그 모델을 강화합니다:
openclaw agents add work
openclaw agents list --bindings

이것은 단순히 외관상의 문제가 아닙니다. 이는 하나의 힌트입니다: 에이전트는 동일한 메모리 더미에 기록하는 하나의 거대한 공유 의식이 아니라, 로컬 상태를 가진 범위가 지정된 단위(scoped units)여야 한다는 것입니다.

피어 투 피어(peer-to-peer) 에이전트 시스템에서 실제로 고장 나는 부분
실제로, 똑같은 3가지 문제가 반복해서 실패합니다.
1.

권한이 모호해집니다. 만약 Research Agent, Analyst Agent, Writer Agent가 모두 작업을 다시 열거나, 목표를 재정의하거나, 옆으로 위임(delegate sideways)할 수 있다면, 그것은 워크플로우(workflow)가 아닙니다. 그것은 관리자가 없는 Slack 채널일 뿐입니다. 이러한 결정이 내려지는 곳은 정확히 단 한 곳이어야 합니다: 최종 답변 승인(approve final answer), 완료된 작업 재오픈(reopen completed work), 실행 종료(terminate the run), 범위 에스컬레이션(escalate scope). 만약 둘 이상의 에이전트가 이를 수행할 수 있다면, 루프(loops)가 발생할 것을 예상해야 합니다.

  1. 메모리가 오염됩니다. 이것은 더 조용히 발생하는 실패입니다. 만약 모든 작업자(worker)가 공유 메모리에 직접 쓸 수 있다면, 일시적인 추측이 영구적인 사실이 되어버립니다. 잘못된 검색 결과가 "알려진 컨텍스트(known context)"가 됩니다. 일회성 예외 사항이 정책이 됩니다. 추측성 가정이 향후 실행에서 재현됩니다. 훨씬 더 나은 패턴은 다음과 같습니다: 작업자가 구조화된 메모리 제안(structured memory proposals)을 내놓으면, 감독자(supervisor) 또는 큐레이터(curator)가 이를 검증하고, 승인된 메모리만 커밋(commit)되는 방식입니다. 이것이 엄격하게 들린다면, 원래 그래야 하기 때문입니다.

  2. 중단 조건(Stopping conditions)이 모호합니다. 많은 에이전트 시스템이 모델이 멍청해서 실패하는 것이 아닙니다. '완료(done)'를 아무도 정의하지 않았기 때문에 실패합니다. 만약 당신의 워크플로우가 다음 질문들에 답할 수 없다면, 시스템은 방황할 것입니다: 무엇을 작업 완료로 간주할 것인가? 누가 종료할 수 있는가? 몇 번의 재시도(retries)가 허용되는가? 신뢰도(confidence)가 낮을 때는 어떻게 되는가? 시스템은 다시 묻는 대신 언제 에스컬레이션(escalate)을 수행하는가? 만약 이러한 규칙들이 명시적이지 않다면, 모델은 즉흥적으로 행동할 것입니다. 즉흥 연주는 비용이 많이 듭니다.

내가 지금 신뢰하는 패턴
만약 내가 n8n, Make, Zapier, OpenClaw 또는 커스텀 Python worker를 위해 무언가를 구축하고 있다면, 이것이 내가 원하는 기본 형태입니다.

  1. 하나의 감독자가 결과를 소유합니다. 오직 하나의 에이전트만이 다음을 수행할 수 있습니다: 최종 출력 승인(approve final output), 작업 재오픈(reopen work), 실행 종료(terminate the run), 다른 작업자의 참여 여부 결정(decide whether another worker gets involved). 그 에이전트가 코디네이터(coordinator)입니다. 동료(peer)가 아닙니다.

  2. 작업자는 좁은 범위의 업무를 맡습니다. 좋은 작업자 역할: Web Search Agent, Data Extraction Agent, SQL Agent, Refund Agent, Writer Agent, Code Review Agent. 나쁜 작업자 역할: 전체 작업을 재해석할 수 있는 일반 전략 협업자(General Strategic Collaborator That Can Reinterpret The Whole Task). 작업자는 한 가지 일을 잘 해내야 합니다.

작업자(Workers)는 결과물(artifacts)을 반환해야 하며, 워크플로우에 대한 의견을 반환해서는 안 됩니다. 제가 원하는 출력은 다음과 같습니다:

순위가 매겨진 소스 목록, JSON 추출, 인용이 포함된 SQL 결과 초안, 코드 차이(code diff), 신뢰도 점수(confidence score)

제가 원하지 않는 출력은 다음과 같습니다:

"내 생각에 Planning Agent는 우리가 이전의 가설을 재검토해야 할지 Reviewer Agent에게 물어봐야 한다고 봅니다."

이런 식의 접근은 3단계짜리 작업을 인위적인 중간 관리직(synthetic middle management)으로 변질시킵니다.

  1. 메모리(Memory)에는 소유자가 있어야 합니다.

다음 중 하나여야 합니다:

  • 감독자(supervisor)가 메모리를 작성하거나,
  • 전담 메모리 큐레이터(memory curator)가 메모리를 작성해야 합니다.

작업자(Workers)는 메모리 이벤트(memory events)를 제안할 수는 있습니다. 하지만 이를 아무렇게나 확정(commit)해서는 안 됩니다. 간단한 형태는 다음과 같습니다:

{ "event_type" : "user_preference_candidate" , "scope" : "account_level" , "evidence" : [ "User explicitly requested CSV export twice" ] , "confidence" : 0.82 , "proposed_by" : "support_agent" }

그 후, 더 높은 권한을 가진 컴포넌트가 해당 이벤트가 영구적인 메모리(durable memory)가 될지 여부를 결정합니다.

  1. 모든 경계(boundary)에는 체크포인트(checkpoint)가 있어야 합니다.

만약 에이전트가 다음과 같은 행동을 한다면:

  • 도구(tool)를 호출하거나,
  • 파일을 작성하거나,
  • API를 호출하거나,
  • 다른 에이전트를 트리거하거나,
  • 메모리를 업데이트한다면,

해당 경계는 검사 가능(inspectable)해야 하며 중단 가능(stoppable)해야 합니다. 나중에가 아니라, 바로 그 시점에 말입니다.

실제 구현 스케치
다음은 Python 스타일의 의사코드(pseudocode)로 작성된 간단한 오케스트레이터(orchestrator) 패턴입니다:

class Supervisor :
def init ( self , workers , memory_store ):
self . workers = workers
self . memory_store = memory_store

def run ( self , task ):
    plan = self . make_plan ( task )
    for step in plan :
        result = self . dispatch ( step )
        if not self . validate ( result , step ):
            return { " status " : " failed " , " reason " : " validation_failed " }
        if result . get ( " memory_event " ):
            self . review_memory_event ( result [ " memory_event " ])
    return self . finalize ( plan )

def dispatch ( self , step ):
    worker = self . workers [ step [ " worker " ]]
    return worker . execute ( step [ " input " ])

def review_memory_event ( self , event ):
    if event [ " confidence " ] > 0.9 :
        self . memory_store .

write(event)

그리고 작업자(worker)는 좁은 범위를 유지합니다:

class SearchWorker:
    def execute(self, input_data):
        query = input_data["query"]
        results = web_search(query)
        return {
            "sources": results[:5],
            "confidence": 0.77,
            "memory_event": None
        }

이것은 의도적으로 지루하게 설계된 것입니다. 지루함은 좋은 것입니다.

자동화에서 이것이 더욱 중요한 이유

에이전트(agents)가 자동화(automations) 내부에서 실행될 때 이 점은 더욱 중요해집니다. 만약 여러분이 다음과 같은 도구에 LLM 워크플로우(workflows)를 연결하고 있다면:

  • n8n
  • Make
  • Zapier
  • OpenClaw
  • 커스텀 크론 잡(custom cron jobs)
  • 큐 워커(queue workers)
  • 내부 지원 파이프라인(internal support pipelines)

여러분은 보통 "에이전트의 성격(agent personality)"보다는 다음과 같은 요소들에 더 신경을 씁니다:

  • 예측 가능한 완료(predictable completion)
  • 제한된 재시도(bounded retries)
  • 관찰 가능한 실패 모드(observable failure modes)
  • 안정적인 비용(stable cost)
  • 쉬운 디버깅(easy debugging)

이것이 계층적 오케스트레이션(hierarchical orchestration)이 자주 승리하는 이유입니다. 이는 여러분이 조사할 수 있는 방식으로 실패합니다. 반면 피어 투 피어(Peer-to-peer) 시스템은 종종 대화의 확산(conversation sprawl) 형태로 실패합니다. 이러한 방식은 디버깅하기 훨씬 어렵고, 비용을 지불하기에도 훨씬 더 짜증이 납니다.

아무도 충분히 언급하지 않는 비용 문제

이 지점이 바로 아키텍처(architecture) 결정이 여러분의 청구서에 영향을 미치는 곳입니다. 느슨한 멀티 에이전트 협업(multi-agent collaboration)은 토큰(tokens)을 빠르게 소모합니다. 모든 측면적인 명확화(sideways clarification), 모든 반복되는 요약, 모든 "정렬 확인(just checking alignment)" 단계가 비용을 추가합니다. 만약 토큰당 과금 방식을 사용하고 있다면, 잘못된 조직 설계(org design)는 단순히 버그를 만드는 데 그치지 않습니다. 그것은 과금 문제(billing problem)를 야기합니다.

이것이 프로덕션 에이전트와 자동화를 운영하는 팀에게 이 주제가 중요한 이유 중 하나입니다. n8n, Make, Zapier 또는 커스텀 워커에서 하루 종일 워크플로우가 실행되고 있다면, 여러분은 시스템이 내부 회의를 생성하는 것이 아니라 유용한 작업을 수행하기를 원할 것입니다.

또한 예측 가능한 가격 책정이 이러한 시스템을 설계하는 방식을 변화시키는 이유이기도 합니다. 만약 Standard Compute와 같이 즉시 사용 가능한 OpenAI 호환 API를 사용하고 있다면, 토큰 지출을 일일이 감시하지 않고도 실제 자동화를 지속적으로 실행하는 데 더 공격적으로 임할 수 있습니다. 고정 월정액 요금제는 에이전트 중심의 워크로드(agent-heavy workloads)에 대한 많은 망설임을 제거해 줍니다.

하지만 그렇다 하더라도, 저는 여전히 조직도(org chart)를 먼저 수정할 것입니다. 무제한 컴퓨팅(Unlimited compute)은 훌륭합니다. 하지만 낭비되는 컴퓨팅은 여전히 낭비입니다.

어떤 패턴이 더 나을까요?

요약 버전: 접근 방식 | 장점

CrewAI: 계층적 프로세스 관리자(Hierarchical Process Manager)가 작업을 조정하고 검증합니다. 계층 구조가 명시적이며 권한이 명확합니다.

OpenAI Agents SDK: 핸드오프(Handoffs)를 통해 명시적인 전송 경계(transfer boundaries)에서 위임이 이루어집니다. 작업이 도구(tools)를 교차하는 지점에 가드레일(guardrails)을 부착할 수 있습니다.

AutoGen: Mixture of Agents 방식은 단일 오케스트레이터(orchestrator)와 워커(worker) 레이어를 사용하는 것이 자유 형식의 그룹 채팅(free-form group chat)보다 추론하기 쉽습니다.

OpenClaw: 스코프가 지정된 에이전트(Scoped Agents) 방식은 에이전트별 상태(state)와 바인딩(bindings)을 통해 하나의 거대한 공유 메모리 덩어리(shared memory blob) 대신 격리(isolation)를 장려합니다.

만약 새벽 2시에 안정적으로 실행되어야 하는 워크플로우가 필요하다면, 저는 대부분의 경우 동료 간 협업(peer collaboration)보다는 계층적 오케스트레이션(hierarchical orchestration)을 선택할 것입니다. 그것이 더 예뻐서가 아닙니다. 디버깅(debug)이 가능하기 때문입니다.

일부 루프가 여전히 프롬프트 문제인가요? 네, 그렇습니다. 때때로 문제는 정말로 다음과 같습니다:

  • 취약한 도구 스키마 (weak tool schema)
  • 잘못된 재시도 로직 (bad retry logic)
  • 허술한 종료 조건 (sloppy termination condition)
  • 불량한 컨텍스트 패킹 (poor context packing)
  • 모델의 비신뢰성 (model unreliability)

모든 루프가 조직도(org-chart) 문제는 아닙니다. 하지만 놀라울 정도로 많은 루프가 조직도 문제입니다. 그리고 저는 사람들이 시스템에 실질적인 권한 구조(authority structure)가 없다는 사실을 인정하는 것보다 프롬프트 튜닝(prompt tuning)이 더 쉽다고 느끼기 때문에 너무 일찍 프롬프트 튜닝에 매달린다고 생각합니다.

저의 현재 경험칙(rule of thumb):
만약 작업이 2개 이상의 위임된 단계(delegated steps)로 나뉜다면, 저는 기본적으로 다음 방식을 따릅니다:

  • 한 명의 감독자 (one supervisor)
  • 좁은 범위의 워커 (narrow workers)
  • 명시적 핸드오프 (explicit handoffs)
  • 스코프가 지정된 메모리 (scoped memory)
  • 강력한 체크포인트 (hard checkpoints)
  • 명시적 종료 (explicit termination)

그 이후에야 비로소 프롬프트를 튜닝하기 시작합니다. 왜냐하면 루프를 도는 에이전트를 위한 직관에 반하는 해결책은 대개 더 많은 자유를 주는 것이 아니라, 더 적은 자유를 주는 것이기 때문입니다.

이것은 마치 시스템을 덜 지능적으로 만드는 것처럼 느껴질 수 있습니다. 하지만 실제로 여러분은 시스템을 덜 정치적으로(less political) 만들고 있는 것입니다. 그리고 그것이 대개 프로덕션 에이전트 시스템(production agent systems)에 필요한 것입니다.

만약 여러분의 에이전트가 계속 루프를 돈다면, 페르소나 프롬프트(personality prompt)를 다시 쓰는 것부터 시작하지 마십시오. 조직도를 다시 그리십시오.

AI 자동 생성 콘텐츠

본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0