Google ADK, A2A 및 Cloud Run을 활용한 멀티 에이전트 딥 리서치 도구 구축

발행: (2025년 12월 30일 오후 12:29 GMT+9)
12 min read
원문: Dev.to

Source: Dev.to

Source:

Introduction

Research는 무게가 실린 단어입니다. 단순히 키워드를 구글링하는 것이 아닙니다. 논문을 읽고, 사실을 검증하고, 그 하나의 완벽한 다이어그램을 찾아내며, 모든 것을 하나의 일관된 형태로 종합하는 과정입니다.

하나의 AI 에이전트에게 이 모든 작업을 순차적으로 시키는 것은 효율적이지 않습니다. 에이전트는 환각을 일으키고, 막히며, 확실히 느리게 동작합니다.

Deep Researcher Tool

TL;DR: 코드를 원하신다면 GitHub에 있는 Deep Research Agent 코드 를 확인하세요.

저는 “Recurrent Neural Networks의 역사”와 같은 주제를 받아서 포괄적이고 일러스트가 포함된 보고서를 생성할 수 있는 시스템을 원했습니다. 또한, Deep Research Tool을 처음부터 직접 만드는 방법도 배우고 싶었습니다.

첫 번째 시도는? 하나의 루프였습니다. 연구를 하고, 이미지를 찾고, 작업을 검토하는 순서였죠. 시간이 무한히 오래 걸렸습니다.

그래서 저는 물었습니다:

이걸 더 빠르게 만들 수 있을까?

이번 포스트에서는 Parallel Research Squad 를 구축합니다. 하나의 에이전트가 모든 일을 하는 대신, 세 개의 전문화된 에이전트를 동시에 실행하고, 중앙 Orchestrator 가 이를 조율하도록 합니다. 우리는 다음을 활용합니다:

Architecture Diagram

Part 1 – 에이전시 디자인 패턴

우리는 이제 더 이상 프롬프트만 작성하는 것이 아니라 시스템 엔지니어링을 하고 있습니다. 견고한 시스템을 구축하기 위해 세 가지 핵심 디자인 패턴을 활용합니다:

1. 오케스트레이터 패턴

모든 결정을 내리는 “갓 에이전트” 대신, 중앙 오케스트레이터를 둡니다—편집장이라고 생각하면 됩니다. 오케스트레이터는 기사를 직접 쓰지는 않으며, 기자에게 이야기를 할당하고, 상태를 관리하며, 오류를 처리하고, 최종 결과물이 마감일을 맞추도록 보장합니다.

2. 병렬화

이것이 우리의 속도 해킹입니다. 대부분의 에이전트 프레임워크는 순차적으로 실행됩니다 (Step A → Step B → Step C). 하지만 “ArXiv 논문 읽기”와 “이미지 검색”은 서로 독립적인 작업입니다. 이를 병렬로 실행하면 전체 지연 시간을 모든 작업을 합한 시간이 아니라 가장 오래 걸리는 작업의 시간으로 줄일 수 있습니다.

3. 평가‑최적화 패턴

첫 번째 초안은 신뢰하지 않습니다. 우리 시스템에는 Judge 에이전트가 포함되어 있습니다. 오케스트레이터는 연구 결과를 Judge에게 보내고, Judge는 엄격한 Pass/Fail 등급과 피드백을 반환합니다. 실패하면 오케스트레이터가 (Optimizer) 로 돌아가 부족한 부분을 수정합니다.

Sequential vs Parallel Processing

Part 2 – 속도 필요성 (병렬 실행)

AI 에이전트에서 가장 큰 병목 현상은 지연 시간입니다. 모델이 “생각”하고 웹을 탐색하는 데 시간이 걸립니다.

ADK를 사용하면 ParallelAgent를 구현합니다. 이것은 단순한 개념이 아니라 비동기 복잡성을 프레임워크가 처리해 주는 기본 요소입니다. ParallelAgent는 병렬로 실행되며, 오케스트레이터는 모든 에이전트가 끝날 때까지 기다렸다가 다음 단계로 넘어갑니다. 서로 의존하지 않는 에이전트를 병렬화하는 간단한 방법입니다.

# orchestrator/app/agent.py
from google.adk.agents import ParallelAgent

# The "Squad" runs together
research_squad = ParallelAgent(
    name="research_squad",
    description=(
        "Runs the researcher, academic scholar, and asset gatherer in parallel."
    ),
    sub_agents=[researcher, academic_scholar, asset_gatherer],
)

이 한 번의 변경만으로 전체 처리 시간이 60 % 감소했습니다. Scholar가 복잡한 PDF를 읽는 동안, Asset Gatherer는 이미 이미지 URL을 검증하고 있습니다.

A2A 핸드쉐이크

Part 3 – The Universal Language (A2A Protocol)

이 에이전트들은 어떻게 대화할까요? 각각은 별도의 마이크로서비스입니다. Researcher는 고메모리 인스턴스에서 실행될 수 있고, Orchestrator는 아주 작은 인스턴스에서 동작합니다.

우리는 Agent‑to‑Agent (A2A) Protocol을 사용합니다. 이는 JSON‑RPC 위에 구축된 AI 에이전트를 위한 표준화된 API입니다.

Why A2A?

  • Decoupling – Orchestrator는 Researcher가 어떻게 동작하는지 알 필요가 없으며, 어디에 있는지만 알면 됩니다.
  • Interoperability – Researcher를 Python으로, Judge를 Go로 작성할 수 있습니다. 두 서비스가 A2A를 사용한다면 협업이 가능합니다.
  • Service Discovery – 개발 단계에서는 에이전트를 localhost 포트에 매핑하고, 프로덕션에서는 Cloud Run URL(또는 기타 서비스 메시)로 매핑합니다.

TL;DR Implementation Checklist

  1. Define sub‑agents (researcher, academic_scholar, asset_gatherer, judge).
  2. Wrap them in a ParallelAgent (research_squad).
  3. Create an Orchestrator that:
    • Sends the topic to research_squad.
    • Receives the combined output.
    • Passes it to judge.
    • If the judge fails, triggers the Optimizer loop.
  4. Deploy each agent as an independent Cloud Run service exposing the A2A endpoint.
  5. Configure service discovery (environment variables or a service registry).

이러한 패턴을 사용하면 느리고 단일체인 “research bot”을 빠르고 확장 가능한 Parallel Research Squad으로 전환할 수 있으며, 고품질의 일러스트가 포함된 보고서를 안정적으로 생성할 수 있습니다. 즐거운 개발 되세요!

# orchestrator/app/agent.py
from google.adk.agents.remote_a2a_agent import RemoteA2aAgent

# The Orchestrator calls the remote Scholar service
academic_scholar = RemoteA2aAgent(
    name="academic_scholar",
    # In prod, this is an internal Cloud Run URL
    agent_card="http://scholar-service:8000/.well-known/agent.json",
    description="Searches for academic papers."
)

Scaling Graph

Source:

Part 4 – 인프라를 슈퍼파워로 (Cloud Run)

우리는 이 시스템을 Google Cloud Run에 배포합니다. 이를 통해 “식료품점” 스케일링 모델을 얻을 수 있습니다.

“식료품점” 모델

한 개의 계산대가 있는 식료품점을 상상해 보세요. 50명이 나타나면 줄이 문 밖까지 뻗어 나갑니다.

우리 시스템에서는 각 에이전트가 하나의 계산대 역할을 합니다.

  • Monolith: 하나의 계산대. 50개의 요청 = 50배의 대기 시간.
  • Cloud Run 위의 마이크로서비스: 50개의 요청 = Cloud Run이 Researcher 인스턴스 50개를 즉시 가동합니다. 모두 동시에 결제됩니다.

Scale to Zero

앱을 사용하는 사람이 없을 때는 0개의 인스턴스가 실행됩니다. 비용은 $0입니다. 이는 비용 효율적인 AI 애플리케이션에 매우 중요합니다.

Note: Cloud Run 서비스가 사용되지 않을 경우 자동으로 0으로 스케일 다운되며, 다음 요청 시 콜드 스타트가 필요합니다. 헬스 체크를 사용하면 서비스를 따뜻하게 유지할 수 있습니다.

Part 5 – 프론트엔드 (Next.js + Real‑Time)

We didn’t want a CLI tool; we wanted a product.
우리는 CLI 도구를 원하지 않았습니다; 제품을 원했습니다.

We built a Next.js frontend that connects to the Orchestrator. Because we know the architecture, we can visualize it. When the research_squad starts, our frontend shows three pulsing indicators side‑by‑side. You actually see the parallelism happening.
우리는 Orchestrator에 연결되는 Next.js 프론트엔드를 구축했습니다. 아키텍처를 알고 있기 때문에 이를 시각화할 수 있습니다. research_squad가 시작되면, 프론트엔드에 나란히 세 개의 펄싱 인디케이터가 표시됩니다. 실제로 병렬 처리가 진행되는 모습을 볼 수 있습니다.

It creates a sense of “liveness” and transparency that builds user trust.
이는 “실시간성”과 투명성을 느끼게 하여 사용자 신뢰를 구축합니다.

결론

우리의 모놀리스를 Parallel Research Squad(병렬 연구 팀)으로 분할함으로써 다음과 같은 시스템을 구축했습니다:

  • 더 빠르게: 병렬 실행으로 대기 시간이 50% 이상 단축됩니다.
  • 더 나은: 전문 에이전트(학자, 수집가)가 일반인 하나보다 더 깊이 있는 작업을 수행합니다.
  • 확장 가능하게: Cloud Run의 마이크로서비스가 무한에 가까운 부하를 처리합니다.

직접 구축하고 싶으신가요?

Back to Blog

관련 글

더 보기 »