Roadmap Belajar

Python untuk AI Engineer

Ini bukan kursus β€œbelajar programming”. Ini kursus belajar Python-nya β€” ditulis untuk software engineer yang sudah paham logika, struktur data, dan HTTP, tapi belum pernah menyentuh Python. Delapan fase, berurutan, tiap fase punya checkpoint konkret.

Durasi
~9,5 minggu
Beban
~8 jam/minggu
Prasyarat
Bisa programming (bahasa apa pun)
Target akhir
AWS GenAI Developer – Pro

Prinsip: jangan belajar semua Python

Python itu luas, dan sebagian besar isinya tidak relevan untuk AI engineering. Waktu terbesar hilang bukan karena materinya susah, tapi karena belajar bagian yang tidak akan pernah dipakai. Daftar ini sama pentingnya dengan daftar materi:

Yang tersisa justru sedikit dan tajam: idiom Python, type hints, Pydantic, async, SDK LLM, FastAPI, testing, packaging. Itulah isi delapan fase di bawah.

0

Setup Toolchain

2–3 jam uvruffmypypytest

Tujuan: punya lingkungan kerja Python modern dan tidak pernah lagi berurusan dengan venv/pip manual.

Perhatian: toolchain Python berubah total dalam 2–3 tahun terakhir. Banyak tutorial masih mengajarkan virtualenv + pip + requirements.txt. Jangan ikuti. Mulai langsung dari uv.

Instalasi & alur kerja harian

# uv β€” package manager + version manager, ditulis dengan Rust (10–100x lebih cepat)
curl -LsSf https://astral.sh/uv/install.sh | sh

uv python install 3.13          # pasang interpreter Python
uv init proyek-pertama          # bikin proyek (pyproject.toml)
cd proyek-pertama
uv add anthropic httpx          # tambah dependency + kunci versi
uv run main.py                  # jalankan (venv dibuat otomatis, tanpa activate)
uv sync                         # samakan venv dengan lockfile

Yang membedakan uv dari pip: ia mengelola interpreter, virtual environment, dependency, dan lockfile sekaligus. Tidak ada lagi langkah source .venv/bin/activate β€” uv run yang mengurus itu.

Empat tool wajib

ToolFungsiPerintah
uvPackage, venv, versi Pythonuv add, uv run, uv sync
ruffLinter + formatter β€” pengganti black, flake8, isort sekaligusuvx ruff check --fix, uvx ruff format
mypyType checker statisuvx mypy .
pytestFramework testinguv run pytest

Editor: VS Code + extension Python dan Ruff. Aktifkan format-on-save sejak hari pertama.

Materi

βœ“ Checkpoint

Kamu bisa uv init proyek baru, tambah dependency, jalankan, dan format kodenya β€” tanpa googling.

1

Sintaks & Idiom Python

1,5 minggu comprehensionunpackingpathlibdataclass

Tujuan: menulis Python yang terasa seperti Python β€” bukan Java atau PHP yang kebetulan pakai sintaks Python.

Kamu sudah paham konsepnya. Yang perlu dipelajari adalah cara Python mengungkapkannya. Bagian ini padat contoh β€” ketik ulang semuanya, jangan copy-paste.

Idiom yang wajib lancar

# ── f-string
f"Halo {nama}, umur {umur + 1}"
f"{harga:,.2f}"                  # format angka: 1,234.50
f"{nilai=}"                      # debug: mencetak "nilai=42"

# ── Unpacking
a, b = b, a                      # swap tanpa variabel bantu
first, *rest = [1, 2, 3, 4]      # first=1, rest=[2,3,4]
config = {**default, **override} # merge dict
def f(*args, **kwargs): ...

# ── Comprehension β€” paling idiomatik, harus refleks
[x * 2 for x in items if x > 0]  # list
{k: v for k, v in pairs}         # dict
{x.id for x in items}            # set
(x for x in big_list)            # generator: lazy, hemat memori

# ── enumerate & zip
# Jangan pernah tulis `for i in range(len(xs))`
for i, item in enumerate(items, start=1): ...
for nama, umur in zip(nama_list, umur_list): ...

# ── Context manager
with open("f.txt") as f: ...     # file otomatis ditutup

# ── Truthiness
nilai = mungkin_none or "default"
hasil = a if kondisi else b
if not items: ...                # bukan `if len(items) == 0`

pathlib β€” jangan pakai os.path lagi

from pathlib import Path

Path("data/file.json").read_text()
(Path.home() / "roadmap" / "catatan.md").exists()
for f in Path("docs").glob("**/*.md"): ...
Path("out").mkdir(parents=True, exist_ok=True)

Struktur data: pilih yang mana?

KebutuhanPakai
Kumpulan data internal@dataclass atau NamedTuple
Validasi data dari luar (API, JSON, env)Pydantic BaseModel β€” Fase 2
Enumenum.StrEnum
Hitung frekuensi, groupingcollections.Counter, defaultdict
Cache hasil fungsifunctools.lru_cache
from dataclasses import dataclass, field

@dataclass
class Dokumen:
    id: str
    isi: str
    skor: float = 0.0
    tag: list[str] = field(default_factory=list)   # jangan `= []`

Jebakan klasik: mutable default argument. def f(items=[]) membuat list yang sama dipakai ulang di setiap pemanggilan. Pakai def f(items=None) lalu items = items or [], atau field(default_factory=list) di dataclass.

Error handling

class RetrievalError(Exception):
    """Gagal mengambil dokumen dari vector store."""

try:
    hasil = ambil(query)
except (ValueError, KeyError) as e:
    logger.warning("gagal parse: %s", e)
    raise RetrievalError("query tidak valid") from e   # jaga rantai penyebab
finally:
    cleanup()

Materi

βœ“ Checkpoint

Tulis ulang satu script utility dari bahasa lamamu ke Python. Kalau hasilnya masih terasa seperti β€œmenulis Java dengan sintaks Python”, ulangi bagian comprehension dan unpacking.

2

Type Hints & Pydantic

1 minggu typingpydanticjson schema

Tujuan: kode yang lolos mypy, dan menguasai Pydantic β€” pondasi yang dipakai FastAPI, structured output LLM, dan definisi tool untuk agent.

Ini pembeda kode Python amatir dengan profesional. Seluruh ekosistem AI modern β€” FastAPI, SDK Anthropic, SDK OpenAI β€” dibangun di atas type hints.

Sintaks modern (Python 3.10+)

from typing import Literal, Any
from collections.abc import Sequence, Iterator, Callable

def cari(query: str, top_k: int = 5) -> list[Dokumen]: ...

def proses(
    data: dict[str, Any],
    mode: Literal["fast", "accurate"] = "fast",
    callback: Callable[[str], None] | None = None,
) -> Iterator[str]: ...

Jangan ikuti tutorial lama: sejak Python 3.9/3.10 pakai list[str], dict[str, int], dan str | None β€” bukan List[str], Dict[str, int], atau Optional[str]. Impor koleksi abstrak dari collections.abc, bukan typing.

Pydantic β€” kuasai ini serius

Pydantic adalah lingua franca Python di dunia AI: validasi request API, parsing output LLM, konfigurasi aplikasi, dan skema tool. Investasi waktu di sini terbayar di semua fase berikutnya.

from typing import Literal
from pydantic import BaseModel, Field, field_validator

class Tiket(BaseModel):
    judul: str = Field(min_length=1, max_length=200)
    prioritas: Literal["low", "medium", "high"] = "medium"
    tag: list[str] = []
    email: str

    @field_validator("email")
    @classmethod
    def cek_email(cls, v: str) -> str:
        if "@" not in v:
            raise ValueError("format email tidak valid")
        return v

t = Tiket.model_validate(json_dari_api)   # parse + validasi
t.model_dump_json()                        # serialize ke JSON
Tiket.model_json_schema()                  # ← JSON Schema

Baris terakhir itu kuncinya. model_json_schema() menghasilkan JSON Schema, dan JSON Schema itulah format yang dipakai untuk mendefinisikan tool pada LLM. Inilah jembatan antara Python biasa dan GenAI engineering β€” dan alasan fase ini tidak boleh dilewati.

Konfigurasi aplikasi

from pydantic_settings import BaseSettings, SettingsConfigDict

class Settings(BaseSettings):
    model_config = SettingsConfigDict(env_file=".env")

    anthropic_api_key: str          # wajib β€” error saat start kalau kosong
    aws_region: str = "us-east-1"
    max_tokens: int = 4096

settings = Settings()   # otomatis baca env var, tervalidasi

Pola ini menggantikan os.getenv() yang tersebar: semua config divalidasi sekali, saat aplikasi start.

Materi

βœ“ Checkpoint

Semua fungsi publik di kodemu punya type hint, dan uvx mypy . lolos tanpa error. Kamu bisa menjelaskan kenapa model_json_schema() penting untuk LLM.

3

Async & HTTP

1 minggu asynciohttpxtenacity

Tujuan: memanggil puluhan API secara paralel dengan batas concurrency, timeout, dan retry yang benar.

Panggilan LLM itu I/O-bound dan lambat β€” bisa puluhan detik. Tanpa async, aplikasimu memblokir dan tidak akan pernah scalable. Ini bagian yang tidak bisa ditawar untuk AI engineer.

Pola dasar

import asyncio
import httpx

async def ambil(client: httpx.AsyncClient, url: str) -> dict:
    r = await client.get(url, timeout=30)
    r.raise_for_status()
    return r.json()

async def main() -> None:
    async with httpx.AsyncClient() as client:
        # gather = jalankan bersamaan, bukan berurutan
        hasil = await asyncio.gather(
            *(ambil(client, u) for u in urls),
            return_exceptions=True,   # satu gagal tidak menjatuhkan semua
        )

asyncio.run(main())

Batasi concurrency β€” wajib untuk API berbayar

sem = asyncio.Semaphore(5)   # maksimal 5 request bersamaan

async def ambil_terbatas(client, url):
    async with sem:
        return await ambil(client, url)

Tanpa ini, gather atas 500 URL akan menembak 500 request sekaligus dan langsung kena rate limit.

Retry dengan exponential backoff

from tenacity import retry, stop_after_attempt, wait_exponential, retry_if_exception_type

@retry(
    stop=stop_after_attempt(5),
    wait=wait_exponential(multiplier=1, min=1, max=30),
    retry=retry_if_exception_type(httpx.HTTPStatusError),
)
async def call_api(): ...

Yang harus dipahami

  • async def / await / asyncio.run() β€” dasar
  • asyncio.gather() β€” fan-out paralel (banyak dokumen, banyak LLM call)
  • asyncio.Semaphore β€” pembatas concurrency
  • asyncio.wait_for() / parameter timeout β€” jangan pernah panggil API tanpa timeout
  • async for / async with β€” dipakai langsung untuk streaming LLM di Fase 4
  • Kapan TIDAK pakai async: pekerjaan CPU-bound (justru melambat), atau script sekali jalan

Soal HTTP client: pakai httpx, bukan requests. httpx punya API sync dan async dalam satu library dengan bentuk yang hampir identik; requests tidak mendukung async sama sekali.

Materi

βœ“ Checkpoint

Buat script yang fetch 20 URL paralel dengan batas concurrency 5, timeout, dan retry otomatis. Ukur waktunya, bandingkan dengan versi sequential β€” kamu harus bisa menjelaskan selisihnya.

4

Bicara dengan LLM

1,5 minggu anthropic sdkstreamingtool usebedrock

Tujuan: menguasai empat pilar aplikasi LLM β€” panggilan dasar, streaming, tool use, dan structured output β€” lalu memindahkannya ke AWS Bedrock tanpa mengubah logika aplikasi.

4.1 Β· Panggilan dasar

uv add anthropic
export ANTHROPIC_API_KEY=sk-ant-...
import anthropic

client = anthropic.Anthropic()   # membaca ANTHROPIC_API_KEY dari environment

response = client.messages.create(
    model="claude-opus-5",
    max_tokens=16000,
    system="Kamu asisten yang menjawab ringkas dalam bahasa Indonesia.",
    messages=[{"role": "user", "content": "Jelaskan apa itu RAG."}],
)

# response.content adalah LIST of block, bukan string. Selalu cek .type
for block in response.content:
    if block.type == "text":
        print(block.text)

Empat hal yang harus benar-benar kamu internalisasi di sini:

  • API-nya stateless. Riwayat percakapan kamu yang kirim ulang setiap kali, lewat array messages. Tidak ada session di sisi server.
  • response.content itu list berisi content block (text, thinking, tool_use) β€” bukan string.
  • response.usage (input_tokens, output_tokens) adalah dasar perhitungan biaya.
  • response.stop_reason β€” end_turn, max_tokens, tool_use, refusal. Cek ini sebelum membaca content.

4.2 Β· Streaming

Wajib untuk UX chat, dan wajib saat max_tokens besar β€” tanpa streaming, koneksi HTTP bisa timeout.

with client.messages.stream(
    model="claude-opus-5",
    max_tokens=64000,
    messages=[{"role": "user", "content": "Tulis artikel panjang"}],
) as stream:
    for teks in stream.text_stream:
        print(teks, end="", flush=True)

    final = stream.get_final_message()   # objek lengkap setelah selesai
    print(f"\n\nToken keluar: {final.usage.output_tokens}")

Versi async tinggal ganti jadi async with + async for β€” inilah gunanya Fase 3.

4.3 Β· Tool use β€” fondasi agent

Ini konsep terpenting di GenAI engineering. LLM tidak mengeksekusi apa pun. Ia hanya meminta kamu menjalankan sebuah fungsi; kamu jalankan, lalu kirim hasilnya kembali. Perulangan inilah yang disebut agentic loop.

from anthropic import beta_tool

@beta_tool
def cari_tiket(status: str, limit: int = 10) -> str:
    """Cari tiket support berdasarkan status.

    Args:
        status: Status tiket, misal "open" atau "closed".
        limit: Jumlah maksimal hasil yang dikembalikan.
    """
    return db.query(status=status, limit=limit)

# SDK mengurus loop-nya: panggil API β†’ eksekusi tool β†’ kirim hasil β†’ ulangi
runner = client.beta.messages.tool_runner(
    model="claude-opus-5",
    max_tokens=16000,
    tools=[cari_tiket],
    messages=[{"role": "user", "content": "Ada berapa tiket yang masih open?"}],
)

for message in runner:
    print(message)

Skema tool dibuat otomatis dari type hint dan docstring. Sekarang jelas kenapa Fase 2 tidak boleh dilewati.

Setelah nyaman dengan tool_runner, pelajari juga manual loop-nya: cek stop_reason == "tool_use", ambil block tool_use, kirim balik tool_result dengan tool_use_id yang cocok. Tujuannya supaya kamu paham apa yang sebenarnya terjadi β€” bukan sekadar memakai abstraksi yang terasa ajaib.

4.4 Β· Structured output

Memaksa LLM mengeluarkan JSON yang tervalidasi β€” inilah yang membuat LLM layak dipakai di dalam pipeline.

from pydantic import BaseModel

class Ekstraksi(BaseModel):
    nama: str
    email: str
    minat: list[str]

response = client.messages.parse(
    model="claude-opus-5",
    max_tokens=4096,
    messages=[{"role": "user", "content": "Ekstrak: Budi ([email protected]), tertarik API dan SDK."}],
    output_format=Ekstraksi,
)

data = response.parsed_output    # instance Ekstraksi, sudah tervalidasi
print(data.nama, data.minat)

4.5 Β· Jembatan ke AWS Bedrock

Bagian yang langsung nyambung ke target sertifikasi. Kode aplikasinya sama persis β€” yang berbeda hanya client dan prefix model ID.

uv add "anthropic[bedrock]"
from anthropic import AnthropicBedrockMantle

client = AnthropicBedrockMantle(aws_region="us-east-1")   # kredensial dari AWS profile/env

response = client.messages.create(
    model="anthropic.claude-opus-5",   # ← prefix "anthropic." khusus Bedrock
    max_tokens=16000,
    messages=[{"role": "user", "content": "Halo"}],
)

Setelah client dibuat, messages.create, .stream, dan tool use semuanya identik. Jadi semua yang kamu pelajari di 4.1–4.4 langsung terpakai di Bedrock.

Sebagai pembanding, pelajari juga Converse API milik AWS lewat boto3 β€” API netral-vendor yang bentuknya seragam untuk semua model di Bedrock. Ini yang paling sering muncul di materi ujian AWS.

4.6 Β· Yang juga harus dipahami

KonsepKenapa penting
Prompt cachingHemat biaya besar untuk konteks berulang. Cache bekerja secara prefix match β€” satu byte berubah di depan, seluruh cache setelahnya hangus.
Token countingclient.messages.count_tokens() untuk estimasi biaya sebelum kirim. Jangan pakai tiktoken β€” itu tokenizer OpenAI dan hasilnya salah untuk Claude.
Adaptive thinkingthinking={"type": "adaptive"} plus output_config={"effort": ...} untuk tugas yang butuh penalaran dalam.
Error handlingTangkap RateLimitError, APIStatusError, APIConnectionError secara terpisah β€” jangan satu except Exception. Yang retryable dan tidak harus dibedakan.
Pemilihan modelPilih per-rute, bukan satu model untuk semua: yang paling capable untuk reasoning berat, yang lebih ringan untuk klasifikasi dan tugas sederhana.

Materi

βœ“ Checkpoint

Buat CLI chatbot yang: streaming, mengingat riwayat percakapan, punya 2 tool (misal kalkulator dan pencarian file lokal), memakai structured output untuk satu perintah, dan mencetak total biaya di akhir sesi.

5

Bangun API dengan FastAPI

1 minggu fastapissedependency injection

Tujuan: membungkus aplikasi LLM-mu jadi HTTP API yang bisa dipakai frontend, lengkap dengan streaming token.

FastAPI adalah standar de facto untuk men-serve model di Python. Ia dibangun di atas Pydantic dan async β€” dua hal yang sudah kamu kuasai di Fase 2 dan 3, jadi fase ini akan terasa cepat.

from fastapi import FastAPI, Depends, HTTPException
from pydantic import BaseModel

app = FastAPI()

class ChatRequest(BaseModel):
    pesan: str
    session_id: str

class ChatResponse(BaseModel):
    balasan: str
    token_terpakai: int

@app.post("/chat")
async def chat(req: ChatRequest) -> ChatResponse:
    ...   # validasi request & serialisasi response otomatis dari type hint

Streaming ke browser (SSE)

FastAPI punya dukungan Server-Sent Events bawaan lewat EventSourceResponse. Cukup yield dari path operation β€” keep-alive ping, header anti-cache, dan pencegahan buffering proxy diurus otomatis.

from collections.abc import AsyncIterable
from fastapi.sse import EventSourceResponse

@app.post("/chat/stream", response_class=EventSourceResponse)
async def chat_stream(req: ChatRequest) -> AsyncIterable[str]:
    async with async_client.messages.stream(
        model="claude-opus-5",
        max_tokens=16000,
        messages=[{"role": "user", "content": req.pesan}],
    ) as stream:
        async for teks in stream.text_stream:
            yield teks

Yang perlu dikuasai

  • Request/response model Pydantic β€” validasi otomatis, plus dokumentasi interaktif gratis di /docs
  • Depends() β€” dependency injection untuk auth, koneksi DB, dan client LLM
  • EventSourceResponse β€” streaming token ke browser
  • lifespan β€” buat client LLM sekali saat startup, bukan tiap request
  • BackgroundTasks β€” pekerjaan yang tidak perlu ditunggu klien
  • Exception handler global β€” ubah error internal jadi respons HTTP yang rapi
  • Jalankan dengan uv run uvicorn main:app --reload

Jebakan async di FastAPI: menaruh kode blocking (misal requests.get() atau query DB sync) di dalam async def akan memblokir seluruh event loop dan menjatuhkan throughput semua request lain. Kalau fungsimu blocking, deklarasikan sebagai def biasa β€” FastAPI otomatis menjalankannya di threadpool.

Materi

βœ“ Checkpoint

Endpoint chat streaming yang berjalan dan bisa dicoba dari browser, dengan client LLM dibuat sekali di lifespan.

6

Data, Testing, Deploy

1,5 minggu numpypytestdockerlogging

Tujuan: proyek yang punya struktur benar, ada testnya, dan bisa dijalankan orang lain lewat satu perintah Docker.

Data β€” secukupnya saja

LibrarySejauh apa perlu
jsonWajib lancar. json.dumps(d, sort_keys=True) untuk output deterministik β€” penting agar prompt caching tidak batal.
numpySecukupnya: array, dot product, cosine similarity β€” untuk bekerja dengan embedding.
pandasDasar saja: read_csv, filter, groupby. Jangan habiskan seminggu di sini.
sqlite3 / SQLAlchemyMenyimpan riwayat percakapan dan metadata dokumen.
ChromaDBVector store lokal untuk belajar RAG. Di AWS nanti: OpenSearch atau pgvector.
import numpy as np

def cosine_similarity(a: np.ndarray, b: np.ndarray) -> float:
    return float(np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b)))

Testing

import pytest
from myapp import ekstrak

def test_ekstrak_email():
    assert ekstrak("Hubungi [email protected]").email == "[email protected]"

@pytest.mark.parametrize("teks,jumlah", [("a b", 2), ("satu", 1), ("", 0)])
def test_hitung_kata(teks, jumlah):
    assert hitung_kata(teks) == jumlah

@pytest.fixture
def fake_llm(monkeypatch):
    ...   # mock LLM β€” JANGAN panggil API asli di unit test

Prinsip testing aplikasi LLM: mock panggilan LLM di unit test supaya deterministik, gratis, dan cepat. Untuk menilai kualitas output LLM, itu bukan unit test β€” itu eval, dijalankan terpisah dengan dataset dan rubrik penilaian sendiri. Mencampur keduanya membuat CI-mu lambat sekaligus flaky.

Struktur proyek & deploy

proyek/
β”œβ”€β”€ pyproject.toml
β”œβ”€β”€ Dockerfile
β”œβ”€β”€ src/myapp/
β”‚   β”œβ”€β”€ __init__.py
β”‚   β”œβ”€β”€ main.py        # entrypoint FastAPI
β”‚   β”œβ”€β”€ llm.py         # semua interaksi dengan LLM
β”‚   β”œβ”€β”€ models.py      # model Pydantic
β”‚   └── settings.py    # config
└── tests/
  • Docker: base python:3.13-slim, multi-stage build, pakai uv sync --frozen
  • Logging: modul logging bawaan, dikonfigurasi sekali di entrypoint β€” bukan print()
  • Secret dari environment variable lewat pydantic-settings β€” jangan pernah hardcode API key

Materi

βœ“ Checkpoint

Proyek dengan struktur src/ di atas, test lolos, ter-Dockerize, dan berjalan dengan satu docker run.

7

Capstone: RAG Chatbot

2 minggu ragembeddingvector storeevaluasi

Tujuan: satu aplikasi utuh yang menggabungkan seluruh fase β€” dan kebetulan persis arsitektur yang diuji di sertifikasi.

Teori tanpa proyek akan hilang dalam sebulan. Kerjakan satu ini sampai tuntas: RAG chatbot atas dokumenmu sendiri.

Requirement

  1. Ingest β€” baca folder PDF/Markdown β†’ chunking β†’ embedding β†’ simpan ke ChromaDB
  2. Retrieval β€” cari chunk paling relevan dengan cosine similarity
  3. Generation β€” kirim chunk + pertanyaan ke LLM, streaming jawaban
  4. Sitasi β€” sebutkan chunk mana yang dipakai; jangan biarkan model mengarang sumber
  5. API β€” FastAPI dengan endpoint streaming SSE
  6. Riwayat β€” percakapan tersimpan di SQLite
  7. Tool β€” LLM bisa memanggil cari_dokumen() sendiri, bukan retrieval yang selalu dipaksa di depan
  8. Biaya β€” tracking token per-request dari response.usage
  9. Test β€” untuk chunking dan retrieval, dengan LLM di-mock
  10. Docker β€” satu perintah untuk menjalankan semuanya

Kenapa proyek ini: arsitekturnya persis yang diuji di AWS Certified Generative AI Developer – Professional, di Domain 1 dan 2 yang menyumbang 57% bobot ujian. Nanti tinggal ganti komponennya ke versi AWS: ChromaDB β†’ Bedrock Knowledge Bases, tool manual β†’ Bedrock Agents, filter β†’ Bedrock Guardrails.

Bonus kalau masih semangat

  • Guardrails β€” filter input/output, deteksi PII sebelum masuk prompt
  • Evaluation β€” dataset 20 pertanyaan + penilaian jawaban dengan LLM-as-judge
  • Contextual retrieval β€” teknik menambahkan konteks ke tiap chunk sebelum embedding, mengurangi kegagalan retrieval secara signifikan
  • Deploy ke AWS Lambda dengan container image

Materi

βœ“ Checkpoint

RAG chatbot berjalan end-to-end: ingest dokumen, jawab dengan sitasi yang benar, streaming ke browser, dan laporkan biaya per percakapan.

Aturan main

  1. Ketik ulang setiap contoh kode. Copy-paste tidak menghasilkan pembelajaran apa pun.
  2. Baca error message sampai habis. Traceback Python sangat informatif β€” baris paling bawah yang paling penting.
  3. Macet lebih dari 30 menit? Lanjut dulu. Sering kali paham belakangan setelah melihat konteks lain.
  4. Type hint sejak hari pertama. β€œNanti saja” berarti tidak pernah.
  5. Satu proyek nyata mengalahkan sepuluh tutorial. Kerjakan checkpoint-nya, jangan dilewati.
  6. Jangan sentuh LangChain dulu. Pelajari SDK mentahnya supaya paham apa yang sebenarnya terjadi. Framework adalah abstraksi di atas hal yang harus kamu pahami lebih dulu.

Setelah ini

Lanjut ke roadmap AWS: menutup gap serverless, IAM, IaC, dan observability, lalu masuk ke Bedrock secara mendalam menuju AWS Certified Generative AI Developer – Professional (AIP-C01). Python yang kamu bangun di sini akan jadi bahasa kerja untuk semuanya.