0Pricing
AI Agents · Pelajaran

Python Asinkron untuk Pengembang Agen

Dasar-dasar asyncio, async def, await, dan loop peristiwa — model mental asinkron.

Python Asinkron untuk Pengembang Agen adalah pelajaran AI Agents gratis di CoddyKit. Ini adalah pelajaran 1 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar AI Agents, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus AI Agents mencakup 4 pelajaran total.

Mengapa Agen Memerlukan Asinkron?

Agen melakukan banyak panggilan yang terikat I/O: API LLM, permintaan web, dan kueri basis data. Kode sinkron menunggu tanpa melakukan pekerjaan lain selama panggilan tersebut selesai. Kode asinkron menjalankan pekerjaan lain selama waktu tunggu itu sehingga meningkatkan kapasitas pemrosesan secara drastis.

Dasar Asinkron: async def dan await

async def mendeklarasikan fungsi korutin. await menangguhkan eksekusi hingga operasi yang ditunggu selesai, sehingga loop peristiwa dapat menjalankan korutin lain sementara itu.

import asyncio

async def fetch_data(source: str) -> str:
    print(f'Starting fetch from {source}')
    await asyncio.sleep(1)  # Simulates a network call
    print(f'Finished fetch from {source}')
    return f'Data from {source}'

async def main():
    # Sequential: takes 2 seconds total
    result1 = await fetch_data('source-A')
    result2 = await fetch_data('source-B')
    print('Sequential results:', result1, result2)

asyncio.run(main())

# asyncio.run() starts the event loop and runs main()
# It is the entry point for async programs

Loop Peristiwa

Loop peristiwa adalah inti asyncio. Loop ini mengelola antrean korutin dan panggilan balik I/O, lalu menjalankannya saat sudah siap. Semua kode asinkron berjalan di dalam loop peristiwa pada satu Thread.

import asyncio

async def task_a():
    print('Task A: start')
    await asyncio.sleep(2)
    print('Task A: done')

async def task_b():
    print('Task B: start')
    await asyncio.sleep(1)
    print('Task B: done')

async def main():
    # asyncio.gather runs both tasks concurrently
    # Total time: ~2 seconds (not 3)
    await asyncio.gather(task_a(), task_b())
    print('Both tasks complete')

# Expected output order:
# Task A: start
# Task B: start
# Task B: done   <- after 1s
# Task A: done   <- after 2s
# Both tasks complete
asyncio.run(main())

Korutin vs Thread

Korutin bersifat kooperatif: korutin menyerahkan kendali secara eksplisit dengan await. Thread bersifat preemptif: OS dapat berpindah di antaranya kapan saja. Korutin lebih ringan, tidak mengalami masalah GIL untuk I/O, dan lebih mudah dianalisis.

import asyncio
import threading
import time

# Thread approach: multiple OS threads
def thread_worker(name):
    print(f'Thread {name}: start')
    time.sleep(1)  # Blocks the thread
    print(f'Thread {name}: done')

threads = [threading.Thread(target=thread_worker, args=(i,)) for i in range(3)]
for t in threads:
    t.start()
for t in threads:
    t.join()

print('---')

# Coroutine approach: single-threaded event loop
async def coro_worker(name):
    print(f'Coro {name}: start')
    await asyncio.sleep(1)  # Suspends, does NOT block other coroutines
    print(f'Coro {name}: done')

async def main():
    await asyncio.gather(*[coro_worker(i) for i in range(3)])

asyncio.run(main())
# Both approaches run 3 tasks in ~1 second total, but coroutines use one thread

Titik Masuk asyncio.run()

asyncio.run() membuat loop peristiwa baru, menjalankan korutin yang diberikan hingga selesai, lalu menutup loop tersebut. Ini adalah titik masuk standar untuk program asinkron di Python 3.7+.

import asyncio

async def agent_main():
    print('Agent starting')
    # All agent async work goes here
    results = await asyncio.gather(
        asyncio.sleep(0.1),  # Simulated LLM call
        asyncio.sleep(0.1),  # Simulated DB query
    )
    print('Agent done')
    return 'complete'

# Run the agent
result = asyncio.run(agent_main())
print('Result:', result)

# WRONG: calling asyncio.run() inside an already-running event loop
# In Jupyter notebooks, use: await agent_main() directly
# Or: nest_asyncio.apply() then asyncio.run()

Kesalahan Umum: Pemblokiran dalam Konteks Asinkron

Jangan pernah memanggil fungsi yang memblokir (time.sleep, requests.get, I/O berkas sinkron) di dalam kode asinkron. Hal ini memblokir seluruh loop peristiwa sehingga semua konkurensi terhenti.

import asyncio
import time
import httpx

# WRONG: blocks the event loop
async def bad_agent_step():
    time.sleep(2)          # Blocks all other coroutines
    # requests.get(url)    # Also blocks - do NOT use requests in async code
    return 'done'

# RIGHT: use async equivalents
async def good_agent_step():
    await asyncio.sleep(2)  # Suspends, other coroutines can run
    
    async with httpx.AsyncClient() as client:
        response = await client.get('https://api.example.com/data')
    return response.text

# For CPU-intensive work: use run_in_executor
import concurrent.futures

async def cpu_intensive_step(data: str):
    loop = asyncio.get_event_loop()
    with concurrent.futures.ProcessPoolExecutor() as pool:
        result = await loop.run_in_executor(pool, expensive_cpu_fn, data)
    return result

def expensive_cpu_fn(data):
    # CPU-bound work runs in separate process
    return data.upper()

print('Blocking vs non-blocking patterns demonstrated')

Lupa await: Kesalahan Tersembunyi

Melupakan await tidak menimbulkan kesalahan—sebaliknya, kode tersebut mengembalikan objek korutin, bukan hasilnya. Ini adalah kesalahan tersembunyi yang menyebabkan kesalahan pada tahap berikutnya atau hasil kosong.

import asyncio

async def get_answer() -> str:
    await asyncio.sleep(0.1)
    return 'The answer is 42'

async def bad_call():
    result = get_answer()   # WRONG: forgot await
    print(type(result))     # <class 'coroutine'> - not a string!
    # Using result as a string here causes AttributeError or wrong behavior
    return result

async def good_call():
    result = await get_answer()  # CORRECT
    print(type(result))           # <class 'str'>
    return result

async def main():
    bad = await bad_call()
    print('Bad result:', bad)    # coroutine object, not the string
    
    good = await good_call()
    print('Good result:', good)  # 'The answer is 42'
    
    # Clean up the uncollected coroutine
    if asyncio.iscoroutine(bad):
        bad.close()

asyncio.run(main())

Masalah Loop Peristiwa Bersarang

Memanggil asyncio.run() di dalam loop peristiwa yang sedang berjalan (misalnya, Jupyter atau FastAPI) menimbulkan RuntimeError. Solusinya: gunakan await secara langsung, atau gunakan nest_asyncio untuk notebook.

import asyncio

async def my_agent_coroutine():
    await asyncio.sleep(0.1)
    return 'done'

# In FastAPI or other async frameworks, the event loop is already running
# Use await directly in async endpoints:
async def fastapi_endpoint():
    # WRONG inside async context:
    # result = asyncio.run(my_agent_coroutine())  # RuntimeError!
    
    # CORRECT: just await
    result = await my_agent_coroutine()
    return result

# In Jupyter notebooks: install nest_asyncio
# import nest_asyncio
# nest_asyncio.apply()
# Then asyncio.run() works

# Detect if running in event loop:
def run_agent(coro):
    try:
        loop = asyncio.get_running_loop()
        # Already in async context
        import concurrent.futures
        with concurrent.futures.ThreadPoolExecutor() as pool:
            future = pool.submit(asyncio.run, coro)
            return future.result()
    except RuntimeError:
        # No running loop
        return asyncio.run(coro)

print('Nested event loop solution defined')

asyncio.create_task

Gunakan asyncio.create_task() untuk menjadwalkan korutin agar berjalan tanpa langsung menunggunya. Dengan demikian, Anda dapat memulai beberapa tugas dan menunggu penyelesaiannya nanti.

import asyncio

async def background_job(job_id: int) -> str:
    await asyncio.sleep(0.5)
    return f'Job {job_id} completed'

async def main():
    # Start all tasks without waiting
    task1 = asyncio.create_task(background_job(1))
    task2 = asyncio.create_task(background_job(2))
    task3 = asyncio.create_task(background_job(3))
    
    # Do other work while tasks run
    print('Tasks started, doing other work...')
    await asyncio.sleep(0.1)
    print('Other work done')
    
    # Now wait for all tasks
    results = await asyncio.gather(task1, task2, task3)
    print('All results:', results)
    
    # Or wait for the first to complete
    task_a = asyncio.create_task(background_job(4))
    task_b = asyncio.create_task(background_job(5))
    done, pending = await asyncio.wait([task_a, task_b], return_when=asyncio.FIRST_COMPLETED)
    for t in pending:
        t.cancel()  # Cancel remaining tasks
    print('First result:', done.pop().result())

asyncio.run(main())

Pengelola Konteks Asinkron

Banyak pustaka asinkron menggunakan pengelola konteks asinkron dengan async with. Hal ini memastikan penyiapan dan pembongkaran koneksi serta sumber daya yang benar dalam kode asinkron.

import asyncio
import httpx

async def fetch_multiple_urls(urls: list) -> list:
    # async with ensures the client is properly closed
    async with httpx.AsyncClient(timeout=10.0) as client:
        # Fetch all URLs concurrently
        tasks = [client.get(url) for url in urls]
        responses = await asyncio.gather(*tasks, return_exceptions=True)
        
        results = []
        for url, response in zip(urls, responses):
            if isinstance(response, Exception):
                results.append({'url': url, 'error': str(response)})
            else:
                results.append({'url': url, 'status': response.status_code})
        return results

# Async generators for streaming
async def stream_agent_events():
    events = ['thinking', 'searching', 'generating', 'done']
    for event in events:
        await asyncio.sleep(0.2)  # Simulate event arrival
        yield event

async def consume_stream():
    async for event in stream_agent_events():
        print(f'Event: {event}')

asyncio.run(consume_stream())

Penanganan Kesalahan dalam Kode Asinkron

Gunakan asyncio.gather(..., return_exceptions=True) untuk menangkap kegagalan setiap tugas tanpa membatalkan seluruh kumpulan. Periksa setiap hasil berdasarkan jenis pengecualiannya.

import asyncio

async def might_fail(task_id: int) -> str:
    await asyncio.sleep(0.1)
    if task_id == 2:
        raise ValueError(f'Task {task_id} failed')
    return f'Task {task_id} succeeded'

async def robust_gather():
    tasks = [might_fail(i) for i in range(1, 5)]
    
    # return_exceptions=True: exceptions are returned as values, not raised
    results = await asyncio.gather(*tasks, return_exceptions=True)
    
    successes = []
    failures = []
    for i, result in enumerate(results):
        if isinstance(result, Exception):
            failures.append({'task': i + 1, 'error': str(result)})
        else:
            successes.append(result)
    
    print(f'Succeeded: {len(successes)}, Failed: {len(failures)}')
    print('Failures:', failures)
    return successes, failures

asyncio.run(robust_gather())

Uji Pemahaman: Python Asinkron

Uji pemahaman Anda tentang Python asinkron untuk pengembangan agen.

Ringkasan Python Asinkron

Aturan utama Python asinkron bagi pengembang agen: gunakan async def/await untuk semua operasi yang terikat I/O; jangan pernah memanggil fungsi yang memblokir dalam konteks asinkron; gunakan asyncio.gather() untuk eksekusi paralel; gunakan return_exceptions=True untuk panggilan paralel yang toleran terhadap kesalahan; gunakan async with untuk pengelolaan sumber daya; jalankan pekerjaan yang intensif CPU dalam eksekutor kumpulan proses.

Pertanyaan yang Sering Diajukan

Apakah pelajaran “Python Asinkron untuk Pengembang Agen” gratis?

Ya — teks lengkap “Python Asinkron untuk Pengembang Agen” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus AI Agents, upgrade ke CoddyKit PRO. Kursus AI Agents mencakup 4 pelajaran total.

Apa yang akan aku pelajari di “Python Asinkron untuk Pengembang Agen”?

Dasar-dasar asyncio, async def, await, dan loop peristiwa — model mental asinkron. Kamu berlatih AI Agents dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.

Apakah aku perlu pengalaman untuk memulai AI Agents?

Tidak diperlukan pengalaman sebelumnya. AI Agents di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 1 dari 4.

Berapa lama pelajaran “Python Asinkron untuk Pengembang Agen” memakan waktu?

Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.

Bisakah aku menulis dan menjalankan kode dalam pelajaran AI Agents ini?

Ya. Setiap pelajaran AI Agents menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.

Semua pelajaran dalam kursus ini

  1. Python Asinkron untuk Pengembang Agen
  2. Antrean Peristiwa dan Perantara Pesan
  3. Eksekusi Alat Paralel Tanpa Pemblokiran
  4. Kerangka Kerja Agen Asinkron: LangChain dan Lainnya
← Kembali ke AI Agents