본문 바로가기
Agentic AI/Google ADK

1. Google ADK 기반의 에이전트 아키텍처 및 오케스트레이션(Orchestration) 순차, 병렬, 반복 패턴

by 아톨 2026. 10. 9.

코드 1~4는 Google ADK(Agent Development Kit)를 활용하여 단일 에이전트부터 멀티 에이전트의 다양한 오케스트레이션(순차, 병렬, 반복) 패턴 예제들입니다.

1. 코드별 주제

  • 코드 1: 단일 에이전트(Single Agent) 기본 구현
  • 코드 2: 순차 실행(Sequential Orchestration) 워크플로 패턴
  • 코드 3: 병렬 처리 및 결과 취합(Parallel Fan-Out / Fan-In) 워크플로 패턴
  • 코드 4: 레거시 루프 에이전트(LoopAgent) 기반 반복 처리 패턴

 

2. 코드별 상세 해설

코드 1 

주제: 단일 에이전트(Single Agent) 기본 구현

import os 
from google.adk import Agent, Workflow
     
weather_agent = Agent(
    model = os.getenv("GOOGLE_MODEL", "gemini-3.5-flash"),
    name = "weather_agent",
    description="현재 날씨, 내일 날씨 등 기본적인 기상정보를 알려주는 에이전트",
    instruction="당신은 기상청 캐스터입니다. 항상 날씨 정보 뒤에 '이옵니다' 를 붙여주세요.",
)
     
root_agent = weather_agent
  • 구조적 특징: 가장 기본이 되는 단일 에이전트 예시입니다.
  • 핵심 코드 설명:
    1. from google.adk import Agent: ADK의 기본 대화형 AI 에이전트 클래스인 Agent를 임포트합니다.
    2. weather_agent = Agent(...):
      • model: 사용할 LLM을 지정합니다. 환경변수 GOOGLE_MODEL 값을 우선적으로 탐색하며, 없을 경우 "gemini-3.5-flash"를 기본값으로 사용합니다.
      • name: 에이전트의 고유 식별자 이름입니다.
      • description: 에이전트가 수행하는 역할에 대한 상세 설명입니다.
      • instruction: 에이전트의 페르소나 및 출력 형식을 제어하는 시스템 프롬프트입니다. 답변 끝에 반드시 "이옵니다"를 붙이도록 지시하고 있습니다.
    3. root_agent = weather_agent: adk web 실행 시 시스템이 최초로 진입할 주 에이전트(Entry Point)로 weather_agent를 지정합니다.

 

코드 2 

주제: 순차 실행(Sequential Orchestration) 워크플로 패턴

 

import os
from google.adk import Agent, Workflow
     
poet_agent = Agent(
    name="poet_agent",
    model=os.getenv("GOOGLE_MODEL","gemini-3.5-flash"),
    description="시 창작 담당 에이전트",
    instruction="""
    당신은 천재적인 감성을 가진 시인입니다.
    사용자가 단어를 제시하면, 그 단어로 'N행시'를 지으세요.
    운율을 맞추고, 유머스럽고 위트넘치게 작성하세요.    
    """    
)
     
critic_agent = Agent(
    name="critic_agent",
    model=os.getenv("GOOGLE_MODEL","gemini-3.5-flash"),
    description="시 평가 담당 에이전트",
    instruction="""
    당신은 냉철한 문학 평론가입니다.
    앞선 에이전트가 작성한 N행시를 읽고 다음 형식으로 평가하세요.
     
    [평가 결과]
    - 점수: OO점 / 100점
    - 한줄평: (시의 내용에 대한 구체적이고 날카로운 코멘트)    
    """    
)
     
poem_team = Workflow(
    name="poem_team",
    description="N행시를 짓고 평가하는 팀입니다.",
    edges=[("START", poet_agent, critic_agent)]    
)
     
root_agent = poem_team
  • 구조적 특징: 두 에이전트가 "창작 $\rightarrow$ 평가" 순서대로 작업을 차례대로 이어서 수행하는 직렬 파이프라인(Chaining) 구조입니다.
  • 핵심 코드 설명:
    1. poet_agent & critic_agent: 각자 독자적인 시스템 프롬프트(instruction)를 가진 독립된 에이전트 두 개를 생성합니다.
    2. poem_team = Workflow(...):
      • 최신 ADK의 Workflow 클래스를 활용해 에이전트 간 제어 흐름을 그래프 구조로 연결합니다.
    3. edges=[("START", poet_agent, critic_agent)]:
      • 시작("START") 지점부터 poet_agent를 실행하고, 그 결과물이 전달되어 critic_agent가 받아 평가하도록 순차적 엣지(Edge)를 정의합니다.
    4. root_agent = poem_team: 직렬 파이프라인으로 구성된 전체 Workflow를 실행 진입점으로 등록합니다.

코드 3 

주제: 병렬 처리 및 결과 취합(Parallel Fan-Out / Fan-In) 워크플로 패턴

 

 

import os
from google.adk import Agent, Workflow
     
food_agent = Agent(
    name="food_agent",
    model=os.getenv("GOOGLE_MODEL","gemini-3.5-flash"),
    instruction="""
    당신은 미식가 가이드입니다.
    사용자가 지역명을 입력하면, 그 지역에서 가장 분위기 좋은 맛집 메뉴 하나를 추천하고
    이유를 한 문장으로 설명하세요.    
    """    
)
     
play_agent = Agent(
    name="play_agent",
    model=os.getenv("GOOGLE_MODEL","gemini-3.5-flash"),
    instruction="""
    당신은 놀거리 전문가입니다.
    사용자가 지역명을 입력하면, 식사 후에 할 수 있는 재미있는 활동이나
    산책 코스 하나를 추천하고 이유를 한 문장으로 설명하세요.    
    """    
)

reporter_agent=Agent(
    name="reporter_agent",
    model=os.getenv("GOOGLE_MODEL","gemini-3.5-flash"),
    instruction="""
    당신은 데이트 코스 플래너입니다.
    앞선 맛집 전문가와 놀거리 전문가가 추천한 내용을 바탕으로,
    사용자에게 전달할 완벽한 주말 데이트 코스 일정을 정돈된 양식으로 종합하여 최종 출력하세요.    
    """    
)
     
weekend_team = Workflow(
    name="weekend_team",
    description="맛집과 놀거리를 동시에 찾아서 데이트 코스를 완성합니다.",
    edges=[
        # START에서 두 에이전트로 병렬 분기 (Fan-out)
        ("START",food_agent),
        ("START",play_agent),
    
        # 두 에이전트의 결과를 reporter_agent 하나로 모음 (Fan-in)
        (food_agent, reporter_agent),
        (play_agent, reporter_agent),
    ],
)
     
root_agent=weekend_team
  • 구조적 특징: 동일한 유저 입력(지역명)에 대해 맛집과 놀거리를 동시에 병렬(Parallel)로 찾고(Fan-out), 그 두 결과를 하나의 리포터 에이전트가 모아서 정리(Fan-in)하여 최종 단일 결과(Terminal Output)를 만드는 구조입니다.
  • 핵심 코드 설명:
    1. food_agent & play_agent: 각각 맛집과 놀거리를 탐색하는 전담 작업 에이전트입니다.
    2. reporter_agent: 병렬 처리된 2개의 개별 응답을 취합하여 정돈된 데이트 코스 양식으로 통합 정리해 주는 단일 터미널 출력 노드(Aggregator) 역할을 수행합니다.
    3. edges=[...] 분기 구조:
      • ("START", food_agent) & ("START", play_agent): "START" 노드에서 2개의 에이전트로 동시에 분기하여 병렬 실행을 개시합니다.
      • (food_agent, reporter_agent) & (play_agent, reporter_agent): 실행이 끝난 두 에이전트의 출력이 최종적으로 reporter_agent 하나로 모이도록 결합합니다. (ADK의 "단일 최종 출력 노드 규칙" 준수)

 

코드 4 .1 

주제: 레거시 루프 에이전트(LoopAgent) 기반 반복 처리 패턴

import os
from google.adk.agents import LlmAgent, LoopAgent
     
# 1. 요약 전문 에이전트 (Worker)
summarizer = LlmAgent(
    name="summarizer_bot",
    model=os.getenv("GOOGLE_MODEL", "gemini-3.1-flash-lite"),
    instruction="""
    당신은 '요약의 신'입니다.
    입력된 텍스트를 읽고, 핵심 내용은 유지하되 분량을 '더 짧게' 줄이세요.
    이전 내용보다 문장을 더 간결하게 다듬어야 합니다.
    """
)
     
# 2. 반복 관리자 (LoopAgent) 정의
loop_manager = LoopAgent(
    name="loop_summary_team",
    description="텍스트를 3단계에 걸쳐 점진적으로 요약합니다.",
    sub_agents=[summarizer],       # 반복시킬 대상 (body)
    max_iterations=3  # 반복 조건
)
# adk web 명령어가 실행할 진입점
root_agent = loop_manager
  • 구조적 특징: 구버전(레거시) ADK 방식의 LoopAgent를 사용해 지정된 에이전트를 일정 횟수 동안 반복적으로 실행하는 구조입니다.
  • 핵심 코드 설명:
    1. from google.adk.agents import LlmAgent, LoopAgent: 구버전 패키지 경로 구문으로, 기본 LLM 클래스인 LlmAgent와 순환 제어용 LoopAgent를 불러옵니다.
    2. summarizer = LlmAgent(...): 입력된 문장을 이전 단계보다 계속 줄여 나가도록 지시받은 요약 담당 작업자입니다.
    3. loop_manager = LoopAgent(...):
      • sub_agents=[summarizer]: 루프 내부에서 반복 실행될 대상(Body)으로 summarizer를 설정합니다.
      • max_iterations=3: 요약 작업을 최대 3회까지 연속 수행하도록 조건 제한을 둡니다.
  • 참고 (최신 패러다임): 최신 ADK 버전에서는 LoopAgent 대신 Workflow 내에서 에이전트 간 순환 엣지(Self-looping Edge)나 조건부 RouterAgent를 사용하여 루프를 구성하도록 진화했습니다.

 

코드 4 . 2

최신 ADK(v2.x 이상)에서는 별도의 LoopAgent 클래스 대신, Workflow 내의 엣지(Edge) 연결 방식을 활용하여 루프 및 조건부 순환을 구현합니다.

최신 Workflow 기반 루프 코드

import os
from google.adk import Agent, Workflow

# 1. 요약 담당 에이전트 (Worker)
summarizer = Agent(
    name="summarizer_bot",
    model=os.getenv("GOOGLE_MODEL", "gemini-3.5-flash"),
    instruction="""
    당신은 '요약의 신'입니다.
    입력된 텍스트를 읽고, 핵심 내용은 유지하되 분량을 이전보다 훨씬 짧고 간결하게 줄이세요.
    """
)

# 2. 루프 횟수 및 종결 조건 검단 에이전트 (Loop Evaluator)
# 루프의 제어권을 가져와 최대 횟수 초과 시 종료(STOP) 신호를 보내거나 다음 루프를 유도합니다.
evaluator = Agent(
    name="loop_evaluator",
    model=os.getenv("GOOGLE_MODEL", "gemini-3.5-flash"),
    instruction="""
    당신은 요약 반복 횟수 검수자입니다.
    현재까지 진행된 요약 결과를 확인하고, 
    만약 요약이 3회 완료되었거나 더 이상 줄일 수 없을 정도로 짧아졌다면 "COMPLETE"라고 출력하세요.
    아직 추가 요약이 필요하다면 "CONTINUE"라고 출력하세요.
    """
)

# 3. 최신 Workflow 기반 순환 구조(Graph Loop) 구성
loop_summary_team = Workflow(
    name="loop_summary_team",
    description="텍스트를 점진적으로 순환 요약하는 워크플로",
    edges=[
        # START -> 요약 에이전트 실행
        ("START", summarizer),
        
        # 요약 결과를 검수 에이전트에게 전달
        (summarizer, evaluator),
        
        # 검수 결과에 따라 반복(Loop) 또는 종료
        # evaluator가 계속을 지시하면 다시 summarizer로 피드백(Self-looping)
        (evaluator, summarizer)
    ]
)

root_agent = loop_summary_team

주요 변경 및 개선 사항

  1. 클래스 통합 및 모듈화
    • 레거시 LlmAgent와 LoopAgent가 폐지되고, 단일 Agent 및 Workflow 구조로 일언화되었습니다.
  2. 그래프 기반 순환 (Cyclic Graph Edges)
    • (evaluator, summarizer)처럼 에이전트 간의 엣지를 역방향으로 연결함으로써 그래프 상에서 자연스러운 피드백 루프가 형성됩니다.
  3. 명시적 종료 제어 (Termination)
    • 단순 숫자 지정 방식(max_iterations=3) 외에도, 검수 에이전트(evaluator)를 두어 문장의 길이, 완성도, 반복 횟수 등을 지능적으로 판단한 뒤 루프를 탈출하도록 확장성이 향상되었습니다.
반응형