Skip to content

Commit 530c0cf

Browse files
committed
swapping file
1 parent a3ba63b commit 530c0cf

File tree

2 files changed

+307
-56
lines changed

2 files changed

+307
-56
lines changed
Lines changed: 307 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,307 @@
1+
---
2+
title: 'How to use Azure AI Agent service with function calling'
3+
titleSuffix: Azure OpenAI
4+
description: Learn how to use Azure AI Agents with function calling.
5+
services: cognitive-services
6+
manager: nitinme
7+
ms.service: azure
8+
ms.topic: how-to
9+
ms.date: 11/20/2024
10+
author: aahill
11+
ms.author: aahi
12+
zone_pivot_groups: selection-function-calling
13+
recommendations: false
14+
---
15+
16+
# Azure AI Agents function calling
17+
18+
::: zone pivot="overview"
19+
20+
Azure AI Agents supports function calling, which allows you to describe the structure of functions to an Assistant and then return the functions that need to be called along with their arguments.
21+
22+
> [!NOTE]
23+
> Runs expire ten minutes after creation. Be sure to submit your tool outputs before the expiration.
24+
25+
### Supported models
26+
27+
The [models page](../../concepts/model-region-support.md) contains the most up-to-date information on regions/models where Agents are supported.
28+
29+
To use all features of function calling including parallel functions, you need to use a model that was released after November 6, 2023.
30+
31+
::: zone-end
32+
33+
::: zone pivot="code-example"
34+
35+
## Define a function for your agent to call
36+
37+
Start by defining a function for your agent to call. When you create a function for an agent to call, you describe its structure of it with any required parameters.
38+
39+
# [Python](#tab/python)
40+
41+
```python
42+
def fetch_weather(location: str) -> str:
43+
"""
44+
Fetches the weather information for the specified location.
45+
46+
:param location (str): The location to fetch weather for.
47+
:return: Weather information as a JSON string.
48+
:rtype: str
49+
"""
50+
# In a real-world scenario, you'd integrate with a weather API.
51+
# Here, we'll mock the response.
52+
mock_weather_data = {"New York": "Sunny, 25°C", "London": "Cloudy, 18°C", "Tokyo": "Rainy, 22°C"}
53+
weather = mock_weather_data.get(location, "Weather data not available for this location.")
54+
weather_json = json.dumps({"weather": weather})
55+
return weather_json
56+
```
57+
58+
59+
See the [python file on GitHub](https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/ai/azure-ai-projects/samples/agents/user_functions.py) for an example of a full series of function definitions. This file is referred to as `user_functions.py` in the following example below.
60+
61+
62+
63+
# [C#](#tab/csharp)
64+
65+
```csharp
66+
// Example of a function that defines no parameters
67+
string GetUserFavoriteCity() => "Seattle, WA";
68+
FunctionToolDefinition getUserFavoriteCityTool = new("getUserFavoriteCity", "Gets the user's favorite city.");
69+
// Example of a function with a single required parameter
70+
string GetCityNickname(string location) => location switch
71+
{
72+
"Seattle, WA" => "The Emerald City",
73+
_ => throw new NotImplementedException(),
74+
};
75+
FunctionToolDefinition getCityNicknameTool = new(
76+
name: "getCityNickname",
77+
description: "Gets the nickname of a city, e.g. 'LA' for 'Los Angeles, CA'.",
78+
parameters: BinaryData.FromObjectAsJson(
79+
new
80+
{
81+
Type = "object",
82+
Properties = new
83+
{
84+
Location = new
85+
{
86+
Type = "string",
87+
Description = "The city and state, e.g. San Francisco, CA",
88+
},
89+
},
90+
Required = new[] { "location" },
91+
},
92+
new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }));
93+
```
94+
95+
<!--See the [C# file on GitHub](https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/ai/azure-ai-projects/samples/agents/user_functions.py) for an additional function definition examples. -->
96+
97+
In the following sample, we create a helper function to get and parse the resolved tools' outputs, and return it.
98+
99+
```csharp
100+
ToolOutput GetResolvedToolOutput(RequiredToolCall toolCall)
101+
{
102+
if (toolCall is RequiredFunctionToolCall functionToolCall)
103+
{
104+
if (functionToolCall.Name == getUserFavoriteCityTool.Name)
105+
{
106+
return new ToolOutput(toolCall, GetUserFavoriteCity());
107+
}
108+
using JsonDocument argumentsJson = JsonDocument.Parse(functionToolCall.Arguments);
109+
if (functionToolCall.Name == getCityNicknameTool.Name)
110+
{
111+
string locationArgument = argumentsJson.RootElement.GetProperty("location").GetString();
112+
return new ToolOutput(toolCall, GetCityNickname(locationArgument));
113+
}
114+
}
115+
return null;
116+
}
117+
```
118+
119+
---
120+
121+
## Create a client
122+
123+
# [Python](#tab/python)
124+
125+
In the sample below we create a client and define a `toolset` which will be used to process the functions defined in `user_functions`.
126+
127+
```python
128+
import os
129+
from azure.ai.projects import AIProjectClient
130+
from azure.identity import DefaultAzureCredential
131+
from azure.ai.projects.models import FunctionTool, ToolSet
132+
from user_functions import user_functions # user functions which can be found in a user_functions.py file.
133+
134+
# Create an Azure AI Client from a connection string, copied from your AI Studio project.
135+
# It should be in the format "<HostName>;<AzureSubscriptionId>;<ResourceGroup>;<HubName>"
136+
# Customers need to login to Azure subscription via Azure CLI and set the environment variables
137+
138+
project_client = AIProjectClient.from_connection_string(
139+
credential=DefaultAzureCredential(),
140+
conn_str=os.environ["PROJECT_CONNECTION_STRING"],
141+
)
142+
143+
# Initialize agent toolset with user functions
144+
functions = FunctionTool(user_functions)
145+
toolset = ToolSet()
146+
toolset.add(functions)
147+
```
148+
149+
# [C#](#tab/csharp)
150+
151+
```csharp
152+
// note: parallel function calling is only supported with newer models like gpt-4-1106-preview
153+
Response<Agent> agentResponse = await client.CreateAgentAsync(
154+
model: "gpt-4-1106-preview",
155+
name: "SDK Test Agent - Functions",
156+
instructions: "You are a weather bot. Use the provided functions to help answer questions. "
157+
+ "Customize your responses to the user's preferences as much as possible and use friendly "
158+
+ "nicknames for cities whenever possible.",
159+
tools: new List<ToolDefinition> { getUserFavoriteCityTool, getCityNicknameTool, getCurrentWeatherAtLocationTool }
160+
);
161+
Agent agent = agentResponse.Value;
162+
```
163+
164+
---
165+
166+
167+
## Submitting function outputs
168+
169+
# [Python](#tab/python)
170+
171+
```python
172+
173+
# Create agent with toolset and process a run
174+
175+
agent = project_client.agents.create_agent(
176+
model="gpt-4o-mini", name="my-agent", instructions="You are a helpful agent", toolset=toolset
177+
)
178+
print(f"Created agent, ID: {agent.id}")
179+
```
180+
181+
# [C#](#tab/csharp)
182+
183+
```csharp
184+
// note: parallel function calling is only supported with newer models like gpt-4-1106-preview
185+
Response<Agent> agentResponse = await client.CreateAgentAsync(
186+
model: "gpt-4o-mini",
187+
name: "SDK Test Agent - Functions",
188+
instructions: "You are a weather bot. Use the provided functions to help answer questions. "
189+
+ "Customize your responses to the user's preferences as much as possible and use friendly "
190+
+ "nicknames for cities whenever possible.",
191+
tools: new List<ToolDefinition> { getUserFavoriteCityTool, getCityNicknameTool, getCurrentWeatherAtLocationTool }
192+
);
193+
Agent agent = agentResponse.Value;
194+
```
195+
196+
---
197+
198+
## Create a thread
199+
200+
# [python](#tab/python)
201+
202+
```python
203+
# Create thread for communication
204+
thread = project_client.agents.create_thread()
205+
print(f"Created thread, ID: {thread.id}")
206+
207+
# Create message to thread
208+
message = project_client.agents.create_message(
209+
thread_id=thread.id,
210+
role="user",
211+
content="Hello, send an email with the datetime and weather information in New York?",
212+
)
213+
print(f"Created message, ID: {message.id}")
214+
```
215+
216+
# [C#](#tab/csharp)
217+
218+
```csharp
219+
Response<AgentThread> threadResponse = await client.CreateThreadAsync();
220+
AgentThread thread = threadResponse.Value;
221+
222+
Response<ThreadMessage> messageResponse = await client.CreateMessageAsync(
223+
thread.Id,
224+
MessageRole.User,
225+
"What's the weather like in my favorite city?");
226+
ThreadMessage message = messageResponse.Value;
227+
```
228+
229+
---
230+
231+
## Create a run and check the output
232+
233+
# [python](#tab/python)
234+
235+
```python
236+
# Create and process agent run in thread with tools
237+
run = project_client.agents.create_and_process_run(thread_id=thread.id, assistant_id=agent.id)
238+
print(f"Run finished with status: {run.status}")
239+
240+
if run.status == "failed":
241+
print(f"Run failed: {run.last_error}")
242+
243+
# Delete the agent when done
244+
project_client.agents.delete_agent(agent.id)
245+
print("Deleted agent")
246+
247+
# Fetch and log all messages
248+
messages = project_client.agents.list_messages(thread_id=thread.id)
249+
print(f"Messages: {messages}")
250+
```
251+
252+
# [C#](#tab/csharp)
253+
254+
```csharp
255+
Response<ThreadRun> runResponse = await client.CreateRunAsync(thread, agent);
256+
257+
#region Snippet:FunctionsHandlePollingWithRequiredAction
258+
do
259+
{
260+
await Task.Delay(TimeSpan.FromMilliseconds(500));
261+
runResponse = await client.GetRunAsync(thread.Id, runResponse.Value.Id);
262+
263+
if (runResponse.Value.Status == RunStatus.RequiresAction
264+
&& runResponse.Value.RequiredAction is SubmitToolOutputsAction submitToolOutputsAction)
265+
{
266+
List<ToolOutput> toolOutputs = new();
267+
foreach (RequiredToolCall toolCall in submitToolOutputsAction.ToolCalls)
268+
{
269+
toolOutputs.Add(GetResolvedToolOutput(toolCall));
270+
}
271+
runResponse = await client.SubmitToolOutputsToRunAsync(runResponse.Value, toolOutputs);
272+
}
273+
}
274+
while (runResponse.Value.Status == RunStatus.Queued
275+
|| runResponse.Value.Status == RunStatus.InProgress);
276+
#endregion
277+
278+
Response<PageableList<ThreadMessage>> afterRunMessagesResponse
279+
= await client.GetMessagesAsync(thread.Id);
280+
IReadOnlyList<ThreadMessage> messages = afterRunMessagesResponse.Value.Data;
281+
282+
// Note: messages iterate from newest to oldest, with the messages[0] being the most recent
283+
foreach (ThreadMessage threadMessage in messages)
284+
{
285+
Console.Write($"{threadMessage.CreatedAt:yyyy-MM-dd HH:mm:ss} - {threadMessage.Role,10}: ");
286+
foreach (MessageContent contentItem in threadMessage.ContentItems)
287+
{
288+
if (contentItem is MessageTextContent textItem)
289+
{
290+
Console.Write(textItem.Text);
291+
}
292+
else if (contentItem is MessageImageFileContent imageFileItem)
293+
{
294+
Console.Write($"<image from ID: {imageFileItem.FileId}");
295+
}
296+
Console.WriteLine();
297+
}
298+
}
299+
```
300+
301+
---
302+
303+
::: zone-end
304+
305+
## See also
306+
307+
* [Lean how to ground agents by using Bing Web Search](./bing-grounding.md)

articles/ai-services/agents/how-to/tools/licensed-data.md

Lines changed: 0 additions & 56 deletions
This file was deleted.

0 commit comments

Comments
 (0)