Next ‘26 Developer Keynote: Building ADK Agents with Skills and Tools

1. Wprowadzenie

W tym ćwiczeniu utworzysz zaawansowanego agenta planowania maratonu za pomocą pakietu Agent Development Kit (ADK). Będziesz stopniowo poznawać możliwości agenta – od dobrze skonstruowanego prompta systemowego po dynamiczne wczytywanie umiejętności i mapowanie narzędzi MCP. Na koniec przetestujesz agenta lokalnie i wdrożysz go w Agent Runtime (Agent Engine).

Jakie zadania wykonasz

  • Zainicjujesz nowy projekt agenta ADK.
  • Utworzysz niezawodny prompt systemowy za pomocą strukturalnego kreatora.
  • Dodasz narzędzia MCP Map Google na potrzeby kontekstu lokalizacji w świecie rzeczywistym.
  • Będziesz dynamicznie wczytywać umiejętności do zestawu narzędzi agenta.
  • Przetestujesz wykonanie agenta lokalnie.
  • Wdrożysz agenta w Agent Engine (Cloud Run).

Czego potrzebujesz

  • Przeglądarka internetowa, np. Chrome.
  • Projekt Google Cloud z włączonymi rozliczeniami.
  • Podstawowa znajomość języka Python.

To ćwiczenie jest przeznaczone dla średnio zaawansowanych programistów, którzy chcą tworzyć wyspecjalizowane agenty generatywnej AI.

Szacowany czas trwania: 45 minut

Zasoby utworzone w tym ćwiczeniu powinny kosztować mniej niż 2 USD.

2. Zanim zaczniesz

Utwórz projekt Google Cloud

  1. W konsoli Google Cloud na stronie wyboru projektu wybierz lub utwórz projekt w chmurze Google Cloud.
  2. Sprawdź, czy w projekcie w chmurze włączone są płatności. Jak sprawdzić, czy w projekcie są włączone płatności.

Uruchamianie Cloud Shell

Cloud Shell to środowisko wiersza poleceń działające w Google Cloud, które jest wstępnie załadowane niezbędnymi narzędziami.

  1. U góry konsoli Google Cloud kliknij Aktywuj Cloud Shell.
  2. Po połączeniu z Cloud Shell sprawdź uwierzytelnianie:
    gcloud auth list
    
  3. Sprawdź, czy projekt jest skonfigurowany:
    gcloud config get project
    
  4. Jeśli projekt nie jest ustawiony zgodnie z oczekiwaniami, ustaw go:
    export PROJECT_ID=<YOUR_PROJECT_ID>
    gcloud config set project $PROJECT_ID
    

Sprawdź uwierzytelnianie:

gcloud auth list

Potwierdź projekt:

gcloud config get project

W razie potrzeby ustaw go:

export PROJECT_ID=<YOUR_PROJECT_ID>
gcloud config set project $PROJECT_ID

Włącz interfejsy API

Aby włączyć wszystkie wymagane interfejsy API, uruchom to polecenie:

gcloud services enable \
  aiplatform.googleapis.com \
  run.googleapis.com \
  secretmanager.googleapis.com \
  mapstools.googleapis.com \
  storage.googleapis.com \
  cloudresourcemanager.googleapis.com \
  serviceusage.googleapis.com

Utwórz klucz interfejsu API Map Google

Aby korzystać z narzędzi MCP Map Google, musisz wygenerować klucz interfejsu API Map Google.

  1. W konsoli Google Cloud użyj paska wyszukiwania, aby przejść do sekcji Google Maps Platform > Dane logowania.
  2. Jeśli pojawi się prośba, potwierdź projekt w chmurze Google Cloud.
  3. Kliknij Utwórz dane logowania i wybierz Klucz interfejsu API.
  4. Skopiuj wygenerowany klucz interfejsu API. Będzie on potrzebny w następnym kroku.

3. Konfigurowanie środowiska

W tym ćwiczeniu kod jest hostowany w GitHubie. Skopiujesz repozytorium, które zawiera strukturę katalogów i wymagane podkomponenty (np. katalog skills/).

  1. Skopiuj repozytorium i przejdź do folderu projektu:
git clone https://github.com/GoogleCloudPlatform/next-26-keynotes
cd next-26-keynotes/devkey/demo-1
  1. Skonfiguruj środowisko wirtualne Pythona i zainstaluj ADK:
uv venv
source .venv/bin/activate
uv sync
  1. Ustaw klucz interfejsu API Map Google. Aplikacja odczytuje go ze zmiennej środowiskowej:
export GOOGLE_MAPS_API_KEY="<YOUR_MAPS_API_KEY>"

Konfigurowanie zmiennych środowiskowych

Agent symulatora używa do konfiguracji pliku .env. Skopiuj przykładowy plik i zaktualizuj go o identyfikator projektu.

  1. Skopiuj przykładowy plik środowiska:
cp planner_agent/sample.env planner_agent/.env
  1. Otwórz plik planner_agent/.env i zaktualizuj pole GOOGLE_CLOUD_PROJECT o rzeczywisty identyfikator projektu Google Cloud, a pole GOOGLE_MAPS_API_KEY o utworzony klucz interfejsu API Map Google.

Plik powinien wyglądać podobnie do tego:

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. Tworzenie nowego agenta ADK

Zapoznaj się z głównym plikiem, który definiuje agenta: planner_agent/agent.py.

W repozytorium build-agents-with-skills agent jest inicjowany za pomocą klasy Agent pakietu ADK. Określa on model bazowy, nazwę tożsamości oraz pobiera instrukcje i narzędzia zdefiniowane w innych modułach.

Otwórz plik planner_agent/agent.py, aby sprawdzić kod inicjujący:

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
)

Klasa Agent abstrahuje historię wiadomości, koordynację narzędzi i komunikację z LLM, dzięki czemu możesz skupić się na zachowaniu agenta.

Obecnie agent jest bardzo ogólny. Możesz wchodzić z nim w interakcje tak jak z każdym innym LLM.

uv run adk run planner_agent

To polecenie rozpocznie czat z agentem. Używa on modelu gemini-3-flash-preview i może odpowiadać na podstawowe pytania.

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**.

Agent zna już pewne fakty dotyczące maratonów. Nie wystarczy to jednak do zaplanowania odpowiedniego maratonu z uwzględnieniem zasad i planowania trasy.

5. Tworzenie prompta systemowego

Prompty systemowe (instrukcje) określają zachowanie agenta. Zamiast jednego długiego ciągu znaków ten projekt używa klasy PromptBuilder (planner_agent/utils.py) do dynamicznego tworzenia instrukcji.

Otwórz plik planner_agent/prompts.py, aby zobaczyć, jak prompt jest podzielony na logiczne sekcje:

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()

W pliku planner_agent/agent.py jest on już zaimportowany.

Znajdź sekcję z tekstem TODO: Replace Instruction and Description i usuń znacznik komentarza z wierszy przypisujących wartości do zmiennych instruction i description.

Ta sekcja kodu powinna wyglądać tak:

instruction=PLANNER_INSTRUCTION_NO_TOOLS
description="Expert GIS analyst for marathon route and event planning."

Importujesz wersję prompta dla agenta, która nie odwołuje się do żadnych narzędzi. Narzędzia dodasz w późniejszym kroku.

Możesz przetestować tę wersję agenta:

uv run adk run planner_agent

W oknie czatu wyślij ten prompt:

Plan a marathon for 10000 participants in Las Vegas on April 24, 2027 in the
evening timeframe

Po chwili powinna pojawić się odpowiedź podobna do tej:

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).
...
...

Dzięki dobrze zdefiniowanemu promptowi dane wyjściowe są już znacznie bliższe oczekiwanemu wynikowi. W następnym kroku dodasz narzędzia, które pozwolą agentowi osiągnąć wyższy poziom.

6. Dodawanie umiejętności i narzędzi

Aby włączyć umiejętności i narzędzia w pliku planner_agent/agent.py, znajdź sekcję z tekstem TODO: Replaces Tools i usuń znacznik komentarza z następnych 2 wierszy. Kod powinien wyglądać tak:

instruction=PLANNER_INSTRUCTION
tools=get_tools()

To jedyna zmiana kodu wymagana w tym kroku. W pozostałej części tej sekcji wyjaśniono koncepcje umiejętności i narzędzi.

Umiejętności

Umiejętność agenta to samodzielna jednostka funkcjonalności, której agent ADK może używać do wykonywania określonego zadania. Umiejętność agenta zawiera niezbędne instrukcje, zasoby i narzędzia wymagane do wykonania zadania zgodnie ze specyfikacją umiejętności agenta. Struktura umiejętności umożliwia jej przyrostowe wczytywanie, co minimalizuje wpływ na okno kontekstu operacyjnego agenta.

W przypadku agenta planowania maratonu zdefiniowano 3 umiejętności:

  1. gis-spatial-engineering – odpowiada za przetwarzanie danych GeoJSON w celu utworzenia trasy maratonu.
  2. mapping – używa narzędzi Map Google do wyszukiwania miejsc i informacji o pogodzie.
  3. race-director – sprawdza, czy trasa maratonu jest zgodna z wytycznymi planowania.

Umiejętności mogą zawierać skrypty, dodatkowe zasoby i odniesienia.

Aplikacja wczytuje wszystkie umiejętności i udostępnia je jako narzędzia w pliku planner_agent/tools.py. Zwróć uwagę, jak to się robi w funkcji 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

Najciekawsza jest metoda load_skill_from_dir z pakietu ADK. Istnieje też inny sposób tworzenia umiejętności w ADK – wbudowany. Nie jest on używany w tym ćwiczeniu, ale wygląda mniej więcej tak:

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.",
        },
    ),
)

Dodawanie narzędzi do mapowania

Aby generować trasy, agent planowania maratonu potrzebuje kontekstu przestrzennego. Zapewnisz go, integrując serwer MCP (Model Context Protocol) Map Google.

W pliku planner_agent/tools.py zwróć uwagę, jak serwer MCP jest rejestrowany za pomocą narzędzia 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)]

Po dodaniu zestawu narzędzi MCP agent automatycznie zyskuje możliwość wysyłania zapytań do Map Google o szczegóły dotyczące tras, wysokości i lokalizacji.

7. Lokalne uruchamianie agenta

Teraz, gdy agent, prompt i narzędzia są połączone, uruchom agenta lokalnie. Tym razem użyjesz polecenia adk web, aby zobaczyć zdarzenia wczytywania umiejętności i wywoływania narzędzi.

uv run adk web

Powinien pojawić się ekran podobny do tego:

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)
  1. Otwórz przeglądarkę i wejdź na adres URL widoczny w terminalu (zwykle http://localhost:8000).
  2. W lewym górnym menu wybierz planner_agent.
  3. W oknie czatu wyślij ten prompt:
Plan a marathon for 10000 participants in Las Vegas on April 24, 2027 in the
evening timeframe

Powinny pojawić się informacje o wczytywaniu umiejętności i wywoływaniu narzędzi. Po chwili agent wygeneruje plan maratonu.

Interfejs powinien wyglądać podobnie do tego:

Internetowy interfejs ADK

8. Wdrażanie agenta

Gdy uznasz, że agent działa lokalnie prawidłowo, możesz wdrożyć go w Agent Engine, który bezpiecznie hostuje agenta w Cloud Run.

Aby wdrożyć agenta, użyj polecenia wdrożenia interfejsu ADK CLI:

uv run adk deploy agent_engine \
  --env_file planner_agent/.env --region=us-central1 \
  planner_agent

Po zakończeniu wdrożenia interfejs CLI wyświetli bezpiecznie hostowany punkt końcowy agenta. Możesz teraz zintegrować ten punkt końcowy z aplikacjami frontendowymi, chatbotami lub innymi systemami backendowymi. Możesz też użyć piaskownicy Agent Runtime, aby przetestować agenta.

Dane wyjściowe wyglądają tak:

Files and dependencies resolved
Deploying to agent engine...
✅ Created agent engine: projects/<PROJECT_ID>/locations/us-west1/reasoningEngines/<AGENT_ID>

Do komunikacji z agentem możesz użyć podanego skryptu w języku Python.

  1. Skopiuj przykładowy plik środowiska:
cp sample.env .env
  1. Otwórz plik .env i zaktualizuj pole GOOGLE_CLOUD_PROJECT o rzeczywisty identyfikator projektu Google Cloud.

Plik powinien wyglądać tak:

GOOGLE_CLOUD_PROJECT=<YOUR_PROJECT_ID>
GOOGLE_CLOUD_LOCATION=us-central1
  1. Możesz wyświetlić listę agentów w projekcie.
python main.py list

Powinien pojawić się ekran podobny do tego:

Listing deployed agents...

ID: <AGENT_ID> | Display Name: planner_agent

Gdy masz już wdrożony identyfikator agenta, możesz wysłać prompt:

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"

Otrzymasz dane wyjściowe podobne do tych:

Streaming response from agent <AGENT_ID>:

{'model_version': 'gemini-3-flash-preview', 'content': {'parts': [{'text': 'Here is a comprehensive
...
...
...

9. Zwalnianie miejsca

Aby uniknąć obciążenia konta Google Cloud bieżącymi opłatami, usuń zasoby utworzone podczas tego ćwiczenia.

Usuń usługę Cloud Run utworzoną przez wdrożenie:

python main.py delete --agent-id ${AGENT_ID}

Jeśli klucz interfejsu API Map Google został zapisany w usłudze Secret Manager, usuń obiekt tajny:

gcloud secrets delete maps-api-key --project=$PROJECT_ID

Jeśli na potrzeby tego ćwiczenia utworzono nowy projekt w chmurze Google, możesz usunąć cały projekt, aby usunąć wszystkie powiązane z nim zasoby i interfejsy API:

gcloud projects delete $PROJECT_ID

10. Gratulacje

Gratulacje! Udało Ci się utworzyć zaawansowanego agenta planowania maratonu za pomocą pakietu ADK.

Czego się nauczysz

  • Inicjowanie projektu pakietu Agent Development Kit (ADK).
  • Używanie klasy PromptBuilder do tworzenia modułowych promptów systemowych.
  • Integrowanie funkcji mapowania za pomocą narzędzi MCP i klasy ApiRegistry.
  • Warunkowe wczytywanie umiejętności za pomocą klasy SkillToolset.
  • Testowanie lokalne i wdrażanie w Agent Engine.

Przyszłe

  • Zapoznaj się z materiałami edukacyjnymi, aby tworzyć i wdrażać agenty klasy korporacyjnej za pomocą programu Gemini Enterprise Agent Ready.

Dokumentacja źródłowa