0Pricing
AI Engineering Academy · Pelajaran

Pemanggilan Fungsi secara Paralel

Tangani respons ketika model memanggil beberapa fungsi secara bersamaan, jalankan fungsi-fungsi tersebut secara paralel dengan asyncio, lalu gabungkan hasilnya dalam satu panggilan API lanjutan.

Pemanggilan Fungsi secara Paralel adalah pelajaran AI Engineering Academy gratis di CoddyKit. Ini adalah pelajaran 3 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 Engineering Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus AI Engineering Academy mencakup 4 pelajaran total.

Apa Itu Pemanggilan Fungsi Paralel?

Model OpenAI dapat memanggil beberapa fungsi secara bersamaan dalam satu respons ketika jawaban memerlukan informasi dari beberapa sumber yang tidak saling bergantung. Alih-alih merangkai pemanggilan alat secara berurutan—dengan setiap pemanggilan menunggu pemanggilan sebelumnya—model menghasilkan beberapa pemanggilan alat sekaligus. Aplikasi Anda menjalankannya secara paralel dan mengirimkan semua hasil secara bersamaan, sehingga latensi berkurang secara drastis.

Mengenali Pemanggilan Alat Paralel

Ketika model mengeluarkan pemanggilan alat paralel, pesan respons berisi daftar tool_calls dengan lebih dari satu entri. Setiap entri memiliki id unik, nama fungsi, dan argumen. Anda harus memproses semuanya sebelum melakukan panggilan API lanjutan—model mengharapkan hasil untuk setiap pemanggilan alat yang dikeluarkannya.

from openai import OpenAI
import json

client = OpenAI()

# A question that naturally requires two independent lookups
response = client.chat.completions.create(
    model='gpt-4o',
    messages=[{'role': 'user', 'content': 'Compare the weather in London and Tokyo right now.'}],
    tools=tools
)

message = response.choices[0].message
print('Number of tool calls:', len(message.tool_calls))
# Might print: Number of tool calls: 2

for tc in message.tool_calls:
    print(f'  {tc.function.name}({tc.function.arguments})')
# get_current_weather({"location": "London"})
# get_current_weather({"location": "Tokyo"})

Menjalankan Pemanggilan Alat dengan asyncio

Jalankan beberapa pemanggilan alat secara bersamaan menggunakan asyncio.gather(). Setiap fungsi alat berjalan dalam coroutine terpisah, dan semua hasil dikumpulkan setelah seluruh coroutine selesai. Cara ini jauh lebih cepat daripada eksekusi berurutan ketika setiap pemanggilan alat melakukan permintaan jaringan.

import asyncio
import json

async def execute_tool_call_async(tool_call) -> tuple:
    '''Execute a single tool call and return (tool_call_id, result).'''
    name = tool_call.function.name
    args = json.loads(tool_call.function.arguments)

    # Async version of your tool (uses httpx, aiohttp, etc.)
    if name == 'get_current_weather':
        result = await async_get_weather(**args)
    elif name == 'get_stock_price':
        result = await async_get_stock(**args)
    else:
        result = f'Unknown tool: {name}'

    return tool_call.id, str(result)

async def execute_all_parallel(tool_calls) -> list:
    '''Execute all tool calls concurrently.'''
    tasks = [execute_tool_call_async(tc) for tc in tool_calls]
    results = await asyncio.gather(*tasks, return_exceptions=True)
    return results

Mengirimkan Semua Hasil Secara Bersamaan

Setelah menjalankan semua pemanggilan alat paralel, tambahkan setiap hasil sebagai pesan role='tool' terpisah ke percakapan. Setiap pesan harus menyertakan tool_call_id yang sesuai. Kirim semuanya dalam satu panggilan API lanjutan agar model dapat menyatukan semua hasil menjadi satu jawaban yang koheren.

async def run_parallel_tool_calls(user_message: str) -> str:
    messages = [{'role': 'user', 'content': user_message}]

    response = client.chat.completions.create(
        model='gpt-4o', messages=messages, tools=tools
    )
    assistant_message = response.choices[0].message
    messages.append(assistant_message)  # Add assistant's tool_calls

    if response.choices[0].finish_reason == 'tool_calls':
        # Execute all tool calls in parallel
        results = await execute_all_parallel(assistant_message.tool_calls)

        # Add all results to conversation
        for tool_call_id, result in results:
            messages.append({
                'role': 'tool',
                'tool_call_id': tool_call_id,
                'content': result
            })

        # One more API call to synthesize results
        final = client.chat.completions.create(model='gpt-4o', messages=messages)
        return final.choices[0].message.content

    return assistant_message.content

Menggunakan ThreadPoolExecutor untuk Alat Sinkron

Jika fungsi alat Anda bersifat sinkron (menggunakan requests, bukan httpx async), Anda tetap dapat menjalankannya secara paralel menggunakan concurrent.futures.ThreadPoolExecutor. Penyiapannya lebih sederhana, tetapi sedikit kurang efisien dibandingkan kode asinkron murni.

from concurrent.futures import ThreadPoolExecutor, as_completed
import json

def execute_all_with_threads(tool_calls) -> list:
    results = []
    with ThreadPoolExecutor(max_workers=len(tool_calls)) as executor:
        future_to_id = {
            executor.submit(execute_tool_call, tc): tc.id
            for tc in tool_calls
        }
        for future in as_completed(future_to_id):
            tool_call_id = future_to_id[future]
            try:
                result = future.result(timeout=15)
            except Exception as e:
                result = f'Tool failed: {str(e)}'
            results.append((tool_call_id, str(result)))
    return results

Menangani Kegagalan Alat Secara Individual

Ketika menjalankan pemanggilan alat secara paralel, satu pemanggilan mungkin gagal sementara yang lain berhasil. Jangan pernah membiarkan satu kegagalan menghambat yang lain. Gunakan return_exceptions=True dalam asyncio.gather() untuk mengumpulkan semua hasil meskipun beberapa pemanggilan menghasilkan pengecualian. Ubah pengecualian menjadi string kesalahan agar model menerima semua hasil dan dapat mempertimbangkan kegagalan sebagian.

async def safe_execute_all(tool_calls) -> list:
    tasks = [execute_tool_call_async(tc) for tc in tool_calls]
    raw_results = await asyncio.gather(*tasks, return_exceptions=True)

    results = []
    for tc, result in zip(tool_calls, raw_results):
        if isinstance(result, Exception):
            results.append((tc.id, f'Tool error: {str(result)}'))
        else:
            tool_call_id, output = result
            results.append((tool_call_id, output))
    return results

Kapan Model Menggunakan Pemanggilan Paralel

Model mengeluarkan pemanggilan alat paralel ketika menentukan bahwa informasi yang diperlukan dapat dikumpulkan secara independen—hasil yang satu tidak bergantung pada hasil lainnya. Contohnya adalah mengambil harga saham untuk beberapa kode saham, mendapatkan cuaca di beberapa kota, atau menanyakan beberapa tabel basis data. Pemanggilan berurutan terjadi ketika hasilnya saling bergantung—pertama mencari ID pengguna, lalu mengambil pesanan untuk ID tersebut.

Membatasi Laju Pemanggilan Paralel

Menjalankan banyak pemanggilan alat secara paralel dapat membebani API eksternal dengan permintaan yang berlangsung bersamaan. Gunakan semaphore untuk membatasi jumlah maksimum pemanggilan alat secara bersamaan. Cara ini mematuhi batas laju API sekaligus tetap lebih efisien daripada pemrosesan yang sepenuhnya berurutan.

import asyncio

async def rate_limited_execute_all(tool_calls, max_concurrent: int = 5) -> list:
    semaphore = asyncio.Semaphore(max_concurrent)

    async def limited_call(tc):
        async with semaphore:
            return await execute_tool_call_async(tc)

    tasks = [limited_call(tc) for tc in tool_calls]
    results = await asyncio.gather(*tasks, return_exceptions=True)

    return [
        (tc.id, str(r) if not isinstance(r, Exception) else f'Error: {r}')
        for tc, r in zip(tool_calls, results)
    ]

Merangkai Pemanggilan Berurutan dan Paralel

Alur kerja agen nyata sering mencampurkan pemanggilan berurutan dan paralel. Model mungkin terlebih dahulu memanggil lookup_user(email), lalu—dengan menggunakan user_id yang dikembalikan—memanggil get_orders(user_id) dan get_preferences(user_id) secara paralel. Implementasikan perulangan luar untuk mendeteksi pemanggilan mana yang dapat diparalelkan (tidak saling bergantung) dan mana yang harus dilakukan secara berurutan (saling bergantung).

async def multi_round_agent(user_message: str) -> str:
    messages = [{'role': 'user', 'content': user_message}]
    MAX_ROUNDS = 5

    for _ in range(MAX_ROUNDS):
        response = client.chat.completions.create(
            model='gpt-4o', messages=messages, tools=tools
        )
        choice = response.choices[0]
        messages.append(choice.message)

        if choice.finish_reason == 'stop':
            return choice.message.content  # Done

        if choice.finish_reason == 'tool_calls':
            # Execute all tool calls in parallel (may be 1 or many)
            results = await safe_execute_all(choice.message.tool_calls)
            for tc_id, result in results:
                messages.append({'role': 'tool', 'tool_call_id': tc_id, 'content': result})
            # Loop continues for potentially sequential next call

    return 'Max rounds reached.'

Mengukur Peningkatan Latensi

Pemanggilan alat paralel dapat mengurangi latensi secara drastis. Jika masing-masing dari tiga pemanggilan alat memerlukan 500 md secara berurutan, totalnya adalah 1500 md. Menjalankannya secara paralel menguranginya menjadi sekitar 500 md—peningkatan kecepatan 3 kali lipat. Selalu ukur dan bandingkan eksekusi berurutan dengan eksekusi paralel dalam skenario khusus Anda, dengan memperhitungkan overhead konkurensi dan batasan laju.

import time
import asyncio

async def benchmark_parallel_vs_sequential():
    tool_calls = [...]  # 5 independent tool calls

    # Sequential
    start = time.time()
    for tc in tool_calls:
        await execute_tool_call_async(tc)
    sequential_time = time.time() - start

    # Parallel
    start = time.time()
    await asyncio.gather(*[execute_tool_call_async(tc) for tc in tool_calls])
    parallel_time = time.time() - start

    print(f'Sequential: {sequential_time:.2f}s')
    print(f'Parallel:   {parallel_time:.2f}s')
    print(f'Speedup:    {sequential_time/parallel_time:.1f}x')

Menelusuri Kesalahan Pemanggilan Alat Paralel

Saat menelusuri masalah pemanggilan alat paralel, catat seluruh siklus permintaan-respons: pesan model dengan semua tool_calls, setiap hasil yang ditambahkan ke percakapan, dan respons akhir model. Jika hasil alat hilang atau urutannya salah, model dapat menghasilkan jawaban yang tidak konsisten. Pencatatan terstruktur dengan tool_call_id sebagai kunci korelasi membuat penelusuran masalah jauh lebih mudah.

Pemeriksaan Singkat

Uji pemahaman Anda tentang pemanggilan fungsi paralel dengan OpenAI.

Rangkuman Pelajaran

Dalam pelajaran ini Anda telah mempelajari: pemanggilan alat secara paralel muncul sebagai beberapa entri dalam daftar tool_calls, asyncio.gather mengeksekusinya secara bersamaan untuk kecepatan maksimum, dan setiap hasil memerlukan tool_call_id yang sesuai saat dikirim kembali ke model. Selanjutnya kita akan membangun antarmuka basis data bahasa alami menggunakan pemanggilan fungsi untuk menerjemahkan kueri bahasa Inggris biasa menjadi SQL.

Pertanyaan yang Sering Diajukan

Apakah pelajaran “Pemanggilan Fungsi secara Paralel” gratis?

Ya — teks lengkap “Pemanggilan Fungsi secara Paralel” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus AI Engineering Academy, upgrade ke CoddyKit PRO. Kursus AI Engineering Academy mencakup 4 pelajaran total.

Apa yang akan aku pelajari di “Pemanggilan Fungsi secara Paralel”?

Tangani respons ketika model memanggil beberapa fungsi secara bersamaan, jalankan fungsi-fungsi tersebut secara paralel dengan asyncio, lalu gabungkan hasilnya dalam satu panggilan API lanjutan. Kamu berlatih AI Engineering Academy 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 Engineering Academy?

Tidak diperlukan pengalaman sebelumnya. AI Engineering Academy 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 3 dari 4.

Berapa lama pelajaran “Pemanggilan Fungsi secara Paralel” 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 Engineering Academy ini?

Ya. Setiap pelajaran AI Engineering Academy 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. Mendefinisikan Skema Fungsi untuk API
  2. Memproses Pemanggilan Alat di Aplikasi Anda
  3. Pemanggilan Fungsi secara Paralel
  4. Membangun Antarmuka Basis Data Bahasa Alami
← Kembali ke AI Engineering Academy