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

1. Wprowadzenie

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

Jakie zadania wykonasz

  • Zainicjuj nowy projekt agenta ADK.
  • Tworzenie za pomocą strukturalnego narzędzia do tworzenia złożonego prompta systemowego
  • Dodaj narzędzia MCP Map Google, aby uzyskać kontekst lokalizacji w świecie rzeczywistym.
  • Dynamiczne wczytywanie umiejętności do zestawu narzędzi agenta
  • Testowanie wykonywania agenta lokalnie
  • Wdróż agenta w Agent Engine (Cloud Run).

Czego potrzebujesz

  • przeglądarka, np. Chrome;
  • projekt Google Cloud z włączonymi płatnościami;
  • podstawowa znajomość Pythona,

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

Szacowany czas trwania: 45 minut

Zasoby utworzone w tym laboratorium powinny kosztować mniej niż 2 PLN.

2. Zanim zaczniesz

Tworzenie projektu Google Cloud

  1. W konsoli Google Cloud na stronie selektora projektu wybierz lub utwórz projekt w chmurze Google.
  2. Sprawdź, czy w projekcie Cloud włączone są płatności. Dowiedz się, 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 zawiera niezbędne narzędzia.

  1. Kliknij Aktywuj Cloud Shell u góry konsoli Google Cloud.
  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
    

Potwierdź uwierzytelnianie:

gcloud auth list

Potwierdź projekt:

gcloud config get project

W razie potrzeby ustaw:

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

Tworzenie klucza interfejsu API Map Google

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

  1. W konsoli Google Cloud użyj paska wyszukiwania, aby przejść do Google Maps Platform > Dane logowania.
  2. W razie potrzeby potwierdź projekt w chmurze Google.
  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 na GitHubie. Sklonujesz repozytorium, które zawiera strukturę katalogów i wymagane podkomponenty (np. katalog skills/).

  1. Sklonuj 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 plik przykładowy i zaktualizuj go, podając identyfikator projektu.

  1. Skopiuj przykładowy plik środowiska:
cp planner_agent/sample.env planner_agent/.env
  1. Otwórz planner_agent/.env i zaktualizuj pole GOOGLE_CLOUD_PROJECT, wpisując rzeczywisty identyfikator projektu Google Cloud, a w polu GOOGLE_MAPS_API_KEY wpisz 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=us-west1
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 definiującym agenta: planner_agent/agent.py.

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

Otwórz 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 od historii wiadomości, koordynacji narzędzi i komunikacji z LLM, dzięki czemu możesz skupić się na zachowaniu agenta.

Obecnie agent jest bardzo ogólny. Możesz z niej korzystać tak samo jak z innych dużych modeli językowych.

uv run adk run planner_agent

To polecenie rozpocznie czat z agentem. Korzysta z 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 na temat maratonów. Nie wystarczy to jednak do zaplanowania odpowiedniego maratonu z regułami i planowaniem trasy.

5. Tworzenie prompta systemowego

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

Otwórz 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 planner_agent/agent.py ten plik został już zaimportowany.

Znajdź sekcję z symbolem TODO: Replace Instruction and Description i usuń znacznik komentarza z ponownego przypisania zmiennych instructiondescription.

Ta część kodu powinna wyglądać tak:

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

Importujesz wersję promptu 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 wynik jest już znacznie bliższy oczekiwanemu. W następnym kroku dodasz narzędzia, które pozwolą Ci rozwinąć możliwości agenta.

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

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

instruction=PLANNER_INSTRUCTION
tools=get_tools()

To jedyna zmiana kodu wymagana na tym etapie. W dalszej części tej sekcji znajdziesz wyjaśnienie pojęć związanych z umiejętnościami i narzędziami.

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 obejmuje niezbędne instrukcje, zasoby i narzędzia wymagane do wykonania zadania zgodnie ze specyfikacją umiejętności agenta. Struktura funkcji umożliwia jej stopniowe wczytywanie, co minimalizuje wpływ na okno kontekstu operacyjnego agenta.

W przypadku agenta planującego maraton zdefiniowano 3 umiejętności:

  1. gis-spatial-engineering – odpowiada za przetwarzanie danych GeoJSON w celu utworzenia trasy maratonu.
  2. mapowanie – korzystaj z 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ą mieć skrypty, dodatkowe komponenty i pliki referencyjne.

Aplikacja wczytuje wszystkie umiejętności i udostępnia je jako narzędzia w planner_agent/tools.py. Zwróć uwagę, jak to jest zrobione w get_tools() funkcji:

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 load_skill_from_dir metoda z pakietu ADK. Istnieje jeszcze jeden sposób tworzenia umiejętności w pakiecie ADK – w linii. Nie jest on używany w tym laboratorium, 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

Planer maratonu potrzebuje kontekstu przestrzennego, aby generować trasy. Możesz to zrobić, integrując serwer MCP (Model Context Protocol) Map Google.

Na ilustracji planner_agent/tools.py widać, jak serwer MCP jest zarejestrowany 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 wyznaczania trasy, wysokości i lokalizacji.

7. Uruchamianie agenta lokalnie

Teraz, gdy agent, prompt i narzędzia są ze sobą połączone, uruchom agenta lokalnie. Tym razem użyjesz adk web, aby zobaczyć zdarzenia związane z obciążeniem umiejętności i wywołaniem narzędzia.

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 przejdź do adresu URL wyświetlanego w terminalu (zwykle http://localhost:8000).
  2. W menu w lewym górnym rogu kliknij 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 się wyświetlić wczytywane umiejętności i wywoływane narzędzia. 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 w odpowiedni sposób, możesz wdrożyć go w Agent Engine, który bezpiecznie hostuje agenta w Cloud Run.

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

uv run adk deploy agent_engine \
  --env_file planner_agent/.env \
  planner_agent

Po zakończeniu wdrażania interfejs wiersza poleceń 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ż przetestować agenta w Agent Runtime Playground.

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

  1. Skopiuj przykładowy plik środowiska:
cp sample.env .env
  1. Otwórz .env i zaktualizuj pole GOOGLE_CLOUD_PROJECT, wpisując w nim rzeczywisty identyfikator projektu Google Cloud.

Plik powinien wyglądać tak:

GOOGLE_CLOUD_PROJECT=<YOUR_PROJECT_ID>
GOOGLE_CLOUD_LOCATION=us-west1
  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 uzyskasz 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. Czyszczenie danych

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 do wykonania zadań z tego ćwiczenia w Codelabs posłużył Ci nowy, specjalnie utworzony projekt w chmurze Google Cloud, możesz go usunąć w całości, aby usunąć wszystkie powiązane z nim zasoby i interfejsy API:

gcloud projects delete $PROJECT_ID

10. Gratulacje

Gratulacje! Za pomocą pakietu ADK udało Ci się utworzyć zaawansowanego agenta Planera maratonu.

Czego się dowiedziałeś(-aś)

  • Inicjowanie projektu pakietu Agent Development Kit (ADK)
  • Używanie symbolu PromptBuilder w promptach systemu modułowego
  • Integracja funkcji mapowania za pomocą narzędzi MCP i ApiRegistry
  • Warunkowe wczytywanie umiejętności za pomocą SkillToolset
  • Testowanie lokalne i wdrażanie w Agent Engine

Dokumentacja