Megosztás a következőn keresztül:


Függvényhívás használata az Azure OpenAI Szolgáltatással (előzetes verzió)

A gpt-35-turbo és a gpt-4 legújabb verziói finomhangolva vannak a függvények használatához, és képesek meghatározni, hogy mikor és hogyan kell meghívni egy függvényt. Ha egy vagy több függvény szerepel a kérésben, a modell meghatározza, hogy a függvényeket a kérés kontextusa alapján kell-e meghívni. Amikor a modell megállapítja, hogy egy függvényt kell meghívni, egy JSON-objektummal válaszol, beleértve a függvény argumentumait is.

A modellek api-hívásokat dolgoznak ki, és az adatkimeneteket a megadott függvények alapján strukturálják. Fontos megjegyezni, hogy bár a modellek képesek generálni ezeket a hívásokat, önön múlik, hogy végrehajtsa őket, biztosítva, hogy ön továbbra is kézben tartsa az irányítást.

Magas szinten három lépésre bonthatja a függvények működését:

  1. A csevegővégzítési API meghívása a függvényekkel és a felhasználó bemenetével
  2. A modell válaszával hívja meg az API-t vagy a függvényt
  3. Hívja meg újra a csevegés befejezése API-t, beleértve a függvény válaszát is a végső válasz lekéréséhez

Fontos

Az functions API verziójának kiadásával 2023-12-01-preview a paraméterek és function_call a paraméterek elavultak. A paraméter cseréje functions tools . A paraméter cseréje function_call tool_choice .

Függvényhívás támogatása

Párhuzamos függvényhívás

  • gpt-35-turbo (1106)
  • gpt-35-turbo (0125)
  • gpt-4 (1106-előzetes verzió)
  • gpt-4 (0125-preview)
  • gpt-4 (vision-preview)
  • gpt-4 (2024-04-09)
  • gpt-4o (2024-05-13)
  • gpt-4o-mini (2024-07-18)

A párhuzamos függvény támogatása először az API-verzióban lett hozzáadva 2023-12-01-preview

Alapszintű függvényhívás eszközökkel

  • A párhuzamos függvényhívást támogató összes modell
  • gpt-4 (0613)
  • gpt-4-32k (0613)
  • gpt-35-turbo-16k (0613)
  • gpt-35-turbo (0613)

Példa egyetlen eszköz/függvény hívására

Először bemutatunk egy egyszerű függvényhívást, amely egyetlen eszköz/függvény definiált használatával három rögzített helyen ellenőrizheti az időt. Nyomtatási utasításokat adtunk hozzá, hogy könnyebben követhető legyen a kód végrehajtása:

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())

Hozam:

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.

Ha olyan modelltelepítést használunk, amely támogatja a párhuzamos függvényhívásokat, ezt egy párhuzamos függvényhívási példává alakíthatjuk úgy, hogy az üzenettömböt úgy módosítjuk, hogy több helyen kérjük az időt egy helyett.

A felcseréléshez az alábbi két sorban szereplő megjegyzéseket kell elvégeznie:

    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

A következőképpen kell kinéznie, és futtassa újra a kódot:

    #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

Ez a következő kimenetet hozza létre:

Hozam:

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

A párhuzamos függvényhívások lehetővé teszik több függvényhívás együttes végrehajtását, lehetővé téve a párhuzamos végrehajtást és az eredmények lekérését. Ez csökkenti az API-ba irányuló hívások számát, amelyeket el kell indítani, és javíthatja az általános teljesítményt.

Az egyszerű időalkalmazásban például egyszerre többször is lekértük. Ez egy csevegőüzenetet eredményezett, amelyben három függvényhívás volt a tool_calls tömbben, amelyek mindegyike egyedi id. Ha válaszolni szeretne ezekre a függvényhívásokra, három új üzenetet adna hozzá a beszélgetéshez, amelyek mindegyike egy függvényhívás eredményét tartalmazza, és a tool_call_id feladóra tools_callshivatkozikid.

Ha arra szeretné kényszeríteni a modellt, hogy meghívjon egy adott függvényt, állítsa be a tool_choice paramétert egy adott függvénynévvel. Azt is kényszerítheti, hogy a modell felhasználói üzenetet hozzon létre a beállítással tool_choice: "none".

Feljegyzés

Az alapértelmezett viselkedés (tool_choice: "auto") az, hogy a modell önállóan döntse el, hogy meghív-e egy függvényt, és ha igen, melyik függvényt hívja meg.

Párhuzamos függvényhívás több függvénnyel

Most egy másik, ezúttal két különböző eszközt/függvényt definiáló, példaként szolgáló függvényt mutatunk be.

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())

Hozam

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?

Fontos

Előfordulhat, hogy a JSON-válasz nem mindig érvényes, ezért további logikát kell hozzáadnia a kódhoz a hibák kezeléséhez. Bizonyos használati esetekben előfordulhat, hogy a függvényhívási teljesítmény javítása érdekében finomhangolást kell használnia.

Gyors tervezés függvényekkel

Amikor a kérés részeként definiál egy függvényt, a rendszer a részleteket a rendszerüzenetbe injektálja a modell betanított szintaxisával. Ez azt jelenti, hogy a függvények jogkivonatokat használnak a parancssorban, és parancssori mérnöki technikákat alkalmazhatnak a függvényhívások teljesítményének optimalizálásához. A modell az üzenet teljes kontextusával határozza meg, hogy egy függvényt kell-e meghívni, beleértve a függvénydefiníciót, a rendszerüzenetet és a felhasználói üzeneteket.

A minőség és a megbízhatóság javítása

Ha a modell nem hívja meg a függvényt, amikor vagy ahogyan elvárja, néhány dolgot megpróbálhat javítani a minőségen.

További részletek megadása a függvénydefinícióban

Fontos, hogy a függvényt értelmesen description adja meg, és adjon meg leírásokat minden olyan paraméterhez, amely nem feltétlenül nyilvánvaló a modell számára. A paraméter leírásában location például további részleteket és példákat is elhelyezhet a hely formátumában.

"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)"
},
További környezet biztosítása a rendszerüzenetben

A rendszerüzenet további kontextust is biztosít a modell számára. Ha például van egy úgynevezett search_hotels függvénye, az alábbihoz hasonló rendszerüzenettel utasíthatja a modellt, hogy hívja meg a függvényt, amikor egy felhasználó segítséget kér egy szálloda megtalálásához.

{"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."}
Utasítsa a modellt, hogy tegyen fel tisztázó kérdéseket

Bizonyos esetekben arra szeretné utasítani a modellt, hogy tegyen fel tisztázó kérdéseket, hogy ne tegyenek feltételezéseket a függvényekkel használandó értékekről. Ha például azt szeretné, search_hotels hogy a modell pontosítást kérjen, ha a felhasználói kérés nem tartalmaz részleteket.location Ha arra szeretné utasítani a modellt, hogy tegyen fel egy tisztázó kérdést, a következő példához hasonló tartalmat is felvehet a rendszerüzenetbe.

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

Hibák csökkentése

Egy másik terület, ahol a parancssori tervezés hasznos lehet, a függvényhívások hibáinak csökkentése. A modellek be vannak tanítva a definiált sémának megfelelő függvényhívások létrehozására, de a modellek olyan függvényhívást hoznak létre, amely nem egyezik a megadott sémával, vagy olyan függvényt próbál meghívni, amelyet nem tartalmazott.

Ha úgy találja, hogy a modell nem megadott függvényhívásokat hoz létre, próbáljon meg belefogni egy mondatot a rendszerüzenetbe, amely azt jelzi "Only use the functions you have been provided with.".

Függvényhívás felelősségteljes használata

Mint minden AI-rendszer, a nyelvi modellek más eszközökkel és rendszerekkel való integrálásához használt függvényhívások potenciális kockázatokat jelentenek. Fontos tisztában lenni azzal, hogy milyen kockázatokat jelenthetnek a függvényhívások, és intézkedéseket kell tenni annak érdekében, hogy felelősségteljesen használja a képességeket.

Íme néhány tipp a függvények biztonságos és biztonságos használatához:

  • Függvényhívások ellenőrzése: Mindig ellenőrizze a modell által generált függvényhívásokat. Ez magában foglalja a paraméterek ellenőrzését, a meghívandó függvényt, valamint annak biztosítását, hogy a hívás igazodjon a kívánt művelethez.
  • Megbízható adatok és eszközök használata: Csak megbízható és ellenőrzött forrásokból származó adatokat használjon. A függvény kimenetében nem megbízható adatok arra utasíthatják a modellt, hogy a kívánttól eltérő módon írjon függvényhívásokat.
  • Kövesse a minimális jogosultság elvét: Csak a függvény feladatának elvégzéséhez szükséges minimális hozzáférést adja meg. Ez csökkenti a lehetséges hatást, ha egy függvényt visszaélnek vagy kihasználnak. Ha például függvényhívásokkal kérdez le egy adatbázist, csak írásvédett hozzáférést kell adnia az alkalmazásnak az adatbázishoz. Emellett nem szabad kizárólag a függvénydefiníció képességeinek biztonsági vezérlőként való kizárásától függenie.
  • Vegye figyelembe a valós hatást: Vegye figyelembe a végrehajtandó függvényhívások valós hatását, különösen azokat, amelyek olyan műveleteket aktiválnak, mint a kód végrehajtása, az adatbázisok frissítése vagy az értesítések küldése.
  • Felhasználói megerősítési lépések implementálása: Különösen a műveleteket végrehajtó függvények esetében javasoljuk, hogy foglaljanak bele egy olyan lépést, amelyben a felhasználó a végrehajtás előtt megerősíti a műveletet.

Ha többet szeretne megtudni az Azure OpenAI-modellek felelős használatára vonatkozó javaslatainkról, tekintse meg az Azure OpenAI-modellek felelős AI-eljárásainak áttekintését.

Következő lépések