ADK에서 멀티 에이전트 패턴을 위한 개발자 가이드

발행: (2026년 1월 28일 오전 09:04 GMT+9)
15 min read

Source: Google Developers Blog

2025년 12월 16일

소프트웨어 개발 분야는 이미 이 교훈을 배웠습니다: 모놀리식 애플리케이션은 확장되지 않습니다. 대규모 전자상거래 플랫폼이든 복잡한 AI 애플리케이션이든, 하나의 모든 것을 담당하는 엔터티에 의존하면 병목 현상이 발생하고 디버깅 비용이 증가하며 특화된 성능이 제한됩니다.

같은 원리가 AI 에이전트에도 적용됩니다. 너무 많은 책임을 맡은 단일 에이전트는 “모든 것을 할 수는 있지만 어느 것도 잘 하지 못하는” 존재가 됩니다. 지시가 복잡해질수록 특정 규칙을 따르는 정도가 떨어지고 오류율이 누적되어 점점 더 많은 “환각”이 발생합니다. 에이전트가 실패했을 때 전체 프롬프트를 다 뜯어내어 버그를 찾아야 할 필요는 없습니다.

신뢰성은 탈중앙화와 전문화에서 나옵니다. 다중 에이전트 시스템(MAS)은 마이크로서비스 아키텍처에 해당하는 AI 버전을 구축하게 해줍니다. 개별 에이전트에게 Parser, Critic, Dispatcher와 같은 구체적인 역할을 할당함으로써, 본질적으로 더 모듈화되고 테스트 가능하며 신뢰할 수 있는 시스템을 만들 수 있습니다.

이 가이드에서는 Google Agent Development Kit (ADK) 를 사용해 순차 파이프라인부터 인간‑인‑루프 패턴까지 여덟 가지 핵심 설계 패턴을 소개합니다. 생산 환경 수준의 에이전트 팀을 구축하는 데 필요한 구체적인 패턴과 의사코드를 제공할 것입니다.

1. Sequential Pipeline Pattern (aka the assembly line)

이 패턴을 고전적인 조립 라인이라고 생각하면 됩니다. Agent A가 작업을 마치면 바로 Agent B에게 배턴을 넘겨줍니다. 선형이며 결정적이고, 데이터가 정확히 어디서 왔는지 항상 알 수 있기 때문에 디버깅이 매우 쉽습니다.

Typical use‑case: 원시 문서 처리.
ParserExtractorSummarizer

Sequential pattern

ADK에서는 SequentialAgent 프리미티브가 오케스트레이션을 대신 수행합니다. 핵심은 상태 관리이며, output_key를 사용해 공유된 session.state에 기록하면 체인에 있는 다음 에이전트가 정확히 어디서 작업을 이어받아야 하는지 알 수 있습니다.

# ADK Pseudocode

# Step 1: Parse the PDF
parser = LlmAgent(
    name="ParserAgent",
    instruction="Parse raw PDF and extract text.",
    tools=[PDFParser],
    output_key="raw_text"
)

# Step 2: Extract structured data
extractor = LlmAgent(
    name="ExtractorAgent",
    instruction="Extract structured data from {raw_text}.",
    tools=[RegexExtractor],
    output_key="structured_data"
)

# Step 3: Summarize
summarizer = LlmAgent(
    name="SummarizerAgent",
    instruction="Generate summary from {structured_data}.",
    tools=[SummaryEngine]
)

# Orchestrate the Assembly Line
pipeline = SequentialAgent(
    name="PDFProcessingPipeline",
    sub_agents=[parser, extractor, summarizer]
)

Source:

2. 코디네이터 / 디스패처 패턴 (aka the concierge)

때때로 체인이 필요하지 않을 때가 있습니다; 대신 의사결정자가 필요합니다. 이 패턴에서는 중앙의 지능형 에이전트가 디스패처 역할을 합니다. 사용자의 의도를 분석하고 요청을 작업에 가장 적합한 전문 에이전트에게 라우팅합니다.

Typical use‑case: 복잡한 고객 서비스 봇으로, 사용자를 “청구(Billing)” 전문 담당자나 “기술 지원(Tech Support)” 전문 담당자에게 라우팅해야 할 때.

코디네이터‑디스패처 패턴

이것은 LLM 기반 위임에 의존합니다. 상위 CoordinatorAgent를 정의하고 전문 sub_agents 목록을 제공합니다. ADK의 AutoFlow 메커니즘은 자식에 대해 제공한 설명을 기반으로 실행을 전환합니다.

# ADK Pseudocode

billing_specialist = LlmAgent(
    name="BillingSpecialist",
    description="Handles billing inquiries and invoices.",
    tools=[BillingSystemDB]
)

tech_support = LlmAgent(
    name="TechSupportSpecialist",
    description="Troubleshoots technical issues.",
    tools=[DiagnosticTool]
)

# The Coordinator (Dispatcher)
coordinator = LlmAgent(
    name="CoordinatorAgent",
    instruction=(
        "Analyze user intent. Route billing issues to BillingSpecialist "
        "and bugs to TechSupportSpecialist."
    ),
    sub_agents=[billing_specialist, tech_support]
)

3. Parallel Fan‑Out / Gather Pattern (aka the octopus)

Speed matters. If you have tasks that don’t depend on each other, why run them one by one? In this pattern, multiple agents execute tasks simultaneously to reduce latency or gain diverse perspectives. Their outputs are then aggregated by a final “synthesizer” agent.

Typical use‑case: 자동 코드 리뷰. Security Auditor, Style Enforcer, 그리고 Performance Analyst 를 병렬로 실행한 뒤, Synthesizer 에이전트와 함께 피드백을 결합합니다.

병렬 팬‑아웃 패턴

The ParallelAgent in ADK runs sub_agents concurrently. Although these agents operate in separate execution threads, they share the same session state, so be mindful of race conditions when writing to shared keys.

# ADK Pseudocode

security_auditor = LlmAgent(
    name="SecurityAuditor",
    instruction="Check the PR for security vulnerabilities.",
    tools=[StaticAnalyzer]
)

style_enforcer = LlmAgent(
    name="StyleEnforcer",
    instruction="Enforce coding style guidelines.",
    tools=[Linter]
)

performance_analyst = LlmAgent(
    name="PerformanceAnalyst",
    instruction="Identify performance bottlenecks.",
    tools=[PerfProfiler]
)

# Synthesizer that gathers the three reports
synthesizer = LlmAgent(
    name="ReviewSynthesizer",
    instruction=(
        "Combine the outputs from SecurityAuditor, StyleEnforcer, and "
        "PerformanceAnalyst into a single, cohesive review comment."
    ),
    tools=[TextCombiner]
)

# Parallel orchestration
parallel_review = ParallelAgent(
    name="ParallelCodeReview",
    sub_agents=[security_auditor, style_enforcer, performance_analyst],
    gather_agent=synthesizer
)

The remaining five patterns (Human‑in‑the‑loop, Critic‑Reviewer, Adaptive Routing, Stateful Conversation, and Self‑Healing) follow similar principles and are detailed in the full ADK documentation.

4. 병렬 팬‑아웃 (일명 “스웜”)

작업을 독립적인 하위 작업으로 나눌 수 있을 때, 여러 에이전트를 병렬로 실행한 뒤 결과를 결합할 수 있습니다. 각 하위 에이전트는 경쟁 상태를 방지하기 위해 세션 상태의 고유 키에 출력을 기록합니다.

# ADK Pseudo

# Define parallel workers
security_scanner = LlmAgent(
    name="SecurityAuditor",
    instruction="Check for vulnerabilities like injection attacks.",
    output_key="security_report"
)

style_checker = LlmAgent(
    name="StyleEnforcer",
    instruction="Check for PEP8 compliance and formatting issues.",
    output_key="style_report"
)

complexity_analyzer = LlmAgent(
    name="PerformanceAnalyst",
    instruction="Analyze time complexity and resource usage.",
    output_key="performance_report"
)

# Fan‑out (the Swarm)
parallel_reviews = ParallelAgent(
    name="CodeReviewSwarm",
    sub_agents=[security_scanner, style_checker, complexity_analyzer]
)

# Gather / Synthesize
pr_summarizer = LlmAgent(
    name="PRSummarizer",
    instruction=(
        "Create a consolidated Pull Request review using "
        "{security_report}, {style_report}, and {performance_report}."
    )
)

# Wrap in a sequence
workflow = SequentialAgent(sub_agents=[parallel_reviews, pr_summarizer])

Source:

5. 계층적 분해 (러시아 인형 방식)

큰 작업은 단일 에이전트의 컨텍스트 창을 초과할 수 있습니다. 상위 레벨 에이전트는 목표를 하위 작업으로 나누고 이를 하위 레벨 에이전트에 위임할 수 있습니다. 단순 라우팅과 달리, 부모 에이전트는 하위 작업의 결과를 기다렸다가 자신의 추론을 계속할 수 있습니다.

계층적 작업 분해 에이전트

하위 에이전트를 AgentTool 로 감싸서 도구처럼 취급할 수 있습니다. 그런 다음 부모 에이전트는 전체 하위 워크플로를 하나의 함수처럼 호출합니다.

# ADK Pseudocode

# Level 3: Tool agents
web_searcher = LlmAgent(
    name="WebSearchAgent",
    description="Searches the web for facts."
)

summarizer = LlmAgent(
    name="SummarizerAgent",
    description="Condenses text."
)

# Level 2: Coordinator agent
research_assistant = LlmAgent(
    name="ResearchAssistant",
    description="Finds and summarizes info.",
    sub_agents=[web_searcher, summarizer]
)

# Level 1: Top‑level agent
report_writer = LlmAgent(
    name="ReportWriter",
    instruction=(
        "Write a comprehensive report on AI trends. "
        "Use the ResearchAssistant to gather info."
    ),
    tools=[AgentTool(research_assistant)]
)

6. Generator & Critic (편집자 책상이라고도 함)

생성 과정을 검증과 분리합니다. Generator는 초안을 생성하고, Critic은 하드코딩된 기준에 따라 초안을 검사합니다. 초안이 실패하면 피드백이 Generator에게 전달되어 수정됩니다. 이 루프는 출력이 품질 게이트를 통과할 때까지 계속됩니다.

generator‑critic agent pattern

구현에서는 초안‑검토 상호작용을 위해 SequentialAgent를 사용하고, 종료 조건을 강제하기 위해 LoopAgent를 사용합니다.

# ADK Pseudocode

# Generator
generator = LlmAgent(
    name="Generator",
    instruction=(
        "Generate a SQL query. If you receive {feedback}, "
        "fix the errors and generate again."
    ),
    output_key="draft"
)

# Critic
critic = LlmAgent(
    name="Critic",
    instruction=(
        "Check if {draft} is valid SQL. If correct, output 'PASS'. "
        "If not, output error details."
    ),
    output_key="feedback"
)

# Loop that repeats until the critic returns PASS
validation_loop = LoopAgent(
    name="ValidationLoop",
    sub_agents=[generator, critic],
    condition_key="feedback",
    exit_condition="PASS"
)

7. 반복적 정제 (조각가라고도 함)

단순히 통과/실패가 아니라 점진적인 개선이 필요한 작업의 경우 Generator → Critic → Refinement 에이전트의 루프를 사용합니다. 루프는 품질 임계값이 충족되면 종료되며, 고정된 반복 횟수 후이든 에이전트가 조기 완료를 신호(escalate=True)하면 종료됩니다.

iterative refinement agent pattern

# ADK Pseudocode

# Generator
generator = LlmAgent(
    name="Generator",
    instruction="Create a first draft of the document.",
    output_key="draft"
)

# Critic (provides improvement notes)
critic = LlmAgent(
    name="Critic",
    instruction="Review {draft} and return a list of improvement suggestions.",
    output_key="feedback"
)

# Refinement (applies suggestions)
refiner = LlmAgent(
    name="Refiner",
    instruction=(
        "Take {draft} and the suggestions in {feedback}, "
        "and produce an improved version."
    ),
    output_key="refined"
)

# Loop that continues until the critic signals quality or max_iterations is hit
refinement_loop = LoopAgent(
    name="IterativeRefinement",
    sub_agents=[generator, critic, refiner],
    condition_key="feedback",
    exit_condition="QUALITY_OK",
    max_iterations=5
)

패턴 요약

패턴사용 시점핵심 프리미티브
Parallel fan‑out동시에 실행할 수 있는 독립적인 하위 작업들ParallelAgent, SequentialAgent
Hierarchical decomposition하나의 컨텍스트 윈도우에 담기엔 너무 큰 작업AgentTool 로 감싼 중첩 LlmAgent
Generator & Critic엄격한 정확성 또는 규정 준수 검사가 필요할 때SequentialAgent + LoopAgent
Iterative refinement여러 차례에 걸쳐 품질이 향상되는 경우사용자 정의 종료 로직이 포함된 LoopAgent

이러한 패턴은 ADK 프레임워크를 사용해 복합적이고 신뢰할 수 있는 워크플로우를 구성할 때 자유롭게 조합할 수 있습니다.

generator = LlmAgent(
    name="Generator",
    instruction="Generate an initial rough draft.",
    output_key="current_draft"
)

# Critique Agent
critic = LlmAgent(
    name="Critic",
    instruction="Review {current_draft}. List ways to optimize it for performance.",
    output_key="critique_notes"
)

# Refiner Agent
refiner = LlmAgent(
    name="Refiner",
    instruction="Read {current_draft} and {critique_notes}. Rewrite the draft to be more efficient.",
    output_key="current_draft"
)

# The Loop (Critique → Refine)
loop = LoopAgent(
    name="RefinementLoop",
    max_iterations=3,
    sub_agents=[critic, refiner]
)

# Complete Workflow
workflow = SequentialAgent(sub_agents=[generator, loop])

8. 인간‑인‑루프 (인간 안전망)

AI 에이전트는 강력하지만, 중요한 의사결정에서는 운전석에 인간이 있어야 할 때가 있습니다. 이 모델에서는 에이전트가 기본 작업을 수행하지만, 인간이 고위험 행동을 승인해야 합니다—특히 되돌릴 수 없거나 큰 영향을 미치는 행동(예: 금융 거래 실행, 프로덕션에 코드 배포, 민감한 데이터에 대한 조치) 등입니다. 이를 통해 안전성과 책임성을 보장합니다.

다이어그램은 Transaction Agent가 일상적인 작업을 처리하는 모습을 보여줍니다. 고위험 검증이 필요할 때는 ApprovalTool Agent를 호출하여 실행을 일시 중지하고 Human Reviewer가 “예” 또는 “아니오”라고 답할 때까지 기다립니다.

human‑in‑the‑loop pattern

ADK는 맞춤형 도구를 통해 이를 구현할 수 있게 합니다. 에이전트는 approval_tool을 호출하여 실행을 일시 중지하거나 외부 시스템을 트리거해 인간 개입을 요청할 수 있습니다.

# ADK Pseudocode
transaction_agent = LlmAgent(
    name="TransactionAgent",
    instruction="Handle routine processing. If high stakes, call ApprovalTool.",
    tools=[ApprovalTool]
)

approval_agent = LlmAgent(
    name="ApprovalToolAgent",
    instruction="Pause execution and request human input."
)

workflow = SequentialAgent(sub_agents=[transaction_agent, approval_agent])

Source:

9. Composite patterns (the mix‑and‑match)

현실 세계의 엔터프라이즈 애플리케이션은 거의 대부분 단일 박스에 들어가지 않습니다. 생산 등급 시스템을 구축하기 위해 이러한 패턴들을 조합해서 사용할 가능성이 높습니다.

예시: 견고한 고객 지원 시스템은 Coordinator를 사용해 요청을 라우팅할 수 있습니다. 사용자가 기술적인 문제를 가지고 있다면, 해당 분기가 문서와 사용자 기록을 Parallel하게 검색하도록 트리거할 수 있습니다. 최종 답변은 Generator → Critic 루프를 거쳐 톤 일관성을 확인한 뒤 사용자에게 전송될 수 있습니다.

composite agent pattern

Back to Blog

관련 글

더 보기 »