Orkestrasi ADK 2: Alur Kerja Grafik, Kolaboratif & Dinamis

1. Ringkasan

Judul ADK 2 adalah tiga pola orkestrasi. Codelab ini mengajarkan ketiganya dengan membangun satu aplikasi — Marathon Race Day Coach — satu per satu langkah yang dapat dijalankan. Setiap level menjawab satu pertanyaan, menambahkan satu ide, dan berjalan sendiri.

Yang akan Anda pelajari

  • Alur kerja grafik (Pilar 1) — saat Anda dapat menggambar alur sebelum input tiba.
  • Agen kolaboratif (Pilar 2) — saat Anda mengetahui tim, tetapi permintaan memilih subset — dan ketiga mode kolaborasi (chat / task / single_turn) berjalan secara live.
  • Alur kerja dinamis (Pilar 3) — saat bentuk pekerjaan itu sendiri bergantung pada input.
  • Cara memilih — pohon keputusan satu pertanyaan, dan cara menyusun pola.

Benang merah

struktur yang diketahui → subset variabel / tim yang diketahui → bentuk yang tidak diketahui → pilih yang tepat

Roadmap pembelajaran Anda

Yang akan Anda build

Satu aplikasi — Marathon Race Day Coach — merakit satu tingkat yang dapat dijalankan dalam satu waktu. Setiap level adalah modul Python biasa yang Anda jalankan dari terminal; pada L5, semua bagian di bawah ini menjadi milik Anda.

Gambar diambil dari kode yang sedang berjalan: setiap garis solid dibaca dari Workflow.graph.edges. Yang merupakan pelajaran pertama — bagian yang dapat digambar sebelumnya adalah Pilar 1, dan bagian yang tidak dapat digambar adalah alasan keberadaan Pilar 2 dan 3.

Seluruh aplikasi — dan apa yang tidak dapat ditampilkan oleh grafik

Yang Anda butuhkan

  • Akun Google (untuk Colab) — tidak perlu penyiapan lokal.
  • ~50 menit (dua level L4 adalah yang paling panjang — anggarkan waktu untuknya).
  • Salah satu dari dua cara untuk mengakses model Gemini. Pilih jalur Anda — Anda menjalankan satu langkah penyiapan dan melewati langkah lainnya:

🎓 Workshop

🏠 Bisa dibawa pulang

Siapa

Anda berada di workshop live dan instruktur memberi Anda link klaim kredit

Semua orang lainnya — termasuk peserta workshop, setelahnya

Anda memerlukan

Link klaim, dan Akun Google yang dapat membuat project Cloud

Kunci API AI Studio gratis

Berjalan di

Vertex AI, dalam project yang ditagih ke kredit workshop Anda

Google AI Studio

Biaya

Dicakup oleh kredit

Paket gratis

Langkah penyiapan

Penyiapan workshop (langkah berikutnya)

Penyiapan di rumah (langkah berikutnya)

Semua hal mulai dari Prolog dan seterusnya identik, apa pun yang terjadi — jalur hanya menentukan endpoint model mana yang dihubungi notebook.

Dua cara untuk mengikuti

Setiap langkah di bawah dipetakan ke satu sel di notebook Colab dan satu folder di repositori GitHub. Pilih salah satu:

  • ▶ Colab (direkomendasikan): Buka notebook → jalankan sel dari atas ke bawah.
  • 💻 Lokal: git clone repo, ./setup_venv.sh, lalu jalankan setiap level sebagai modul (python -m ...) atau jelajahi semuanya dengan ./run.sh (adk web).

2. Penyiapan workshop · Klaim kredit Anda dan beralih ke Vertex AI

Di workshop ini, Anda akan diberi kredit Google Cloud. Anda akan mengklaimnya, membuat project yang ditagih ke project tersebut, dan mengarahkan notebook ke Vertex AI, bukan AI Studio. Satu sel melakukan semuanya setelah klaim.

1 · Klaim kredit Anda (~1 menit)

  1. Buka link klaim yang dibagikan instruktur Anda. Sepertinya https://me.developers.google.com/benefits/claim/your-workshop-name.
  2. Login dan ikuti halaman untuk menerima kredit.
  3. Catat Akun Google yang Anda gunakan. Setiap langkah di bawah harus dijalankan sebagai akun yang sama.

2 · Buka notebook dan instal ADK 2 (~1 menit)

Klik Open in Colab ▶, lalu jalankan sel kode pertama. Kode ini menyematkan versi ADK 2 yang tepat yang digunakan untuk memverifikasi codelab ini dan mencetak ✓ installed.

3 · Jalankan sel "Workshop setup" (~3 menit)

Ini adalah sel berjudul 🎓 Path A · Workshop. Jalankan dan Colab akan meminta Anda untuk memberikan otorisasi — pilih Akun Google yang sama dengan yang Anda gunakan untuk mengklaim kredit, lalu izinkan akses.

Sel ini melakukan empat hal: membuat project bernama adk-2-tutorial-XXXX di kredit Anda, mengaktifkan Vertex AI API di project tersebut, menetapkan empat variabel lingkungan yang dibaca oleh setiap sel berikutnya, lalu melakukan panggilan pengujian ke Vertex dan menunggu hingga Vertex menjawab — sehingga penyiapan selesai atau memberi tahu Anda alasannya, bukan gagal di dalam level nanti.

Output yang diharapkan — baris terakhir adalah yang penting:

Signed in as: you@example.com
...
Successfully created GCP project 'adk-2-tutorial-4817'.
Successfully linked 'adk-2-tutorial-4817' to billing account '01ABCD-...'.
   waiting for Vertex AI to come up on the new project... (10s)
   waiting for Vertex AI to come up on the new project... (20s)

 Vertex AI on adk-2-tutorial-4817 · us-central1 · gemini-2.5-flash  answered a test call

4 · Lewati langkah "Penyiapan di rumah"

Jangan jalankan sel kunci AI Studio — tindakan ini akan mengalihkan notebook kembali ke AI Studio dan mengurungkan tindakan yang baru saja Anda lakukan. (Sel mencegah hal ini dan akan menolak untuk berjalan, tetapi langkah yang lebih rapi adalah dengan melewatkannya.) Langsung buka sel Blok penyusun bersama dari sini.

5 · Jalankan sel "Shared building blocks"

Eksekusi sekali. File ini menentukan skema Pydantic + skenario marathon standar yang digunakan kembali oleh setiap level mulai dari L2 dan seterusnya. Anda akan melihat ✓ schemas + scenarios ready.

Setelah workshop

Kredit Anda dan project yang dibuatnya tidak akan berlaku selamanya. Untuk terus menjalankan level ini secara gratis setelah workshop selesai, jalankan langkah Penyiapan untuk di rumah — kunci AI Studio gratis, tanpa project Cloud, tanpa penagihan. Sel tersebut adalah satu-satunya hal yang berubah.

Untuk membersihkan lebih awal: buka Konsol Cloud, pilih adk-2-tutorial-XXXX, lalu hapus. Tidak ada hal lain dalam codelab ini yang membuat resource yang dapat ditagih.

3. Penyiapan di rumah · Kunci API AI Studio

Semua materi di jalur ini berjalan di kunci API Google AI Studio gratis — tanpa project Google Cloud, tanpa penagihan, tanpa penginstalan lokal. Seluruh langkah ini akan memakan waktu sekitar 3 menit.

1 · Buka notebook

Klik Open in Colab ▶. Anda akan diarahkan ke notebook — pengantar markdown, lalu satu sel yang dapat dijalankan per level. Anda menjalankan sel dari atas ke bawah; setiap sel mencetak outputnya sendiri tepat di bawahnya.

2 · Instal ADK 2 (~1 menit)

Jalankan sel kode pertama. Menyematkan versi persis yang digunakan untuk memverifikasi codelab ini:

%pip install -q "google-adk==2.3.0" python-dotenv pydantic nest_asyncio

Tunggu hingga selesai — Anda akan melihat ✓ installed. (Penginstalan memerlukan waktu sekitar 30–60 detik pada saat pertama; setelah itu, penginstalan akan di-cache.)

3 · Dapatkan kunci Gemini API Anda dari AI Studio (~1 menit)

  1. Buka aistudio.google.com/app/apikey di tab browser baru.
  2. Login dengan Akun Google Anda.
  3. Klik Create API key (kanan atas).
  4. Pilih project Google yang sudah ada atau biarkan project tersebut membuat project baru.
  5. Salin kunci — dimulai dengan AIza... dan panjangnya sekitar 40 karakter.

4 · Tambahkan kunci Anda ke Colab (~1 menit)

Opsi A — Secret Colab (direkomendasikan; kunci tetap tersembunyi):

  1. Klik ikon kunci 🔑 di sidebar kiri Colab.
  2. Klik + Tambahkan secret baru.
  3. Tetapkan Name ke GOOGLE_API_KEY.
  4. Tempelkan kunci Anda ke Nilai.
  5. Alihkan Akses notebook ke AKTIF.

Opsi B — tempel saat diminta (cepat): lewati rahasia; saat Anda menjalankan sel berikutnya, perintah tersembunyi 🔑 Enter your Google AI Studio API key: akan ditampilkan — tempel dan tekan Enter.

5 · Jalankan sel kunci

Kode ini membaca secret (atau kembali ke perintah tempel), lalu mengarahkan ADK ke AI Studio (bukan Vertex AI):

import os

# 🏠 TAKE-HOME ONLY — if you ran the Workshop setup cell, skip this one.
if os.environ.get("GOOGLE_GENAI_USE_VERTEXAI") == "True":
    raise SystemExit("✋ You're set up on the workshop path (Vertex AI). Skip this cell.")

# Google AI Studio API key — add GOOGLE_API_KEY in the 🔑 Secrets panel (or paste when prompted).
try:
    from google.colab import userdata
    key = userdata.get("GOOGLE_API_KEY")
except Exception:
    import getpass
    key = getpass.getpass("Enter your Google AI Studio API key: ")

os.environ["GOOGLE_API_KEY"] = "".join(key.split())    # drop any stray whitespace/newlines
os.environ["GOOGLE_GENAI_USE_VERTEXAI"] = "False"      # use AI Studio, not Vertex AI
print("✅ API key set — using Google AI Studio.")

Output yang diharapkan: ✅ API key set — using Google AI Studio.

6 · Jalankan sel "Shared building blocks"

Jalankan sel Shared building blocks satu kali. File ini menentukan skema Pydantic + skenario marathon standar yang digunakan kembali oleh setiap level mulai dari L2 dan seterusnya. Anda akan melihat ✓ schemas + scenarios ready.

Anda sudah siap! 🎽 Satu pengalihan cepat sebelum L0 — versi yang dibangun semua orang terlebih dahulu.

4. Prolog · Mengapa tidak menggunakan satu perintah besar?

⚡ Sebelum Anda menjalankannya, tentukan SATU hal yang harus diperhatikan: dari mana setiap angka spesifik berasal? Itulah seluruh latihan — yang lainnya hanyalah hiasan.

Sebelum tangga, jalankan hal yang digantikan tangga: satu agen yang perintahnya menjanjikan segalanya — mengambil data cuaca, menganalisis kursus, membaca log pelatihan, merutekan berdasarkan kondisi, menghasilkan rencana.

Yang akan Anda lihat: strategi yang percaya diri, spesifik, dan diformat dengan baik... yang angkanya dibuat-buat. Dalam satu eksekusi langsung, model ini dibuka dengan "Saya telah menarik metrik cuaca hari ini" dan melaporkan suhu 52°F, kecepatan angin 9 mph, dan analisis log pelatihan yang belum pernah dilihatnya. Tidak ada API cuaca di sini, tidak ada data kursus, tidak ada log — satu panggilan model buram yang mengada-ada inputnya atau membatasi input tersebut hingga tidak berguna.

Itulah penyakitnya, dan ada empat gejala yang perlu diberi nama:

  1. Anda tidak dapat memercayainya — data dibuat-buat, dengan lancar.
  2. Anda tidak dapat mengujinya — perutean langkah 4 ada di dalam prosa; tidak ada if untuk pengujian unit.
  3. Anda tidak dapat menukar langkah — tidak ada sambungan tempat API cuaca sebenarnya dapat terhubung.
  4. Anda membayar untuk semuanya, setiap saat — lima langkah, satu panggilan besar, tidak ada caching bagian deterministik.

Tahan perasaan itu. Sembilan level berikutnya menghilangkan langkah-langkah tersebut dari perintah, satu per satu: pengambilan fungsi (L1–L2a), perutean pernyataan if (L2b), spesialis membagi tugas (L3a–L3b), dan kode membatasi bentuk (L4a–L4b).

Pelatih mega-prompt — percaya diri, tanpa apa pun di belakang bagan

💻 Lokal: python -m shared.prologue

5. L0 · Agen ADK 2 pertama Anda

Roadmap — Anda berada di sini: L0

⚡ Singkatnya: agen adalah model + petunjuk + alat yang dapat dipanggilnya; Runner mengeksekusinya. Semua yang ada setelah level ini hanyalah lebih banyak agen, yang disusun dalam bentuk yang lebih baik.

Pertanyaannya: bisakah Anda membuat model menjawab — dan menjangkau kode sebenarnya saat aritmatika penting?

Satu ide — tiga bagian:

  • Agent — hal yang memberikan alasan (model Gemini + petunjuk).
  • Runner — hal yang menjalankan agen di dalam sesi dan melakukan streaming peristiwa.
  • alat — fungsi Python biasa (pace_splits) yang diputuskan model untuk dipanggil. ADK membaca tanda tangan + docstring dan memberikan deklarasi model; tidak ada penulisan skema.

Setelah prolog, ini adalah perbaikan pertama: LLM yang melakukan aritmatika kecepatan dalam pikirannya akan dengan senang hati salah — pace_splits adalah Python deterministik, jadi angka dalam jawaban dihitung, bukan diimprovisasi.

Colab: jalankan sel L0 · 📁 GitHub: L0_first_agent/ · 💻 Lokal: python -m L0_first_agent.agent

Alur L0

def pace_splits(target_finish: str) -> dict:
    """Convert a goal time like '3:30:00' into exact per-mile / per-km paces."""
    ...                                  # deterministic Python — no LLM

pace_coach = Agent(
    name="pace_coach", model=MODEL,
    tools=[pace_splits],                 # the model may call it; ADK reads the signature
    instruction="You are a friendly, concise marathon coach. ... If the runner "
                "mentions a goal time, call pace_splits — never do arithmetic yourself.",
)
runner = Runner(node=pace_coach, session_service=InMemorySessionService(), auto_create_session=True)
async for event in runner.run_async(user_id="u1", session_id="s1", new_message=msg):
    ...  # events carry the model's text

🔍 Penanda: Agent(...) · tools=[pace_splits] · Runner(...). Dan dalam output, baris 🔧 — itulah model yang memutuskan, di tengah jawaban, untuk memanggil kode Anda.

Yang akan Anda lihat:

   🔧 model called tool  pace_splits({'target_finish': '3:30:00'})
   🔧 tool returned      {'per_mile': '8:00', 'per_km': '4:58', ...}
🧠 Coach: To finish in 3:30:00, you need an average pace of 8:00 per mile...

Baris 🔧 adalah pelajaran: di tengah jawaban, model memilih untuk memanggil fungsi Anda, dan 8:00/mile yang tepat dalam jawabannya berasal dari kode Anda — bukan dari statistik token.

Anda mungkin bertanya-tanya: apakah model selalu memanggil alat? Tidak — model memutuskan, per pertanyaan. Ajukan pertanyaan yang tidak berisi angka dan baris 🔧 akan hilang (playground akan meminta Anda mencoba hal ini).

👀 Baca: pace_splits (fungsi biasa) dan baris tools=[pace_splits]. · ▶ Jalankan. · ✏️ Perubahan: ajukan pertanyaan umum (tanpa waktu sasaran) — perhatikan garis 🔧 menghilang: model memutuskan kapan alat layak dipanggil. Kemudian, tulis ulang instruction dan jalankan kembali — petunjuknya adalah bagian program lainnya.

6. L1 · Alur Kerja pertama Anda

Peta jalan — Anda di sini: L1

⚡ Singkatnya: fungsi biasa dan agen LLM adalah jenis node yang sama. Pekerjaan yang dapat diprediksi → fungsi (0 LLM, deterministik); penalaran → agen.

Pertanyaan: bagaimana cara menggabungkan kode biasa dan LLM dalam satu alur, tanpa membayar panggilan model pada bagian yang hanya berupa kode?

Satu ide: dalam Workflow, fungsi Python biasa dan agen LLM hanyalah node dalam daftar edges yang sama.

START ──► fetch_conditions (function, 0 LLM) ──► advise (agent, 1 LLM)

Colab: jalankan sel L1 · 📁 GitHub: L1_graph_basics/ · 💻 Lokal: python -m L1_graph_basics.workflow

Alur L1

Node fungsi mencetak data yang dihasilkannya (tanpa panggilan model), lalu agen memberikan saran yang merujuk pada suhu dan angin yang sebenarnya:

def fetch_conditions(node_input):                # function node — 0 LLM
    return Event(output=Conditions(temp_f=78, wind_mph=12, conditions="sunny").model_dump())

advise = Agent(name="advise", model=MODEL, mode="single_turn",
               input_schema=Conditions, instruction="...give pacing + gear advice...")

workflow = Workflow(edges=[(START, fetch_conditions, advise)])

🔍 Penanda: satu tuple tepi — (START, fetch_conditions, advise) — dengan fungsi Python kosong di tengahnya, dan input_schema= yang memvalidasi penyerahan.

Yang baru vs L0: Workflow(edges=[...]), START (tempat input masuk), node fungsi yang menampilkan Event(output=...), dan input_schema=Conditions sehingga output fungsi divalidasi terhadap skema tersebut sebelum dilihat oleh agen (sebagai teks JSON — input_schema memvalidasi batas, tidak memberikan objek Python kepada agen).

Anda mungkin bertanya-tanya: apakah fungsi-lalu-agen adalah urutan yang diperlukan? Tidak — pesanan apa pun, campuran apa pun, jumlah berapa pun. advise berjalan kedua hanya karena memerlukan data fetch_conditions. Pelajaran ini adalah gelar kebangsawanan, bukan urutan.

👀 Baca: fetch_conditions menampilkan data tanpa panggilan model; advise memiliki input_schema=Conditions. · ▶ Jalankan. · ✏️ Perubahan: tetapkan temp_f=30 dalam fungsi dan jalankan ulang — saran akan berubah, dan fungsi tetap memerlukan 0 panggilan LLM.

7. L2a · Fan-out paralel + JoinNode (Pilar 1a)

Peta jalan — Anda ada di sini: L2a

⚡ TL;DR: sebarkan secara paralel (gratis), tunggu semua, gabungkan, berikan gambaran lengkap kepada satu agen.

Pertanyaan: Anda dapat menggambar alur sebelum input tiba. Mulai dengan kerangka: kumpulkan data secara paralel, gabungkan, serahkan ke satu agen.

Bentuk:

START ──► fetch_weather ──┐
START ──► analyze_course ─┼─► JoinNode ─► strategy (1 agent)
START ──► pull_fitness ───┘   (bundles)

Colab: jalankan sel L2a · 📁 GitHub: L2a_parallel_join/ · 💻 Lokal: python -m L2a_parallel_join.workflow

Alur L2a

🔍 Penanda: tiga tepi yang semuanya dimulai di START — yang merupakan fan-out — dan JoinNode, titik pertemuan.

  • Ketiga pengambilan tersebut adalah fungsi — fungsi tersebut berjalan secara paralel, 0 panggilan LLM.
  • JoinNode menunggu ketiga fungsi tersebut dan menggabungkannya ke dalam satu payload yang diketik (BundledRunData), yang dikunci berdasarkan nama fungsi.
  • Agen strategy membaca paket dan menulis RaceStrategy.

Yang akan Anda lihat: setiap pengambilan mencetak stempel waktu started / finished. Ketiganya dimulai pada 0,0 detik dan fan-out berakhir pada 2,0 detik — pengambilan paling lambat, bukan 4,5 detik yang merupakan jumlah durasinya. Tumpang-tindih tersebut adalah paralelisme. (Waktu proses total yang dicetak di akhir adalah ~8 detik karena juga berisi panggilan LLM agen strategi — baca stempel waktu pengambilan untuk klaim paralel, bukan total.)

💡 Callback prolog: mega-prompt menciptakan cuacanya sendiri. Di sini, suhu berasal dari fungsi pengambilan — kode nyata, sambungan nyata. Tukar dict bawaan dengan API cuaca yang sebenarnya dan tidak ada perubahan lain.

Anda mungkin bertanya-tanya: berapa banyak

JoinNode

perlu saya pahami? Satu kalimat: fungsi ini menunggu hingga setiap cabang paralel selesai, mengemas output ke dalam satu dict yang dikunci oleh nama fungsi upstream, dan tidak menghitung apa pun. Dict tersebut adalah alasan mengapa router L2b dapat menulis node_input["fetch_weather"]["temp_f"].

👀 Baca: tiga tepi keluar dari START; JoinNode menggabungkannya untuk satu agen. · ▶ Jalankan dan baca stempel waktunya, bukan totalnya. · ✏️ Perubahan: membuat satu pengambilan data tidur 3.0 — prediksi waktu berakhir fan-out baru terlebih dahulu, lalu verifikasi.

8. L2b · Menambahkan perute deterministik (Pilar 1b)

Roadmap — Anda berada di sini: L2b

⚡ Singkatnya: L2a tidak diubah + if biasa menentukan agen mana yang berjalan. Membuat cabang, tanpa meminta model.

Pertanyaan: rencana harus berbeda untuk cuaca panas vs. dingin. Bagaimana cara Anda membuat cabang — tanpa meminta model untuk memutuskan?

Bentuk (L2a + router):

... JoinNode ─► route_by_weather ─► hot_strategy
               (if-statement)   ─► normal_strategy
                                ─► cold_strategy

Colab: jalankan sel L2b — coba run("NORMAL") / run("COLD") · 📁 GitHub: L2b_router/ · 💻 Lokal: python -m L2b_router.workflow COLD

Alur L2b

def route_by_weather(node_input):                        # an if-statement, 0 LLM
    temp = node_input["fetch_weather"]["temp_f"]
    route = "HOT" if temp >= 70 else "COLD" if temp <= 40 else "NORMAL"
    return Event(output=node_input, route=route)

(route_by_weather, {"HOT": hot_strategy, "NORMAL": normal_strategy, "COLD": cold_strategy})

🔍 Penanda: Event(output=..., route=...) — node fungsi yang memberi nama jalur — dan dict-edge {"HOT": ..., "NORMAL": ..., "COLD": ...} yang memetakan nama ke node.

Kesimpulan — tiga jenis pekerjaan, tiga rumah:

  • Pekerjaan yang dapat diprediksi → fungsi (3 pengambilan paralel)
  • Aturan yang jelas → perutean eksplisit (route_by_weather adalah pernyataan if, bukan keputusan model)
  • Penalaran → model (tepat satu agen strategi yang berjalan)

Yang akan Anda lihat: temp=78F -> route=HOT, lalu RaceStrategy terstruktur. Biaya bersih: 1 panggilan LLM.

⚠️ Jika Anda menambahkan cabang keempat, berikan entri DEFAULT_ROUTE ke route-dict juga. Rute yang tidak cocok dengan dict bukanlah error — cabang akan berakhir, dan program akan keluar 0 tanpa output, yang merupakan jalan buntu yang membingungkan untuk di-debug.

Anda mungkin bertanya-tanya: jadi L2b benar-benar L2a ditambah router? Ya — pengambilan dan penggabungan tidak berubah, dan masih persis 1 panggilan LLM. Yang berubah: "selalu agen yang sama" menjadi "salah satu dari tiga agen, dipilih berdasarkan data".

👀 Baca: route_by_weather — router adalah pernyataan if, bukan agen. · ▶ Run run("COLD") juga. · ✏️ Perubahan: tambahkan cabang WINDY dengan agen keempat — dan baca peringatan DEFAULT_ROUTE di atas sebelum Anda melakukannya.

9. L3a · Agen kolaboratif: satu bendera, dua dunia — Pilar 2

Peta jalan — Anda berada di sini: L3a

⚡ TL;DR: tim yang sama, satu bendera. chat menyerahkan seluruh percakapan kepada satu spesialis dan tidak pernah kembali; single_turn mengubah setiap spesialis menjadi alat — subset paralel, kembali otomatis, satu sintesis.

Pertanyaan: Anda mengenal tim, tetapi permintaan memutuskan anggota mana yang harus menjawab. Bagaimana cara Anda membiarkan LLM memilih subset — dan menjalankannya secara bersamaan?

Bentuk: koordinator atas enam spesialis (medis, cuaca, kecepatan, peralatan, nutrisi, mental). Level ini menjalankan tim yang sama dua kali — perintah koordinator yang sama, enam spesialis yang sama. Satu-satunya perbedaan adalah satu tanda pada sub-agen. Kontras adalah pelajarannya.

Colab: jalankan sel L3a · 📁 GitHub: L3a_collaborative/ · 💻 Lokal: python -m L3a_collaborative.concierge --mode chat "What about fueling?"

Alur L3a

🔍 Penanda: mode="single_turn" di pabrik — dan di output, TRANSFER → (ketukan 1) versus serangkaian DISPATCH → baris yang memiliki satu stempel waktu (ketukan 2).

Beat 1 · Jalankan default terlebih dahulu — dan lihat tugasnya gagal

Tidak ada mode= yang ditulis → sub-agen ditetapkan secara default ke chat. Yang akan Anda lihat:

TRANSFER  nutrition_specialist   (transfer_to_agent  the only tool chat subagents provide)
Final speaker: nutrition_specialist

Koordinator tidak memiliki alat delegasi — sub-agen chat hanya memberinya transfer_to_agent, penyerahan berurutan seluruh percakapan kepada satu spesialis. Spesialis tersebut akan menjawab pengguna secara langsung, dan proses akan berakhir di sana. Tidak ada pengiriman paralel. Tidak ada pengembalian. Tidak ada sintesis. Ajukan pertanyaan umum dan situasinya akan semakin buruk: enam spesialis, satu transfer.

Itu bukan bug — itu adalah mode percakapan yang sedang menjalankan tugasnya. Percakapan milik siapa pun yang memegangnya, hingga seseorang secara eksplisit mentransfernya. Benar untuk asisten yang tidak memiliki batasan; salah untuk langkah pipeline.

Beat 2 · Satu bendera, dua dunia

Satu-satunya perbedaan: mode="single_turn" pada setiap spesialis. Pertanyaan yang sama, jalankan lagi:

[t= 7.8s] DISPATCH  medical_specialist       same timestamp =
[t= 7.8s] DISPATCH  weather_specialist         one turn, many calls
[t=14.5s]    medical_specialist replied      replies land inside
[t=14.5s]    weather_specialist replied        one short window
🧠 Concierge (synthesized): <one answer>

Sekarang, ADK menyuntikkan satu alat delegasi per spesialis — yang dinamai sesuai dengan sub-agen, yang dijelaskan oleh description=-nya (teks tersebut adalah yang dibaca koordinator saat memilih subset; lewati dan Anda hanya merutekan berdasarkan nama). Koordinator mengeluarkan beberapa panggilan dalam satu giliran, ADK menjalankannya secara paralel, masing-masing otomatis menampilkan hasilnya, dan koordinator melakukan sintesis.

Pertanyaan

Spesialis yang memecat

"Bagaimana dengan pengisian bahan bakar?"

hanya nutrisi

"Lutut saya sakit di mil ke-18"

khusus medis

"Apakah saya harus balapan hari ini?"

medis + cuaca + kecepatan

"Ada yang perlu saya khawatirkan?"

semua 6

Alasan setiap spesialis mendapatkan seluruh ringkasan: setiap subagen single_turn berjalan di cabang sesi terisolasi sendiri — subagen tidak dapat melihat percakapan atau rekan-rekannya. Tidak ada yang bersifat ambien: koordinator harus meneruskan seluruh SpecialistInput (pertanyaan + strategi + data runner) secara terpisah ke setiap panggilan paralel.

💡 Tempat ADK 2 memberikan akses langsung: LLM memilih subset per permintaan DAN menjalankannya secara paralel — dideklarasikan melalui sub_agents + mode="single_turn". Anda dapat menyusun bentuk yang sama di 1.x dengan membungkus setiap spesialis dalam AgentTool; yang berubah adalah bahwa sekarang ini merupakan deklarasi, bukan plumbing. (ParallelAgent selalu-semua dan transfer_to_agent adalah serial.)

⚠️ Dua peringatan yang perlu diperhatikan: (1) model memilih subset, sehingga kurang deterministik daripada perute hard-code L2 — subset yang tepat dapat bervariasi dari satu proses ke proses lainnya. (2) Terkadang Anda akan melihat baris Error validating input: ... untuk satu spesialis. Outputnya hampir tidak pernah berupa output spesialis — output_schema membuat Gemini menerapkan hal tersebut di sisi server. Ini adalah input: koordinator harus mereproduksi seluruh SpecialistInput bertingkat secara verbatim untuk setiap panggilan paralel, dan terkadang koordinator gagal melakukannya. ADK menampilkan error sebagai hasil alat tersebut, koordinator dipulihkan, dan sintesis tetap dilakukan.

Anda mungkin bertanya-tanya: apakah

chat

hanya delegasi gaya 1.x — satu agen dalam satu waktu? Pada dasarnya ya: ini adalah perilaku default 1.x, kini dengan nama. Perbedaan dengan single_turn bersifat tiga dimensi: apa yang dipegang koordinator (satu transfer_to_agent vs satu alat per spesialis) · berapa banyak yang dapat bekerja (satu, yang memiliki percakapan vs N secara paralel) · apakah kontrol kembali (tidak pernah vs otomatis, dengan hasil). Dan tentang kode: cabang if mode == pabrik hanya ada sehingga satu tim dapat dibangun dengan kedua cara untuk kontras ini — aplikasi nyata meng-hardcode satu mode dan if menghilang.

👀 Baca: pabrik _specialist — parameter mode adalah seluruh level. · ▶ Jalankan kedua ketukan. · ✏️ Perubahan: tanyakan "lutut saya sakit di kilometer ke-18"prediksi subset terlebih dahulu, lalu periksa baris DISPATCH.

# The factory's mode parameter is THE variable this level teaches:
def _specialist(name, domain, focus, mode):
    kwargs = {}
    if mode == "single_turn":   # the structured contract only makes sense for a TOOL
        kwargs = dict(mode="single_turn",
                      input_schema=SpecialistInput, output_schema=SpecialistResponse)
    return Agent(name=name, model=MODEL,
                 description=f"Marathon {domain} specialist. Consult for: {focus}.",
                 instruction=..., **kwargs)

race_concierge = Agent(name="race_concierge", model=MODEL,
                       sub_agents=[...six specialists...],   # NOTE: no `mode` on the coordinator
                       instruction="...DECIDE which specialists are relevant... call them IN PARALLEL... SYNTHESIZE...")

10. L3b · Mode tugas: percakapan dengan garis akhir — Pilar 2

Roadmap — Anda berada di sini: L3b

⚡ Singkatnya: mode tengah — berbicara dengan pengguna hingga kolom dikumpulkan, lalu otomatis menampilkan dengan objek yang divalidasi.

Pertanyaan: L3a menyisakan celah. chat memiliki seluruh percakapan; single_turn tidak pernah berbicara dengan pengguna. Namun, pekerjaan penerimaan yang sebenarnya berada di antara keduanya: "berbicara dengan pengguna HINGGA Anda mengumpulkan X — lalu kembali dengan objek yang divalidasi." Mode apa itu?

Bentuk:

race_desk (coordinator)
  └─ gear_fitter (mode="task", output_schema=GearOrder)

Colab: jalankan sel L3b · 📁 GitHub: L3b_task_desk/ · 💻 Lokal: python -m L3b_task_desk.desk

Alur L3b

gear_fitter menahan tugas tetap terbuka — tugas yang dijeda, bukan error

🔍 Penanda: mode="task" + output_schema= pada agen yang sama — dan dalam output, panggilan ⏸ jeda dan finish_task.

Yang akan Anda lihat:

━━ TURN 1 ━━  user: 'I need shoes for the marathon.'
  race_desk  delegate: gear_fitter
  gear_fitter: What is your shoe size?
    The run ENDED  but nothing failed. This is a PAUSED task.

━━ TURN 2 ━━  user: 'Size 9, wide.'   (same session  resumes the task)
  gear_fitter  finish_task   (payload validates as GearOrder)
  race_desk: Your order ... in size 9 Wide has been confirmed.

Tiga hal terjadi yang tidak dapat dilakukan oleh mode L3a:

  1. Eksekusi benar-benar berhenti di tengah tugas — tugas dijeda, bukan error dan bukan kegagalan. Agen mengajukan pertanyaan klarifikasi dan menahan tugas tetap terbuka. (Di adk web, Anda cukup mengetik jawaban; skrip harness akan mengirimkannya sebagai pesan kedua pada sesi yang sama.)
  2. Pesan berikutnya melanjutkan agen tugas YANG SAMA — tidak ada pengalihan rute, tidak ada pendelegasian ulang. Sesi mengetahui siapa yang sedang menunggu.
  3. finish_task mengakhirinya — alat yang disisipkan ADK karena mode="task". Agen harus memanggilnya untuk menyelesaikan, dan payload-nya harus divalidasi terhadap output_schema. Percakapan dengan garis akhir yang diketik — lalu kontrol otomatis kembali ke koordinator, hasil terlampir.

Aturan satu pertanyaan untuk memilih mode

💡 Obrolan "Apakah pengguna perlu berbicara dengan agen — dan SAMPAI KAPAN?" = tanpa batas waktu · tugas = hingga kolom diisi · sekali_putar = tidak pernah.

Mode

Memerlukan interaksi manusia

Paralel?

Kembali ke induk

chat (default sub-agen) — asisten dukungan, kopilot terbuka

percakapan lengkap

tidak

manual (melalui transfer)

task — penerimaan, pemesanan, pemecahan masalah

hanya pertanyaan klarifikasi

tidak

otomatis (melalui finish_task, dengan objek yang divalidasi)

single_turn — mengklasifikasikan · mengekstrak · menilai · membuat

tidak ada

ya

otomatis (dengan hasilnya)

mode hanya berjalan di subagen — tidak pernah di koordinator. Selain itu, node alur kerja secara default adalah single_turn (itulah sebabnya L1–L2b tidak pernah menulisnya), sedangkan subagen secara default adalah chat (itulah sebabnya L3a harus melakukannya).

⚠️ Dua catatan versi sebelum Anda membangunnya: (1) task

sebagai node grafik statis bergantung pada versi — pada 2.0.0b1–2.3.0 (pin codelab ini), Workflow(...) akan muncul saat konstruksi; gunakan persis seperti yang dilakukan level ini (koordinator chat dengan sub-agen tugas) atau kirim melalui ctx.run_node. Diangkat di 2.5.0. (2) "Agen tugas harus berupa agen leaf" (tidak memiliki subagen sendiri) adalah batasan ADK yang didokumentasikan — tetapi merupakan kontrak, bukan penjaga runtime: baik 2.3.0 maupun 2.5.0 tidak akan menghentikan Anda. Jangan menganggap tidak adanya error sebagai izin.

💡 Pelajari lebih lanjut: agen task yang disematkan dalam alur kerja grafik (bentuk 2.5.0+), dengan perutean yang dapat mengulang percakapan untuk percobaan ulang: repo pendamping 22_agent_in_workflow · panduan mode lengkap: docs/agent-modes.md.

Anda mungkin bertanya-tanya: apa arti

task

membelikanku sesuatu yang tidak bisa dibeli oleh dua orang lainnya? Tiga hal: kembali otomatis (chat mengalihkan percakapan) · akhir yang diketik (payload finish_task harus divalidasi terhadap skema — Anda mendapatkan data kembali, bukan transkrip) · jeda/lanjutkan (⏸ adalah tugas yang ditahan dan menunggu manusia, bukan penundaan).

👀 Telah dibaca: gear_fittermode="task" + output_schema adalah seluruh kontrak. · ▶ Jalankan. · ✏️ Perubahan: run_desk("I need a hydration vest", "2 liters, medium") — pertanyaan klarifikasi disesuaikan, garis akhir tetap diketik.

11. L4a · Fan-out paralel berukuran runtime (Pilar 3a)

Roadmap — Anda berada di sini: L4a

⚡ Singkatnya: kerangka masih berupa tiga langkah statis — penyembunyian dinamis di dalam langkah tengah, dengan lebar ditentukan oleh data saat runtime.

⚠️ Perhatian: ini adalah langkah paling sulit dalam tangga. Level sebelumnya adalah 44 baris; level ini sekitar 120 baris — tiga agen dan dua node alur kerja, dan semuanya bukan padding. Luangkan waktu sekitar 15 menit, dan fokus pada baris Baca/Jalankan/Ubah di bagian akhir: Anda tidak perlu memahami setiap baris pada bacaan pertama.

Pertanyaan: bentuk pekerjaan bergantung pada input. Anda tidak dapat menggambar grafik sebelumnya. Mulai dengan lebar runtime: biarkan LLM memutuskan berapa banyak sub-pertanyaan.

Bentuk (satu tingkat dalam):

START ─► decompose ─► research_topic (parallel_worker) ─► synthesize
                                 
                             └──┴──┴─ (flat: no children yet)

Pertanyaan terbuka diuraikan menjadi N sub-pertanyaan — N dipilih oleh LLM saat runtime (3–7) — yang masing-masing diteliti secara paralel, lalu disintesis menjadi satu ringkasan.

Colab: jalankan sel L4a · 📁 GitHub: L4a_flat_research/ · 💻 Lokal: python -m L4a_flat_research.deep_research

Alur L4a

🔍 Penanda — tidak ada

dynamic=True

. Dinamis adalah cara menulis, bukan konfigurasi. Dua penanda dan hanya dua: @node(parallel_worker=True) (mengambil daftar berukuran runtime, menjalankan satu pekerja per item) dan ctx.run_node(...) (menjadwalkan node kode secara langsung). Melihat salah satu → Anda berada dalam mode dinamis.

Yang akan Anda lihat: dekomposer mencetak misalnya 5 sub-pertanyaan, yang diteliti secara paralel, lalu ringkasan yang disintesis. Angka berbeda di setiap proses — grafik tetap tidak dapat melakukannya.

Dua tanda pada pekerja yang perlu dipahami:

  • rerun_on_resume=True wajib ada di setiap node yang memanggil ctx.run_node — ADK akan memunculkan ValueError tanpa rerun_on_resume=True. Saat dilanjutkan, node pengiriman harus dieksekusi ulang untuk membangun kembali turunan yang dibuatnya, karena turunan tersebut tidak ada dalam grafik statis.
  • retry_config= membatasi cara ini GAGAL. Pekerja paralel membatalkan setiap saudara dan memunculkan kembali jika satu turunan gagal — jadi tanpa percobaan ulang, satu 429 sementara akan membatalkan seluruh proses, termasuk setiap panggilan yang sudah dibayar. Percobaan ulang dilakukan pada node per item dalam, sehingga setiap cabang melakukan percobaan ulang secara independen.

Anda mungkin bertanya-tanya: dari mana ADK "tahu" bahwa ini bersifat dinamis? Tidak perlu — tidak ada yang dideklarasikan di mana pun. Pengurai menghasilkan daftar saat runtime; pekerja paralel menyesuaikan ukurannya dengan apa pun yang tiba. Dinamisme adalah properti alur data yang Anda tulis, bukan mode yang Anda aktifkan.

👀 Baca: dua tanda pada research_topicparallel_worker dan rerun_on_resume. · ▶ Jalankan. · ✏️ Perubahan: tukar dengan pertanyaan terbuka Anda sendiri — N berubah karena input menentukan lebar.

12. L4b · Menambahkan pembuatan secara rekursif (Pilar 3b)

Roadmap — Anda berada di sini: L4b

⚡ Singkatnya: rekursi ditulis, bukan diberikan — pekerja memanggil dirinya sendiri melalui ctx.run_node, Python biasa — jadi jeda juga harus ditulis. Itu MAX_DEPTH.

Pertanyaan: satu temuan penelitian terkadang memunculkan sub-topik sempit yang layak diselidiki sendiri. Bagaimana cara Anda membiarkan cabang memunculkan lebih banyak pekerjaan paralel — dan membatasinya?

Bentuk (sekarang rekursif):

START ─► decompose ─► research_topic (parallel_worker, recursive) ─► synthesize
                                 
                                 └─ research(q3) ─► maybe spawn children
                               └─── research(q2) ─► maybe spawn children
                             └────── research(q1) ─► maybe spawn children

Colab: jalankan sel L4b · 📁 GitHub: L4b_recursion/ · 💻 Lokal: python -m L4b_recursion.deep_research

Alur L4b

@node(parallel_worker=True, rerun_on_resume=True)
async def research_topic(ctx, node_input):
    finding = coerce(await ctx.run_node(research_agent, node_input=...), ResearchFinding)
    if finding.needs_deeper and finding.deeper_questions and depth < MAX_DEPTH:   # boundary in CODE
        children = await ctx.run_node(research_topic, node_input=deeper)          # recursive fan-out
    yield Event(output={..., "children": children})

🔍 Penanda: ctx.run_node(research_topic, ...) di dalam research_topic itu sendiri — referensi mandiri adalah rekursi — dan penjaga depth < MAX_DEPTH satu baris di atasnya.

Yang akan Anda lihat: node riset mencetak spawning N deeper — rekursi terjadi secara langsung — lalu bentuk pohon runtime (misalnya, 5 top-level + 10 recursive children). Pohon ini berbeda pada setiap eksekusi.

⚠️ Sebelum Anda menaikkan kenop: langit-langit akan tumbuh dengan cepat — MAX_DEPTH=3 mengambil kasus terburuk dari ~30 panggilan menjadi ~93. Di akhir proses, Anda mungkin melihat baris log cancelling N leftover tasks: itu adalah ADK yang menghentikan grup tugas paralelnya setelah hasilnya selesai. Tidak berbahaya — dan bergantung pada konfigurasi logging, Anda mungkin tidak akan pernah melihatnya.

Anda mungkin bertanya-tanya: bukankah rekursif dinamis diaktifkan secara default? Tidak — L4a sepenuhnya dinamis dengan rekursi nol. Dynamic hanya memberikan alur kontrol Python biasa; L4b memilih untuk menulis rekursi dengannya. Dan karena Anda yang menulis rekursi, Anda harus menulis batasnya — di sinilah "biarkan LLM membentuk pekerjaan, pertahankan batas dalam kode" berhenti menjadi slogan.

👀 Baca: penjaga: if finding.needs_deeper and depth < MAX_DEPTH. · ▶ Jalankan. · ✏️ Perubahan: tetapkan MAX_DEPTH = 1 dan jalankan ulang — hierarki diratakan (dan prosesnya menjadi lebih murah). Batasnya adalah MILIK ANDA, dalam kode.

13. L5 · Pola mana yang sebaiknya Anda gunakan?

Roadmap — Anda di sini: L5

⚡ Singkatnya: satu sumbu menentukan segalanya — siapa yang memilih langkah berikutnya: grafik yang Anda buat, LLM, atau kode Anda.

Anda telah membangun ketiganya. Berikut adalah model yang membuatnya berguna: sesuaikan pola dengan bentuk masalah Anda.

Sumbu: siapa yang memutuskan apa yang akan dijalankan selanjutnya?

Pilar

Siapa yang memutuskan apa yang akan dijalankan berikutnya

Bawaan

1 · Grafik

grafik yang Anda gambar

L2a / L2b

2 · Kolaboratif

LLM

L3a / L3b

3 · Dinamis

kode Python Anda, saat runtime

L4a / L4b

Langkah 0: apakah Anda memerlukan grafik?

ADK menyediakan agen alur kerja yang telah dibuat sebelumnyaSequentialAgent, ParallelAgent, LoopAgent. Untuk rangkaian agen biasa, itu adalah jawaban benar yang paling murah dan tidak ada grafik yang perlu dirakit. Lewati mereka saat Anda memerlukan perutean eksplisit (router L2b), penggabungan (JoinNode L2a), atau node yang bukan agen (fungsi biasa, nol panggilan LLM) — yang terakhir biasanya menjadi alasannya.

Would a prebuilt SequentialAgent / ParallelAgent / LoopAgent do?

├─ YES ──────────────────────────────► use it; stop here

└─ NO  I need routing, a join, or non-agent nodes
   
   Can you draw the workflow before the input arrives?
   
   ├─ YES ───────────────────────────► Pillar 1 · Graph workflow    (L2a/L2b)
   
   └─ NO
      ├─ Known team, request picks the subset? ─► Pillar 2 · Collaborative  (L3a/L3b)
      └─ Does the shape depend on the input?  ──► Pillar 3 · Dynamic        (L4a/L4b)

L5 · pola mana

Framing jujur 1.x vs 2

Ini bukan "2.0 dapat melakukan hal-hal yang tidak dapat dilakukan 1.x" — 1.x dapat membangun semuanya. Perubahannya adalah 2.0 memberikan rumah yang lebih langsung untuk setiap bentuk, sehingga alur kontrol yang diketahui meninggalkan perintah dan menjadi struktur yang dapat Anda lihat dan uji.

Pola

Biaya 1.x

Beranda ADK 2

Grafik

4 panggilan LLM dalam build umum; perutean tersembunyi dalam perintah

node fungsi + agen sebagai peer → 1 panggilan, perute if-pernyataan

Kolaboratif

dapat dibangun melalui saluran AgentTool; ParallelAgent selalu semua, transfer_to_agent serial

tim yang dinyatakan: sub_agents + mode="single_turn"

Dinamis

rekursi mengeluarkan Anda dari framework

parallel_worker + ctx.run_node rekursif di dalam framework

Seluruh aplikasi, dan apa yang tidak dapat ditampilkan oleh grafik

Anda kini telah membuat setiap bagian di bawah. Workflow mengekspos strukturnya di graph.edges, sehingga gambar ini dibuat dari kode, bukan digambar dengan tangan — dan apa yang ditemukan introspeksi adalah ringkasan lab ini:

Pilar

Isi graph.edges

Mengapa

1 · Grafik (L2b)

10 tepi, rute, dan semuanya

Anda menggambarnya sebelum ada input yang masuk

2 · Kolaboratif (L3a)

0 tepi — hanya sub_agents + mode

LLM memilih subset per permintaan

3 · Dynamic (L4a/L4b)

3 tepi — identik di kedua gambar

rekursi ditulis dalam Python, bukan dihubungkan dalam grafik

Baris terakhir adalah bukti untuk jawaban pertanyaan L4b: L4a dan L4b memiliki grafik yang sama, dan hanya salah satunya yang berulang.

Yang dapat Anda buat sekarang

Setiap pola yang baru saja Anda jalankan adalah bentuk produk nyata:

Anda telah berlatih

Di alam liar, itu adalah

Mulai dari

Grafik + router (L2a/L2b)

pipeline dokumen, langkah-langkah ETL dengan LLM, rantai peninjauan/persetujuan, alat evaluasi

L2b repo ini

Koordinator + tim single_turn (L3a)

kopilot dukungan dengan tim spesialis, meja penanganan masalah, peninjauan multi-lensa

Mode 2 demo maraton

Agen task (L3b)

formulir pendaftaran, alur pemesanan, orientasi, KYC — semua "kumpulkan lalu lakukan tindakan"

22_agent_in_workflow

Lebar/kedalaman dinamis (L4a/L4b)

agen riset, generator laporan, pemindaian audit atas input berukuran tidak diketahui

Mode 3 demo marathon

Mereka menyusun

Ketiga pola tersebut tidak saling eksklusif. Node grafik dapat memanggil koordinator kolaboratif; spesialis dapat meluncurkan alur kerja dinamis. Pilih pola yang tepat untuk setiap bagian masalah — dengan begitu, Anda dapat menghindari pengubahan setiap sistem agen menjadi satu perintah raksasa.

Seluruh aplikasi — dan apa yang tidak dapat ditampilkan oleh grafik

💡 Coba di alur kerja Anda sendiri: skrip yang menggambar ini adalah scripts/graph_dump.py. Arahkan ke Workflow mana pun dan alat ini akan mencetak tepi sebenarnya — diagram struktural gratis dari apa pun yang Anda buat.

14. Selamat

Sembilan agen, satu tongkat estafet, penyelesaian yang tertib

Anda telah membangun Pelatih Hari Balap Maraton dan, di sepanjang prosesnya, ketiga pola orkestrasi ADK 2.

Yang telah Anda pelajari

  • Prolog — perintah mega yang menciptakan cuacanya sendiri: alasan struktur ada.
  • L0–L1Agent, Runner, alat nyata yang dipilih model untuk dipanggil, dan Workflow pertama Anda (node fungsi + node agen sebagai peer).
  • L2a / L2b — alur kerja grafik: fan-out paralel + JoinNode, lalu pemilihan rute deterministik — satu panggilan LLM.
  • L3a — agen kolaboratif: tim yang sama berjalan di chat (terhenti) lalu single_turn (subset paralel + sintesis) — satu tanda, dua dunia.
  • L3b — Mode task: pertanyaan klarifikasi yang dijeda, kelanjutan yang sudah ditulis, finish_task menampilkan objek yang divalidasi.
  • L4a / L4b — alur kerja dinamis: lebar runtime (fan-out), lalu kedalaman runtime (rekursi) dengan batas dalam kode.
  • L5 — pohon keputusan, dan cara menyusun pola.

Baris yang perlu dipertahankan

Fungsi menyiapkan konteks. Edge menentukan alur kerja. Router memilih jalur. Model menulis jawaban.

Biarkan LLM membentuk pekerjaan, tetapi pertahankan batas dalam kode.

Cocokkan pola dengan bentuk masalah Anda.

Langkah berikutnya

  • Jalankan aplikasi lengkap yang digunakan untuk menyaring tingkat ini — Marathon Race Day Coach, build FastAPI + SSE dengan UI browser yang menampilkan ketiga mode secara live: github.com/cuppibla/adk-2-marathon-demo.
  • Lebih luas: adk-workflows-compared — semua 23 contoh alur kerja ADK 2 resmi, masing-masing dengan port 1.x dan panduan waktu penggunaan. Mulai dengan docs/three-pillars.md, lalu hal-hal yang dilewati codelab ini: 07_loop, 17_request_input, 22_agent_in_workflow.
  • Membuat masalah Anda sendiri: bagian mana yang memiliki struktur yang diketahui (L2), tim yang diketahui (L3a/L3b), bentuk yang tidak diketahui (L4)?
  • Pelajari kode: github.com/cuppibla/adk2-tutorial.
  • Sudah mengikuti workshop? Kredit Anda — dan project yang dibuatnya — tidak akan berlaku selamanya. Untuk terus menjalankan level ini secara gratis, lakukan langkah Penyiapan untuk dibawa pulang: kunci AI Studio gratis, tanpa project Cloud, tanpa penagihan. Menukar satu sel tersebut adalah satu-satunya perubahan.