Bagikan melalui


Cara menggunakan panggilan fungsi dengan Azure OpenAI Service (Pratinjau)

Versi terbaru gpt-35-turbo dan gpt-4 disempurnakan untuk bekerja dengan fungsi dan dapat menentukan kapan dan bagaimana fungsi harus dipanggil. Jika satu atau beberapa fungsi disertakan dalam permintaan Anda, model menentukan apakah salah satu fungsi harus dipanggil berdasarkan konteks perintah. Ketika model menentukan bahwa fungsi harus dipanggil, ia merespons dengan objek JSON termasuk argumen untuk fungsi tersebut.

Model merumuskan panggilan API dan menyusun output data, semuanya berdasarkan fungsi yang Anda tentukan. Penting untuk dicatat bahwa meskipun model dapat menghasilkan panggilan ini, terserah Anda untuk mengeksekusinya, memastikan Anda tetap memegang kendali.

Pada tingkat tinggi Anda dapat memecah bekerja dengan fungsi menjadi tiga langkah:

  1. Panggil API penyelesaian obrolan dengan fungsi Anda dan input pengguna
  2. Gunakan respons model untuk memanggil API atau fungsi Anda
  3. Panggil API penyelesaian obrolan lagi, termasuk respons dari fungsi Anda untuk mendapatkan respons akhir

Penting

Parameter functions dan function_call telah ditolak dengan rilis 2023-12-01-preview versi API. Penggantian untuk functions adalah tools parameter . Penggantian untuk function_call adalah tool_choice parameter .

Dukungan panggilan fungsi

Panggilan fungsi paralel

  • gpt-35-turbo (1106)
  • gpt-35-turbo (0125)
  • gpt-4 (Pratinjau 1106)
  • gpt-4 (Pratinjau 0125)
  • gpt-4 (pratinjau visi)
  • gpt-4 (2024-04-09)
  • gpt-4o (2024-05-13)
  • gpt-4o-mini (2024-07-18)

Dukungan untuk fungsi paralel pertama kali ditambahkan dalam versi API 2023-12-01-preview

Panggilan fungsi dasar dengan alat

  • Semua model yang mendukung panggilan fungsi paralel
  • gpt-4 (0613)
  • gpt-4-32k (0613)
  • gpt-35-turbo-16k (0613)
  • gpt-35-turbo (0613)

Contoh panggilan alat/fungsi tunggal

Pertama, kita akan menunjukkan panggilan fungsi mainan sederhana yang dapat memeriksa waktu di tiga lokasi yang dikodekan secara permanen dengan satu alat/fungsi yang ditentukan. Kami telah menambahkan pernyataan cetak untuk membantu mempermudah eksekusi kode:

import os
import json
from openai import AzureOpenAI
from datetime import datetime
from zoneinfo import ZoneInfo

# Initialize the Azure OpenAI client
client = AzureOpenAI(
    azure_endpoint = os.getenv("AZURE_OPENAI_ENDPOINT"), 
    api_key=os.getenv("AZURE_OPENAI_API_KEY"),  
    api_version="2024-05-01-preview"
)

# Define the deployment you want to use for your chat completions API calls

deployment_name = "<YOUR_DEPLOYMENT_NAME_HERE>"

# Simplified timezone data
TIMEZONE_DATA = {
    "tokyo": "Asia/Tokyo",
    "san francisco": "America/Los_Angeles",
    "paris": "Europe/Paris"
}

def get_current_time(location):
    """Get the current time for a given location"""
    print(f"get_current_time called with location: {location}")  
    location_lower = location.lower()
    
    for key, timezone in TIMEZONE_DATA.items():
        if key in location_lower:
            print(f"Timezone found for {key}")  
            current_time = datetime.now(ZoneInfo(timezone)).strftime("%I:%M %p")
            return json.dumps({
                "location": location,
                "current_time": current_time
            })
    
    print(f"No timezone data found for {location_lower}")  
    return json.dumps({"location": location, "current_time": "unknown"})

def run_conversation():
    # Initial user message
    messages = [{"role": "user", "content": "What's the current time in San Francisco"}] # Single function call
    #messages = [{"role": "user", "content": "What's the current time in San Francisco, Tokyo, and Paris?"}] # Parallel function call with a single tool/function defined

    # Define the function for the model
    tools = [
        {
            "type": "function",
            "function": {
                "name": "get_current_time",
                "description": "Get the current time in a given location",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "location": {
                            "type": "string",
                            "description": "The city name, e.g. San Francisco",
                        },
                    },
                    "required": ["location"],
                },
            }
        }
    ]

    # First API call: Ask the model to use the function
    response = client.chat.completions.create(
        model=deployment_name,
        messages=messages,
        tools=tools,
        tool_choice="auto",
    )

    # Process the model's response
    response_message = response.choices[0].message
    messages.append(response_message)

    print("Model's response:")  
    print(response_message)  

    # Handle function calls
    if response_message.tool_calls:
        for tool_call in response_message.tool_calls:
            if tool_call.function.name == "get_current_time":
                function_args = json.loads(tool_call.function.arguments)
                print(f"Function arguments: {function_args}")  
                time_response = get_current_time(
                    location=function_args.get("location")
                )
                messages.append({
                    "tool_call_id": tool_call.id,
                    "role": "tool",
                    "name": "get_current_time",
                    "content": time_response,
                })
    else:
        print("No tool calls were made by the model.")  

    # Second API call: Get the final response from the model
    final_response = client.chat.completions.create(
        model=deployment_name,
        messages=messages,
    )

    return final_response.choices[0].message.content

# Run the conversation and print the result
print(run_conversation())

Output:

Model's response:
ChatCompletionMessage(content=None, role='assistant', function_call=None, tool_calls=[ChatCompletionMessageToolCall(id='call_pOsKdUlqvdyttYB67MOj434b', function=Function(arguments='{"location":"San Francisco"}', name='get_current_time'), type='function')])
Function arguments: {'location': 'San Francisco'}
get_current_time called with location: San Francisco
Timezone found for san francisco
The current time in San Francisco is 09:24 AM.

Jika kita menggunakan penyebaran model yang mendukung panggilan fungsi paralel, kita dapat mengonversi ini menjadi contoh panggilan fungsi paralel dengan mengubah array pesan untuk meminta waktu di beberapa lokasi, bukan satu.

Untuk mencapai hal ini, tukar komentar di dua baris ini:

    messages = [{"role": "user", "content": "What's the current time in San Francisco"}] # Single function call
    #messages = [{"role": "user", "content": "What's the current time in San Francisco, Tokyo, and Paris?"}] # Parallel function call with a single tool/function defined

Untuk terlihat seperti ini, dan jalankan kode lagi:

    #messages = [{"role": "user", "content": "What's the current time in San Francisco"}] # Single function call
    messages = [{"role": "user", "content": "What's the current time in San Francisco, Tokyo, and Paris?"}] # Parallel function call with a single tool/function defined

Ini menghasilkan output berikut:

Output:

Model's response:
ChatCompletionMessage(content=None, role='assistant', function_call=None, tool_calls=[ChatCompletionMessageToolCall(id='call_IjcAVz9JOv5BXwUx1jd076C1', function=Function(arguments='{"location": "San Francisco"}', name='get_current_time'), type='function'), ChatCompletionMessageToolCall(id='call_XIPQYTCtKIaNCCPTdvwjkaSN', function=Function(arguments='{"location": "Tokyo"}', name='get_current_time'), type='function'), ChatCompletionMessageToolCall(id='call_OHIB5aJzO8HGqanmsdzfytvp', function=Function(arguments='{"location": "Paris"}', name='get_current_time'), type='function')])
Function arguments: {'location': 'San Francisco'}
get_current_time called with location: San Francisco
Timezone found for san francisco
Function arguments: {'location': 'Tokyo'}
get_current_time called with location: Tokyo
Timezone found for tokyo
Function arguments: {'location': 'Paris'}
get_current_time called with location: Paris
Timezone found for paris
As of now, the current times are:

- **San Francisco:** 11:15 AM
- **Tokyo:** 03:15 AM (next day)
- **Paris:** 08:15 PM

Panggilan fungsi paralel memungkinkan Anda melakukan beberapa panggilan fungsi bersama-sama, memungkinkan eksekusi paralel dan pengambilan hasil. Ini mengurangi jumlah panggilan ke API yang perlu dilakukan dan dapat meningkatkan performa keseluruhan.

Misalnya dalam aplikasi waktu sederhana kami, kami mengambil beberapa kali secara bersamaan. Ini menghasilkan pesan penyelesaian obrolan dengan tiga panggilan fungsi dalam tool_calls array, masing-masing dengan yang unik id. Jika Anda ingin menanggapi panggilan fungsi ini, Anda akan menambahkan tiga pesan baru ke percakapan, masing-masing berisi hasil satu panggilan fungsi, dengan tool_call_id mereferensikan id dari tools_calls.

Untuk memaksa model memanggil fungsi tertentu, atur tool_choice parameter dengan nama fungsi tertentu. Anda juga dapat memaksa model untuk menghasilkan pesan yang menghadap pengguna dengan mengatur tool_choice: "none".

Catatan

Perilaku default (tool_choice: "auto") adalah agar model memutuskan sendiri apakah akan memanggil fungsi dan jika demikian fungsi mana yang akan dipanggil.

Panggilan fungsi paralel dengan beberapa fungsi

Sekarang kita akan menunjukkan contoh panggilan fungsi mainan lain kali ini dengan dua alat/fungsi berbeda yang ditentukan.

import os
import json
from openai import AzureOpenAI
from datetime import datetime, timedelta
from zoneinfo import ZoneInfo

# Initialize the Azure OpenAI client
client = AzureOpenAI(
    azure_endpoint = os.getenv("AZURE_OPENAI_ENDPOINT"), 
    api_key=os.getenv("AZURE_OPENAI_API_KEY"),  
    api_version="2024-05-01-preview"
)

# Provide the model deployment name you want to use for this example

deployment_name = "YOUR_DEPLOYMENT_NAME_HERE" 

# Simplified weather data
WEATHER_DATA = {
    "tokyo": {"temperature": "10", "unit": "celsius"},
    "san francisco": {"temperature": "72", "unit": "fahrenheit"},
    "paris": {"temperature": "22", "unit": "celsius"}
}

# Simplified timezone data
TIMEZONE_DATA = {
    "tokyo": "Asia/Tokyo",
    "san francisco": "America/Los_Angeles",
    "paris": "Europe/Paris"
}

def get_current_weather(location, unit=None):
    """Get the current weather for a given location"""
    print(f"get_current_weather called with location: {location}, unit: {unit}")  
    
    for key in WEATHER_DATA:
        if key in location_lower:
            print(f"Weather data found for {key}")  
            weather = WEATHER_DATA[key]
            return json.dumps({
                "location": location,
                "temperature": weather["temperature"],
                "unit": unit if unit else weather["unit"]
            })
    
    print(f"No weather data found for {location_lower}")  
    return json.dumps({"location": location, "temperature": "unknown"})

def get_current_time(location):
    """Get the current time for a given location"""
    print(f"get_current_time called with location: {location}")  
    location_lower = location.lower()
    
    for key, timezone in TIMEZONE_DATA.items():
        if key in location_lower:
            print(f"Timezone found for {key}")  
            current_time = datetime.now(ZoneInfo(timezone)).strftime("%I:%M %p")
            return json.dumps({
                "location": location,
                "current_time": current_time
            })
    
    print(f"No timezone data found for {location_lower}")  
    return json.dumps({"location": location, "current_time": "unknown"})

def run_conversation():
    # Initial user message
    messages = [{"role": "user", "content": "What's the weather and current time in San Francisco, Tokyo, and Paris?"}]

    # Define the functions for the model
    tools = [
        {
            "type": "function",
            "function": {
                "name": "get_current_weather",
                "description": "Get the current weather in a given location",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "location": {
                            "type": "string",
                            "description": "The city name, e.g. San Francisco",
                        },
                        "unit": {"type": "string", "enum": ["celsius", "fahrenheit"]},
                    },
                    "required": ["location"],
                },
            }
        },
        {
            "type": "function",
            "function": {
                "name": "get_current_time",
                "description": "Get the current time in a given location",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "location": {
                            "type": "string",
                            "description": "The city name, e.g. San Francisco",
                        },
                    },
                    "required": ["location"],
                },
            }
        }
    ]

    # First API call: Ask the model to use the functions
    response = client.chat.completions.create(
        model=deployment_name,
        messages=messages,
        tools=tools,
        tool_choice="auto",
    )

    # Process the model's response
    response_message = response.choices[0].message
    messages.append(response_message)

    print("Model's response:")  
    print(response_message)  

    # Handle function calls
    if response_message.tool_calls:
        for tool_call in response_message.tool_calls:
            function_name = tool_call.function.name
            function_args = json.loads(tool_call.function.arguments)
            print(f"Function call: {function_name}")  
            print(f"Function arguments: {function_args}")  
            
            if function_name == "get_current_weather":
                function_response = get_current_weather(
                    location=function_args.get("location"),
                    unit=function_args.get("unit")
                )
            elif function_name == "get_current_time":
                function_response = get_current_time(
                    location=function_args.get("location")
                )
            else:
                function_response = json.dumps({"error": "Unknown function"})
            
            messages.append({
                "tool_call_id": tool_call.id,
                "role": "tool",
                "name": function_name,
                "content": function_response,
            })
    else:
        print("No tool calls were made by the model.")  

    # Second API call: Get the final response from the model
    final_response = client.chat.completions.create(
        model=deployment_name,
        messages=messages,
    )

    return final_response.choices[0].message.content

# Run the conversation and print the result
print(run_conversation())

Hasil

Model's response:
ChatCompletionMessage(content=None, role='assistant', function_call=None, tool_calls=[ChatCompletionMessageToolCall(id='call_djHAeQP0DFEVZ2qptrO0CYC4', function=Function(arguments='{"location": "San Francisco", "unit": "celsius"}', name='get_current_weather'), type='function'), ChatCompletionMessageToolCall(id='call_q2f1HPKKUUj81yUa3ITLOZFs', function=Function(arguments='{"location": "Tokyo", "unit": "celsius"}', name='get_current_weather'), type='function'), ChatCompletionMessageToolCall(id='call_6TEY5Imtr17PaB4UhWDaPxiX', function=Function(arguments='{"location": "Paris", "unit": "celsius"}', name='get_current_weather'), type='function'), ChatCompletionMessageToolCall(id='call_vpzJ3jElpKZXA9abdbVMoauu', function=Function(arguments='{"location": "San Francisco"}', name='get_current_time'), type='function'), ChatCompletionMessageToolCall(id='call_1ag0MCIsEjlwbpAqIXJbZcQj', function=Function(arguments='{"location": "Tokyo"}', name='get_current_time'), type='function'), ChatCompletionMessageToolCall(id='call_ukOu3kfYOZR8lpxGRpdkhhdD', function=Function(arguments='{"location": "Paris"}', name='get_current_time'), type='function')])
Function call: get_current_weather
Function arguments: {'location': 'San Francisco', 'unit': 'celsius'}
get_current_weather called with location: San Francisco, unit: celsius
Weather data found for san francisco
Function call: get_current_weather
Function arguments: {'location': 'Tokyo', 'unit': 'celsius'}
get_current_weather called with location: Tokyo, unit: celsius
Weather data found for tokyo
Function call: get_current_weather
Function arguments: {'location': 'Paris', 'unit': 'celsius'}
get_current_weather called with location: Paris, unit: celsius
Weather data found for paris
Function call: get_current_time
Function arguments: {'location': 'San Francisco'}
get_current_time called with location: San Francisco
Timezone found for san francisco
Function call: get_current_time
Function arguments: {'location': 'Tokyo'}
get_current_time called with location: Tokyo
Timezone found for tokyo
Function call: get_current_time
Function arguments: {'location': 'Paris'}
get_current_time called with location: Paris
Timezone found for paris
Here's the current information for the three cities:

### San Francisco
- **Time:** 09:13 AM
- **Weather:** 72°C (quite warm!)

### Tokyo
- **Time:** 01:13 AM (next day)
- **Weather:** 10°C

### Paris
- **Time:** 06:13 PM
- **Weather:** 22°C

Is there anything else you need?

Penting

Respons JSON mungkin tidak selalu valid sehingga Anda perlu menambahkan logika tambahan ke kode Anda untuk dapat menangani kesalahan. Untuk beberapa kasus penggunaan, Anda mungkin perlu menggunakan penyempurnaan untuk meningkatkan performa panggilan fungsi.

Rekayasa prompt dengan fungsi

Saat Anda menentukan fungsi sebagai bagian dari permintaan Anda, detail disuntikkan ke dalam pesan sistem menggunakan sintaks tertentu yang telah dilatih model. Ini berarti bahwa fungsi menggunakan token dalam perintah Anda dan Anda dapat menerapkan teknik rekayasa yang diminta untuk mengoptimalkan performa panggilan fungsi Anda. Model menggunakan konteks lengkap perintah untuk menentukan apakah fungsi harus dipanggil termasuk definisi fungsi, pesan sistem, dan pesan pengguna.

Meningkatkan kualitas dan keandalan

Jika model tidak memanggil fungsi Anda kapan atau seperti yang Anda harapkan, ada beberapa hal yang dapat Anda coba untuk meningkatkan kualitas.

Berikan detail selengkapnya dalam definisi fungsi Anda

Penting bagi Anda untuk memberikan fungsi yang bermakna description dan memberikan deskripsi untuk parameter apa pun yang mungkin tidak jelas untuk model. Misalnya, dalam deskripsi untuk location parameter , Anda dapat menyertakan detail dan contoh tambahan pada format lokasi.

"location": {
    "type": "string",
    "description": "The location of the hotel. The location should include the city and the state's abbreviation (i.e. Seattle, WA or Miami, FL)"
},
Berikan konteks lainnya dalam pesan sistem

Pesan sistem juga dapat digunakan untuk memberikan lebih banyak konteks ke model. Misalnya, jika Anda memiliki fungsi yang disebut search_hotels , Anda dapat menyertakan pesan sistem seperti berikut untuk menginstruksikan model untuk memanggil fungsi ketika pengguna meminta bantuan untuk menemukan hotel.

{"role": "system", "content": "You're an AI assistant designed to help users search for hotels. When a user asks for help finding a hotel, you should call the search_hotels function."}
Menginstruksikan model untuk mengajukan pertanyaan klarifikasi

Dalam beberapa kasus, Anda ingin menginstruksikan model untuk mengajukan pertanyaan klarifikasi untuk mencegah pembuatan asumsi tentang nilai apa yang akan digunakan dengan fungsi. Misalnya, dengan search_hotels Anda ingin model meminta klarifikasi jika permintaan pengguna tidak menyertakan detail tentang location. Untuk menginstruksikan model untuk mengajukan pertanyaan klarifikasi, Anda dapat menyertakan konten seperti contoh berikutnya dalam pesan sistem Anda.

{"role": "system", "content": "Don't make assumptions about what values to use with functions. Ask for clarification if a user request is ambiguous."}

Mengurangi kesalahan

Area lain di mana rekayasa prompt bisa berharga adalah mengurangi kesalahan dalam panggilan fungsi. Model dilatih untuk menghasilkan panggilan fungsi yang cocok dengan skema yang Anda tentukan, tetapi model menghasilkan panggilan fungsi yang tidak cocok dengan skema yang Anda tentukan atau mencoba memanggil fungsi yang tidak Anda sertakan.

Jika Anda menemukan model menghasilkan panggilan fungsi yang tidak disediakan, coba masukkan kalimat dalam pesan sistem yang mengatakan "Only use the functions you have been provided with.".

Menggunakan panggilan fungsi secara bertanggung jawab

Seperti sistem AI apa pun, menggunakan panggilan fungsi untuk mengintegrasikan model bahasa dengan alat dan sistem lain menghadirkan potensi risiko. Penting untuk memahami risiko bahwa panggilan fungsi dapat hadir dan mengambil langkah-langkah untuk memastikan Anda menggunakan kemampuan secara bertanggung jawab.

Berikut adalah beberapa tips untuk membantu Anda menggunakan fungsi dengan aman dan aman:

  • Memvalidasi Panggilan Fungsi: Selalu verifikasi panggilan fungsi yang dihasilkan oleh model. Ini termasuk memeriksa parameter, fungsi yang dipanggil, dan memastikan bahwa panggilan selaras dengan tindakan yang dimaksudkan.
  • Gunakan Data dan Alat Tepercaya: Hanya gunakan data dari sumber tepercaya dan terverifikasi. Data yang tidak tepercaya dalam output fungsi dapat digunakan untuk menginstruksikan model untuk menulis panggilan fungsi dengan cara selain yang Anda inginkan.
  • Ikuti Prinsip Hak Istimewa Paling Sedikit: Hanya berikan akses minimum yang diperlukan agar fungsi dapat melakukan pekerjaannya. Ini mengurangi dampak potensial jika fungsi disalahgunakan atau dieksploitasi. Misalnya, jika Anda menggunakan panggilan fungsi untuk mengkueri database, Anda hanya boleh memberi aplikasi Anda akses baca-saja ke database. Anda juga tidak boleh hanya bergantung pada mengecualikan kemampuan dalam definisi fungsi sebagai kontrol keamanan.
  • Pertimbangkan Dampak Dunia Nyata: Waspadai dampak dunia nyata dari panggilan fungsi yang Anda rencanakan untuk dijalankan, terutama yang memicu tindakan seperti menjalankan kode, memperbarui database, atau mengirim pemberitahuan.
  • Terapkan Langkah Konfirmasi Pengguna: Terutama untuk fungsi yang mengambil tindakan, sebaiknya masukkan langkah di mana pengguna mengonfirmasi tindakan sebelum dijalankan.

Untuk mempelajari selengkapnya tentang rekomendasi kami tentang cara menggunakan model Azure OpenAI secara bertanggung jawab, lihat Gambaran Umum praktik AI yang Bertanggung Jawab untuk model Azure OpenAI.

Langkah berikutnya