Panggilan alat terprogram dengan AZURE OpenAI Responses API

Pemanggilan alat secara terprogram memungkinkan model menggunakan kode untuk mengatur alat selama permintaan Responses API. Alih-alih memerlukan giliran model terpisah untuk setiap pemanggilan alat, model dapat menghasilkan program yang memanggil alat dan memproses hasilnya. Program ini dapat melakukan operasi seperti percabangan atau perulangan.

Artikel ini menjelaskan kapan pemanggilan alat secara terprogram berguna dan perbedaannya dengan pemanggilan fungsi, pemanggilan alat paralel, dan pencarian alat.

Pertimbangan ketersediaan

Sebelum menerapkan panggilan alat terprogram, konfirmasikan bahwa penyebaran model Azure OpenAI dan versi SDK Azure Anda mendukung fitur tersebut. Jangan berasumsi bahwa dukungan untuk Responses API juga berarti adanya dukungan untuk panggilan alat terprogram.

Untuk penyiapan titik akhir dan autentikasi, lihat Menggunakan AZURE OpenAI Responses API.

Panggilan alat programmatic dan panggilan fungsi

Dengan panggilan fungsi standar, aplikasi Anda biasanya berpartisipasi dalam setiap langkah panggilan alat:

Model -> panggilan alat -> aplikasi menjalankan alat -> model -> panggilan alat berikutnya -> aplikasi menjalankan alat -> model

Dengan panggilan alat terprogram, model dapat menghasilkan kode yang mengatur beberapa operasi alat:

Model -> program yang dihasilkan -> operasi alat -> hasil program -> model

Pendekatan ini dapat mengurangi jumlah putaran model yang diperlukan untuk alur kerja yang melibatkan beberapa alat.

Alur ini menggambarkan perbedaan konseptual dalam orkestrasi. Mereka tidak menentukan operasi apa yang dijalankan oleh aplikasi atau layanan Anda.

Contoh: Bandingkan inventaris dengan permintaan

Contoh Python ini memaparkan dua fungsi yang didefinisikan aplikasi yang mengembalikan inventori sampel dan data permintaan. Model ini menggunakan panggilan alat terprogram untuk membandingkan hasilnya. Aplikasi Anda menjalankan fungsi dan mengembalikan hasilnya sehingga runtime dapat melanjutkan program yang dihasilkan.

Blok kode membentuk satu skrip. Gabungkan semuanya dalam urutan yang ditampilkan.

klien Azure OpenAI

Gunakan deployment Azure OpenAI yang mendukung pemanggilan alat secara terprogram dan versi SDK OpenAI yang menyertakan output_schema, allowed_callers, dan informasi pemanggil. Instal paket openai dan azure-identity di lingkungan Python Anda:

pip install --upgrade openai azure-identity

Konfigurasikan autentikasi Microsoft Entra ID seperti yang dijelaskan dalam Menggunakan AZURE OpenAI Responses API. Identitas Anda memerlukan izin untuk memanggil penyebaran Azure OpenAI Anda.

Ganti YOUR-RESOURCE-NAME dengan nama sumber daya Anda. Nilai model nanti dalam contoh adalah nama deployment Azure Anda, bukan pengidentifikasi katalog model.

import json

from azure.identity import DefaultAzureCredential, get_bearer_token_provider
from openai import OpenAI

# Use the Azure OpenAI v1 endpoint and Microsoft Entra ID authentication.
endpoint = "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/"
credential = DefaultAzureCredential()
token_provider = get_bearer_token_provider(
    credential, "https://cognitiveservices.azure.com/.default"
)
openai = OpenAI(base_url=endpoint, api_key=token_provider)

Fungsi yang ditentukan oleh aplikasi

Fungsi mengembalikan data sampel tetap: 42 unit yang tersedia dan 31 unit yang diminta untuk SKU yang ditentukan. Ganti implementasi mereka dengan inventori dan sumber data permintaan Anda di aplikasi Anda.

def get_inventory(sku):
    return {"sku": sku, "available_units": 42}


def get_demand(sku):
    return {"sku": sku, "requested_units": 31}


implementations = {
    "get_inventory": get_inventory,
    "get_demand": get_demand,
}

Definisi alat

Setiap fungsi mendeklarasikan skema input dan output_schema yang menjelaskan hasil JSON. Pengaturan allowed_callers ke ["programmatic"] membuat fungsi tersedia untuk program yang dihasilkan, bukan untuk panggilan model langsung.

tools = [
    {
        "type": "function",
        "name": "get_inventory",
        "description": "Return the SKU and available inventory units.",
        "strict": True,
        "parameters": {
            "type": "object",
            "properties": {"sku": {"type": "string"}},
            "required": ["sku"],
            "additionalProperties": False,
        },
        "output_schema": {
            "type": "object",
            "properties": {
                "sku": {"type": "string"},
                "available_units": {"type": "number"},
            },
            "required": ["sku", "available_units"],
            "additionalProperties": False,
        },
        "allowed_callers": ["programmatic"],
    }
]

Tambahkan demand function dan kemampuan pemanggilan alat terprogram ke daftar yang sama:

tools.extend([
    {
        "type": "function",
        "name": "get_demand",
        "description": "Return the SKU and requested demand units.",
        "strict": True,
        "parameters": {
            "type": "object",
            "properties": {"sku": {"type": "string"}},
            "required": ["sku"],
            "additionalProperties": False,
        },
        "output_schema": {
            "type": "object",
            "properties": {
                "sku": {"type": "string"},
                "requested_units": {"type": "number"},
            },
            "required": ["sku", "requested_units"],
            "additionalProperties": False,
        },
        "allowed_callers": ["programmatic"],
    },
    {"type": "programmatic_tool_calling"},
])

Hasil alat dan informasi pemanggil

Aplikasi mengirimkan panggilan fungsi berdasarkan nama dan menserialisasikan setiap hasil. Pertahankan informasi milik panggilan caller sehingga runtime dapat melanjutkan program yang benar. Nama alat yang tidak diketahui dan argumen yang tidak valid menghasilkan error daripada mengembalikan hasil palsu.

def run_tool(call):
    run = implementations.get(call.name)
    if run is None:
        raise ValueError(f"Unknown tool: {call.name}")

    arguments = json.loads(call.arguments)
    if (
        not isinstance(arguments, dict)
        or set(arguments) != {"sku"}
        or not isinstance(arguments["sku"], str)
    ):
        raise ValueError(f"Invalid arguments for tool: {call.name}")

    result = run(**arguments)
    output = {
        "type": "function_call_output",
        "call_id": call.call_id,
        "output": json.dumps(result),
    }
    if call.caller is not None:
        output["caller"] = call.caller.model_dump(exclude_none=True)
    return output

Kelanjutan respons

Ganti YOUR-MODEL-DEPLOYMENT dengan nama deployment Azure OpenAI yang didukung.

Dengan store=False, aplikasi melanjutkan percakapan. Pertahankan setiap item output, termasuk item program dan penalaran, sebelum menambahkan hasil alat. Perulangan berhenti pada jawaban akhir atau penolakan dan menghasilkan error jika respons gagal atau batas permintaan tercapai.

input_items = [
    {"role": "user", "content": "Compare inventory with demand for sku_123."}
]
MAX_REQUESTS = 10
for _ in range(MAX_REQUESTS):
    response = openai.responses.create(
        model="YOUR-MODEL-DEPLOYMENT",
        store=False, input=input_items, tools=tools,
    )
    if response.status != "completed":
        raise RuntimeError(f"Response ended with status {response.status}")
    input_items.extend(
        item.model_dump(exclude_none=True) for item in response.output
    )
    calls = [item for item in response.output if item.type == "function_call"]
    if calls:
        input_items.extend(run_tool(call) for call in calls)
        continue
    if response.output_text:
        print(response.output_text)
        break
    refusals = [
        part.refusal for item in response.output if item.type == "message"
        for part in item.content if part.type == "refusal"
    ]
    if refusals:
        print("\n".join(refusals))
        break
else:
    raise RuntimeError("Programmatic tool calling exceeded the request limit")

Jawaban akhir harus menjelaskan bahwa inventaris mencakup permintaan: 42 unit yang tersedia dikurangi 31 unit yang diminta, tersisa 11 unit. Kata-kata dapat bervariasi. Penolakan dicetak sebagai gantinya jika model menolak permintaan.

Aplikasi menjalankan fungsi inventaris dan permintaan, sementara program yang dihasilkan mengoordinasikan penggunaannya dan memproses hasilnya.

Kapan menggunakan pemanggilan tool

Pertimbangkan pemanggilan alat secara terprogram saat suatu tugas:

  • Memerlukan beberapa pemanggilan tool yang terkait.
  • Berisi logika bersyarat.
  • Perlu iterasi pada hasil tool.
  • Melakukan pemrosesan data perantara sebelum menghasilkan jawaban.
  • Jika tidak, ini akan memerlukan giliran model berulang untuk mengoordinasikan alat.

Untuk alur kerja sederhana yang melibatkan satu atau dua fungsi independen, panggilan fungsi standar mungkin lebih mudah diterapkan.

Tool calling terprogram dan tool calling paralel

Pemanggilan alat paralel dan pemanggilan alat terprogram mengatasi kebutuhan orkestrasi yang berbeda.

Gunakan pemanggilan alat paralel ketika beberapa operasi independen dapat dijalankan secara bersamaan. Misalnya, ambil cuaca untuk lima lokasi independen.

Gunakan pemanggilan alat secara terprogram saat operasi alat memerlukan koordinasi, komputasi menengah, percabangan, atau perulangan. Misalnya, ambil pesanan seorang pelanggan, pilih pesanan yang cocok dengan kondisi, dan kueri informasi pengiriman untuk pesanan tersebut.

Kontrol pencarian alat menentukan definisi alat mana yang dimuat ke dalam konteks model.

Pemanggilan alat secara terprogram mengontrol bagaimana model mengorkestrasi alat setelah tersedia.

Perbedaannya adalah antara tool discovery dan orkestrasi alat. Hubungan konseptual mereka tidak menunjukkan dengan jelas apakah deployment Anda mendukung penggunaan kedua fitur dalam permintaan yang sama.

Pertimbangan keamanan

Perlakukan program yang dihasilkan sebagai kode yang tidak tepercaya.

Saat membuka akses ke alat:

  • Ikuti prinsip hak akses minimum.
  • Validasi argumen alat bantu.
  • Batasi akses ke operasi sensitif.
  • Autentikasi dan otorisasi operasi secara independen dari output model.
  • Catat eksekusi alat untuk audit dan diagnostik tanpa merekam rahasia atau data sensitif yang tidak perlu.
  • Hindari mengekspos alat atau data yang tidak perlu.

Jangan mengandalkan kode yang dihasilkan model sebagai batas otorisasi.