Google ADK로 멀티에이전트 시스템을 구축할 때 두 가지 까다로운 함정
Source: Dev.to
부모‑에이전트 충돌
발생 상황
# Agents/my_app/root_agent.py
from Agents.my_app.sub_agent_a.agent import sub_agent_a
from Agents.my_app.sub_agent_b.agent import sub_agent_b
def _build_sub_agents() -> list:
return [sub_agent_a, sub_agent_b]
root_agent = LlmAgent(
name="my_app",
sub_agents=_build_sub_agents(),
# …
)
adk web로 로컬에서는 정상 동작합니다.- Cloud Run에서는 다음과 같이 충돌합니다:
pydantic_core._pydantic_core.ValidationError: 1 validation error for LlmAgent
Value error, Agent `SubAgentA` already has a parent agent,
current parent: `my_app`, trying to add: `my_app`
발생 원인
ADK의agent_loader가 매 요청마다importlib.import_module(agent_name)을 호출합니다.- 첫 번째 요청에서는 모듈이 로드되고
root_agent가 생성되며 각 서브‑에이전트는parent_agent = root_agent를 갖게 됩니다. - 두 번째 요청에서는 모듈이 다시 임포트되지만, 모듈 레벨 싱글톤인
sub_agent_a와sub_agent_b는 이전 로드에서 만든 같은 파이썬 객체이며 여전히 이전parent_agent를 보유하고 있습니다. - 새로운
LlmAgent가 다시parent_agent를 할당하려 할 때, 검증 로직이 오류를 발생시킵니다.
LlmAgent.__init__에서 간소화된 코드 조각:
for sub in sub_agents:
if sub.parent_agent is not None:
raise ValueError(f"Agent `{sub.name}` already has a parent agent ...")
sub.parent_agent = self
해결 방법
새로운 루트 에이전트를 만들기 전에 parent_agent 참조를 초기화합니다:
def _build_sub_agents() -> list:
agents = [sub_agent_a, sub_agent_b]
for agent in agents:
agent.parent_agent = None # 각 재로드 전에 초기화
return agents
할당은 동기적으로 이루어지며, 바로 뒤에서 새로운 부모가 설정되므로 안전합니다.
명령 문자열에서 컨텍스트 변수 찾을 수 없음
발생 상황
KeyError: 'Context variable not found: `hostname`.'
트레이스백은 google/adk/utils/instructions_utils.py를 가리키며, 여기서 ADK가 세션 상태를 명령 문자열에 주입합니다.
발생 원인
ADK는 정규식 r'{+[^{}]*}+'을 사용해 명령 텍스트를 스캔하고, 모든 {var_name}을 해당 세션‑스테이트 값으로 교체합니다. {word} 형태의 패턴은 변수가 아니라 문자 그대로 사용하고 싶어도 변수로 인식됩니다.
예시 명령:
The URL format is `https://{hostname}/api/{resource_id}/`
ADK는 {hostname}과 {resource_id}를 해석하려 시도하고, 세션에 존재하지 않으면 KeyError가 발생합니다.
중괄호를 두 개({{hostname}})로 이스케이프해도 정규식이 여전히 매치하기 때문에 동작하지 않습니다.
해결 방법
명령 문자열에서 리터럴 템플릿 텍스트에 중괄호를 사용하지 마세요. 대신 꺾쇠 괄호(<>), 대괄호([]), 혹은 일반 문장 형태를 사용합니다:
The URL format is `https:///api//`
{word} 패턴은 모두 세션 변수로 해석되므로, 실제 자리 표시자가 필요할 경우 “(또는 [word] 등) 로 대체하십시오.
두 가지 함정 요약
| 버그 | 트리거 | 해결책 |
|---|---|---|
| 부모‑에이전트 충돌 | 모듈‑레벨 싱글톤 서브‑에이전트 + 요청당 ADK 모듈 재로드 | 서브‑에이전트를 생성자에 전달하기 전에 agent.parent_agent = None 로 초기화 |
| 컨텍스트 변수 찾을 수 없음 | 명령 문자열 내 {word} 패턴 | 리터럴 자리 표시자로 “ 혹은 [word](또는 다른 비중괄호 구분자) 사용 |