ADK로 멀티 에이전트 시스템 빌드

1. 소개

개요

이 실습에서는 Google 에이전트 개발 키트 (Google ADK)를 사용하여 복잡한 멀티 에이전트 시스템을 조정하는 방법을 알아봅니다. 간단한 상담사 계층 구조에서 자동화된 공동작업 워크플로를 구축하는 단계로 이동합니다.

빌드할 항목

다음과 같은 두 가지 멀티 에이전트 시스템을 빌드합니다.

  • '브레인스토밍' 에이전트와 '관광명소 계획' 에이전트 간에 대화를 전달하는 방법을 학습하는 간단한 여행 계획 에이전트
  • 자동화된 에이전트 (예: 연구원, 각본가, 비평가)의 '작가 회의실'을 사용하여 루프에서 함께 작업하여 전체 영화 줄거리를 만드는 고급 영화 추천 생성기

학습할 내용

  • 상위 에이전트와 하위 에이전트 관계를 만드는 방법
  • 도구에서 세션 state에 데이터를 쓰는 방법
  • 키 템플릿을 사용하여 state에서 읽는 방법 (예: {my_key?}))를 제공합니다.
  • 단계별 워크플로에 SequentialAgent를 사용하는 방법
  • LoopAgent을 사용하여 반복적인 개선 주기를 만드는 방법
  • ParallelAgent를 사용하여 독립적인 작업을 동시에 실행하는 방법

2. 멀티 에이전트 시스템

에이전트 개발 키트 (ADK)를 사용하면 개발자가 생성 모델에서 더 안정적이고 정교한 다단계 동작을 구현할 수 있습니다. ADK를 사용하면 하나의 복잡한 프롬프트 대신 작업을 분담하여 문제에 대해 협업하는 여러 개의 간단한 에이전트의 흐름을 빌드할 수 있습니다.

이 접근 방식은 단일 모놀리식 프롬프트를 사용하는 것보다 다음과 같은 여러 장점이 있습니다.

  • 간단한 설계: 크고 복잡한 프롬프트를 설계하는 것보다 작고 전문화된 에이전트의 흐름을 설계하고 정리하는 것이 더 간단합니다.
  • 안정성: 전문화된 에이전트는 하나의 크고 복잡한 에이전트보다 특정 작업에서 더 안정적입니다.
  • 유지보수 가능성: 시스템의 다른 부분을 중단하지 않고 작고 특화된 에이전트를 수정하거나 개선하는 것이 더 쉽습니다.
  • 모듈성: 하나의 워크플로를 위해 빌드된 에이전트를 다른 워크플로에서 쉽게 재사용할 수 있습니다.

계층적 에이전트 트리

계층적 에이전트를 보여주는 트리 구조

ADK에서는 에이전트를 트리 구조로 정리합니다. 이 계층 구조는 대화의 흐름을 제어하는 데 중요합니다. 어떤 에이전트가 어떤 다른 에이전트에게 대화를 '전달'할 수 있는지를 제한하기 때문입니다. 이렇게 하면 시스템의 동작을 더 쉽게 예측하고 디버그할 수 있습니다. 제공되는 혜택은 다음과 같습니다

  • 직관적인 설계: 구조가 실제 팀에서 영감을 받아 추론하기가 더 쉽습니다.
  • 제어된 흐름: 계층 구조를 통해 작업 위임을 정밀하게 제어할 수 있으므로 디버깅에 도움이 됩니다. 예를 들어 설명이 비슷한 두 개의 보고서 작성 에이전트가 있는 경우에도 트리 구조를 사용하면 올바른 보고서 작성 에이전트가 호출됩니다.

전체 구조는 root_agent로 시작합니다. 이 에이전트는 상위 역할을 하며 하나 이상의 하위 에이전트를 가질 수 있습니다. 하위 에이전트도 자체 하위 에이전트의 상위가 되어 트리를 형성할 수 있습니다.

3. 프로젝트 설정

Google 계정

아직 개인 Google 계정이 없다면 Google 계정을 만들어야 합니다.

직장 또는 학교 계정 대신 개인 계정을 사용합니다.

Google Cloud 콘솔에 로그인

개인 Google 계정을 사용하여 Google Cloud 콘솔에 로그인합니다.

결제 사용 설정

$5 Google Cloud 크레딧 사용 (선택사항)

이 워크숍을 진행하려면 크레딧이 있는 결제 계정이 필요합니다. 자체 결제를 사용하려는 경우 이 단계를 건너뛰어도 됩니다.

  1. 이 링크를 클릭하고 개인 Google 계정으로 로그인합니다. 다음과 같이 표시됩니다.크레딧 페이지를 보려면 여기를 클릭하세요.
  2. 여기를 클릭하여 크레딧에 액세스 버튼을 클릭합니다. 그러면 결제 프로필을 설정하는 페이지로 이동합니다.결제 프로필 설정 페이지
  3. 확인을 클릭합니다.

이제 Google Cloud Platform 평가판 결제 계정에 연결되었습니다.

결제 개요 스크린샷

개인 결제 계정 설정

Google Cloud 크레딧을 사용하여 결제를 설정한 경우 이 단계를 건너뛸 수 있습니다.

개인 결제 계정을 설정하려면 Cloud 콘솔에서 여기에서 결제를 사용 설정하세요.

참고:

  • 이 실습을 완료하는 데 드는 Cloud 리소스 비용은 미화 1달러 미만입니다.
  • 이 실습이 끝나면 단계에 따라 리소스를 삭제하여 추가 요금이 발생하지 않도록 할 수 있습니다.
  • 신규 사용자는 미화$300 상당의 무료 체험판을 사용할 수 있습니다.

프로젝트 만들기(선택사항)

이 실습에 사용할 현재 프로젝트가 없는 경우 여기에서 새 프로젝트를 만드세요.

4. Cloud Shell 편집기 열기

  1. 이 링크를 클릭하여 Cloud Shell 편집기로 바로 이동합니다.
  2. 오늘 언제든지 승인하라는 메시지가 표시되면 승인을 클릭하여 계속합니다.클릭하여 Cloud Shell 승인
  3. 터미널이 화면 하단에 표시되지 않으면 다음을 실행하여 엽니다.
    • 보기를 클릭합니다.
    • 터미널을 클릭합니다.Cloud Shell 편집기에서 새 터미널 열기
  4. 터미널에서 다음 명령어를 사용하여 프로젝트를 설정합니다.
    gcloud config set project [PROJECT_ID]
    
    • 예:
      gcloud config set project lab-project-id-example
      
    • 프로젝트 ID가 기억나지 않는 경우 다음을 사용하여 모든 프로젝트 ID를 나열할 수 있습니다.
      gcloud projects list
      
      Cloud Shell 편집기 터미널에서 프로젝트 ID 설정
  5. 다음 메시지가 표시되어야 합니다.
    Updated property [core/project].
    

5. API 사용 설정

Vertex AI API를 사용하고 Gemini 모델과 상호작용하려면 Google Cloud 프로젝트에서 Vertex AI API를 사용 설정해야 합니다.

  1. 터미널에서 API를 사용 설정합니다.
    gcloud services enable aiplatform.googleapis.com
    

다음은 수동 파일 생성 대신 GitHub 저장소를 클론하고 종속 항목을 설치하는 안내로 업데이트된 섹션입니다.

Python용 Vertex AI SDK 소개

Python 애플리케이션에서 Vertex AI에 호스팅된 모델과 상호작용하려면 Python용 Vertex AI SDK를 사용합니다. 이 SDK를 사용하면 기본 API 호출의 복잡성을 직접 처리하지 않고도 프롬프트를 전송하고, 모델 매개변수를 지정하고, 응답을 수신하는 프로세스를 간소화할 수 있습니다.

Python용 Vertex AI SDK에 관한 포괄적인 문서는 Python용 Vertex AI SDK 소개 | Google Cloud에서 확인할 수 있습니다.

6. 프로젝트 환경 설정

저장소 클론하기

  1. 터미널에서 시작 파일이 포함된 저장소를 클론합니다.
    git clone --depth 1 https://github.com/GoogleCloudPlatform/devrel-demos.git
    
    --depth 1 플래그는 최신 버전만 클론하므로 더 빠릅니다.
  2. 터미널에서 이 실습의 올바른 작업 디렉터리로 이동합니다.
    cd devrel-demos/ai-ml/build-multiagent-systems-with-adk/adk_multiagent_systems
    

가상 환경 활성화

  1. 터미널에서 uv를 사용하여 가상 환경을 만들고 활성화합니다.
    uv venv
    source .venv/bin/activate
    
  2. 터미널에서 requirements.txt 파일의 google-adk 및 기타 종속 항목을 설치합니다.
    uv pip install -r requirements.txt
    

파일 구조 검토

이제 모든 파일이 생성되었으므로 탐색기에서 adk_multiagent_systems 폴더를 열어 전체 구조를 확인합니다.

  1. Cloud Shell 편집기 메뉴에서 파일 > 폴더 열기...를 선택합니다.
    폴더 열기가 선택된 Cloud Shell 편집기 파일 메뉴
  2. 팝업되는 상자에 사용자 이름 뒤에 devrel-demos/ai-ml/build-multiagent-systems-with-adk/adk_multiagent_systems/ 폴더 정보를 추가합니다. 확인을 클릭합니다.
    다음과 같이 표시됩니다.
    프로젝트 경로가 포함된 폴더 열기 대화상자
  3. 왼쪽의 탐색기 패널이 새로고침됩니다. 이제 parent_and_subagentsworkflow_agents 하위 디렉터리가 포함된 전체 프로젝트 구조가 표시되며 다음 단계를 진행할 준비가 되었습니다.
    열린 adk_multiagent_systems 폴더를 보여주는 탐색기 패널

환경 변수 설정

  1. 이미 adk_multiagent_systems 디렉터리에 있습니다. 터미널에서 환경 변수를 저장할 .env 파일을 만듭니다.
    cloudshell edit .env
    
  2. 편집기에서 열리는 .env 파일에 다음을 붙여넣습니다.
    GOOGLE_GENAI_USE_VERTEXAI=TRUE
    GOOGLE_CLOUD_PROJECT="[YOUR-PROJECT-ID]"
    GOOGLE_CLOUD_LOCATION=global
    MODEL="gemini-2.5-flash"
    
  3. [YOUR-PROJECT-ID]를 실제 Google Cloud 프로젝트 ID로 바꿉니다. (예: PROJECT_ID = "google-cloud-labs")
    프로젝트 ID가 기억나지 않으면 터미널에서 다음 명령어를 실행합니다. 모든 프로젝트와 ID의 목록이 표시됩니다.
    gcloud projects list
    
  4. 터미널에서 이 .env 파일을 하위 에이전트 디렉터리에 복사하여 하위 에이전트도 변수에 액세스할 수 있도록 합니다.
    cp .env parent_and_subagents/.env
    cp .env workflow_agents/.env
    
    이제 파일 구조가 다음과 같이 표시됩니다.
    열린 adk_multiagent_systems 폴더를 보여주는 탐색기 패널

7. 상위 에이전트, 하위 에이전트, 피어 에이전트 간의 트랜스퍼 살펴보기

대화는 항상 root_agent로 시작됩니다. 기본적으로 상위 에이전트는 하위 에이전트의 description를 사용하여 대화를 트랜스퍼할 시기를 결정합니다. 하위 에이전트의 name을 사용하여 상위 에이전트의 instruction에서 이러한 트랜스퍼를 명시적으로 안내할 수도 있습니다.

한 번 테스트해 보겠습니다.

  1. Cloud Shell 편집기에서 adk_multiagent_systems/parent_and_subagents/agent.py를 엽니다. agent.py 파일에 있는 세 가지 에이전트를 확인합니다.
    • root_agent (steering라는 이름 지정): 사용자에게 질문하여 전송할 하위 에이전트를 결정합니다. 처음에는 하위 에이전트의 description만 사용합니다.
    • travel_brainstormer: 사용자가 목적지를 브레인스토밍하도록 지원합니다.
    • attractions_planner: 사용자가 특정 국가에서 할 일을 나열하도록 지원합니다.
  2. root_agent를 만들 때 다음 줄을 추가하여 travel_brainstormerattractions_plannerroot_agent의 하위 에이전트로 설정합니다.
        sub_agents=[travel_brainstormer, attractions_planner]
    
  3. 터미널에서 에이전트와 채팅합니다.
    cd ~/devrel-demos/ai-ml/build-multiagent-systems-with-adk/adk_multiagent_systems
    adk run parent_and_subagents
    
  4. 터미널[user]: 프롬프트에서 다음을 입력합니다.
    hello
    
    출력 예시 (사용자마다 다를 수 있음):
    [steering]: Hi there! Do you already have a country in mind for your trip, or would you like some help deciding where to go?
    
  5. 이제 터미널에서 에이전트에게 다음과 같이 말합니다.
    I could use some help deciding.
    
    출력 예시 (사용자마다 다를 수 있음):
    [travel_brainstormer]: Okay! To give you the best recommendations, I need to understand what you're looking for in a trip.
    ...
    
    [travel_brainstormer] 태그를 확인합니다. root_agent는 하위 에이전트의 description 기반하여 제어 권한을 이전했습니다.
  6. 터미널user: 프롬프트에서 exit를 입력하고 Enter 키를 눌러 대화를 종료합니다.
  7. 이제 좀 더 명시적으로 설명해 보겠습니다. agent.py에서 root_agentinstruction에 다음을 추가합니다.
            If they need help deciding, send them to 'travel_brainstormer'.
            If they know what country they'd like to visit, send them to the 'attractions_planner'.
    
  8. 터미널에서 에이전트를 다시 실행합니다.
    adk run parent_and_subagents
    
  9. 터미널[user]: 프롬프트에서 다음을 입력합니다.
    hello
    
  10. 이렇게 대답하세요.
    I would like to go to Japan.
    
    출력 예시 (사용자마다 다를 수 있음):
    [attractions_planner]: Okay, I can help you with that! Here are some popular attractions in Japan:
    ...
    
    새 안내에 따라 attractions_planner로 이전됩니다.
  11. 이제 다음을 포함하여 답장하세요.
    Actually I don't know what country to visit.
    
    출력 예시 (사용자마다 다를 수 있음):
    [travel_brainstormer]: Okay! I can help you brainstorm some countries for travel...
    
    attractions_planner피어travel_brainstormer로 트랜스퍼된 것을 확인할 수 있습니다. 이는 기본적으로 허용됩니다.
  12. 사용자 프롬프트에서 exit를 입력하여 세션을 종료합니다.

요약

이 섹션에서는 에이전트 계층 구조와 대화 흐름의 기본사항을 알아봤습니다.

  • 대화는 항상 root_agent로 시작됩니다.
  • 상위 에이전트는 description에 따라 하위 에이전트로 자동 전송될 수 있습니다.
  • name로 하위 에이전트로 트랜스퍼할 상위 instruction를 제공하여 이 흐름을 명시적으로 제어할 수 있습니다.
  • 기본적으로 에이전트는 peer 에이전트 (계층 구조의 형제)로 트랜스퍼할 수 있습니다.

8. 세션 상태를 사용하여 정보 저장 및 검색

모든 ADK 대화에는 세션 상태 사전이 포함된 Session가 있습니다. 이 상태는 모든 에이전트가 액세스할 수 있으므로 에이전트 간에 정보를 전달하거나 대화 전반에 걸쳐 목록과 같은 데이터를 유지하는 데 적합합니다.

상태에 값을 추가하고 상태에서 읽는 방법을 살펴보려면 다음 안내를 따르세요.

  1. adk_multiagent_systems/parent_and_subagents/agent.py 파일로 돌아갑니다.
  2. 다음 함수 정의를 # Tools 헤더 뒤에 붙여넣습니다.
    def save_attractions_to_state(
    tool_context: ToolContext,
    attractions: List[str]
    ) -> dict[str, str]:
        """Saves the list of attractions to state["attractions"].
    
        Args:
            attractions [str]: a list of strings to add to the list of attractions
    
        Returns:
            None
        """
        # Load existing attractions from state. If none exist, start an empty list
        existing_attractions = tool_context.state.get("attractions", [])
    
        # Update the 'attractions' key with a combo of old and new lists.
        # When the tool is run, ADK will create an event and make
        # corresponding updates in the session's state.
        tool_context.state["attractions"] = existing_attractions + attractions
    
        # A best practice for tools is to return a status message in a return dict
        return {"status": "success"}
    
    이 코드에서 다음 사항을 살펴봅니다.
    • 함수는 tool_context: ToolContext를 받습니다. 이 객체는 세션으로 연결되는 게이트웨이입니다.
    • tool_context.state["attractions"] = ... 줄은 세션의 상태 사전에서 직접 읽고 씁니다. 나머지는 ADK에서 처리합니다.
  3. tools 매개변수를 추가하여 attractions_planner 에이전트에 도구를 추가합니다.
        tools=[save_attractions_to_state]
    
  4. attractions_planner 에이전트의 기존 instruction에 다음 글머리기호 목록을 추가합니다.
            - When they reply, use your tool to save their selected attraction and then provide more possible attractions.
            - If they ask to view the list, provide a bulleted list of { attractions? } and then suggest some more.
    
  5. 터미널에서 다음 명령어를 사용하여 에이전트 개발 키트 웹 UI를 실행합니다.
    adk web
    
    출력
    INFO:     Started server process [2434]
    INFO:     Waiting for application startup.
    +-------------------------------------------------------+
    | ADK Web Server started                                |
    |                                                       |
    | For local testing, access at http://localhost:8000.   |
    +-------------------------------------------------------+
    
    INFO:     Application startup complete.
    INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
    
  6. Cloud Shell 터미널에서 새 탭에서 웹 인터페이스를 보려면 웹 미리보기 버튼을 클릭하고 포트 변경을 선택합니다.
    웹 미리보기 메뉴
  7. 포트 번호 8000을 입력하고 변경 및 미리보기를 클릭합니다. ADK 개발 UI가 표시된 새 브라우저 탭이 열립니다.
    텍스트 상자에 8000이 입력된 포트 변경 팝업 상자
  8. 왼쪽의 에이전트 선택 드롭다운에서 parent_and_subagents를 선택합니다.
  9. hello로 대화를 시작합니다.
  10. 에이전트가 인사하면 다음으로 답합니다.
    I'd like to go to Egypt.
    
    attractions_planner로 트랜스퍼되고 관광 명소 목록이 제공됩니다.
  11. 예를 들어 다음과 같이 관광 명소 한 곳을 선택합니다.
    I'll go to the Sphinx
    
  12. 네, 스핑크스를 목록에 저장했습니다.와 같은 대답이 표시됩니다.
  13. 대답 도구 상자(체크표시로 표시됨)를 클릭하여 도구의 대답으로 생성된 이벤트를 확인합니다.
    상태 변경을 설명하는 stateDelta가 포함된 actions 필드가 포함되어 있습니다.
  14. 상담사의 목록에 있는 다른 명소로 답장합니다.
  15. 왼쪽 탐색 메뉴에서 'X'를 클릭하여 앞서 검사한 이벤트에 대한 포커스를 해제합니다.
  16. 왼쪽 사이드바에서 상태 탭을 클릭합니다. 이제 세션의 상태에 attractions 배열이 표시되며, 여기에는 선택한 항목이 모두 포함되어야 합니다.웹 UI의 세션 상태 미리보기
  17. 에이전트에게 다음 메시지를 보냅니다.
    What is on my list?
    
    이제 에이전트가 상태에서 읽어 목록을 반환해야 합니다.
  18. 에이전트 실험을 마쳤으면 웹브라우저 탭을 닫고 Cloud Shell 터미널에서 Ctrl+C를 눌러 서버를 중지합니다.

섹션 요약

이 섹션에서는 Session 상태를 사용하여 데이터를 공유하는 방법을 알아봤습니다.

  • 상태 쓰기: tool_context.state 객체를 사용하여 도구 내에서 상태 사전에 씁니다 (예: tool_context.state["my_list"] = [...])에 복사합니다.
  • 상태 읽기: 키 템플릿 (예:instruction Here is your list: {my_list?})에 복사합니다.
  • 상태 검사: 상태 탭을 사용하여 ADK Dev UI에서 세션 상태를 실시간으로 모니터링할 수 있습니다.

9. 워크플로 에이전트

지금까지 상위 에이전트가 하위 에이전트로 트랜스퍼한 다음 사용자를 기다리는 방법을 살펴보았습니다. 워크플로 에이전트는 다릅니다. 사용자 입력을 기다리지 않고 자동화된 흐름에서 하위 에이전트를 연속적으로 실행합니다.

'계획 및 실행' 또는 '초안 작성 및 수정' 파이프라인과 같은 자동화된 다단계 작업에 적합합니다. ADK는 이를 관리하기 위해 3개의 기본 제공 워크플로 에이전트를 제공합니다.

  • SequentialAgent
  • LoopAgent
  • ParallelAgent

이 실습의 나머지 부분에서는 이 세 가지 워크플로 에이전트를 사용하여 멀티 에이전트 시스템을 빌드하는 데 중점을 둡니다.

역사적 인물에 관한 새 영화의 피치 문서를 작성하는 에이전트를 빌드합니다. 에이전트가 조사, 반복적인 글쓰기, 보고서 생성을 처리합니다.

결국 시스템은 다음과 같이 표시됩니다.

film_concept_team 멀티 에이전트 시스템 다이어그램

가장 간단한 워크플로를 시작으로 한 단계씩 이 시스템을 빌드합니다.

10. SequentialAgent로 멀티 에이전트 시스템 빌드

SequentialAgent는 하위 에이전트를 간단한 선형 시퀀스로 실행하는 워크플로 에이전트입니다. sub_agents 목록에 있는 각 에이전트는 순서대로 차례로 실행됩니다. 이는 지금 빌드할 영화 추천 에이전트와 같이 태스크를 특정 순서로 실행해야 하는 파이프라인에 적합합니다.

첫 번째 버전은 다음과 같은 구조로 작성됩니다.

Film_concept_team 멀티 에이전트 시스템 1단계

  • root_agent (greeter)이 사용자를 환영하고 영화 주제를 가져옵니다.
  • 그런 다음 film_concept_team라는 SequentialAgent로 전송되며, 이 SequentialAgent는 다음을 수행합니다.
    1. researcher 에이전트를 실행하여 Wikipedia에서 사실을 가져옵니다.
    2. screenwriter 에이전트를 실행하여 이러한 사실을 사용하여 줄거리를 작성합니다.
    3. file_writer 에이전트를 실행하여 최종 플롯을 파일에 저장합니다.

실행해 보겠습니다.

  1. Cloud Shell 편집기에서 adk_multiagent_systems/workflow_agents/agent.py를 엽니다.
    이 에이전트 정의 파일을 읽어 봅니다. 하위 에이전트는 상위 에이전트에 할당되기 전에 정의되어야 하므로 대화 흐름 순서대로 파일을 읽으려면 파일의 하단에서 상단으로 에이전트를 읽으면 됩니다.
  2. append_to_state 도구를 확인합니다. 이 도우미 함수를 사용하면 상담사가 세션 상태의 목록에 데이터를 추가할 수 있습니다. researcherscreenwriter가 작업을 전달하는 방식입니다.
  3. 에이전트를 사용해 봅니다. 터미널에서 실시간 다시 로드가 사용 설정된 웹 인터페이스를 실행합니다.
    cd ~/devrel-demos/ai-ml/build-multiagent-systems-with-adk/adk_multiagent_systems
    adk web --reload_agents
    
  4. Cloud Shell 터미널에서 새 탭에서 웹 인터페이스를 보려면 웹 미리보기 버튼을 클릭하고 포트 변경을 선택합니다.
    웹 미리보기 메뉴
  5. 포트 번호 8000을 입력하고 변경 및 미리보기를 클릭합니다. ADK 개발 UI가 표시된 새 브라우저 탭이 열립니다.
    텍스트 상자에 8000이 입력된 포트 변경 팝업 상자
  6. 에이전트 선택 드롭다운에서 workflow_agents를 선택합니다.
  7. hello로 대화를 시작합니다. greeter 에이전트가 응답합니다.
  8. 메시지가 표시되면 역사적 인물을 입력합니다. 다음 중 하나를 사용하거나 직접 만들 수 있습니다.
    • 장중경
    • 김구글
    • 마르쿠스 아우렐리우스
  9. 이제 SequentialAgent이(가) 인계됩니다. 중간 메시지는 표시되지 않습니다. researcher, screenwriter, file_writer가 순차적으로 실행됩니다. 상담사는 전체 시퀀스가 완료된 경우에만 응답합니다.
    실패하면 오른쪽 상단에서 + 새 세션을 클릭하고 다시 시도할 수 있습니다.
  10. 에이전트가 파일이 작성되었음을 확인하면 Cloud Shell 편집기의 movie_pitches 디렉터리에서 새 .txt 파일을 찾아 열어 출력을 확인합니다.
  11. ADK 개발 UI에서 채팅 기록의 마지막 에이전트 아이콘을 클릭하여 이벤트 뷰를 엽니다.
  12. 이벤트 뷰에는 에이전트 트리의 시각적 그래프가 표시됩니다. greeterfilm_concept_team를 호출하고 film_concept_team가 각 하위 에이전트를 순서대로 호출하는 것을 확인할 수 있습니다.adk 웹 그래프
  13. 그래프에서 에이전트의 요청응답 탭을 클릭하여 세션 상태를 포함해 전달된 정확한 데이터를 검사할 수 있습니다.

섹션 요약

이 섹션에서는 워크플로 에이전트를 사용하는 방법을 알아봤습니다.

  • SequentialAgent는 단계 사이에 사용자 입력을 기다리지 않고 순서대로 하위 에이전트를 하나씩 실행합니다.
  • 사용자가 root_agent와 대화하고 root_agentSequentialAgent작업을 넘겨 완료하므로 '워크플로'입니다.
  • 시퀀스의 하위 에이전트는 세션 상태 (예: { PLOT_OUTLINE? })를 사용하여 이전 상담사의 업무에 액세스할 수 있습니다.
  • 개발자 UI의 이벤트 그래프를 사용하여 전체 에이전트 간 워크플로를 시각화하고 디버그할 수 있습니다.

11. 반복 작업을 위한 LoopAgent 추가

LoopAgent는 순서대로 하위 에이전트를 실행한 다음 처음부터 반복하는 워크플로 에이전트입니다. 이 '루프'는 max_iterations 개수에 도달하거나 하위 에이전트가 기본 제공 exit_loop 도구를 호출하는 등의 조건이 충족될 때까지 계속됩니다.

이 기능은 반복적인 개선이 필요한 작업에 유용합니다. 이 LoopAgent를 추가하여 영화 피치 에이전트의 '작가 회의실'을 만듭니다. 이를 통해 researcher, screenwriter, 새로운 critic 에이전트가 루프에서 작동하여 critic가 준비되었다고 판단할 때까지 각 패스를 통해 플롯을 개선할 수 있습니다. 또한 에이전트가 아이디어를 조사하고 구체화할 수 있도록 하여 '고대 의사'와 같은 모호한 사용자 입력을 처리하는 데도 도움이 됩니다.

Film_concept_team 멀티 에이전트 시스템 2단계

변경하려면 다음 단계를 따르세요.

  1. adk_multiagent_systems/workflow_agents/agent.py에서 exit_loop 가져오기를 추가합니다 (다른 google.adk 가져오기 근처).
    from google.adk.tools import exit_loop
    
  2. critic 에이전트를 추가합니다. 이 상담사가 줄거리를 검토합니다. 좋은 경우 exit_loop를 호출합니다. 그렇지 않으면 다음 루프를 위해 상태에 피드백을 추가합니다.
    # Agents 섹션 아래에 다음 에이전트 정의를 붙여넣습니다.
    critic = Agent(
        name="critic",
        model=model_name,
        description="Reviews the outline so that it can be improved.",
        instruction="""
        INSTRUCTIONS:
        Consider these questions about the PLOT_OUTLINE:
        - Does it meet a satisfying three-act cinematic structure?
        - Do the characters' struggles seem engaging?
        - Does it feel grounded in a real time period in history?
        - Does it sufficiently incorporate historical details from the RESEARCH?
    
        If the PLOT_OUTLINE does a good job with these questions, exit the writing loop with your 'exit_loop' tool.
        If significant improvements can be made, use the 'append_to_state' tool to add your feedback to the field 'CRITICAL_FEEDBACK'.
        Explain your decision and briefly summarize the feedback you have provided.
    
        PLOT_OUTLINE:
        { PLOT_OUTLINE? }
    
        RESEARCH:
        { research? }
        """,
        before_model_callback=log_query_to_model,
        after_model_callback=log_model_response,
        tools=[append_to_state, exit_loop]
    )
    
  3. writers_room LoopAgent를 만듭니다. 여기에는 루프에서 작동할 세 개의 에이전트가 포함됩니다.
    film_concept_team 에이전트 정의 에 다음 코드를 붙여넣습니다.
    writers_room = LoopAgent(
        name="writers_room",
        description="Iterates through research and writing to improve a movie plot outline.",
        sub_agents=[
            researcher,
            screenwriter,
            critic
        ],
        max_iterations=5,
    )
    
  4. writers_room 루프를 사용하도록 film_concept_team SequentialAgent를 업데이트합니다. researcherscreenwriter을 단일 writers_room 에이전트로 바꿉니다. 기존 film_concept_team 정의를 다음으로 바꿉니다.
    film_concept_team = SequentialAgent(
        name="film_concept_team",
        description="Write a film plot outline and save it as a text file.",
        sub_agents=[
            writers_room,
            file_writer
        ],
    )
    
  5. ADK 개발 UI 탭으로 돌아가서 오른쪽 상단에 있는 + 새로운 세션을 클릭합니다.
  6. hello로 새 대화를 시작합니다.
  7. 메시지가 표시되면 이번에는 상담사에게 더 광범위한 주제를 알려줍니다. 다음은 몇 가지 아이디어입니다.
    • 대중을 위한 제품을 만든 산업 디자이너
    • 지도 제작자
    • 작물 수확량을 늘린 사람
    이제 에이전트가 루프를 통해 작동합니다. ADK 개발 UI에서 에이전트가 여러 번 실행될 때 로그가 표시됩니다 (예: '[연구원]', '[각본가]', '[비평가]', '[연구원]', '[각본가]', '[비평가]...').
  8. 루프가 완료되면 에이전트가 파일을 작성합니다. adk_multiagent_systems/movie_pitches 디렉터리에서 생성된 파일을 검토합니다.
  9. 개발자 UI에서 이벤트 그래프를 검사하여 루프 구조를 확인합니다.

섹션 요약

이 섹션에서는 LoopAgent를 사용하는 방법을 알아봤습니다.

  • LoopAgent는 하위 에이전트 시퀀스를 반복하여 반복 작업의 '내부 루프'를 만드는 워크플로 에이전트입니다.
  • 루프 내의 상담사는 세션 상태를 사용하여 작업 (예: PLOT_OUTLINE) 및 의견 (예: CRITICAL_FEEDBACK)를 서로에게 전달합니다.
  • max_iterations 한도에 도달하거나 에이전트가 exit_loop 도구를 호출하면 루프가 중지될 수 있습니다.

12. '팬아웃 및 수집'에 ParallelAgent 사용

ParallelAgent는 모든 하위 에이전트를 동시에 실행하는 워크플로 에이전트입니다. 이는 두 가지 서로 다른 연구 작업을 실행하는 것과 같이 독립적인 하위 작업으로 나눌 수 있는 작업에 유용합니다.

ParallelAgent를 사용하여 병렬로 작동하는 '사전 제작팀'을 만듭니다. 한 상담사는 흥행 가능성을 조사하고 다른 상담사는 동시에 캐스팅 아이디어를 브레인스토밍합니다. 이를 '팬아웃 및 수집' 패턴이라고 합니다. ParallelAgent가 작업을 '팬아웃'하고 후속 에이전트 (file_writer)가 결과를 '수집'합니다.

Film_concept_team 멀티 에이전트 시스템 3단계

최종 에이전트 흐름은 다음과 같습니다.

  1. greeter (루트)가 채팅을 시작합니다.
  2. film_concept_team (SequentialAgent)로 전송되며, film_concept_team는 다음을 실행합니다.
    • 플롯을 만들 writers_room (LoopAgent)입니다.
    • 새로운 preproduction_team (ParallelAgent)를 사용하면 박스오피스와 캐스팅을 동시에 조사할 수 있습니다.
    • 모든 결과를 수집하고 파일을 저장하는 file_writer

변경하려면 다음 단계를 따르세요.

  1. adk_multiagent_systems/workflow_agents/agent.py에서 새 ParallelAgent와 하위 에이전트를 # Agents 헤더 아래에 붙여넣습니다.
    box_office_researcher = Agent(
        name="box_office_researcher",
        model=model_name,
        description="Considers the box office potential of this film",
        instruction="""
        PLOT_OUTLINE:
        { PLOT_OUTLINE? }
    
        INSTRUCTIONS:
        Write a report on the box office potential of a movie like that described in PLOT_OUTLINE based on the reported box office performance of other recent films.
        """,
        output_key="box_office_report"
    )
    
    casting_agent = Agent(
        name="casting_agent",
        model=model_name,
        description="Generates casting ideas for this film",
        instruction="""
        PLOT_OUTLINE:
        { PLOT_OUTLINE? }
    
        INSTRUCTIONS:
        Generate ideas for casting for the characters described in PLOT_OUTLINE
        by suggesting actors who have received positive feedback from critics and/or
        fans when they have played similar roles.
        """,
        output_key="casting_report"
    )
    
    preproduction_team = ParallelAgent(
        name="preproduction_team",
        sub_agents=[
            box_office_researcher,
            casting_agent
        ]
    )
    
  2. preproduction_team (writers_roomfile_writer 사이)을 포함하도록 film_concept_team SequentialAgentsub_agents 목록을 업데이트합니다. 기존 film_concept_team 정의를 다음으로 대체합니다.
    film_concept_team = SequentialAgent(
        name="film_concept_team",
        description="Write a film plot outline and save it as a text file.",
        sub_agents=[
            writers_room,
            preproduction_team,
            file_writer
        ],
    )
    
  3. 상태에서 새 보고서를 '수집'하고 파일에 추가하도록 file_writer 에이전트의 instruction를 업데이트합니다.
    file_writerinstruction 문자열을 다음으로 바꿉니다.
        instruction="""
        INSTRUCTIONS:
        - Create a marketable, contemporary movie title suggestion for the movie described in the PLOT_OUTLINE.
        If a title has been suggested in PLOT_OUTLINE, you can use it, or replace it with a better one.
        - Use your 'write_file' tool to create a new txt file with the following arguments:
        - for a filename, use the movie title
        - Write to the 'movie_pitches' directory.
        - For the 'content' to write, include:
        - The PLOT_OUTLINE
        - The BOX_OFFICE_REPORT
        - The CASTING_REPORT
    
        PLOT_OUTLINE:
        { PLOT_OUTLINE? }
    
        BOX_OFFICE_REPORT:
        { box_office_report? }
    
        CASTING_REPORT:
        { casting_report? }
        """,
    
  4. ADK 개발 UI 탭으로 돌아가서 + 새 세션을 클릭합니다.
  5. hello를 입력하여 대화를 시작합니다.
  6. 메시지가 표시되면 새로운 캐릭터 아이디어를 입력합니다. 다음은 몇 가지 아이디어입니다.
    • Wi-Fi 기술을 발명한 여배우
    • 흥미로운 셰프
    • 만국박람회 전시의 주요 참가자
  7. 에이전트가 작업을 완료하면 adk_multiagent_systems/movie_pitches 디렉터리에서 최종 파일을 검사합니다. 이제 줄거리, 박스오피스 보고서, 캐스팅 보고서가 모두 하나의 문서에 포함됩니다.

섹션 요약

이 섹션에서는 ParallelAgent를 사용하는 방법을 알아봤습니다.

  • ParallelAgent는 작업을 '팬아웃'하여 하위 에이전트를 순서대로 실행하는 대신 동시에 실행합니다.
  • 이는 서로 종속되지 않는 작업 (예: 두 가지 다른 주제 조사)에 매우 효율적입니다.
  • 병렬 에이전트의 결과는 후속 에이전트에 의해 '수집'됩니다. 이는 병렬 에이전트가 세션 상태에 작업을 저장하고 (output_key 사용) 최종 에이전트 (예: file_writer)가 해당 키를 읽도록 함으로써 이루어집니다.

13. 커스텀 워크플로 에이전트

SequentialAgent, LoopAgent, ParallelAgent의 사전 정의된 워크플로 에이전트가 요구사항을 충족하기에 부족한 경우 CustomAgent를 사용하면 유연하게 새로운 워크플로 로직을 구현할 수 있습니다.

흐름 제어, 조건부 실행 또는 하위 에이전트 간 상태 관리를 위한 패턴을 정의할 수 있습니다. 이는 복잡한 워크플로, 스테이트풀(Stateful) 조정 또는 커스텀 비즈니스 로직을 프레임워크의 조정 레이어에 통합하는 데 유용합니다.

CustomAgent 생성은 이 실습의 범위를 벗어나지만 필요할 경우 사용할 수 있다는 점을 알아두면 좋습니다.

14. 축하합니다.

Google 에이전트 개발 키트 (ADK)를 사용하여 정교한 멀티 에이전트 시스템을 빌드했습니다. 단순한 상위-하위 에이전트 관계에서 창작 프로젝트를 조사하고, 작성하고, 다듬을 수 있는 복잡한 자동화 워크플로를 오케스트레이션하는 단계로 발전했습니다.

요약

이 실습에서 다음 작업을 수행했습니다.

  • 상위 에이전트와 하위 에이전트 관계가 있는 계층적 트리로 에이전트를 구성합니다.
  • 자동 (description 사용) 및 명시적 (instruction 사용)으로 제어되는 에이전트 간 트랜스퍼
  • 도구를 사용하여 tool_context.state 사전에 데이터를 썼습니다.
  • 키 템플릿 (예: { PLOT_OUTLINE? })를 사용하여 세션 상태를 읽고 에이전트의 프롬프트를 안내합니다.
  • 간단한 단계별 워크플로 (조사 -> 작성 -> 저장)를 만들기 위해 SequentialAgent를 구현했습니다.
  • critic 에이전트 및 exit_loop 도구와 함께 LoopAgent를 사용하여 반복적인 개선 주기를 만들었습니다.
  • ParallelAgent를 사용하여 독립적인 작업 (예: 캐스팅 및 박스오피스 조사)을 동시에 실행하도록 '팬아웃'했습니다.

지속적인 실험

배운 내용을 활용하는 방법은 다양합니다. 다음은 참고할 수 있는 팁입니다.

  • 상담사 추가: preproduction_team ParallelAgent에 새 상담사를 추가해 보세요. 예를 들어 PLOT_OUTLINE를 기반으로 영화의 슬로건을 작성하는 marketing_agent를 만들 수 있습니다.
  • 도구 추가: researcher 에이전트에 더 많은 도구를 제공합니다. Google 검색 API를 사용하여 Wikipedia에 없는 정보를 찾는 도구를 만들 수 있습니다.
  • 탐색CustomAgent: 실습에서는 표준 템플릿에 맞지 않는 워크플로에 CustomAgent를 언급했습니다. 예를 들어 세션 상태에 특정 키가 있는 경우에만 조건부로 에이전트를 실행하는 에이전트를 빌드해 보세요.