1. 소개
이 Codelab에서는 에이전트 개발 키트 (ADK)를 사용하여 정교한 마라톤 플래너 에이전트 를 빌드합니다. 잘 구성된 시스템 프롬프트부터 동적 기술 로드 및 매핑 MCP 도구까지 에이전트의 기능을 점진적으로 살펴봅니다. 마지막으로 에이전트를 로컬에서 테스트하고 에이전트 런타임 (Agent Engine)에 배포합니다.
실습할 내용
- 새 ADK 에이전트 프로젝트 초기화
- 구조화된 빌더를 사용하여 강력한 시스템 프롬프트 작성
- 실제 위치 컨텍스트를 위한 Google 지도 MCP 도구 추가
- 에이전트의 도구 모음에 기술 로드 동적으로
- 로컬에서 에이전트 실행 테스트
- Agent Engine (Cloud Run)에 에이전트 배포
필요한 항목
- 웹브라우저(예: Chrome)
- 결제가 사용 설정된 Google Cloud 프로젝트
- Python에 대한 기본적인 이해
이 Codelab은 전문 생성형 AI 에이전트를 빌드하려는 중급 개발자를 위한 것입니다.
예상 소요 시간: 45분
이 Codelab에서 만든 리소스의 비용은 $2 미만이어야 합니다.
2. 시작하기 전에
Google Cloud 프로젝트 만들기
- Google Cloud 콘솔의 프로젝트 선택기 페이지에서 Google Cloud 프로젝트를 선택하거나 만듭니다.
- Cloud 프로젝트에 결제가 사용 설정되어 있는지 확인합니다. 프로젝트에 결제가 사용 설정되어 있는지 확인하는 방법을 알아보세요.
Cloud Shell 시작
Cloud Shell 은 Google Cloud에서 실행되는 명령줄 환경으로, 필요한 도구가 미리 로드되어 있습니다.
- Google Cloud 콘솔 상단에서 Cloud Shell 활성화 를 클릭합니다.
- Cloud Shell에 연결되면 인증을 확인합니다.
gcloud auth list - 프로젝트가 구성되었는지 확인합니다.
gcloud config get project - 프로젝트가 예상대로 설정되지 않은 경우 설정합니다.
export PROJECT_ID=<YOUR_PROJECT_ID> gcloud config set project $PROJECT_ID
인증 확인
gcloud auth list
프로젝트 확인하기
gcloud config get project
필요한 경우 설정합니다.
export PROJECT_ID=<YOUR_PROJECT_ID> gcloud config set project $PROJECT_ID
API 사용 설정
이 명령어를 실행하여 필요한 모든 API를 사용 설정합니다.
gcloud services enable \ aiplatform.googleapis.com \ run.googleapis.com \ secretmanager.googleapis.com \ mapstools.googleapis.com \ storage.googleapis.com \ cloudresourcemanager.googleapis.com \ serviceusage.googleapis.com
Google 지도 API 키 만들기
Google 지도 MCP 도구를 사용하려면 지도 API 키를 생성해야 합니다.
- Google Cloud 콘솔에서 검색창을 사용하여 Google Maps Platform > 사용자 인증 정보 로 이동합니다.
- 메시지가 표시되면 Google Cloud 프로젝트를 확인합니다.
- 사용자 인증 정보 만들기 를 클릭한 후 API 키 를 선택합니다.
- 생성된 API 키를 복사합니다. 다음 단계에 이 항목이 필요합니다.
3. 환경 설정
이 Codelab의 코드는 GitHub에서 호스팅됩니다. 디렉터리 구조와 필요한 하위 구성요소 (예: skills/ 디렉터리)가 포함된 저장소를 클론합니다.
- 저장소를 클론하고 프로젝트 폴더로 이동합니다.
git clone https://github.com/GoogleCloudPlatform/next-26-keynotes cd next-26-keynotes/devkey/demo-1
- Python 가상 환경을 설정하고 ADK를 설치합니다.
uv venv source .venv/bin/activate uv sync
- 지도 API 키를 설정합니다. 애플리케이션은 환경 변수에서 이를 읽습니다.
export GOOGLE_MAPS_API_KEY="<YOUR_MAPS_API_KEY>"
환경 변수 구성
시뮬레이터 에이전트는 구성에 .env 파일을 사용합니다. 샘플 파일을 복사하고 프로젝트 ID로 업데이트합니다.
- 샘플 환경 파일을 복사합니다.
cp planner_agent/sample.env planner_agent/.env
planner_agent/.env를 열고GOOGLE_CLOUD_PROJECT필드를 실제 Google Cloud 프로젝트 ID로 업데이트하고GOOGLE_MAPS_API_KEY필드를 만든 Google 지도 API 키로 업데이트합니다.
파일은 다음과 비슷하게 표시됩니다.
GOOGLE_GENAI_USE_VERTEXAI=1
GOOGLE_CLOUD_PROJECT=<YOUR_PROJECT_ID>
GOOGLE_CLOUD_LOCATION=global
GOOGLE_MAPS_API_KEY=<YOUR_MAPS_API_KEY>
GOOGLE_CLOUD_AGENT_ENGINE_ENABLE_TELEMETRY=true
OTEL_PYTHON_LOGGING_AUTO_INSTRUMENTATION_ENABLED=true
OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=true
ADK_CAPTURE_MESSAGE_CONTENT_IN_SPANS=true
4. 새 ADK 에이전트 만들기
에이전트를 정의하는 핵심 파일인 planner_agent/agent.py를 살펴봅니다.
build-agents-with-skills 저장소에서 에이전트는 ADK의 Agent 클래스를 사용하여 초기화됩니다. 기본 모델, ID 이름을 지정하고 다른 모듈에 정의된 안내 및 도구를 가져옵니다.
planner_agent/agent.py를 열어 초기화 코드를 살펴봅니다.
instruction="Answer user questions to the best of your knowledge"
description="A helpful assistant for user questions."
tools=[]
# ...
root_agent = Agent(
model='gemini-3-flash-preview',
name='planner_agent',
description=description,
instruction=instruction,
tools=tools
)
Agent 클래스는 메시지 기록, 도구 조정, LLM 통신을 추상화하여 에이전트의 동작에 집중할 수 있도록 합니다.
현재 에이전트는 매우 일반적입니다. 다른 LLM과 마찬가지로 상호작용할 수 있습니다.
uv run adk run planner_agent
이 명령어는 에이전트와의 채팅을 시작합니다. gemini-3-flash-preview를 모델로 사용하며 기본적인 질문에 답변할 수 있습니다.
Running agent planner_agent, type exit to exit.
[user]: What is the length of a Marathon
[planner_agent]: The official length of a marathon is **26.2 miles**, which is
equivalent to **42.195 kilometers**.
에이전트는 이미 마라톤에 관한 몇 가지 사실을 알고 있습니다. 하지만 규칙 및 경로 계획을 포함한 적절한 마라톤을 계획하기에는 충분하지 않습니다.
5. 시스템 프롬프트 만들기
시스템 프롬프트 (안내)는 에이전트의 동작을 지시합니다. 이 프로젝트는 단일 거대 문자열 대신 PromptBuilder (planner_agent/utils.py)를 사용하여 안내를 동적으로 작성합니다.
planner_agent/prompts.py를 열어 프롬프트가 논리적 섹션으로 구성되는 방식을 확인합니다.
from collections import OrderedDict
from .utils import PromptBuilder
ROLE = """\
...
"""
RULES = """\
...
"""
WORKFLOW = """\
...
"""
###
# Planner instructions with no tools mentioned
PLANNER_INSTRUCTION_NO_TOOLS = PromptBuilder(
OrderedDict(
role=ROLE,
rules=RULES,
tools=TOOLS_PROMPT_ONLY,
workflow=WORKFLOW_PROMPT_ONLY,
)
).build()
# Planner instruction with skills and tools defined
PLANNER_INSTRUCTION = PromptBuilder(
OrderedDict(
role=ROLE,
rules=RULES,
skills=SKILLS,
tools=TOOLS,
workflow=WORKFLOW,
)
).build()
planner_agent/agent.py에서 이미 가져왔습니다.
TODO: Replace Instruction and Description 섹션을 찾아 instruction 및 description 변수 재할당의 주석 처리를 삭제합니다.
코드의 해당 섹션은 다음과 같습니다.
instruction=PLANNER_INSTRUCTION_NO_TOOLS
description="Expert GIS analyst for marathon route and event planning."
도구를 참조하지 않는 에이전트의 프롬프트 버전을 가져오고 있습니다. 나중에 도구를 추가합니다.
이 버전의 에이전트를 테스트할 수 있습니다.
uv run adk run planner_agent
채팅 창에서 다음 프롬프트를 보냅니다.
Plan a marathon for 10000 participants in Las Vegas on April 24, 2027 in the
evening timeframe
잠시 후에 다음과 비슷한 응답이 표시됩니다.
Running agent planner_agent, type exit to exit.
[user]: Plan a marathon for 10000 participants in Las Vegas on April 24, 2027 in the evening timeframe
[planner_agent]: Here is the comprehensive marathon plan for Las Vegas.
As requested, I have designed this event for an evening start on April 24, 2027. Because certain parameters (theme and budget) were not specified, I have applied pragmatic defaults: this will be a "Neon Nights" scenic theme to capitalize on the evening Strip, operating on a moderate-to-high budget given the infrastructure needed to secure major Las Vegas corridors.
### 1. Intent Alignment
* **City & Theme:** Las Vegas, Nevada. Theme: "Neon Nights" an evening race maximizing the visual impact of the illuminated city.
* **Date & Time:** Saturday, April 24, 2027. Late April evenings in Las Vegas offer optimal running weather (temperatures dropping from ~70°F at sunset to ~60°F). Race start is 6:30 PM (sunset is approx. 7:20 PM).
...
...
잘 정의된 프롬프트를 사용하면 출력이 이미 예상 결과에 훨씬 더 가깝습니다. 다음 단계에서는 에이전트를 한 단계 더 발전시키기 위해 도구를 추가합니다.
6. 기술 및 도구 추가
planner_agent/agent.py에서 기술 및 도구를 사용 설정하려면 TODO: Replaces Tools 섹션을 찾아 다음 두 줄의 주석 처리를 삭제합니다. 코드는 다음과 같습니다.
instruction=PLANNER_INSTRUCTION
tools=get_tools()
이 단계에서 필요한 코드 변경사항은 이것이 전부입니다. 이 섹션의 나머지 부분에서는 기술 및 도구의 개념을 설명합니다.
특기
에이전트 기술은 ADK 에이전트가 특정 작업을 실행하는 데 사용할 수 있는 자체 포함된 기능 단위입니다. 에이전트 기능은 에이전트 기능 사양에 따라 작업에 필요한 안내, 리소스, 도구를 캡슐화합니다. 기능의 구조를 사용하면 에이전트의 운영 컨텍스트 윈도우에 미치는 영향을 최소화하기 위해 기능을 점진적으로 로드할 수 있습니다.
마라톤 계획 에이전트의 경우 다음과 같은 3가지 기술이 정의되어 있습니다.
- gis-spatial-engineering - GeoJSON 데이터를 처리하여 마라톤 경로를 만듭니다.
- 매핑 - Google 지도 도구를 사용하여 장소 및 날씨 정보를 검색합니다.
- race-director - 마라톤 경로가 계획 가이드라인을 따르는지 확인합니다.
기술에는 스크립트, 추가 애셋, 참조가 있을 수 있습니다.
애플리케이션은 모든 기술을 로드하고 planner_agent/tools.py에서 도구로 제공합니다. get_tools() 함수에서 이 작업이 어떻게 이루어지는지 확인합니다.
def get_tools() -> list:
"""Build the planner's tool list with lazy-loaded skills."""
from google.adk.code_executors.unsafe_local_code_executor import UnsafeLocalCodeExecutor
skills_dir = pathlib.Path(__file__).parent / "skills"
skills = []
if skills_dir.exists():
skills = [
load_skill_from_dir(d)
for d in sorted(skills_dir.iterdir())
if d.is_dir() and not d.name.startswith("_") and (d / "SKILL.md").exists()
]
additional_tools = _load_additional_tools(skills_dir)
skill_toolset = SkillToolset(
skills=skills,
code_executor=UnsafeLocalCodeExecutor(),
additional_tools=additional_tools,
)
tools = [
skill_toolset,
PreloadMemoryTool(),
]
tools.extend(get_maps_tools())
return tools
가장 흥미로운 부분은 ADK의 load_skill_from_dir 메서드입니다. ADK에서 기술을 만드는 또 다른 방법은 인라인입니다. 이 Codelab에서는 사용되지 않지만 다음과 같습니다.
from google.adk.skills import models
greeting_skill = models.Skill(
frontmatter=models.Frontmatter(
name="greeting-skill",
description=(
"A friendly greeting skill that can say hello to a specific person."
),
),
instructions=(
"Step 1: Read the 'references/hello_world.txt' file to understand how"
" to greet the user. Step 2: Return a greeting based on the reference."
),
resources=models.Resources(
references={
"hello_world.txt": "Hello! So glad to have you here!",
"example.md": "This is an example reference.",
},
),
)
매핑 도구 추가
마라톤 플래너는 경로를 생성하기 위해 공간 컨텍스트가 필요합니다. Google 지도 MCP (모델 컨텍스트 프로토콜) 서버를 통합하여 이를 제공합니다.
planner_agent/tools.py에서 MCP 서버가 ApiRegistry 도구에 등록되는 방식을 확인합니다.
from google.adk.integrations.api_registry import ApiRegistry
class MapsApiRegistry(ApiRegistry):
"""ApiRegistry subclass that strips ADC headers to force API key auth."""
def get_toolset(self, *args, **kwargs): # noqa: ANN002, ANN003
toolset = super().get_toolset(*args, **kwargs)
conn = getattr(toolset, "_connection_params", None)
headers = getattr(conn, "headers", None) if conn else None
if headers:
headers.pop("Authorization", None) # type: ignore[union-attr]
headers.pop("x-goog-user-project", None) # type: ignore[union-attr]
return toolset
def get_maps_tools() -> list:
"""Return Maps MCP toolset if configured."""
project_id = os.getenv("GOOGLE_CLOUD_PROJECT", "").strip()
maps_key = _resolve_maps_key()
if not project_id or not maps_key:
return []
# Map the MCP server location on Google Cloud
mcp_server_name = f"projects/{project_id}/locations/global/mcpServers/google-mapstools.googleapis.com-mcp"
# Initialize the custom API registry that supports header injection
api_registry = MapsApiRegistry(
api_registry_project_id=project_id,
header_provider=header_provider,
)
return [api_registry.get_toolset(mcp_server_name=mcp_server_name)]
MCP 도구 모음을 추가하면 에이전트가 Google 지도에 경로, 고도, 위치 세부정보를 자동으로 쿼리할 수 있습니다.
7. 로컬에서 에이전트 실행
이제 에이전트, 프롬프트, 도구가 연결되었으므로 로컬에서 에이전트를 실행합니다. 이번에는 adk web을 사용하여 기능 로드 및 도구 호출 이벤트를 볼 수 있습니다.
uv run adk web
다음과 비슷한 내용이 표시됩니다.
INFO: Started server process [99665]
INFO: Waiting for application startup.
+-----------------------------------------------------------------------------+
| ADK Web Server started |
| |
| For local testing, access at http://127.0.0.1:8000. |
+-----------------------------------------------------------------------------+
INFO: Application startup complete.
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
- 브라우저를 열고 터미널에 표시된 URL (일반적으로
http://localhost:8000)로 이동합니다. - 왼쪽 상단의 드롭다운에서
planner_agent를 선택합니다. - 채팅 창에서 다음 프롬프트를 보냅니다.
Plan a marathon for 10000 participants in Las Vegas on April 24, 2027 in the
evening timeframe
기술이 로드되고 도구가 호출되는 것을 볼 수 있습니다. 잠시 후에 에이전트가 마라톤 계획을 생성합니다.
UI는 다음과 비슷하게 표시됩니다.

8. 에이전트 배포
에이전트가 로컬에서 실행되는 방식에 만족하면 Cloud Run에서 에이전트를 안전하게 호스팅하는 Agent Engine에 배포할 수 있습니다.
에이전트를 배포하려면 ADK CLI 배포 명령어를 사용합니다.
uv run adk deploy agent_engine \ --env_file planner_agent/.env --region=us-central1 \ planner_agent
배포가 완료되면 CLI는 에이전트의 안전하게 호스팅된 엔드포인트를 출력합니다. 이제 이 엔드포인트를 프런트엔드 애플리케이션, 챗봇 또는 기타 백엔드 시스템에 통합할 수 있습니다. Agent Runtime Playground를 사용하여 에이전트를 테스트할 수도 있습니다.
출력은 다음과 같이 표시됩니다.
Files and dependencies resolved Deploying to agent engine... ✅ Created agent engine: projects/<PROJECT_ID>/locations/us-west1/reasoningEngines/<AGENT_ID>
제공된 Python 스크립트를 사용하여 에이전트와 통신할 수 있습니다.
- 샘플 환경 파일을 복사합니다.
cp sample.env .env
.env를 열고GOOGLE_CLOUD_PROJECT필드를 실제 Google Cloud 프로젝트 ID로 업데이트합니다.
파일이 다음과 같이 표시됩니다.
GOOGLE_CLOUD_PROJECT=<YOUR_PROJECT_ID>
GOOGLE_CLOUD_LOCATION=us-central1
- 프로젝트에서 에이전트를 나열할 수 있습니다.
python main.py list
다음과 비슷한 내용이 표시됩니다.
Listing deployed agents... ID: <AGENT_ID> | Display Name: planner_agent
배포된 에이전트 ID가 있으면 프롬프트를 보낼 수 있습니다.
export AGENT_ID=<AGENT_ID>
python main.py prompt --agent-id ${AGENT_ID} --message "Plan a marathon for
10000 participants in Las Vegas on April 24, 2027 in the evening timeframe"
다음과 같은 출력이 표시됩니다.
Streaming response from agent <AGENT_ID>:
{'model_version': 'gemini-3-flash-preview', 'content': {'parts': [{'text': 'Here is a comprehensive
...
...
...
9. 정리
Google Cloud 계정에 지속적으로 비용이 청구되지 않도록 하려면 이 Codelab 중에 만든 리소스를 삭제합니다.
배포로 만든 Cloud Run 서비스를 삭제합니다.
python main.py delete --agent-id ${AGENT_ID}
Secret Manager에 지도 API 키를 저장한 경우 보안 비밀을 삭제합니다.
gcloud secrets delete maps-api-key --project=$PROJECT_ID
이 Codelab을 위해 새 Google Cloud 프로젝트를 만든 경우 전체 프로젝트를 삭제하여 연결된 모든 리소스와 API를 삭제할 수 있습니다.
gcloud projects delete $PROJECT_ID
10. 축하합니다
축하합니다. ADK를 사용하여 정교한 마라톤 플래너 에이전트를 빌드했습니다.
학습한 내용
- 에이전트 개발 키트 (ADK) 프로젝트 초기화
- 모듈식 시스템 프롬프트에
PromptBuilder활용 - MCP 도구 및
ApiRegistry를 사용하여 매핑 기능 통합 SkillToolset을 사용하여 기술 조건부 로드- 로컬에서 테스트하고 Agent Engine에 배포