Functie-aanroepen gebruiken met Azure OpenAI Service (preview)
De nieuwste versies van gpt-35-turbo en gpt-4 zijn afgestemd op het werken met functies en kunnen bepalen wanneer en hoe een functie moet worden aangeroepen. Als een of meer functies zijn opgenomen in uw aanvraag, bepaalt het model of een van de functies moet worden aangeroepen op basis van de context van de prompt. Wanneer het model bepaalt dat een functie moet worden aangeroepen, reageert het met een JSON-object, inclusief de argumenten voor de functie.
De modellen formuleren API-aanroepen en structureer gegevensuitvoer, allemaal op basis van de functies die u opgeeft. Het is belangrijk om te weten dat terwijl de modellen deze aanroepen kunnen genereren, het aan u is om ze uit te voeren, zodat u de controle behoudt.
Op hoog niveau kunt u het werken met functies in drie stappen opsplitsen:
- Roep de API voor voltooiing van de chat aan met uw functies en de invoer van de gebruiker
- Het antwoord van het model gebruiken om uw API of functie aan te roepen
- Roep de API voor voltooiingen van de chat opnieuw aan, inclusief het antwoord van uw functie om een definitief antwoord te krijgen
Belangrijk
De functions
en function_call
parameters zijn afgeschaft met de release van de versie van de 2023-12-01-preview
API. De vervanging voor functions
is de tools
parameter. De vervanging voor function_call
is de tool_choice
parameter.
Ondersteuning voor functiegesprekken
Parallelle functie aanroepen
gpt-35-turbo
(1106)gpt-35-turbo
(0125)gpt-4
(1106-preview)gpt-4
(0125-preview)gpt-4
(vision-preview)gpt-4
(2024-04-09)gpt-4o
(2024-05-13)gpt-4o-mini
(2024-07-18)
Ondersteuning voor parallelle functie is voor het eerst toegevoegd in API-versie 2023-12-01-preview
Eenvoudige functie aanroepen met hulpprogramma's
- Alle modellen die ondersteuning bieden voor parallelle functie-aanroepen
gpt-4
(0613)gpt-4-32k
(0613)gpt-35-turbo-16k
(0613)gpt-35-turbo
(0613)
Voorbeeld van het aanroepen van één hulpprogramma/functie
Eerst laten we een eenvoudige functie-aanroep van speelgoed zien die de tijd op drie vastgelegde locaties kan controleren met één hulpprogramma/functie gedefinieerd. We hebben afdrukinstructies toegevoegd om de uitvoering van de code gemakkelijker te maken:
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())
Uitvoer:
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.
Als we een modelimplementatie gebruiken die ondersteuning biedt voor parallelle functie-aanroepen, kunnen we dit omzetten in een voorbeeld van een parallelle functie die wordt aangeroepen door de berichtenmatrix te wijzigen om te vragen naar de tijd op meerdere locaties in plaats van één.
U kunt dit doen door de opmerkingen in deze twee regels te wisselen:
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
U ziet er als volgt uit en voert de code opnieuw uit:
#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
Hiermee wordt de volgende uitvoer gegenereerd:
Uitvoer:
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
Met parallelle functieaanroepen kunt u meerdere functieaanroepen tegelijk uitvoeren, waardoor parallelle uitvoering en het ophalen van resultaten mogelijk zijn. Dit vermindert het aantal aanroepen naar de API die moet worden uitgevoerd en kan de algehele prestaties verbeteren.
In onze eenvoudige tijd-app hebben we bijvoorbeeld meerdere keren tegelijk opgehaald. Dit resulteerde in een chatvoltooiingsbericht met drie functie-aanroepen in de tool_calls
matrix, elk met een unieke id
. Als u wilt reageren op deze functie-aanroepen, voegt u drie nieuwe berichten toe aan het gesprek, elk met het resultaat van één functie-aanroep, met een tool_call_id
verwijzing naar de id
waaruit tools_calls
.
Als u wilt afdwingen dat het model een specifieke functie aanroept, stelt u de tool_choice
parameter in met een specifieke functienaam. U kunt het model ook dwingen om een gebruikersgericht bericht te genereren door de instelling in te stellen tool_choice: "none"
.
Notitie
Het standaardgedrag (tool_choice: "auto"
) is bedoeld om het model zelf te laten beslissen of een functie moet worden aangeroepen en als dat het zo is welke functie moet worden aangeroepen.
Parallelle functie aanroepen met meerdere functies
Nu laten we een ander voorbeeld van een speelgoedfunctie zien waarin twee verschillende hulpprogramma's/functies zijn gedefinieerd.
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())
Uitvoer
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?
Belangrijk
Het JSON-antwoord is mogelijk niet altijd geldig, dus u moet extra logica toevoegen aan uw code om fouten te kunnen verwerken. Voor sommige gebruiksscenario's moet u mogelijk fine-tuning gebruiken om de prestaties van functie-aanroepen te verbeteren.
Vragen om engineering met functies
Wanneer u een functie definieert als onderdeel van uw aanvraag, worden de details opgenomen in het systeembericht met behulp van specifieke syntaxis waarop het model is getraind. Dit betekent dat functies tokens in uw prompt verbruiken en dat u prompt engineeringtechnieken kunt toepassen om de prestaties van uw functie-aanroepen te optimaliseren. Het model gebruikt de volledige context van de prompt om te bepalen of een functie moet worden aangeroepen, inclusief functiedefinitie, het systeembericht en de gebruikersberichten.
Kwaliteit en betrouwbaarheid verbeteren
Als het model uw functie niet aanroept wanneer of hoe u verwacht, zijn er een paar dingen die u kunt proberen om de kwaliteit te verbeteren.
Geef meer informatie op in uw functiedefinitie
Het is belangrijk dat u een zinvolle description
functie opgeeft en beschrijvingen opgeeft voor een parameter die mogelijk niet duidelijk is voor het model. In de beschrijving voor de location
parameter kunt u bijvoorbeeld extra details en voorbeelden opnemen over de indeling van de locatie.
"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)"
},
Geef meer context op in het systeembericht
Het systeembericht kan ook worden gebruikt om meer context aan het model te bieden. Als u bijvoorbeeld een functie hebt die u hebt aangeroepen search_hotels
, kunt u een systeembericht zoals het volgende opnemen om het model te instrueren om de functie aan te roepen wanneer een gebruiker om hulp vraagt bij het vinden van een 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."}
Het model instrueren om vragen te stellen
In sommige gevallen wilt u het model instrueren om vragen te stellen om aannames te voorkomen over welke waarden moeten worden gebruikt met functies. U wilt bijvoorbeeld search_hotels
dat het model om verduidelijking vraagt als de gebruikersaanvraag geen details over location
bevat. Als u het model wilt instrueren om een duidelijkere vraag te stellen, kunt u inhoud opnemen zoals in het volgende voorbeeld in uw systeembericht.
{"role": "system", "content": "Don't make assumptions about what values to use with functions. Ask for clarification if a user request is ambiguous."}
Fouten verminderen
Een ander gebied waar prompt-engineering waardevol kan zijn, is het verminderen van fouten in functie-aanroepen. De modellen worden getraind om functie-aanroepen te genereren die overeenkomen met het schema dat u definieert, maar de modellen produceren een functie-aanroep die niet overeenkomt met het schema dat u hebt gedefinieerd of een functie probeert aan te roepen die u niet hebt opgenomen.
Als u merkt dat het model functieaanroepen genereert die niet zijn opgegeven, kunt u een zin opnemen in het systeembericht met de tekst "Only use the functions you have been provided with."
.
Het gebruik van functie-aanroepen op verantwoorde wijze
Net als elk AI-systeem biedt het gebruik van functie-aanroepen om taalmodellen te integreren met andere hulpprogramma's en systemen potentiële risico's. Het is belangrijk om inzicht te hebben in de risico's die functiegesprekken kunnen opleveren en maatregelen kunnen nemen om ervoor te zorgen dat u de mogelijkheden op verantwoorde wijze gebruikt.
Hier volgen enkele tips om u te helpen functies veilig en veilig te gebruiken:
- Functie-aanroepen valideren: controleer altijd de functie-aanroepen die zijn gegenereerd door het model. Dit omvat het controleren van de parameters, de functie die wordt aangeroepen en ervoor zorgen dat de aanroep overeenkomt met de beoogde actie.
- Vertrouwde gegevens en hulpprogramma's gebruiken: gebruik alleen gegevens uit vertrouwde en geverifieerde bronnen. Niet-vertrouwde gegevens in de uitvoer van een functie kunnen worden gebruikt om het model te instrueren om functie-aanroepen op een andere manier te schrijven dan u bedoelde.
- Volg het principe van minimale bevoegdheden: ververleent alleen de minimale toegang die nodig is voor de functie om de taak uit te voeren. Dit vermindert de mogelijke impact als een functie wordt misbruikt of misbruikt. Als u bijvoorbeeld functieoproepen gebruikt om een query uit te voeren op een database, moet u uw toepassing alleen-lezentoegang geven tot de database. U moet ook niet alleen afhankelijk zijn van het uitsluiten van mogelijkheden in de functiedefinitie als beveiligingsbeheer.
- Houd rekening met echte impact: houd rekening met de werkelijke impact van functie-aanroepen die u wilt uitvoeren, met name die acties activeren, zoals het uitvoeren van code, het bijwerken van databases of het verzenden van meldingen.
- Implementeer gebruikersbevestigingsstappen: met name voor functies die acties ondernemen, raden we u aan een stap op te nemen waarbij de gebruiker de actie bevestigt voordat deze wordt uitgevoerd.
Volgende stappen
- Meer informatie over Azure OpenAI.
- Bekijk de GitHub-opslagplaats met Azure OpenAI-voorbeelden voor meer voorbeelden over het werken met functies
- Ga aan de slag met het GPT-35-Turbo-model met de GPT-35-Turbo quickstart.