Skip to content

Commit 3f4bb80

Browse files
Merge pull request #6484 from aahill/agents-java-2
consolidating code
2 parents e6052d8 + 29d4d35 commit 3f4bb80

File tree

1 file changed

+76
-88
lines changed

1 file changed

+76
-88
lines changed

articles/ai-foundry/agents/how-to/tools/function-calling.md

Lines changed: 76 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,28 @@ Azure AI Agents supports function calling, which allows you to describe the stru
2929

3030
::: zone pivot="python"
3131

32+
## Example agent code
3233

33-
## Define a function for your agent to call
34-
Start by defining a function for your agent to call. When you create a function for an agent to call, you describe its structure with any required parameters in a docstring.
34+
> [!NOTE]
35+
> You can find a streaming example on [GitHub](https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/ai/azure-ai-agents/samples/agents_streaming/sample_agents_stream_eventhandler_with_functions.py).
36+
37+
Use the following code sample to create an agent and call the function.
3538

3639
```python
40+
import os, time
41+
from azure.identity import DefaultAzureCredential
42+
from azure.ai.projects import AIProjectClient
43+
from azure.ai.agents.models import FunctionTool
3744
import json
3845
import datetime
3946
from typing import Any, Callable, Set, Dict, List, Optional
4047

48+
49+
# Start by defining a function for your agent to call.
50+
# When you create a function for an agent to call, you describe its structure
51+
# with any required parameters in a docstring.
52+
53+
4154
def fetch_weather(location: str) -> str:
4255
"""
4356
Fetches the weather information for the specified location.
@@ -52,29 +65,10 @@ def fetch_weather(location: str) -> str:
5265

5366
# Define user functions
5467
user_functions = {fetch_weather}
55-
```
56-
57-
## Create a client and agent
58-
59-
<!--
60-
In the sample below we create a client and define a `toolset` which will be used to process the functions defined in `user_functions`.
61-
62-
`toolset`: When using the toolset parameter, you provide not only the function definitions and descriptions but also their implementations. The SDK will execute these functions within `create_and_run_process` or streaming. These functions will be invoked based on their definitions.
63-
-->
64-
65-
> [!NOTE]
66-
> You can find a streaming example on [GitHub](https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/ai/azure-ai-agents/samples/agents_streaming/sample_agents_stream_eventhandler_with_functions.py).
67-
68-
69-
```python
70-
import os, time
71-
from azure.identity import DefaultAzureCredential
72-
from azure.ai.projects import AIProjectClient
73-
from azure.ai.agents.models import FunctionTool
7468

7569
# Retrieve the project endpoint from environment variables
7670
project_endpoint = os.environ["PROJECT_ENDPOINT"]
77-
71+
model_name = os.environ["MODEL_DEPLOYMENT_NAME"]
7872
# Initialize the AIProjectClient
7973
project_client = AIProjectClient(
8074
endpoint=project_endpoint,
@@ -87,15 +81,13 @@ functions = FunctionTool(functions=user_functions)
8781
with project_client:
8882
# Create an agent with custom functions
8983
agent = project_client.agents.create_agent(
90-
model=os.environ["MODEL_DEPLOYMENT_NAME"],
84+
model=model_name,
9185
name="my-agent",
9286
instructions="You are a helpful agent",
9387
tools=functions.definitions,
9488
)
9589
print(f"Created agent, ID: {agent.id}")
96-
```
97-
## Create a thread
98-
```python
90+
9991
# Create a thread for communication
10092
thread = project_client.agents.threads.create()
10193
print(f"Created thread, ID: {thread.id}")
@@ -107,9 +99,7 @@ message = project_client.agents.messages.create(
10799
content="Hello, send an email with the datetime and weather information in New York?",
108100
)
109101
print(f"Created message, ID: {message['id']}")
110-
```
111-
## Create a run and check the output
112-
```python
102+
113103
# Create and process a run for the agent to handle the message
114104
run = project_client.agents.runs.create(thread_id=thread.id, agent_id=agent.id)
115105
print(f"Created run, ID: {run.id}")
@@ -123,7 +113,7 @@ while run.status in ["queued", "in_progress", "requires_action"]:
123113
tool_calls = run.required_action.submit_tool_outputs.tool_calls
124114
tool_outputs = []
125115
for tool_call in tool_calls:
126-
if tool_call.name == "fetch_weather":
116+
if tool_call.function.name == "fetch_weather":
127117
output = fetch_weather("New York")
128118
tool_outputs.append({"tool_call_id": tool_call.id, "output": output})
129119
project_client.agents.runs.submit_tool_outputs(thread_id=thread.id, run_id=run.id, tool_outputs=tool_outputs)
@@ -147,9 +137,7 @@ print("Deleted agent")
147137
> [!NOTE]
148138
> You can find a streaming example on [GitHub](https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/ai/Azure.AI.Agents.Persistent/samples/Sample8_PersistentAgents_FunctionsWithStreaming.md).
149139
150-
## Configure client and define functions
151-
152-
First, set up the configuration using `appsettings.json` and create a `PersistentAgentsClient`.
140+
## Configure the client and define functions
153141

154142
```csharp
155143
using Azure;
@@ -158,24 +146,22 @@ using Azure.Identity;
158146
using Microsoft.Extensions.Configuration;
159147
using System.Text.Json;
160148

161-
// Load configuration from appsettings.json file
149+
//First, set up the configuration using `appsettings.json`, load it, and create a `PersistentAgentsClient`.
150+
162151
IConfigurationRoot configuration = new ConfigurationBuilder()
163152
.SetBasePath(AppContext.BaseDirectory)
164153
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
165154
.Build();
166155

167156
// Read necessary configuration values (Project Endpoint and Model Deployment Name)
168-
var projectEndpoint = configuration["ProjectEndpoint"];
169-
var modelDeploymentName = configuration["ModelDeploymentName"];
157+
var projectEndpoint = configuration["PROJECT_ENDPOINT"];
158+
var modelDeploymentName = configuration["MODEL_DEPLOYMENT_NAME"];
170159
// Initialize the client to interact with the Azure AI Agents Persistent Client using default credentials
171160
PersistentAgentsClient client = new(projectEndpoint, new DefaultAzureCredential());
172-
```
173161

174-
## Define functions
175-
Define the local C# functions that your agent can call, along with their `FunctionToolDefinition` to describe their purpose and parameters to the agent.
162+
//Define the local C# functions that your agent can call,
163+
//along with their `FunctionToolDefinition` to describe their purpose and parameters to the agent.
176164
177-
```csharp
178-
// Function to get the user's favorite city (hardcoded for example)
179165
string GetUserFavoriteCity() => "Seattle, WA";
180166
// Definition for the GetUserFavoriteCity function, describing its purpose to the agent
181167
FunctionToolDefinition getUserFavoriteCityTool = new("getUserFavoriteCity", "Gets the user's favorite city.");
@@ -240,14 +226,14 @@ FunctionToolDefinition getCurrentWeatherAtLocationTool = new(
240226
Required = new[] { "location" },
241227
},
242228
new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }));
243-
```
244229

245-
## Implement function execution logic
230+
//Implement function execution logic
246231
247-
Create a helper function, `GetResolvedToolOutput`, to process `RequiredToolCall` objects from the agent. This function will invoke the appropriate C# local function and return its output to the agent.
232+
/*
233+
Create a helper function, `GetResolvedToolOutput`, to process `RequiredToolCall` objects from the agent.
234+
This function will invoke the appropriate C# local function and return its output to the agent.
235+
*/
248236

249-
```csharp
250-
// Helper function to execute the correct local C# function based on the tool call request from the agent
251237
ToolOutput GetResolvedToolOutput(RequiredToolCall toolCall)
252238
{
253239
// Check if the required call is a function call
@@ -285,13 +271,15 @@ ToolOutput GetResolvedToolOutput(RequiredToolCall toolCall)
285271
// Return null if the tool call type isn't handled
286272
return null;
287273
}
288-
```
289274

290-
## Create agent and conversation thread
275+
//Create agent and conversation thread
291276
292-
Now, create the `PersistentAgent`, providing the model deployment name, a descriptive name, instructions for its behavior, and the list of `FunctionToolDefinitions` it can use. Then, create a `PersistentAgentThread` and add an initial user message to start the conversation.
277+
/*
278+
Create the `PersistentAgent`, providing the model deployment name, a descriptive name,
279+
instructions for its behavior, and the list of `FunctionToolDefinitions` it can use.
280+
Then, create a `PersistentAgentThread` and add an initial user message to start the conversation.
281+
*/
293282

294-
```csharp
295283
// Create the agent instance
296284
PersistentAgent agent = client.Administration.CreateAgent(
297285
model: modelDeploymentName,
@@ -309,14 +297,17 @@ client.Messages.CreateMessage(
309297
thread.Id,
310298
MessageRole.User,
311299
"What's the weather like in my favorite city?");
312-
```
313300

314-
## Process run and handle function calls
301+
//Process run and handle function calls
315302
316-
Create a `ThreadRun` for the agent on the thread. Poll for the run's completion status. If the run status is `RequiresAction`, it means the agent needs to call one of your local functions. Use the `GetResolvedToolOutput` helper to get the function's result and submit it back to the run.
303+
/*
304+
Create a `ThreadRun` for the agent on the thread. Poll for the run's completion status.
305+
If the run status is `RequiresAction`, it means the agent needs to call one of your local functions.
306+
Use the `GetResolvedToolOutput` helper to get the function's result and submit it back to the run.
307+
308+
Start a run for the agent to process the messages in the thread
309+
*/
317310

318-
```csharp
319-
// Start a run for the agent to process the messages in the thread
320311
ThreadRun run = client.Runs.CreateRun(thread.Id, agent.Id);
321312

322313
// Loop to check the run status and handle required actions
@@ -340,20 +331,21 @@ do
340331
toolOutputs.Add(GetResolvedToolOutput(toolCall));
341332
}
342333
// Submit the collected tool outputs back to the run
343-
run = client.Runs.SubmitToolOutputsToRun(run, toolOutputs);
334+
run = client.Runs.SubmitToolOutputsToRun(run, toolOutputs, null);
344335
}
345336
}
346337
// Continue looping while the run is in progress or requires action
347338
while (run.Status == RunStatus.Queued
348339
|| run.Status == RunStatus.InProgress
349340
|| run.Status == RunStatus.RequiresAction);
350-
```
351341

352-
## Retrieve and display results
342+
// Retrieve and display results
353343
354-
After the run completes, retrieve all messages from the thread to see the full conversation, including the agent's final response.
344+
/*
345+
After the run completes, retrieve all messages from the thread to see the full conversation,
346+
including the agent's final response.
347+
*/
355348

356-
```csharp
357349
// Retrieve all messages from the completed thread, oldest first
358350
Pageable<PersistentThreadMessage> messages = client.Messages.GetMessages(
359351
threadId: thread.Id,
@@ -378,28 +370,39 @@ foreach (PersistentThreadMessage threadMessage in messages)
378370
}
379371
}
380372
}
381-
```
382373

383-
## Clean up resources
374+
// Clean up resources
384375
376+
/*
385377
Finally, clean up the created resources by deleting the thread and the agent.
378+
*/
386379

387-
```csharp
388380
// Delete the conversation thread
389381
client.Threads.DeleteThread(threadId: thread.Id);
390382
// Delete the agent definition
391383
client.Administration.DeleteAgent(agentId: agent.Id);
392-
```
393384

394385
::: zone-end
395386

396387
::: zone pivot="javascript"
397388

398-
## Define a function for your agent to call
399-
400-
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 in a docstring.
389+
## Example code
401390

402391
```javascript
392+
393+
// Define a function for your agent to call
394+
395+
/*
396+
Start by defining a function for your agent to call. When you create a function for an agent to call,
397+
you describe its structure of it with any required parameters in a docstring.
398+
*/
399+
400+
const { AgentsClient, ToolUtility, isOutputOfType } = require("@azure/ai-agents");
401+
const { delay } = require("@azure/core-util");
402+
const { DefaultAzureCredential } = require("@azure/identity");
403+
404+
require("dotenv/config");
405+
403406
class FunctionToolExecutor {
404407
functionTools;
405408

@@ -488,36 +491,24 @@ class FunctionToolExecutor {
488491
});
489492
}
490493
}
491-
```
492-
493-
## Create a client and agent
494-
495-
496-
```javascript
497-
const { AgentsClient, ToolUtility, isOutputOfType } = require("@azure/ai-agents");
498-
const { delay } = require("@azure/core-util");
499-
const { DefaultAzureCredential } = require("@azure/identity");
500494

501-
require("dotenv/config");
495+
// Create a client and agent
502496
503497
const projectEndpoint = process.env["PROJECT_ENDPOINT"];
498+
const modelName = process.env["MODEL_DEPLOYMENT_NAME"];
504499

505500
const client = new AgentsClient(projectEndpoint, new DefaultAzureCredential());
506501
const functionToolExecutor = new FunctionToolExecutor();
507502
const functionTools = functionToolExecutor.getFunctionDefinitions();
508-
const agent = await client.createAgent("gpt-4o", {
503+
const agent = await client.createAgent(modelName, {
509504
name: "my-agent",
510505
instructions:
511506
"You are a weather bot. Use the provided functions to help answer questions. Customize your responses to the user's preferences as much as possible and use friendly nicknames for cities whenever possible.",
512507
tools: functionTools,
513508
});
514509
console.log(`Created agent, agent ID: ${agent.id}`);
515-
```
516510

517-
## Create a thread
518-
519-
```javascript
520-
// Create thread
511+
// Create a thread
521512
const thread = await client.threads.create();
522513
console.log(`Created Thread, thread ID: ${thread.id}`);
523514

@@ -528,12 +519,9 @@ const message = await client.messages.create(
528519
"What's the weather like in my favorite city?",
529520
);
530521
console.log(`Created message, message ID ${message.id}`);
531-
```
532522

533-
## Create a run and check the output
523+
// Create a run and check the output
534524
535-
```javascript
536-
// Create run
537525
let run = await client.runs.create(thread.id, agent.id);
538526
console.log(`Created Run, Run ID: ${run.id}`);
539527

@@ -579,7 +567,7 @@ for await (const threadMessage of messages) {
579567
}
580568
});
581569
}
582-
// Delete agent
570+
// Delete agent - comment this out if you want to keep your agent
583571
await client.deleteAgent(agent.id);
584572
console.log(`Deleted agent, agent ID: ${agent.id}`);
585573

0 commit comments

Comments
 (0)