Skip to content

Commit 2b5f841

Browse files
Merge pull request #261232 from mrbullwinkle/mrb_12_14_2023_tools
[Azure OpenAI] Tools updates
2 parents 0e80716 + 6a2c0ef commit 2b5f841

File tree

2 files changed

+120
-1
lines changed

2 files changed

+120
-1
lines changed

articles/ai-services/openai/how-to/function-calling.md

Lines changed: 117 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,123 @@ At a high level you can break down working with functions into three steps:
2424
> [!IMPORTANT]
2525
> The `functions` and `function_call` parameters have been deprecated with the release of the [`2023-12-01-preview`](https://github.com/Azure/azure-rest-api-specs/blob/main/specification/cognitiveservices/data-plane/AzureOpenAI/inference/preview/2023-12-01-preview/inference.json) version of the API. The replacement for `functions` is the [`tools`](../reference.md#chat-completions) parameter. The replacement for `function_call` is the [`tool_choice`](../reference.md#chat-completions) parameter.
2626
27-
## Using function in the chat completions API
27+
## Parallel function calling
28+
29+
Parallel function calls are supported with:
30+
31+
### Supported models
32+
33+
* `gpt-35-turbo` (1106)
34+
* `gpt-4` (1106-preview)
35+
36+
### Supported API versions
37+
38+
* [`2023-12-01-preview`](https://github.com/Azure/azure-rest-api-specs/blob/main/specification/cognitiveservices/data-plane/AzureOpenAI/inference/preview/2023-12-01-preview/inference.json)
39+
40+
Parallel function calls allow you to perform multiple function calls together, allowing for parallel execution and retrieval of results. This reduces the number of calls to the API that need to be made and can improve overall performance.
41+
42+
For example for a simple weather app you may want to retrieve the weather in multiple locations at the same time. This will result in a a chat completion message with three function calls in the `tool_calls` array, each with a unique `id`. If you wanted to respond to these function calls, you would add 3 new messages to the conversation, each containing the result of one function call, with a `tool_call_id` referencing the `id` from `tools_calls`.
43+
44+
Below we provide a modified version of OpenAI's `get_current_weather` example. This example as with the original from OpenAI is to provide the basic structure, but is not a fully functioning standalone example. Attempting to execute this code without further modification would result in an error.
45+
46+
In this example, a single function get_current_weather is defined. The model calls the function multiple times, and after sending the function response back to the model, it decides the next step. It responds with a user-facing message which was telling the user the temperature in San Francisco, Tokyo, and Paris. Depending on the query, it may choose to call a function again.
47+
48+
To force the model to call a specific function set the `tool_choice` parameter with a specific function name. You can also force the model to generate a user-facing message by setting `tool_choice: "none"`.
49+
50+
> [!NOTE]
51+
> The default behavior (`tool_choice: "auto"`) is for the model to decide on its own whether to call a function and if so which function to call.
52+
53+
```python
54+
from openai import AzureOpenAI
55+
import json
56+
57+
client = AzureOpenAI(
58+
azure_endpoint = os.getenv("AZURE_OPENAI_ENDPOINT"),
59+
api_key=os.getenv("AZURE_OPENAI_KEY"),
60+
api_version="2023-12-01-preview"
61+
)
62+
63+
from openai import OpenAI
64+
import json
65+
66+
# Example function hard coded to return the same weather
67+
# In production, this could be your backend API or an external API
68+
def get_current_weather(location, unit="fahrenheit"):
69+
"""Get the current weather in a given location"""
70+
if "tokyo" in location.lower():
71+
return json.dumps({"location": "Tokyo", "temperature": "10", "unit": unit})
72+
elif "san francisco" in location.lower():
73+
return json.dumps({"location": "San Francisco", "temperature": "72", "unit": unit})
74+
elif "paris" in location.lower():
75+
return json.dumps({"location": "Paris", "temperature": "22", "unit": unit})
76+
else:
77+
return json.dumps({"location": location, "temperature": "unknown"})
78+
79+
def run_conversation():
80+
# Step 1: send the conversation and available functions to the model
81+
messages = [{"role": "user", "content": "What's the weather like in San Francisco, Tokyo, and Paris?"}]
82+
tools = [
83+
{
84+
"type": "function",
85+
"function": {
86+
"name": "get_current_weather",
87+
"description": "Get the current weather in a given location",
88+
"parameters": {
89+
"type": "object",
90+
"properties": {
91+
"location": {
92+
"type": "string",
93+
"description": "The city and state, e.g. San Francisco, CA",
94+
},
95+
"unit": {"type": "string", "enum": ["celsius", "fahrenheit"]},
96+
},
97+
"required": ["location"],
98+
},
99+
},
100+
}
101+
]
102+
response = client.chat.completions.create(
103+
model="<REPLACE_WITH_YOUR_MODEL_DEPLOYMENT_NAME>",
104+
messages=messages,
105+
tools=tools,
106+
tool_choice="auto", # auto is default, but we'll be explicit
107+
)
108+
response_message = response.choices[0].message
109+
tool_calls = response_message.tool_calls
110+
# Step 2: check if the model wanted to call a function
111+
if tool_calls:
112+
# Step 3: call the function
113+
# Note: the JSON response may not always be valid; be sure to handle errors
114+
available_functions = {
115+
"get_current_weather": get_current_weather,
116+
} # only one function in this example, but you can have multiple
117+
messages.append(response_message) # extend conversation with assistant's reply
118+
# Step 4: send the info for each function call and function response to the model
119+
for tool_call in tool_calls:
120+
function_name = tool_call.function.name
121+
function_to_call = available_functions[function_name]
122+
function_args = json.loads(tool_call.function.arguments)
123+
function_response = function_to_call(
124+
location=function_args.get("location"),
125+
unit=function_args.get("unit"),
126+
)
127+
messages.append(
128+
{
129+
"tool_call_id": tool_call.id,
130+
"role": "tool",
131+
"name": function_name,
132+
"content": function_response,
133+
}
134+
) # extend conversation with function response
135+
second_response = client.chat.completions.create(
136+
model="<REPLACE_WITH_YOUR_1106_MODEL_DEPLOYMENT_NAME>",
137+
messages=messages,
138+
) # get a new response from the model where it can see the function response
139+
return second_response
140+
print(run_conversation())
141+
```
142+
143+
## Using function in the chat completions API (Deprecated)
28144

29145
Function calling is available in the `2023-07-01-preview` API version and works with version 0613 of gpt-35-turbo, gpt-35-turbo-16k, gpt-4, and gpt-4-32k.
30146

articles/ai-services/openai/reference.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,9 @@ In the example response, `finish_reason` equals `stop`. If `finish_reason` equal
265265

266266
Output formatting adjusted for ease of reading, actual output is a single block of text without line breaks.
267267

268+
> [!IMPORTANT]
269+
> The `functions` and `function_call` parameters have been deprecated with the release of the [`2023-12-01-preview`](https://github.com/Azure/azure-rest-api-specs/blob/main/specification/cognitiveservices/data-plane/AzureOpenAI/inference/preview/2023-12-01-preview/inference.json) version of the API. The replacement for `functions` is the `tools` parameter. The replacement for `function_call` is the `tool_choice` parameter. Parallel function calling which was introduced as part of the [`2023-12-01-preview`](https://github.com/Azure/azure-rest-api-specs/blob/main/specification/cognitiveservices/data-plane/AzureOpenAI/inference/preview/2023-12-01-preview/inference.json) is only supported with `gpt-35-turbo` (1106) and `gpt-4` (1106-preview) also known as GPT-4 Turbo Preview.
270+
268271
| Parameter | Type | Required? | Default | Description |
269272
|--|--|--|--|--|
270273
| ```messages``` | array | Required | | The collection of context messages associated with this chat completions request. Typical usage begins with a [chat message](#chatmessage) for the System role that provides instructions for the behavior of the assistant, followed by alternating messages between the User and Assistant roles.|

0 commit comments

Comments
 (0)