Membangun Perencana Rute Balap Formula E Multi-Agen dengan ADK & A2A

1. 1. Ringkasan

Dalam codelab ini, Anda akan membangun sistem multi-agen yang mendesain sirkuit jalan raya Formula E dan mendapatkan persetujuan berdasarkan serangkaian aturan FIA yang disederhanakan.

Anda akan menggunakan agents-cli untuk membuat dua project Agent Development Kit (ADK) standar, lalu menulis bagian yang penting: satu Kemampuan Agen, tiga agen, dan satu evaluasi. Semua hal lainnya (tata letak project, server, dependensi, konfigurasi deployment) berasal dari CLI.

Baru mengenal Formula E?

Anda tidak perlu tahu tentang motorsport. Lima istilah ini sudah cukup:

  • Formula E: kejuaraan balap mobil listrik FIA. Sebagian besar balapan diadakan di sirkuit jalan raya sementara di pusat kota.
  • Homologasi: persetujuan resmi FIA bahwa sirkuit aman untuk balapan. Tidak ada homologasi, tidak ada balapan.
  • Pengereman regeneratif: saat mobil mengerem, motornya mengisi ulang daya baterai. Pengereman yang lebih keras memulihkan lebih banyak energi, sehingga aturan codelab ini meminta setidaknya satu zona pengereman berat.
  • Lapisan CAD: lapisan bernama dalam gambar desain sirkuit, seperti garis balap, jalur pit, dan pembatas. FIA memeriksa apakah parameter wajib ada.
  • Attack Mode: pengemudi mendapatkan peningkatan daya sementara dengan mengemudi melalui zona aktivasi yang ditempatkan di luar jalur balap.

Agen Anda memainkan kedua peran: satu mendesain sirkuit, dan dua memeriksanya untuk FIA.

Yang akan Anda buat

Arsitektur: dalam project track-planner, yang berjalan di Cloud Shell, agen track_planner menggunakan get_track_topology, fia_assessor, dan remote_gatekeeper. remote_gatekeeper memanggil agen gatekeeper melalui A2A. Dalam project gatekeeper, yang berjalan di Agent Runtime, agen gatekeeper menggunakan verify_infrastructure_checklist.

Kotak hijau adalah agen dan kotak putus-putus adalah alatnya, sama seperti cara playground ADK menggambarnya. Dua alat menggabungkan agen lain: fia_assessor adalah agen FIA Assessor dengan keterampilan kepatuhan FIA, dan remote_gatekeeper memanggil agen Gatekeeper di project lain melalui A2A.

Agen

Project

Tugas

thinking_level

Lead Architect

track-planner

Membaca lokasi, bertanya kepada Penilai, memperbaiki masalah, meminta persetujuan Penjaga Gerbang

HIGH

Penilai FIA

track-planner

Memeriksa tata letak menggunakan keterampilan FIA dan alat penilaian

MEDIUM

Penjaga Gerbang Model Digital Akurat

gatekeeper

Menjalankan checklist homologasi akhir

LOW

Yang akan Anda pelajari

  • Cara agents-cli scaffold create menyusun project ADK, dan file yang Anda edit.
  • Cara mengemas pengetahuan domain sebagai Agent Skill (SKILL.md, references/, scripts/) dan memuatnya dengan SkillToolset ADK.
  • Cara mencocokkan thinking_level dengan tugas setiap agen.
  • Cara mengevaluasi agen dengan agents-cli eval run.
  • Cara men-deploy agen ke Agent Runtime, perbedaan Identitas Agen dengan akun layanan, dan cara memanggil agen yang di-deploy melalui protokol A2A.

2. 2. Menyiapkan lingkungan Anda

Sebelum memulai

Anda memerlukan project Google Cloud dengan penagihan yang diaktifkan. Jika Anda mengikuti codelab ini di suatu acara, gunakan akun dan project yang diberikan kepada Anda.

Membuka Cloud Shell dan menetapkan project Anda

Buka Cloud Shell, lalu jalankan:

# Cloud Shell sometimes opens without a project set. If so, this sets it to
# the first project on your account.
if [ -z "$(gcloud config get-value project 2>/dev/null)" ]; then
  gcloud config set project "$(gcloud projects list --format='value(projectId)' --limit=1)"
fi

export GOOGLE_CLOUD_PROJECT="$(gcloud config get-value project)"
export REGION="us-central1"
export ASSETS="$HOME/devrel-demos/codelabs/formula-e-track-planner"
echo "Project: $GOOGLE_CLOUD_PROJECT  Region: $REGION"

Membuat kredensial untuk agen Anda

gcloud sudah login, tetapi kode Python yang dijalankan agen Anda menggunakan Kredensial Default Aplikasi (ADC), yang memerlukan login terpisah:

gcloud auth application-default login

Buka link yang ditampilkan, login dengan akun yang sama, salin kodenya, dan tempelkan kembali ke Cloud Shell. Kemudian, tetapkan project yang akan ditagih kuota:

gcloud auth application-default set-quota-project "$GOOGLE_CLOUD_PROJECT"

Mengaktifkan API

gcloud services enable \
    aiplatform.googleapis.com \
    cloudbuild.googleapis.com \
    artifactregistry.googleapis.com \
    storage.googleapis.com \
    cloudresourcemanager.googleapis.com \
    serviceusage.googleapis.com \
    compute.googleapis.com \
    iam.googleapis.com \
    logging.googleapis.com \
    cloudtrace.googleapis.com

Fungsi setiap API:

API

Digunakan untuk

aiplatform

Model Gemini dan Agent Runtime

cloudresourcemanager, serviceusage, iam

Pemeriksaan project dan izin yang dijalankan gcloud dan agents-cli deploy

compute

Membuat akun layanan default Compute Engine yang digunakan oleh deployment di Langkah 7

storage, logging, cloudtrace

Penyimpanan, log, dan trace, seperti yang direkomendasikan dalam panduan penyiapan Agent Runtime

cloudbuild, artifactregistry

Build dan image container, yang disertakan sebagai tindakan pencegahan untuk deployment di Langkah 7

Banyak project yang telah mengaktifkan beberapa fitur ini. Mengaktifkan API yang sudah aktif tidak akan mengubah apa pun.

Menginstal uv dan agents-cli

curl -LsSf https://astral.sh/uv/install.sh | sh
export PATH="$HOME/.local/bin:$PATH"
uv tool install google-agents-cli==1.10.0
agents-cli --version

Codelab ini diuji dengan agents-cli 1.10.0, jadi instal versi tersebut untuk mendapatkan file yang dihasilkan yang sama.

3. 3. Membuat scaffold project dan menambahkan aset

Membuat kedua project

agents-cli scaffold create akan menghasilkan project ADK lengkap yang dapat di-deploy. Jalankan dua kali, sekali untuk setiap sistem agen.

Pertama, perencana jalur:

cd ~
agents-cli scaffold create track-planner \
  --agent adk \
  --deployment-target agent_runtime \
  --region "$REGION" \
  --prototype \
  --yes

Kemudian, penjaga gerbang:

cd ~
agents-cli scaffold create gatekeeper \
  --agent adk \
  --deployment-target agent_runtime \
  --region "$REGION" \
  --prototype \
  --yes

Bendera

Arti

--agent adk

Mulai dari template ADK Python

--deployment-target agent_runtime

Membuat server dan konfigurasi untuk Agent Runtime

--prototype

Lewati CI/CD; buat project tetap minimal

--yes

Menerima setelan default tanpa perintah

Mempelajari tata letak

Project yang dihasilkan akan terlihat seperti ini. Anda hanya mengedit file yang ditandai ✍️:

track-planner/
├── agents-cli-manifest.yaml   # Records the template, deployment target and root agent name
├── pyproject.toml             # Dependencies (google-adk, a2a-sdk, ...)
├── .env                       # Your project and model location, filled in for you
├── Dockerfile                 # Used by `agents-cli deploy`; copies app/ into the image
├── app/
│   ├── agent.py               # ✍️ Your agents
│   ├── fast_api_app.py        # Generated server: ADK API, A2A routes, Agent Runtime routes
│   └── app_utils/             # Generated helpers (A2A, sessions)
└── tests/
    ├── unit/                  # Fast tests with no model calls
    ├── integration/           # Generated server tests
    └── eval/                  # ✍️ eval_config.yaml and datasets for `agents-cli eval`

Untuk deskripsi setiap file yang dihasilkan, lihat Struktur project dalam panduan Agents CLI.

Mencoba agen yang dihasilkan

Sebelum mengubah apa pun, jalankan agen template untuk melihat apa yang diberikan scaffold kepada Anda. Instal dependensi dan mulai playground lokal di port 8080:

cd ~/track-planner
agents-cli install
agents-cli playground --port 8080

Untuk membukanya, klik tombol Web Preview di toolbar Cloud Shell (ikon mata di kanan atas), lalu pilih Preview on port 8080.

Di playground, ajukan pertanyaan kepada agen template yang dapat dijawab oleh alatnya, misalnya:

What's the weather in San Francisco?

Panel samping menampilkan setiap peristiwa, termasuk panggilan alat get_weather dan hasilnya. Anda akan menggunakan tampilan yang sama nanti untuk mengikuti agen Anda sendiri.

Setelah selesai, kembali ke terminal dan tekan Ctrl+C untuk menghentikan playground.

Menambahkan aset Formula E

Data lokasi, aturan FIA, skrip fisika, alat, dan set data evaluasi bukan bagian dari pelajaran, jadi Anda menyalinnya dari GitHub, bukan mengetiknya:

cd ~
git clone --depth 1 --filter=blob:none --sparse \
  --branch formula-e-lab-v1 \
  https://github.com/tdsymonds/devrel-demos.git
git -C devrel-demos sparse-checkout set codelabs/formula-e-track-planner

cp -r "$ASSETS/track-planner/." ~/track-planner/
cp -r "$ASSETS/gatekeeper/." ~/gatekeeper/

formula-e-lab-v1 adalah tag rilis tetap, sehingga semua orang mendapatkan file yang sama. $ASSETS ditetapkan di Langkah 2 dan mengarah ke folder yang baru saja Anda clone.

Tindakan ini akan menambahkan file berikut:

track-planner/
├── app/
│   ├── tools.py                                  # get_track_topology, evaluate_track_layout
│   ├── auth.py                                   # A2A client with per-request token refresh
│   ├── data/circuits.json                        # Five candidate venues
│   └── skills/fia-compliance-skill/
│       ├── references/track_regulations.md       # The FIA rules
│       └── scripts/calculate_regen_zones.py      # Braking-energy calculator
└── tests/
    ├── unit/test_tools.py
    └── eval/datasets/track_eval.json, track_eval_quick.json
gatekeeper/
├── app/tools.py                                  # verify_infrastructure_checklist
└── tests/unit/test_tools.py

Menginstal dan menguji

(cd ~/track-planner && agents-cli install && uv run pytest tests/unit)
(cd ~/gatekeeper && agents-cli install && uv run pytest tests/unit)

agents-cli install menjalankan uv sync untuk membuat lingkungan virtual bagi setiap project. Semua pengujian unit akan berhasil.

4. 4. Menulis keahlian kepatuhan FIA

Keahlian Agen mengemas petunjuk, dokumen referensi, dan skrip dalam satu folder. SkillToolset ADK memuatnya dalam tiga level, sehingga agen hanya membaca apa yang diperlukan:

Level

File

Saat agen melihatnya

1

SKILL.md front matter (name, description)

Selalu (beberapa lusin token)

2

SKILL.md body

Saat memanggil load_skill

3

references/, scripts/

Saat memanggil load_skill_resource atau run_skill_script

Kemampuan ini ada di app/skills/ karena Dockerfile yang dihasilkan hanya menyalin app/ ke dalam image yang di-deploy.

Melihat file level 3

Anda telah menyalin file level 3 keterampilan di Langkah 3:

  • references/track_regulations.md menyimpan aturan yang diperiksa Assessor: batas panjang dan lebar, pembatas yang diperlukan setiap zona pengereman, lapisan CAD wajib (ditambah lapisan medis untuk rute rumah sakit), target regenerasi, dan aturan Mode Serangan.
  • scripts/calculate_regen_zones.py adalah kalkulator. Dengan kecepatan masuk, kecepatan keluar, dan jarak pengereman di zona pengereman, model ini menghitung energi yang dipulihkan dan pembatas yang diperlukan di tikungan, sehingga agen tidak perlu menebak fisika.

Jalankan skrip untuk Tikungan 10 London, tempat mobil mengerem dari 215 hingga 55 km/jam dalam jarak 82 meter:

cd ~/track-planner
uv run python app/skills/fia-compliance-skill/scripts/calculate_regen_zones.py \
  --entry-kph 215 --exit-kph 55 --brake-dist-m 82

Mobil memulihkan sekitar 508 kW di sini, di atas target 250 kW. Kecepatannya melambat pada lebih dari 2G, sehingga tikungan memerlukan pembatas Tecpro (F1_TEC3):

{"entry_kph": 215.0, "exit_kph": 55.0, "brake_dist_m": 82.0, "deceleration_g": 2.07, "estimated_regen_kw": 507.7, "meets_250kw_target": true, "required_barrier_layer": "F1_TEC3"}

Menulis SKILL.md

Buat file yang mengikat skill:

cloudshell edit app/skills/fia-compliance-skill/SKILL.md

Tambahkan konten ini:

---
name: fia-compliance-skill
description: >
  FIA Formula E street circuit rules: length and width limits, mandatory CAD
  layers, barrier selection, and Gen3 regenerative braking estimates. Use when
  designing, checking or fixing a Formula E circuit layout.
---

# FIA Formula E Compliance

Follow these steps for every circuit you check.

1. **Read the rules.** Call `load_skill_resource` with
   `file_path="references/track_regulations.md"`.
2. **Estimate regeneration for every heavy braking zone.** Call
   `run_skill_script` with `file_path="scripts/calculate_regen_zones.py"` and
   `args={"entry-kph": <entry>, "exit-kph": <exit>, "brake-dist-m": <distance>}`.
   Never guess kW values. Use the highest `estimated_regen_kw` as the
   circuit's peak regeneration.
3. **Check barriers.** Any zone whose `required_barrier_layer` is `F1_TEC3`
   needs the `F1_TEC3` CAD layer.
4. **Report.** List every rule the layout fails and a concrete fix for each
   one.

description adalah apa yang dibaca model untuk memutuskan kapan harus menggunakan keahlian, sehingga menjelaskan apa yang dicakup oleh keahlian dan kapan harus menggunakannya.

Lihat cara kerja keterampilan

Buka app/tools.py di Cloud Shell Editor:

cloudshell edit app/tools.py

Temukan fungsi build_fia_skill_toolset:

def build_fia_skill_toolset() -> SkillToolset:
    return SkillToolset(
        skills=[load_skill_from_dir(SKILL_DIR)],
        code_executor=UnsafeLocalCodeExecutor(),
    )
  • load_skill_from_dir membaca folder keterampilan: SKILL.md, references/, dan scripts/.
  • SkillToolset mengubahnya menjadi alat yang dapat dipanggil agen: list_skills, load_skill, load_skill_resource, dan run_skill_script.
  • UnsafeLocalCodeExecutor memungkinkan run_skill_script menjalankan skrip Python di mesin ini. Hal ini tidak masalah untuk lab; gunakan eksekutor dengan sandbox dalam produksi.

Anda akan melampirkan toolset ini ke Assessor di langkah berikutnya.

5. 5. Menulis agen

Model Gemini 3 mengontrol penalaran dengan thinking_level (LOW, MEDIUM, atau HIGH), bukan anggaran token. Di ADK, Anda menetapkannya dengan types.ThinkingConfig(thinking_level=types.ThinkingLevel.HIGH). Sesuaikan dengan tugas setiap agen: lebih banyak berpikir berarti perencanaan yang lebih baik, tetapi latensi dan biaya yang lebih tinggi.

Pemilah Komunikasi (LOW)

Gatekeeper hanya menjalankan checklist deterministik, sehingga tidak memerlukan banyak penalaran. Ganti agen template:

cloudshell edit ~/gatekeeper/app/agent.py
"""FIA Digital Twin Gatekeeper agent.

This agent runs in its own project and is deployed to Agent Runtime. The track
planner calls it over the A2A protocol.
"""

from google.adk.agents import Agent
from google.adk.apps import App
from google.adk.models import Gemini
from google.genai import types

from app.tools import verify_infrastructure_checklist

# Tested with Gemini 3.8 Flash. To try Gemini 4 Argon, change this to
# "gemini-4-argon", delete the `temperature` settings below (Argon ignores
# them) and run `uv add "google-genai>=2.30.1"` in this project first.
MODEL = "gemini-3.8-flash"

root_agent = Agent(
    # Must match `root_agent_name` in agents-cli-manifest.yaml.
    name="gatekeeper",
    model=Gemini(
        model=MODEL,
        retry_options=types.HttpRetryOptions(attempts=3),
    ),
    description=(
        "FIA Digital Twin Gatekeeper. Runs the final homologation checklist "
        "for a Formula E circuit blueprint."
    ),
    instruction=(
        "You are the FIA Digital Twin Gatekeeper. For every circuit blueprint "
        "you receive, call `verify_infrastructure_checklist` with its circuit "
        "ID, CAD layers, minimum width and peak regeneration. Reply with the "
        "status and any missing CAD layers. Never approve a blueprint the "
        "checklist rejects."
    ),
    # A deterministic checklist needs little reasoning: keep it fast and cheap.
    generate_content_config=types.GenerateContentConfig(
        temperature=0.0,
        thinking_config=types.ThinkingConfig(
            thinking_level=types.ThinkingLevel.LOW,
        ),
    ),
    tools=[verify_infrastructure_checklist],
)

app = App(
    root_agent=root_agent,
    name="app",
)

Menjalankan Gatekeeper secara lokal

Buka tab Cloud Shell kedua dan mulai server yang dihasilkan Gatekeeper di port 8001:

cd ~/gatekeeper
APP_URL=http://localhost:8001 uv run uvicorn app.fast_api_app:app --port 8001

Kembali ke tab pertama, lihat kartu agen A2A Gatekeeper. Berikut cara agen lain menemukan apa itu Gatekeeper dan apa yang dapat dilakukannya:

curl -s http://localhost:8001/a2a/app/.well-known/agent-card.json | jq .

Anda akan melihat JSON seperti ini (dipersingkat):

{
  "name": "gatekeeper",
  "description": "FIA Digital Twin Gatekeeper. Runs the final homologation checklist for a Formula E circuit blueprint.",
  "supportedInterfaces": [
    {"url": "http://localhost:8001/a2a/app", "protocolBinding": "JSONRPC", "protocolVersion": "1.0"}
  ],
  "skills": [
    {"id": "gatekeeper", "name": "model", "description": "FIA Digital Twin Gatekeeper. ..."},
    {"id": "gatekeeper-verify_infrastructure_checklist", "name": "verify_infrastructure_checklist", "description": "Runs the final homologation checklist ..."}
  ]
}
  • name dan description berasal langsung dari definisi Agent(...) Anda.
  • skills mencantumkan hal yang dapat dilakukan agen. ADK menambahkan verify_infrastructure_checklist secara otomatis, menggunakan docstring alat.
  • supportedInterfaces memberi tahu pemanggil tempat untuk mengirim permintaan A2A. Itulah sebabnya Anda memulai server dengan APP_URL=http://localhost:8001: pemanggil membaca kartu terlebih dahulu, lalu mengirimkan permintaannya ke url apa pun yang diiklankan kartu.

Tidak ada yang ditulis secara manual di sini: server scaffold membuat kartu dari agen Anda. Perencana jalur akan membaca kartu ini untuk menemukan dan memanggil Gatekeeper.

Penilai (MEDIUM) dan Lead Architect (HIGH)

Perencana jalur memiliki dua agen:

  • Penilai mempertimbangkan beberapa aturan, sehingga mendapatkan MEDIUM. Agen ini digabungkan dalam AgentTool, sehingga Lead Architect memanggilnya seperti fungsi dan mendapatkan kembali keputusannya.
  • Lead Architect merencanakan, memperbaiki, dan mengoordinasikan, sehingga mendapatkan HIGH. Permintaan ini mencapai Gatekeeper melalui RemoteA2aAgent, yang dibuat oleh create_remote_gatekeeper_agent() di app/auth.py, dan juga menggabungkannya dalam AgentTool.

Mengapa kedua helper digabungkan sebagai alat? AgentTool menampilkan jawabannya kepada pemanggil, sehingga Lead Architect tetap memegang kendali dan menulis blueprint akhir. Jika Gatekeeper adalah sub_agent, Lead Architect akan menyerahkan percakapan kepadanya, dan status singkat Gatekeeper akan menjadi jawaban akhir.

Buka file app/agent.py perencana jalur:

cloudshell edit ~/track-planner/app/agent.py

Salin kode berikut dan ganti seluruh konten ~/track-planner/app/agent.py dengan kode tersebut:

"""Formula E track planner: Lead Architect, FIA Assessor and remote Gatekeeper.

- The Lead Architect (root agent) designs the circuit and stays in charge.
- The FIA Assessor checks the layout and is called as a tool (`AgentTool`).
- The Gatekeeper runs in a separate project. It is also called as a tool, over
  A2A, so its verdict comes back to the Lead Architect.
"""

from google.adk.agents import Agent
from google.adk.apps import App
from google.adk.models import Gemini
from google.adk.tools.agent_tool import AgentTool
from google.genai import types

from app.auth import create_remote_gatekeeper_agent
from app.tools import build_fia_skill_toolset
from app.tools import evaluate_track_layout
from app.tools import get_track_topology

# Tested with Gemini 3.8 Flash. To try Gemini 4 Argon, change this to
# "gemini-4-argon", delete the `temperature` settings below (Argon ignores
# them) and run `uv add "google-genai>=2.30.1"` in this project first.
MODEL = "gemini-3.8-flash"

fia_skill_toolset = build_fia_skill_toolset()

# 1. FIA Assessor: MEDIUM thinking to weigh several rules without much latency.
assessor_agent = Agent(
    name="fia_assessor",
    model=Gemini(
        model=MODEL,
        retry_options=types.HttpRetryOptions(attempts=3),
    ),
    description=(
        "FIA safety and energy assessor. Audits a proposed circuit against "
        "the geometry, regeneration and CAD layer rules."
    ),
    instruction=(
        "You are the FIA Assessor. Load the `fia-compliance-skill` and follow "
        "it. Estimate regeneration for each braking zone with "
        "`calculate_regen_zones.py`, then call `evaluate_track_layout` with "
        "the highest value. Reply with the verdict, the score and every "
        "remediation note."
    ),
    generate_content_config=types.GenerateContentConfig(
        temperature=0.1,
        thinking_config=types.ThinkingConfig(
            thinking_level=types.ThinkingLevel.MEDIUM,
        ),
    ),
    tools=[fia_skill_toolset, evaluate_track_layout],
)

# 2. Remote Gatekeeper, reached over A2A (see app/auth.py).
remote_gatekeeper = create_remote_gatekeeper_agent()

# 3. Lead Architect: HIGH thinking for multi-step planning and trade-offs.
root_agent = Agent(
    # Must match `root_agent_name` in agents-cli-manifest.yaml.
    name="track_planner",
    model=Gemini(
        model=MODEL,
        retry_options=types.HttpRetryOptions(attempts=3),
    ),
    description=(
        "Lead Formula E circuit architect. Designs FIA-compliant street "
        "circuits and gets them homologated."
    ),
    instruction=(
        "You are the Lead Formula E Circuit Architect. For every request:\n"
        "1. Call `get_track_topology` for the venue.\n"
        "2. Call the `fia_assessor` tool with the full topology.\n"
        "3. If the Assessor rejects the layout, propose concrete fixes (for "
        "example widen a sector to 10.0m or add missing CAD layers) and "
        "re-assess the fixed layout.\n"
        "4. Once the Assessor passes it, call the `remote_gatekeeper` tool "
        "with the circuit ID, CAD layers, minimum width and peak "
        "regeneration for final approval.\n"
        "5. Finish with a short blueprint: circuit ID, length, minimum width, "
        "peak regeneration, every CAD layer by name, and the Gatekeeper's "
        "status."
    ),
    generate_content_config=types.GenerateContentConfig(
        temperature=0.2,
        thinking_config=types.ThinkingConfig(
            thinking_level=types.ThinkingLevel.HIGH,
        ),
    ),
    # Both helpers are tools, so their answers come back to the Lead Architect
    # and it writes the final blueprint.
    tools=[
        get_track_topology,
        AgentTool(agent=assessor_agent),
        AgentTool(agent=remote_gatekeeper),
    ],
)

app = App(
    root_agent=root_agent,
    name="app",
)

Menjalankan seluruh sistem di playground

Pastikan Gatekeeper masih berjalan di tab kedua Anda. Di tab pertama, mulai playground perencana jalur:

cd ~/track-planner
agents-cli playground --port 8080

Klik Web Preview > Preview on port 8080, seperti yang Anda lakukan di Langkah 3.

Minta sirkuit di tempat yang memenuhi aturan:

Design and homologate a Formula E circuit at Tokyo Bay.

Perhatikan panel peristiwa saat agen bekerja. Anda akan melihat, secara berurutan:

  1. get_track_topology: Lead Architect memuat data Tokyo Bay.
  2. fia_assessor: Lead Architect menyerahkan tata letak ke Assessor, yang memanggil load_skill, load_skill_resource, dan run_skill_script (sekali per zona pengereman), lalu evaluate_track_layout.
  3. remote_gatekeeper: Lead Architect memanggil Gatekeeper melalui A2A. Anda akan melihat permintaan yang dicatat di tab kedua.
  4. Blueprint akhir dari Lead Architect, yang mencantumkan setiap lapisan CAD dan status DISETUJUI Gatekeeper.

Klik peristiwa apa pun untuk melihat input dan output persisnya.

Sekarang mulai sesi baru dan coba tempat yang melanggar aturan:

Can the Monaco Harbour layout be homologated? If not, fix it and try again.

Kali ini, Penilai menolak chicane 6,8 m, Arsitek Utama mengusulkan chicane yang lebih lebar, dan tata letak yang diperbaiki dikirim kembali ke Penilai sebelum mencapai Penentu Keputusan.

Setelah selesai, tekan Ctrl+C di tab pertama untuk menghentikan playground. Biarkan Gatekeeper berjalan di tab kedua: Anda akan membutuhkannya di langkah berikutnya.

6. 6. Mengevaluasi agen

agents-cli eval run menjalankan agen Anda pada set data, mencatat setiap giliran dan panggilan alat, serta menilai hasilnya. Anda memutuskan apa yang akan diukur di tests/eval/eval_config.yaml.

Melihat set data

Buka set data di Cloud Shell Editor:

cd ~/track-planner
cloudshell edit tests/eval/datasets/track_eval.json

File ini menyimpan daftar eval_cases. Setiap kasus memiliki eval_case_id, prompt (apa yang ditanyakan pengguna), dan reference (seperti apa jawaban yang baik). LLM penilai membandingkan jawaban agen dengan referensi.

eval_case_id

Yang diuji

fe_001_tokyo_compliant

Tempat yang lulus setiap aturan dan disetujui

fe_002_monaco_narrow

Chicane 6,8 m gagal memenuhi aturan lebar

fe_003_berlin_too_long

Sirkuit 4.350 m gagal memenuhi aturan panjang

fe_004_missing_layers

Tata letak yang tidak memiliki lapisan CAD wajib

fe_005_low_regen

Zona pengereman di bawah target 250 kW

fe_006_sao_paulo_medical

Akses rumah sakit yang memerlukan lapisan CAD medis

fe_007_attack_mode

Zona Mode Serangan di jalur balap

fe_008_multiturn_remediation

Percakapan multi-turn: Monaco ditolak, pengguna meminta perbaikan, dan tata letak yang diperbaiki harus disetujui

Kasus terakhir menggunakan agent_data, bukan prompt. Fitur ini memutar ulang giliran percakapan sebelumnya, sehingga Anda dapat menguji cara agen menangani permintaan lanjutan, bukan hanya satu pertanyaan.

track_eval_quick.json dalam folder yang sama hanya berisi dua kasus: kasus 1 (satu pertanyaan) dan kasus 8 (percakapan). Anda akan menjalankan kueri tersebut karena lebih cepat dan menggunakan lebih sedikit kuota.

Menulis metrik

Set data ini berisi pertanyaan yang harus diajukan kepada agen. eval_config.yaml menjelaskan cara menilai jawaban. agents-cli eval run membacanya setelah agen menjawab setiap kasus, dan menjalankan setiap metrik pada setiap jawaban.

Buka file yang dihasilkan scaffold:

cloudshell edit tests/eval/eval_config.yaml

Notebook ini sudah berisi penilai LLM generik (custom_response_quality) dan metrik agent_turn_count yang hanya menghitung giliran. Itu adalah awal yang baik untuk agen mana pun, tetapi tidak menjelaskan apa pun tentang Formula E. Anda akan mempertahankan juri dan menambahkan metrik yang memeriksa aturan khusus untuk domain ini.

Evaluasi yang baik biasanya menggabungkan dua jenis metrik:

Jenis

Cara penghitungan skor

Cocok untuk

Kompromi

LLM-as-a-judge

Model membaca jawaban dan reference kasus, lalu memberikan skor 1 hingga 5 beserta penjelasannya

Kualitas yang tidak pasti: apakah jawabannya benar, lengkap, dan jelas?

Memerlukan biaya panggilan model per kasus; skor dapat sedikit bervariasi di antara operasi

Metrik kode

Fungsi Python kecil memeriksa jawaban

Fakta yang tepat dan dapat diperiksa: apakah jawaban menyertakan sesuatu yang harus ada?

Hanya memeriksa apa yang dapat Anda ekspresikan dalam kode

Ganti konten file dengan:

metrics_to_run:
  - custom_response_quality
  - fia_cad_layer_compliance

custom_metrics:
  # LLM-as-a-judge. response_quality.py is generated by `agents-cli scaffold
  # create`; it grades the final answer against the case's `reference`.
  - name: custom_response_quality
    custom_function_file: response_quality.py

  # Deterministic code metric: an approved blueprint must name every
  # mandatory FIA CAD layer.
  - name: fia_cad_layer_compliance
    custom_function: |
      def evaluate(instance):
          response = str(instance.get("response") or "")
          reference = str(instance.get("reference") or "")
          # Only approvals must list every layer. Rejections and other
          # questions (such as Attack Mode) don't, so skip them.
          if "APPROVED" not in reference:
              return {"score": 1.0, "explanation": "Not an approval case."}
          required = [
              "F1_TRACK_CENTRELINE",
              "F1_PIT_ENTRY_SPEED_LIMIT_LANE",
              "F1_WALL_TEMP",
              "F1_TEC3",
          ]
          missing = [layer for layer in required if layer not in response]
          return {
              "score": round(1 - len(missing) / len(required), 2),
              "explanation": "Missing: " + (", ".join(missing) or "none"),
          }

Fungsi setiap bagian:

  • metrics_to_run mencantumkan metrik yang akan dijalankan, berdasarkan nama. Menghapus nama di sini akan menonaktifkan metrik tersebut tanpa menghapusnya.
  • custom_response_quality adalah juri LLM. custom_function_file mengarah ke tests/eval/response_quality.py, yang dihasilkan oleh scaffold. Buka jika Anda ingin melihat perintah penilaian.
  • fia_cad_layer_compliance adalah metrik kode Anda, yang ditulis inline di bagian custom_function. Untuk setiap kasus, agen akan menerima instance (perintah, response akhir agen, dan reference). Untuk kasus yang jawaban yang diharapkan adalah persetujuan, agen akan memeriksa apakah respons menyebutkan keempat lapisan CAD wajib dan mencantumkan lapisan yang tidak ada. Misalnya, blueprint yang tidak menyertakan F1_TEC3 akan mendapatkan skor 0, 75. Kasus lainnya diberi skor 1,0, karena penolakan atau jawaban Mode Serangan tidak perlu mencantumkan setiap lapisan.

Mengapa perlu memeriksa lapisan CAD? Blueprint yang disetujui, tetapi tidak menyertakan lapisan wajib, adalah salah meskipun terlihat bagus, dan juri LLM dapat mengabaikan hal tersebut. Pemeriksaan kode menerapkan aturan yang sama dengan cara yang sama pada setiap operasi.

Menjalankan evaluasi

Biarkan Gatekeeper lokal tetap berjalan di tab kedua, lalu jalankan:

agents-cli eval run \
  --dataset tests/eval/datasets/track_eval_quick.json \
  --config tests/eval/eval_config.yaml \
  --concurrency 1
ls artifacts/grade_results/

Evaluasi memerlukan waktu beberapa menit. Setiap kasus menjalankan seluruh alur multi-agen, sekitar sepuluh panggilan model dengan Lead Architect di HIGH yang berpikir, sehingga Step 1/2: eval generate adalah bagian yang lambat. Tidak macet.

Setelah selesai, buka laporan HTML di artifacts/grade_results/ dengan Cloud Shell Editor. Skor fia_cad_layer_compliance yang rendah menunjukkan bahwa jawaban akhir Lead Architect mengabaikan lapisan. Coba perketat petunjuknya dan jalankan evaluasi lagi.

7. 7. Men-deploy Gatekeeper ke Agent Runtime

Anda hanya men-deploy Gatekeeper. Perencana jalur terus berjalan di Cloud Shell dan memanggilnya.

Buka tab Cloud Shell baru

Deployment memerlukan waktu 5 hingga 8 menit, jadi lakukan di tab baru saat evaluasi dari Langkah 6 selesai:

  1. Klik Open a new tab (+) di toolbar Cloud Shell.
  2. Tab baru tidak menyimpan variabel dari Langkah 2, jadi tetapkan lagi:
    export GOOGLE_CLOUD_PROJECT="$(gcloud config get-value project)"
    export REGION="us-central1"
    export ASSETS="$HOME/devrel-demos/codelabs/formula-e-track-planner"
    export PATH="$HOME/.local/bin:$PATH"
    echo "Project: $GOOGLE_CLOUD_PROJECT  Region: $REGION"
    

Biarkan Gatekeeper lokal berjalan di tab kedua Anda: evaluasi masih menggunakannya, dan deployment tidak perlu menghentikannya.

Deploy

Di tab baru, deploy Gatekeeper. Agen ini berjalan sebagai akun layanan default Compute Engine project:

cd ~/gatekeeper
PROJECT_NUMBER=$(gcloud projects describe "$GOOGLE_CLOUD_PROJECT" --format="value(projectNumber)")
agents-cli deploy \
  --no-agent-identity \
  --service-account "${PROJECT_NUMBER}-compute@developer.gserviceaccount.com" \
  --project "$GOOGLE_CLOUD_PROJECT" \
  --region "$REGION" \
  --no-confirm-project

Deployment memerlukan waktu sekitar 5 hingga 8 menit. Jangan tutup tab Cloud Shell saat berjalan. Jika aliran log terputus, periksa progres dengan agents-cli deploy --status. Sambil menunggu, kembali ke Langkah 6 dan baca laporan evaluasi Anda.

Memeriksa identitas agen

agents-cli mencatat resource yang di-deploy di deployment_metadata.json:

export RUNTIME_ID=$(jq -r .remote_agent_runtime_id ~/gatekeeper/deployment_metadata.json)
echo "$RUNTIME_ID"

curl -s -H "Authorization: Bearer $(gcloud auth print-access-token)" \
  "https://${REGION}-aiplatform.googleapis.com/v1beta1/${RUNTIME_ID}" \
  | jq -r .spec.effectiveIdentity

Baris kedua output adalah identitas yang dijalankan Gatekeeper:

Di-deploy dengan

Contoh output

Akun layanan (default)

123456789012-compute@developer.gserviceaccount.com

Agent Identity

agents.global.org-.system.id.goog/resources/aiplatform/projects//locations/us-central1/reasoningEngines/

Akun layanan digunakan bersama oleh semua hal dalam project yang menggunakannya. Identitas Agen adalah milik satu agen ini, sehingga Anda dapat memberinya peran yang tepat dan melihat tindakannya secara terpisah di log audit.

8. 8. Menghubungkan ke Gatekeeper yang di-deploy melalui A2A

Agent Runtime menyajikan rute A2A yang dihasilkan Gatekeeper di balik jalur /api yang diautentikasi.

Pastikan evaluasi dari Langkah 6 telah selesai, lalu hentikan Gatekeeper lokal di tab kedua Anda (Ctrl+C). Mulai sekarang, perencana jalur akan memanggil model yang di-deploy. Di tab pertama, arahkan perencana trek ke sana:

export RUNTIME_ID=$(jq -r .remote_agent_runtime_id ~/gatekeeper/deployment_metadata.json)
: "${RUNTIME_ID:?No deployed Gatekeeper found. Complete Step 7 first.}"
cd ~/track-planner
echo "GATEKEEPER_A2A_URL=https://${REGION}-aiplatform.googleapis.com/reasoningEngines/v1/${RUNTIME_ID}/api/a2a/app" >> .env

Alasan klien memperbarui tokennya

Buka app/auth.py. Token akses Google Cloud akan berakhir setelah satu jam, sehingga klien yang menetapkan header Authorization tetap saat memulai akan mulai gagal dengan 401 Unauthorized setelah satu jam. GoogleAuthRefresh membuat subclass httpx.Auth dan memeriksa kredensial pada setiap permintaan, serta memperbaruinya jika diperlukan. create_remote_gatekeeper_agent() hanya melampirkannya untuk URL https://.

Menjalankannya secara menyeluruh

Mulai playground lagi agar mengambil GATEKEEPER_A2A_URL baru:

agents-cli playground --port 8080

Klik Web Preview > Preview on port 8080, mulai sesi baru, dan tanyakan:

Assess the Monaco Harbour layout, widen the chicane to 11m, and get Gatekeeper approval.

Peristiwa terlihat sama seperti pada Langkah 5, tetapi panggilan remote_gatekeeper kini mengarah ke Gatekeeper di Agent Runtime, bukan tab kedua Anda.

Melihat panggilan masuk di Agent Runtime

Buktikan bahwa permintaan benar-benar mencapai Gatekeeper yang di-deploy melalui A2A:

  1. Di Konsol Cloud, telusuri Agent Platform, lalu buka Deployments di menu kiri.
  2. Pilih gatekeeper.
  3. Buka tab Sessions.

Anda akan melihat sesi baru yang ID Pengguna-nya diawali dengan A2A_USER_. Server A2A Gatekeeper membuatnya saat perencana jalur Anda memanggilnya. Buka tab Traces di halaman yang sama untuk melihat panggilan model Gatekeeper dan panggilan alat verify_infrastructure_checklist-nya untuk permintaan tersebut.

Opsional: deploy juga perencana jalur

Sejauh ini, perencana jalur berjalan di Cloud Shell, sehingga panggilan A2A-nya ke Gatekeeper menggunakan kredensial Anda. Deploy perencana juga dan kedua agen berjalan di Agent Runtime, saling memanggil dengan identitas yang di-deploy masing-masing.

Tekan Ctrl+C untuk menghentikan playground, lalu deploy perencana dengan cara yang sama seperti Gatekeeper:

cd ~/track-planner
PROJECT_NUMBER=$(gcloud projects describe "$GOOGLE_CLOUD_PROJECT" --format="value(projectNumber)")
agents-cli deploy \
  --no-agent-identity \
  --service-account "${PROJECT_NUMBER}-compute@developer.gserviceaccount.com" \
  --project "$GOOGLE_CLOUD_PROJECT" \
  --region "$REGION" \
  --no-confirm-project

Kedua agen berjalan sebagai akun layanan Compute Engine yang sama. Pertahankan --service-account: tanpanya, perencana akan berjalan sebagai agen layanan default Agent Runtime dan tidak dapat memanggil Gatekeeper (lihat Mengapa akun layanan ini? di Langkah 7).

Cara perencana yang di-deploy menjangkau Gatekeeper:

  • agents-cli deploy menyalin nilai di .env ke dalam deployment, sehingga perencana mendapatkan GATEKEEPER_A2A_URL yang Anda tambahkan di atas.
  • Di dalam Agent Runtime, GoogleAuthRefresh di app/auth.py mengambil identitas planner yang di-deploy, bukan identitas Anda.

Deployment memerlukan waktu sekitar 5 hingga 8 menit. Setelah selesai, periksa identitas yang digunakan untuk menjalankan perencana:

export PLANNER_ID=$(jq -r .remote_agent_runtime_id deployment_metadata.json)
curl -s -H "Authorization: Bearer $(gcloud auth print-access-token)" \
  "https://${REGION}-aiplatform.googleapis.com/v1beta1/${PLANNER_ID}" \
  | jq -r .spec.effectiveIdentity

Untuk mencoba sistem yang di-deploy:

  1. Di Konsol Cloud, kembali ke Agent Platform > Deployments.
  2. Pilih track-planner dan buka tab Playground.
  3. Masukkan:
    Design and homologate a Formula E circuit at Tokyo Bay.
    
  4. Tunggu blueprint dengan status APPROVED Gatekeeper.
  5. Kembali ke Deployments, pilih gatekeeper, lalu buka tab Sessions. Sesi A2A_USER_ terbaru berasal dari perencana yang di-deploy, bukan dari Cloud Shell.

Saat Anda melakukan pembersihan di langkah berikutnya, hapus juga perencana:

curl -X DELETE -H "Authorization: Bearer $(gcloud auth print-access-token)" \
  "https://${REGION}-aiplatform.googleapis.com/v1beta1/${PLANNER_ID}?force=true"

9. 9. Pemecahan masalah dan pembersihan

Pemecahan masalah

Gejala

Perbaiki

UREQ_TOS_NOT_ACCEPTED

Setujui Persyaratan Layanan di Konsol Cloud, lalu coba lagi.

Project adalah (unset)

Jalankan kembali perintah project di Langkah 2.

service account info is missing 'email' field

Jalankan gcloud auth application-default login (Langkah 2), lalu mulai ulang server yang sedang berjalan.

FileNotFoundError untuk SKILL.md

Selesaikan Langkah 4, atau salin $ASSETS/solution/track-planner/. ke ~/track-planner/.

Connection refused hingga localhost:8001

Mulai Gatekeeper lokal (Langkah 5), atau tetapkan GATEKEEPER_A2A_URL ke Gatekeeper yang di-deploy (Langkah 8).

Permission 'resourcemanager.projects.setIamPolicy' denied saat deployment

Akun Anda tidak dapat menggunakan Identitas Agen. Ikuti kotak pembersihan di Langkah 7, lalu gunakan deployment akun layanan.

Perencana jalur yang di-deploy melaporkan 403 Forbidden dari Gatekeeper

Identitas perencana tidak diizinkan untuk memanggil Gatekeeper. Deploy ulang dengan --service-account seperti pada Langkah 7, atau dengan --agent-identity jika Anda adalah pemilik project.

429 RESOURCE_EXHAUSTED

Anda telah mencapai kuota Gemini. Tunggu sebentar, atau tambahkan --concurrency 1 --qps 2 ke agents-cli eval run.

Address already in use

Hentikan server lain, atau pilih --port lain.

Pembersihan

Hapus Gatekeeper yang di-deploy agar tidak terus berjalan:

export RUNTIME_ID=$(jq -r .remote_agent_runtime_id ~/gatekeeper/deployment_metadata.json)
: "${RUNTIME_ID:?No deployed Gatekeeper found.}"
curl -X DELETE -H "Authorization: Bearer $(gcloud auth print-access-token)" \
  "https://${REGION}-aiplatform.googleapis.com/v1beta1/${RUNTIME_ID}?force=true"

Jika Anda membuat project hanya untuk codelab ini, Anda dapat menghapus seluruh project. Jika Anda berada di suatu acara, simpan project yang diberikan kepada Anda hingga penyelenggara menginstruksikan sebaliknya.

Yang telah Anda pelajari

  • agents-cli scaffold create memberi Anda project ADK standar yang dapat di-deploy; Anda hanya perlu menulis agen, skill, dan evaluasi.
  • Keahlian Agen menjaga pengetahuan domain tetap berada di luar perintah hingga agen membutuhkannya.
  • thinking_level memungkinkan Anda menukar kedalaman penalaran dengan kecepatan per agen.
  • agents-cli eval run mengubah "apakah ini berhasil?" menjadi skor yang dapat Anda lacak.
  • Identitas Agen dan A2A memungkinkan agen yang di-deploy secara independen bekerja sama dengan aman.

Pelajari lebih lanjut