Lewati ke konten utama

Tutorial Function Calling GPT-5

Panduan praktis function calling GPT-5: dari fungsi berbasis JSON-schema hingga alat free-form, kendala Lark/CFG, preamble, dan allowlist alat.
ยท 11 mnt Baca

Jelajahi bersama AI

Dengan peluncuran GPT-5, OpenAI memperluas pemanggilan alat/fungsi di API untuk mencakup panggilan alat bebas (teks mentah, tanpa JSON), kendala tata bahasa melalui Lark/CFG, allowlist alat, dan penalaran penggunaan alat yang ditingkatkan. Secara bersama-sama, ini menjadikan GPT-5 benar-benar sebagai model agentik; Anda dapat menghubungkan API, basis data, dan alat kustom ke Responses API dan menghasilkan jawaban yang terverifikasi atau bahkan mengotomatisasi alur kerja.

Dalam tutorial ini, saya akan membahas function tools, custom tools, kendala tata bahasa, allowlist alat, dan preamble, beserta contoh kode dan penjelasan jelas tentang cara kerjanya dan kapan menggunakannya.

Function Calling di GPT-5: Apa & Mengapa

Function Calling di GPT-5 memungkinkan Anda menambah kemampuan model dengan data dan aksi dari aplikasi Anda. Model dapat menentukan kapan memanggil alat, sementara Anda menangani logika dan mengembalikan hasil untuk respons akhir yang terverifikasi.

Jenis Function Calling:

  1. Function Tools (JSON Schema): Memberikan input dan output terstruktur yang dapat dipanggil model secara presisi.
  2. Custom Tools (Free-Form): Menyediakan input dan output teks yang fleksibel untuk integrasi tidak terstruktur.

Apa itu function calling?

GPT-5 mendukung function tools terstruktur (menggunakan JSON Schema) dan custom tools yang menerima payload teks bebas (seperti SQL, skrip, atau konfigurasi) untuk integrasi mulus dengan runtime eksternal.

Function tools didefinisikan oleh JSON Schema, memastikan model memahami argumen apa yang harus diberikan dan memungkinkan validasi input yang ketat. Anda dapat membaca lebih lanjut di tutorial OpenAI Function Calling kami.

Mengapa menggunakan function calling?

  • Fleksibilitas: Alat free-form memungkinkan model menghasilkan teks persis seperti yang diperlukan sistem Anda, tanpa batasan JSON kaku, ideal untuk kode, kueri, atau konfigurasi.
  • Keandalan dan Kontrol: Function tools menerapkan argumen terstruktur, meningkatkan prediktabilitas dan mengurangi kesalahan parsing.
  • Alur Kerja Agentik: GPT-5 dirancang untuk penggunaan alat dan tugas pengkodean yang kompleks dan multi-langkah, menjadikan pemanggilan alat sebagai fitur utama.

Bagaimana cara kerja function calling?

  1. Kirim prompt yang mencakup semua alat yang tersedia.
  2. Model mengeluarkan panggilan alat (baik dengan argumen atau teks bebas).
  3. Aplikasi Anda mengeksekusi alat (menjalankan fungsi Python).
  4. Kembalikan output dari alat ke model.
  5. Model kemudian merespons atau mungkin memanggil alat tambahan.

Sumber: Function calling - OpenAI API

Kapan menggunakan Function vs. Custom Tools

  • Gunakan function tools saat Anda menginginkan validasi ketat dan argumen bertipe yang dapat diprediksi melalui JSON Schema.
  • Gunakan custom tools (free-form) saat runtime Anda memerlukan teks mentah (seperti skrip, SQL, atau konfigurasi) atau ketika Anda perlu iterasi cepat tanpa skema.

Function Tools (JSON Schema): Kirim Data Terstruktur

Menggunakan Function Tools dengan JSON Schema memungkinkan Anda memperoleh hasil yang dapat diprediksi dan terstruktur dari model. Model mengevaluasi alat yang Anda deklarasikan, menentukan kapan menggunakannya, mengusulkan argumen tervalidasi JSON, lalu mengeksekusi fungsi terkait di kode Anda.

Setelah itu, Anda dapat meminta model untuk menghasilkan respons hanya berdasarkan data yang dikembalikan oleh alat, memastikan output terverifikasi, dapat dibaca mesin, dan mudah diintegrasikan.

Contoh ini mengilustrasikan beberapa konsep kunci:

  • Penemuan alat dan pembuatan argumen: Model memilih alat yang sesuai dan otomatis mengisi argumen bertipe JSON-nya.
  • Loop eksekusi alat: Aplikasi Anda mengeksekusi alat yang diminta dan mengirimkan hasilnya kembali ke model.
  • Jawaban akhir berbentuk skema: Respons akhir didasarkan ketat pada output dari alat, yang meminimalkan ketidakakuratan dan memastikan keandalan.

1. Menyiapkan

  1. Buat akun OpenAI dan hasilkan kunci API di dasbor platform. Di dasbor, buka bagian API, lalu โ€œView API keys,โ€ dan klik โ€œCreate new secret keyโ€.
  2. Tambahkan metode pembayaran atau kredit ke akun Anda agar panggilan API dapat berjalan; penggunaan akan mengurangi saldo prabayar saat Anda membuat permintaan.
  3. Simpan kunci API Anda sebagai variabel lingkungan bernama OPENAI_API_KEY sebelum memulai aplikasi Anda.
  4. Instal OpenAI Python SDK resmi dengan pip install openai.

2. Definisikan alat

Anda menyediakan daftar alat dengan nama, deskripsi, dan JSON Schema untuk parameter. Skema membantu model menyuplai argumen yang tertata rapi.

  • make_coffee mengharapkan satu parameter string: coffee_type.
  • random_coffee_fact tidak memerlukan parameter (objek kosong). Definisi ini diteruskan melalui argumen tools pada panggilan API agar model mengetahui apa yang tersedia.
import os
from openai import OpenAI
import json

client = OpenAI(api_key = os.environ["OPENAI_API_KEY"])

tools = [
    {
        "type": "function",
        "name": "make_coffee",
        "description": "Gives a simple recipe for making a coffee drink.",
        "parameters": {
            "type": "object",
            "properties": {
                "coffee_type": {
                    "type": "string",
                    "description": "The coffee drink, e.g. espresso, cappuccino, latte"
                }
            },
            "required": ["coffee_type"],
        },
    },
    {
        "type": "function",
        "name": "random_coffee_fact",
        "description": "Returns a fun fact about coffee.",
        "parameters": {"type": "object","properties":{}}
    }
]

3. Implementasikan alat

Anda mengimplementasikan fungsi Python yang benar-benar melakukan pekerjaan:

  • make_coffee(coffee_type) mengembalikan string resep ringkas yang sesuai dengan minuman yang diminta.
  • random_coffee_fact() mengembalikan payload fakta singkat.

Keduanya mengembalikan dict yang dapat diserialisasi ke JSON, ideal untuk dikirim kembali ke model.

def make_coffee(coffee_type):
    recipes = {
        "espresso": "Grind fine, 18g coffee โ†’ 36g espresso in ~28s.",
        "cappuccino": "Brew 1 espresso shot, steam 150ml milk, pour and top with foam.",
        "latte": "Brew 1 espresso shot, steam 250ml milk, pour for silky texture.",
    }
    return {"coffee_type": coffee_type, "recipe": recipes.get(coffee_type.lower(), "Unknown coffee type!")}

def random_coffee_fact():
    return {"fact": "Coffee is the second most traded commodity in the world, after oil."}

4. Mulai percakapan

Mulai percakapan dengan pertanyaan pengguna: {"role": "user", "content": "How do I make a latte?"}

Model dapat mengembalikan pesan yang mencakup item function_call, seperti make_coffee dengan {"coffee_type":"latte"}. Anda kemudian harus menambahkan pesan model kembali ke input_list: input_list += response.output. Ini membantu menjaga status percakapan untuk giliran berikutnya.

# Track used tools
used_tools = []

input_list = [{"role": "user", "content": "How do I make a latte?"}]

response = client.responses.create(
    model="gpt-5",
    tools=tools,
    input=input_list,
)
input_list += response.output

5. Eksekusi panggilan alat dan lampirkan output

Anda harus melakukan iterasi pada response.output dan mengidentifikasi item di mana item.type sama dengan "function_call". Untuk item ini, parsing item.arguments dan terapkan permintaan ke fungsi Python Anda.

Untuk fungsi make_coffee, panggil menggunakan make_coffee(args["coffee_type"]). Untuk fungsi random_coffee_fact, cukup panggil random_coffee_fact().

Setelah mengeksekusi fungsi, tambahkan pesan function_call_output yang mencakup hal berikut:

  • call_id (yang menautkan output ini ke permintaan model)
  • output (string JSON dari hasil fungsi Anda).
for item in response.output:
    if getattr(item, "type", "") == "function_call":
        used_tools.append(item.name)
        args = json.loads(item.arguments or "{}")

        if item.name == "make_coffee":
            result = make_coffee(args["coffee_type"])
        elif item.name == "random_coffee_fact":
            result = random_coffee_fact()
        else:
            result = {"error": f"Unknown tool {item.name}"}

        input_list.append({
            "type": "function_call_output",
            "call_id": item.call_id,
            "output": json.dumps(result)
        })

6. Hasilkan jawaban akhir

Anda membuat panggilan client.responses.create kedua, meneruskan input_list yang telah diperbarui dan kini mencakup output alat.

Variabel used_tools menangkap nama alat yang muncul dalam panggilan fungsi model. Kita akan menggunakannya untuk menampilkan alat yang digunakan.

final = client.responses.create(
    model="gpt-5",
    tools=tools,
    input=input_list,
    instructions="Answer using only the tool results."
)

print("Final output:\n", final.output_text)

print("\n--- Tool Usage ---")
for t in tools:
    status = "USED โœ…" if t["name"] in used_tools else "NOT USED โŒ"
    print(f"{t['name']}: {status}")

Karena pengguna menanyakan tentang latte, model memilih make_coffee dengan coffee_type = "latte", kode Anda mengeksekusinya, dan respons akhir dibangun hanya dari hasil alat tersebut.

Final output:
 {"coffee_type":"latte","recipe":"Brew 1 espresso shot, steam 250ml milk, pour for silky texture."}

--- Tool Usage ---
make_coffee: USED โœ…
random_coffee_fact: NOT USED โŒ

Custom Tools (Free-Form): Kirim Teks Mentah

Gunakan custom tools free-form GPT-5 agar model dapat mengirim teks mentah langsung ke alat Anda, seperti kode, SQL, perintah shell, atau CSV sederhana, tanpa memerlukan JSON Schema.

Kemampuan ini melampaui panggilan fungsi berbasis JSON lama, memberi Anda fleksibilitas lebih besar untuk integrasi dengan eksekutor, mesin kueri, atau interpreter DSL (domain-specific language).

Dalam mode free-form, model menghasilkan panggilan alat kustom dengan payload teks tidak terstruktur yang dapat Anda rute ke runtime Anda. Anda kemudian mengembalikan hasilnya untuk digunakan model dalam memfinalisasi jawaban bagi pengguna.

Sekarang kita akan menulis kode yang memungkinkan model memilih alat yang sesuai dan mengembalikan teks mentah tidak terstruktur sebagai output. Output ini kemudian diteruskan ke fungsi Python untuk menghasilkan hasil. Dengan cara ini, pengguna dapat memberikan bahan yang mereka miliki, dan model akan menghasilkan resep yang disesuaikan dengan kebutuhan mereka.

Dalam contoh kode ini, kita telah:

  1. Menginisialisasi klien OpenAI dan mendefinisikan satu custom tool bernama meal_planner yang menerima input teks mentah.
  2. Membuat Python plan_meal yang mengambil string bahan dipisahkan koma dan mengembalikan ide hidangan.
  3. Memulai percakapan dengan pesan pengguna yang mencantumkan bahan yang tersedia.
  4. Melakukan panggilan model awal yang menginstruksikan GPT-5 untuk memanggil alat hanya menggunakan daftar bahan yang bersih, dan menambahkan output model ke riwayat percakapan.
  5. Menemukan panggilan alat kustom yang dipancarkan dan mengekstrak string input mentah yang dipisahkan koma.
  6. Mengeksekusi alat dengan meneruskan daftar tersebut ke plan_meal, lalu mengirim hasilnya kembali ke model sebagai function_call_output yang ditautkan melalui call_id.
  7. Melakukan panggilan model terakhir untuk mengubah ide mentah alat menjadi resep ringkas langkah demi langkah, dan mencetak detail panggilan alat serta output akhir.
from openai import OpenAI
import json
import random

client = OpenAI()

# --- Custom tool ---
tools = [
    {
        "type": "custom",
        "name": "meal_planner",
        "description": "Takes ONLY a comma-separated list of ingredients and suggests a meal idea."
    }
]

# --- Fake meal planner ---
def plan_meal(ingredients: str) -> str:
    ideas = [
        f"Stir-fry: {ingredients} with garlic & soy sauce.",
        f"One-pot rice: cook {ingredients} together in broth until fluffy.",
        f"Soup: simmer {ingredients} in stock with herbs.",
        f"Sheet-pan bake: roast {ingredients} at 200ยฐC for ~20 min."
    ]
    return random.choice(ideas)

# --- Start conversation ---
messages = [
    {"role": "user", "content": "I only have chicken, rice, and broccoli. Any dinner ideas?"}
]

# 1) Ask model with clear instruction
resp = client.responses.create(
    model="gpt-5",
    tools=tools,
    input=messages,
    instructions="If the user mentions ingredients, call the meal_planner tool with ONLY a comma-separated list like 'chicken, rice, broccoli'."
)

messages += resp.output

# 2) Find the tool call
tool_call = next((x for x in resp.output if getattr(x, "type", "") == "custom_tool_call"), None)
assert tool_call, "No tool call found!"

# Get clean CSV input
ingredients_csv = tool_call.input.strip()

# 3) Run the tool
meal_result = plan_meal(ingredients_csv)

# 4) Send tool output back
messages.append({
    "type": "function_call_output",
    "call_id": tool_call.call_id,
    "output": meal_result
})

# 5) Final model response
final = client.responses.create(
    model="gpt-5",
    tools=tools,
    input=messages,
    instructions="Turn the meal idea into a short recipe with 3-4 steps."
)

print("\n--- Tool Call ---")
print("Name:", tool_call.name)
print("Input:", ingredients_csv)
print("Output:", meal_result)


print("\n--- Final Output ---\n", final.output_text)

Hasilnya, kita menerima statistik tentang alat yang digunakan, termasuk instalasi, input, dan output. Selain itu, output akhir memberikan resep lengkap tentang cara membuat hidangan tersebut.

--- Tool Call ---
Name: meal_planner
Input: chicken, rice, broccoli
Output: One-pot rice: cook chicken, rice, broccoli together in broth until fluffy.

--- Final Output ---
 One-Pot Chicken, Rice & Broccoli

- Season bite-size chicken pieces with salt and pepper; sear in a little oil in a pot until lightly browned.
- Add 1 cup rinsed rice and 2 cups broth (or water + salt). Bring to a boil, then cover and simmer on low for 12 minutes.
- Scatter 2 cups small broccoli florets on top, cover, and cook 5-7 more minutes until rice is fluffy and broccoli is tender.
- Rest 5 minutes off heat, fluff, and adjust seasoning. Optional: stir in a knob of butter or a splash of soy.

Kendala Tata Bahasa (Lark): Batasi Output Alat

GPT-5 kini mendukung context-free grammar (CFG) untuk memastikan format output benar-benar terkendali.

Dengan menerapkan tata bahasa, seperti SQL atau DSL (domain-specific language), pada responsnya, GPT-5 menjamin bahwa output secara konsisten mengikuti struktur yang diperlukan. CFG sangat penting untuk proses otomatis dan alur kerja berisiko tinggi.

GPT-5 dapat menggunakan tata bahasa yang didefinisikan dalam format seperti Lark untuk membatasi output alat selama generasi. Pendekatan constrained decoding ini meningkatkan keandalan dengan mencegah penyimpangan format dan memastikan konsistensi struktur.

Sekarang kita akan menulis kode di mana model memilih sebuah alat dan mengeluarkan HANYA ekspresi aritmetika yang valid menurut tata bahasa; ekspresi ini kemudian dievaluasi di Python, hasilnya dikembalikan ke percakapan, dan respons akhir disajikan secara jelas dalam bahasa alami.

Dalam contoh kode ini, kita telah:

  1. Menginisialisasi klien OpenAI dan mendefinisikan custom tool math_solver yang harus mengeluarkan HANYA ekspresi aritmetika yang valid menurut tata bahasa (Lark CFG).
  2. Memulai percakapan dengan pertanyaan matematika berbahasa alami dari pengguna.
  3. Melakukan panggilan model pertama yang menginstruksikan GPT-5 untuk memanggil math_solver dengan ekspresi yang sesuai tata bahasa.
  4. Menemukan panggilan alat yang dipancarkan dan mengekstrak string ekspresi mentah dari payload alat.
  5. Mengevaluasi ekspresi secara lokal di lingkungan terbatas untuk menghasilkan hasil konkret.
  6. Mengembalikan hasil eksekusi alat kembali ke percakapan, ditautkan melalui call_id asli.
  7. Melakukan panggilan model terakhir untuk menyajikan hasil evaluasi dengan jelas dalam bahasa alami.
from openai import OpenAI
import json

client = OpenAI()

# --- Local fake evaluator ---
def eval_expression(expr: str) -> str:
    try:
        # Evaluate safely using Python's eval on restricted globals
        result = eval(expr, {"__builtins__": {}}, {})
        return f"{expr} = {result}"
    except Exception as e:
        return f"Error evaluating expression: {e}"

# --- Custom tool with grammar constraint ---
tools = [
    {
        "type": "custom",
        "name": "math_solver",
        "description": "Solve a math problem by outputting ONLY a valid arithmetic expression.",
        "format": {
            "type": "grammar",
            "syntax": "lark",
            "definition": r"""
start: expr

?expr: term
     | expr "+" term   -> add
     | expr "-" term   -> sub

?term: factor
     | term "*" factor -> mul
     | term "/" factor -> div

?factor: NUMBER
       | "(" expr ")"

%import common.NUMBER
%ignore " "
"""
        },
    }
]

# --- User asks ---
msgs = [
    {"role": "user", "content": "What is (12 + 8) * 3 minus 5 divided by 5?"}
]

# 1) First model call: GPT-5 must emit a grammar-valid expression
resp = client.responses.create(
    model="gpt-5",
    tools=tools,
    input=msgs,
    instructions="Always call the math_solver tool with a grammar-valid arithmetic expression like '(12 + 8) * 3 - 5 / 5'."
)

msgs += resp.output

tool_call = next(
    x for x in resp.output
    if getattr(x, "type", "") in ("custom_tool_call", "tool_call", "function_call")
)

expr = getattr(tool_call, "input", "") or getattr(tool_call, "arguments", "")
print("\n=== Grammar-Constrained Expression ===")
print(expr)

# 2) Run the local evaluator
tool_result = eval_expression(expr)
print("\n=== Tool Execution Result ===")
print(tool_result)

# 3) Return tool output
msgs.append({
    "type": "function_call_output",
    "call_id": tool_call.call_id,
    "output": tool_result
})

# 4) Final pass: GPT-5 presents answer nicely
final = client.responses.create(
    model="gpt-5",
    input=msgs,
    tools=tools,
    instructions="Present the evaluated result clearly in natural language."
)

print("\n=== Final Output ===")
print(final.output_text)

Seperti yang Anda lihat, model telah memilih alat dan kemudian menghasilkan ekspresi yang dibatasi tata bahasa. Setelah itu, ekspresi diteruskan melalui fungsi Python untuk menghasilkan jawaban. Pada akhirnya, kita memiliki jawaban yang tepat dalam bahasa alami.

=== Grammar-Constrained Expression ===
(12 + 8) * 3 - 5 / 5

=== Tool Execution Result ===
(12 + 8) * 3 - 5 / 5 = 59.0

=== Final Output ===
59

Allowlist Alat: Batasi dengan Aman Apa yang Dapat Digunakan Model

Pengaturan allowed_tools memungkinkan Anda membatasi model pada pilihan alat yang aman dari seluruh toolset Anda. Ini meningkatkan prediktabilitas dan mencegah panggilan alat yang tidak diinginkan, sekaligus tetap memberi fleksibilitas dalam set yang diizinkan.

Anda dapat membiarkan model memilih di antara alat yang diizinkan atau mewajibkannya menggunakan satu alat, mencerminkan perilaku โ€œforce toolโ€ yang terlihat di stack lain, dan selaras dengan praktik terbaik umum untuk orkestrasi pemanggilan alat.

Sekarang kita akan menulis kode di mana kita mengizinkan satu alat, membuat model hanya memanggil alat itu, menjalankannya, mengumpankan hasilnya kembali, lalu menghasilkan ringkasan singkat yang berfokus pada pengguna.

Catatan: Silakan buat akun Firecrawl gratis, hasilkan kunci API, simpan sebagai variabel lingkungan FIRECRAWL_API_KEY, dan instal Firecrawl Python SDK menggunakan pip install firecrawl-py.

Dalam contoh kode ini, kita telah:

  1. Mendefinisikan toolset lengkap dengan dummy_web_search dan firecrawl_search.
  2. Membatasi model hanya pada firecrawl_search melalui tool_choice = { type: "allowed_tools", mode: "required", tools: [...] }.
  3. Mengeluarkan panggilan model pertama, menangkap nama dan argumen panggilan alat, dan mencetaknya agar terlihat.
  4. Saat firecrawl_search dipanggil, deserialisasi argumen, eksekusi Firecrawl, konversi responsnya menjadi dict yang dapat diserialisasi JSON, dan ekstrak payload data yang aman.
  5. Memberi makan kembali hasil alat ke percakapan menggunakan function_call_output yang ditautkan oleh call_id, lalu melakukan panggilan model terakhir untuk meringkas menjadi 3โ€“4 poin dengan tautan Markdown.
  6. Menyertakan cabang fallback yang akan menjalankan alat dummy (meskipun allowlist mencegahnya pada run ini).
  7. Mencetak jawaban bahasa alami akhir.
from openai import OpenAI
from firecrawl import Firecrawl
import json
import os

client = OpenAI()
firecrawl = Firecrawl(api_key=os.environ["FIRECRAWL_API_KEY"])

# --- Full toolset ---
tools = [
    {
        "type": "function",
        "name": "dummy_web_search",
        "description": "A fake web search that always returns static dummy results.",
        "parameters": {
            "type": "object",
            "properties": {
                "query": {"type": "string"},
                "limit": {"type": "integer"}
            },
            "required": ["query"]
        },
    },
    {
        "type": "function",
        "name": "firecrawl_search",
        "description": "Perform a real web search using Firecrawl.",
        "parameters": {
            "type": "object",
            "properties": {
                "query": {"type": "string"},
                "limit": {"type": "integer"}
            },
            "required": ["query"]
        },
    },
]

# --- Dummy implementation ---
def dummy_web_search(query, limit=3):
    return {
        "query": query,
        "results": [f"[Dummy] Result {i+1} for '{query}'" for i in range(limit)]
    }

# --- User asks ---
messages = [
    {"role": "user", "content": "Find me the latest info about the stock market."}
]

# --- Restrict to Firecrawl only ---
resp = client.responses.create(
    model="gpt-5",
    tools=tools,
    input=messages,
    instructions="Only the firecrawl_search tool is allowed. Do not use dummy_web_search.",
    tool_choice={
        "type": "allowed_tools",
        "mode": "required",  # force Firecrawl
        "tools": [{"type": "function", "name": "firecrawl_search"}],
    },
)

for item in resp.output:
    if getattr(item, "type", "") in ("function_call", "tool_call"):
        print("\n--- Tool Call ---")
        print("Tool name:", item.name)
        print("Arguments:", item.arguments)

        if item.name == "firecrawl_search":
            args = json.loads(item.arguments)

            # Firecrawl returns a SearchData object โ†’ convert it
            results_obj = firecrawl.search(
                query=args["query"],
                limit=args.get("limit", 3),
            )

            # ๐Ÿ”ฅ Convert to JSON-serializable dict
            if hasattr(results_obj, "to_dict"):
                results = results_obj.to_dict()
            elif hasattr(results_obj, "dict"):
                results = results_obj.dict()
            else:
                results = json.loads(results_obj.json()) if hasattr(results_obj, "json") else results_obj

            print("\n--- Firecrawl Raw Results ---")
            print(json.dumps(results, indent=2)[:500])

            # โœ… Extract only the data portion for summarization
            safe_results = results.get("data", results)

            # Feed back to GPT
            messages += resp.output
            messages.append({
                "type": "function_call_output",
                "call_id": item.call_id,
                "output": json.dumps(safe_results)  # now safe
            })

            # Final pass
            final = client.responses.create(
                model="gpt-5",
                tools=tools,
                input=messages,
                instructions="Summarize the Firecrawl search results into 3-4 bullet points with clickable [Title](URL) links."
            )

            print("\n--- Final Natural Language Answer ---")
            print(final.output_text)

        elif item.name == "dummy_web_search":
            args = json.loads(item.arguments)
            results = dummy_web_search(args["query"], args.get("limit", 3))
            print("\n--- Dummy Web Search Results ---")
            print(json.dumps(results, indent=2))

Model memilih Firecrawl search, dan dengan itu, ia menghasilkan respons akhir dalam format markdown.

Preamble: Beri Tahu Model Cara Memanggil Alat

Preamble adalah penjelasan singkat yang dihasilkan model sebelum memanggil alat, menjelaskan alasan panggilan. Ini meningkatkan transparansi, membangun kepercayaan pengguna, dan memperjelas debugging dalam alur kerja kompleks. Anda dapat mengaktifkannya dengan instruksi sederhana seperti โ€œjelaskan sebelum memanggil alat,โ€ biasanya tanpa menambah latensi yang berarti.

Sekarang kita akan menulis kode di mana model terlebih dahulu menghasilkan satu baris โ€œPreamble:โ€ yang menjelaskan mengapa ia memanggil alat, lalu memanggil alatnya, Anda mengeksekusinya secara lokal, mengembalikan hasilnya, dan model menghasilkan jawaban akhir yang jelas.

Dalam contoh kode ini, kita telah:

  1. Menginisialisasi klien OpenAI dan mendefinisikan function tool bertipe ketat (medical_advice) dengan JSON Schema.
  2. Menambahkan instruksi sistem yang memberi tahu model untuk mengeluarkan satu baris โ€œPreamble:โ€ sebelum panggilan alat apa pun.
  3. Memulai percakapan dengan pertanyaan gejala dari pengguna.
  4. Melakukan panggilan model pertama untuk memperoleh preamble dan panggilan alat dengan argumennya.
  5. Mengekstrak dan mengeksekusi alat secara lokal untuk menghasilkan saran.
  6. Mengembalikan output alat kembali ke model, ditautkan melalui call_id.
  7. Melakukan panggilan model terakhir agar GPTโ€‘5 menyajikan hasil sebagai jawaban yang ringkas dan ramah pengguna.
from openai import OpenAI
import json
import random

client = OpenAI()

# --- Fake tool implementation ---
def medical_advice(symptom: str):
    remedies = {
        "headache": "You can take acetaminophen (paracetamol) or ibuprofen, rest in a quiet room, and stay hydrated.",
        "cough": "Drink warm fluids, use honey in tea, and consider over-the-counter cough syrup.",
        "fever": "Use acetaminophen to reduce fever, stay hydrated, and rest. See a doctor if >39ยฐC.",
    }
    return {"advice": remedies.get(symptom.lower(), "Please consult a healthcare provider for guidance.")}

# --- Tool definition ---
tools = [{
    "type": "function",
    "name": "medical_advice",
    "description": "Provide safe, general over-the-counter advice for common symptoms.",
    "parameters": {
        "type": "object",
        "properties": {"symptom": {"type": "string"}},
        "required": ["symptom"],
        "additionalProperties": False
    },
    "strict": True,
}]

# --- Messages (system preamble instruction) ---
messages = [
    {"role": "system", "content": "Before you call a tool, explain why you are calling it in ONE short sentence prefixed with 'Preamble:'."},
    {"role": "user", "content": "What should I take for a headache?"}
]

# 1) First call: expect preamble + tool call
resp = client.responses.create(model="gpt-5", input=messages, tools=tools)
print("=== First Response ===")
for item in resp.output:
    t = getattr(item, "type", None)
    if t == "message":
        # Extract just the model's text
        content = getattr(item, "content", None)
        text = None
        if isinstance(content, list):
            text = "".join([c.text for c in content if hasattr(c, "text")])
        elif content:
            text = str(content)
        if text:
            # โœ… Only print once
            print(text)
    if t in ("function_call", "tool_call", "custom_tool_call"):
        print("Tool:", getattr(item, "name", None))
        print("Args:", getattr(item, "arguments", None))

# Extract tool call
tool_call = next(x for x in resp.output if getattr(x, "type", None) in ("function_call","tool_call","custom_tool_call"))
messages += resp.output

# 2) Execute tool locally
args = json.loads(getattr(tool_call, "arguments", "{}"))
symptom = args.get("symptom", "")
tool_result = medical_advice(symptom)

# 3) Return tool result
messages.append({
    "type": "function_call_output",
    "call_id": tool_call.call_id,
    "output": json.dumps(tool_result)
})

# 4) Final model call โ†’ natural answer
final = client.responses.create(model="gpt-5", input=messages, tools=tools)
print("\n=== Final Answer ===")
print(final.output_text)

Anda dapat melihat bahwa sebelum memanggil alat, model memberikan penjelasan mengapa alat tersebut dipanggil. Ini baik untuk observabilitas dan debugging.

Ringkasan

GPT-5 adalah model paling canggih dari OpenAI hingga saat ini, sangat unggul dalam pengkodean dan alur kerja berbasis agen. Fitur API terbarunya memungkinkan pengembangan sistem siap produksi dari awal hingga akhir secara lugas.

Dalam tutorial ini, Anda mempelajari cara:

  1. Mengembalikan output terstruktur menggunakan Function Tools dan JSON Schema untuk otomatisasi hilir yang andal.
  2. Mengaktifkan free-form dengan Custom Tools (teks mentah), memungkinkan model menghasilkan kode, SQL, skrip shell, dan file CSV di luar sekadar panggilan JSON.
  3. Format terbatas menggunakan kendala tata bahasa Lark saat presisi krusial, seperti dalam matematika, SQL, atau DSL.
  4. Membatasi akses alat dengan allowlist (atau memaksa satu alat) untuk meningkatkan keamanan, kontrol, dan determinisme.
  5. Meningkatkan transparansi dengan preamble singkat, sehingga model menjelaskan mengapa ia memanggil alat tertentu, membantu observabilitas dan debugging.

Untuk mempelajari lebih lanjut tentang apa yang dapat Anda lakukan dengan berbagai alat OpenAI, saya merekomendasikan jalur keterampilan OpenAI Fundamentals dan kursus Working with the OpenAI API kami.

Abid Ali Awan

Penulis

Abid Ali Awan

Sebagai data scientist tersertifikasi, saya bersemangat memanfaatkan teknologi mutakhir untuk menciptakan aplikasi machine learning yang inovatif. Dengan latar belakang kuat di pengenalan ucapan, analisis dan pelaporan data, MLOps, conversational AI, dan NLP, saya mengasah keterampilan dalam mengembangkan sistem cerdas yang berdampak nyata. Selain keahlian teknis, saya juga komunikator andal yang mampu menyederhanakan konsep kompleks menjadi bahasa yang jelas dan ringkas. Karena itu, saya menjadi blogger yang dicari di bidang data science, membagikan wawasan dan pengalaman kepada komunitas profesional data yang terus berkembang. Saat ini, saya berfokus pada pembuatan dan penyuntingan konten, bekerja dengan large language model untuk mengembangkan konten yang kuat dan menarik agar membantu bisnis dan individu memaksimalkan data mereka.

Topik

Terkait

blogs

40 Pertanyaan Wawancara DBMS Teratas di 2026

blogs

Spaghetti Plot dan Jalur Badai