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 programsLoop 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 threadTitik 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
- Python Asinkron untuk Pengembang Agen
- Antrean Peristiwa dan Perantara Pesan
- Eksekusi Alat Paralel Tanpa Pemblokiran
- Kerangka Kerja Agen Asinkron: LangChain dan Lainnya