Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Poznámka
Tento příklad používá rozhraní API pro dokončování chatu kompatibilní s OpenAI prostřednictvím koncového bodu Foundry Models. Volání funkcí prostřednictvím rozhraní Responses API používá jiný formát požadavků a odpovědí. Další informace najdete v tématu Použití rozhraní API odpovědí Azure OpenAI.
Pokud do požadavku zahrnete jednu nebo více funkcí, model se rozhodne, jestli má volat některou z funkcí na základě kontextu výzvy. Když se model rozhodne volat funkci, odpoví objektem JSON, který obsahuje argumenty funkce.
Model generuje volání funkcí a strukturované argumenty na základě zadaných funkcí. Vaše aplikace spustí funkce a vrátí výsledky do modelu, takže zůstanete pod kontrolou provedených akcí.
Na vysoké úrovni můžete rozdělit práci s funkcemi do tří kroků:
- Zavolejte rozhraní API pro dokončování chatu spolu s vašimi funkcemi a vstupem uživatele.
- Použití odpovědi modelu k volání rozhraní API nebo funkce
- Znovu volejte rozhraní API pro dokončování chatu, včetně odpovědi z vaší funkce, abyste získali konečnou odpověď.
Požadavky
- Nasazení modelu Foundry, které podporuje volání funkcí prostřednictvím rozhraní API pro dokončování chatu.
- Koncový bod prostředku Foundry ve formátu
https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/. - Pro ověřování Microsoft Entra ID:
- Je nakonfigurovaná vlastní subdoména. Další informace naleznete v tématu Názvy vlastních subdomén.
- Balíčky:
pip install openai azure-identity.
Příklad volání jednoho nástroje nebo funkce
Tento příklad ukazuje ukázkové volání funkce, které zjišťuje čas ve třech napevno zadaných místech s použitím jediného definovaného nástroje nebo funkce. Příkazy Print usnadňují provádění kódu:
import os
import json
from openai import OpenAI
from datetime import datetime
from zoneinfo import ZoneInfo
from azure.identity import DefaultAzureCredential, get_bearer_token_provider
token_provider = get_bearer_token_provider(
DefaultAzureCredential(), "https://ai.azure.com/.default"
)
client = OpenAI(
base_url = "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/",
api_key=token_provider,
)
# 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())
Výstup:
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.
Pokud používáme nasazení modelu, které podporuje paralelní volání funkcí, můžeme ho převést na příklad volání paralelní funkce tak, že změníme pole zpráv tak, aby místo jednoho požadovalo čas v několika umístěních.
Chcete-li toho dosáhnout, prohodíte komentáře v těchto dvou řádcích:
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
Aby to vypadalo takto, spusťte kód znovu:
#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
Tím se vygeneruje následující výstup:
Výstup:
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
Paralelní volání funkcí umožňují společně provádět více volání funkcí, což umožňuje paralelní spouštění a načítání výsledků. Tím se sníží počet volání rozhraní API, které je potřeba provést, a může zlepšit celkový výkon.
Například v naší jednoduché aplikaci jsme načetli vícekrát najednou. Výsledkem je zpráva o dokončení chatu se třemi voláními funkce v tool_calls poli, z nichž každý má jedinečný id. Pokud byste chtěli reagovat na tato volání funkce, přidali byste do konverzace tři nové zprávy, z nichž každá obsahuje výsledek jednoho volání funkce, s tool_call_id odkazem na id z tool_calls.
Chcete-li vynutit, aby model volal konkrétní funkci, nastavte tool_choice na pojmenovaný objekt nástroje, například: tool_choice={"type": "function", "function": {"name": "get_current_time"}}. Chcete-li vynutit uživatelskou zprávu, nastavte tool_choice="none".
Poznámka
Výchozí chování (tool_choice: "auto") je, aby se model sám rozhodl, jestli má volat funkci, a pokud ano, která funkce se má volat.
Paralelní volání funkcí s více funkcemi
Teď si ukážeme další příklad volání ukázkové funkce, tentokrát se dvěma různými definovanými nástroji a funkcemi.
import os
import json
from openai import OpenAI
from datetime import datetime, timedelta
from zoneinfo import ZoneInfo
from azure.identity import DefaultAzureCredential, get_bearer_token_provider
token_provider = get_bearer_token_provider(
DefaultAzureCredential(), "https://ai.azure.com/.default"
)
client = OpenAI(
base_url = "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/",
api_key=token_provider,
)
# 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"""
location_lower = location.lower()
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())
Výstup
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?
Důležité
Odpověď JSON nemusí být vždy platná, takže je potřeba do kódu přidat další logiku, aby bylo možné zpracovat chyby. V některých případech použití můžete zjistit, že k vylepšení výkonu volání funkcí potřebujete použít jemné ladění.
Vytváření promptů pomocí funkcí
Když definujete funkci jako součást požadavku, podrobnosti se vloží do systémové zprávy pomocí konkrétní syntaxe, na které byl model natrénován. To znamená, že funkce spotřebovávají tokeny ve vašem příkazu a že můžete použít techniky návrhu výzev k optimalizaci výkonu volání funkcí. Model používá úplný kontext výzvy k určení, jestli by měla být volána funkce, včetně definice funkce, systémové zprávy a zpráv uživatelů.
Zlepšení kvality a spolehlivosti
Pokud model nevolá vaši funkci ve chvíli nebo způsobem, jak očekáváte, můžete zkusit zlepšit kvalitu.
Zadání dalších podrobností v definici funkce
Je důležité, abyste poskytli smysluplný popis funkce a poskytli popisy všech parametrů, které nemusí být modelu zřejmé. Například v popisu parametru location můžete zahrnout další podrobnosti a příklady ve formátu umístění.
"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)"
},
Poskytnutí dalšího kontextu v systémové zprávě
Systémovou zprávu lze také použít k poskytnutí dalšího kontextu modelu. Pokud máte například funkci pojmenovanou search_hotels, můžete do modelu zahrnout systémovou zprávu, například následující, a přikázat modelu, aby tuto funkci zavolal, když uživatel požádá o pomoc s vyhledáním hotelu.
{"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."}
Řekněte modelu, aby se zeptal na objasnění otázek.
V některých případech chcete modelu říct, aby se ptal na objasňující otázky, aby se zabránilo dělání předpokladů o tom, jaké hodnoty použít s funkcemi. Například u search_hotels by model chtěl požádat o objasnění, pokud by žádost uživatele neobsahovala podrobnosti o location. Pokud chcete modelu dát pokyn, aby položil objasňující otázku, můžete do systémové zprávy zahrnout obsah podobný následujícímu příkladu.
{"role": "system", "content": "Don't make assumptions about what values to use with functions. Ask for clarification if a user request is ambiguous."}
Omezení chyb
Další oblastí, ve které může být příprava výzvy cenná, je snížení chyb ve voláních funkcí. Modely se vytrénují tak, aby generovaly volání funkcí odpovídající schématu, které definujete, ale modely vytvářejí volání funkce, které neodpovídá vámi definovanému schématu, nebo se pokusí volat funkci, kterou jste nezahrnuli.
Pokud zjistíte, že model generuje volání funkcí, která nebyla poskytnuta, zkuste do systémové zprávy zahrnout větu, která říká "Only use the functions you have been provided with.".
Zodpovědné používání volání funkcí
Stejně jako jakýkoli systém umělé inteligence představuje použití volání funkcí k integraci jazykových modelů s jinými nástroji a systémy potenciální rizika. Je důležité porozumět rizikům, která volání funkcí může představovat, a přijmout opatření k zajištění zodpovědného používání schopností.
Tady je několik tipů, které vám pomůžou bezpečně a bezpečně používat funkce:
- Ověření volání funkce: Vždy ověřte volání funkce vygenerovaná modelem. To zahrnuje kontrolu parametrů, volání funkce a zajištění toho, aby volání odpovídalo zamýšlené akci.
- Použití důvěryhodných dat a nástrojů: Používejte pouze data z důvěryhodných a ověřených zdrojů. Nedůvěryhodná data ve výstupu funkce se dají použít k tomu, aby model dal pokyn k zápisu volání funkcí jiným způsobem, než jste chtěli.
- Postupujte podle principu nejnižšího oprávnění: Udělte funkci pouze minimální přístup potřebný k provedení své úlohy. To snižuje potenciální dopad v případě, že je funkce nesprávně použita nebo zneužita. Pokud například používáte volání funkcí k dotazování databáze, měli byste aplikaci udělit přístup jen pro čtení k databázi. Neměli byste také záviset výhradně na vyloučení funkcí v definici funkce jako bezpečnostních prvků.
- Zvažte skutečný dopad: Pamatujte na skutečný dopad volání funkcí, která plánujete provést, zejména těch, které vyvolají akce, jako je provádění kódu, aktualizace databází nebo odesílání oznámení.
- Implementujte kroky potvrzení uživatele: Zejména pro funkce, které provádějí akce, doporučujeme přidat krok, ve kterém uživatel před spuštěním akci potvrdí.
Další informace o zodpovědných postupech AI pro foundry Models najdete v přehledu zodpovědných postupů umělé inteligence.
Důležité
V rozhraní Chat Completions API jsou parametry functions a function_call zastaralé. Použijte parametr tools místo functions a parametr tool_choice použijte místo function_call.
Podpora volání funkcí
Foundry Models podporují volání funkce prostřednictvím rozhraní API pro dokončování chatu nebo rozhraní API pro odpovědi. Podpora se liší podle modelu, rozhraní API, typu nasazení a verze modelu.
Pokud chcete najít model, který podporuje volání funkcí, projděte si následující katalogy:
V podrobnostech modelu vyhledejte následující funkce:
- Rozhraní API pro dokončování chatu nebo odpovědi v závislosti na rozhraní API, které plánujete použít.
- Funkce nebo nástroje pro podporu volání funkcí
- Paralelní volání nástrojů , pokud vaše aplikace potřebuje model k vyžádání více volání funkcí v jedné odpovědi.
Tento článek ukazuje, jak implementovat volání funkcí pomocí rozhraní API pro dokončování chatu. Informace o formátu požadavků a odpovědí rozhraní Responses API najdete v článku Použití rozhraní Azure OpenAI Responses API.
Poznámka
Parametr tool_choice je nyní podporován s parametrem o3-mini a o1. Další informace najdete v průvodci modely odůvodnění.
Důležité
Popisy nástrojů a funkcí jsou aktuálně omezené na 1 024 znaků. Pokud se tento limit změní, aktualizujeme tento článek.
Další kroky
- Používejte orchestraci více agentů s rozhraním Responses API.
- Přečtěte si další informace o Foundry Models.
- Další příklady práce s funkcemi najdete v úložišti OpenAI Samples GitHub.