Skip to content

Commit 6aaebcd

Browse files
authored
Merge pull request #4796 from aahill/petersamples
code updates
2 parents f9f5f8e + 8f812f9 commit 6aaebcd

File tree

4 files changed

+342
-183
lines changed

4 files changed

+342
-183
lines changed

articles/ai-services/agents/how-to/tools/azure-ai-search-samples.md

Lines changed: 98 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -136,112 +136,132 @@ print("Deleted agent")
136136

137137
:::zone pivot="csharp"
138138

139-
## Step 1: Create an Azure AI Client
140-
First, create an Azure AI Client using the connection string of your project.
139+
## Step 1: Create a project client
140+
Create a client object, which will contain the project endpoint for connecting to your AI project and other resources.
141141

142142
```csharp
143+
using Azure;
144+
using Azure.AI.Agents.Persistent;
145+
using Azure.Identity;
146+
using Microsoft.Extensions.Configuration;
143147
using System;
144-
using System.Threading.Tasks;
145-
using Azure.Core;
146-
using Azure.Core.TestFramework;
147-
using NUnit.Framework;
148-
using System.Collections.Generic;
149-
150-
// Create an Azure AI Client from a connection string, copied from your Azure AI Foundry project.
151-
// At the moment, it should be in the format "<HostName>;<AzureSubscriptionId>;<ResourceGroup>;<ProjectName>"
152-
// Customer needs to login to Azure subscription via Azure CLI and set the environment variables
153-
var connectionString = TestEnvironment.AzureAICONNECTIONSTRING;
154-
var clientOptions = new AIProjectClientOptions();
155-
156-
// Adding the custom headers policy
157-
clientOptions.AddPolicy(new CustomHeadersPolicy(), HttpPipelinePosition.PerCall);
158-
var projectClient = new AIProjectClient(connectionString, new DefaultAzureCredential(), clientOptions);
159-
```
148+
using System.Threading;
160149

161-
## Step 2: Get the connection ID for the Azure AI Search resource
162-
Get the connection ID of the Azure AI Search connection in the project.
150+
// Get Connection information from app configuration
151+
IConfigurationRoot configuration = new ConfigurationBuilder()
152+
.SetBasePath(AppContext.BaseDirectory)
153+
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
154+
.Build();
163155

164-
```csharp
165-
ListConnectionsResponse connections = await projectClient.GetConnectionsClient().GetConnectionsAsync(ConnectionType.AzureAISearch).ConfigureAwait(false);
156+
var projectEndpoint = configuration["ProjectEndpoint"];
157+
var modelDeploymentName = configuration["ModelDeploymentName"];
158+
var azureAiSearchConnectionId = configuration["AzureAiSearchConnectionId"];
166159

167-
if (connections?.Value == null || connections.Value.Count == 0)
168-
{
169-
throw new InvalidOperationException("No connections found for the Azure AI Search.");
170-
}
160+
// Create the Agent Client
161+
PersistentAgentsClient agentClient = new(projectEndpoint, new DefaultAzureCredential());
171162
```
172163

173-
## Step 3: Configure the Azure AI Search tool
174-
Using the connection ID you got in the previous step, you can now configure the Azure AI Search tool to use your Azure AI Search index.
164+
## Step 2: Configure the Azure AI Search tool
165+
Using the AI Search Connection ID, configure the Azure AI Search tool to use your Azure AI Search index.
175166

176167
```csharp
177-
// TO DO: replace this value with the connection ID of the search index
178-
ConnectionResponse connection = connections.Value[0];
168+
AzureAISearchResource searchResource = new(
169+
indexConnectionId: azureAiSearchConnectionId,
170+
indexName: "sample_index",
171+
topK: 5,
172+
filter: "category eq 'sleeping bag'",
173+
queryType: AzureAISearchQueryType.Simple
174+
);
175+
176+
ToolResources toolResource = new() { AzureAISearch = searchResource };
179177

180-
// Initialize agent Azure AI search tool and add the search index connection ID and index name
181-
// TO DO: replace <your-index-name> with the name of the index you want to use
182-
ToolResources searchResource = new ToolResources
183-
{
184-
AzureAISearch = new AzureAISearchResource
185-
{
186-
IndexList = { new IndexResource(connection.Id, "<your-index-name>", "<select-search-type>") }
187-
}
188-
};
189178
```
190179

191-
## Step 4: Create an agent with the Azure AI Search tool enabled
180+
## Step 3: Create an agent with the Azure AI Search tool enabled
192181
Change the model to the one deployed in your project. You can find the model name in the Azure AI Foundry under the **Models** tab. You can also change the name and instructions of the agent to suit your needs.
193182

194183
```csharp
195-
AgentsClient agentClient = projectClient.GetAgentsClient();
196-
197-
Response<Agent> agentResponse = await agentClient.CreateAgentAsync(
198-
model: "gpt-4o-mini",
199-
name: "my-assistant",
200-
instructions: "You are a helpful assistant.",
201-
tools: new List<ToolDefinition> { new AzureAISearchToolDefinition() },
202-
toolResources: searchResource);
203-
Agent agent = agentResponse.Value;
184+
// Create an agent with Tools and Tool Resources
185+
PersistentAgent agent = agentClient.Administration.CreateAgent(
186+
model: modelDeploymentName,
187+
name: "my-agent",
188+
instructions: "You are a helpful agent.",
189+
tools: [new AzureAISearchToolDefinition()],
190+
toolResources: toolResource);
191+
204192
```
205193

206-
## Step 5: Ask the agent questions about data in the index
194+
## Step 4: Ask the agent questions about data in the index
207195
Now that the agent is created, ask it questions about the data in your Azure AI Search index.
208196

209197
```csharp
210198
// Create thread for communication
211-
Response<AgentThread> threadResponse = await agentClient.CreateThreadAsync();
212-
AgentThread thread = threadResponse.Value;
199+
PersistentAgentThread thread = agentClient.Threads.CreateThread();
213200

214-
// Create message to thread
215-
Response<ThreadMessage> messageResponse = await agentClient.CreateMessageAsync(
201+
// Create message and run the agent
202+
ThreadMessage message = agentClient.Messages.CreateMessage(
216203
thread.Id,
217204
MessageRole.User,
218-
"what are my health insurance plan coverage types?");
219-
ThreadMessage message = messageResponse.Value;
205+
"What is the temperature rating of the cozynights sleeping bag?");
206+
ThreadRun run = agentClient.Runs.CreateRun(thread, agent);
207+
208+
```
209+
210+
## Step 4: Wait for the agent to complete and print the output
220211

221-
// Run the agent
222-
Response<ThreadRun> runResponse = await agentClient.CreateRunAsync(thread, agent);
212+
Wait for the agent to complete the run and print output to console.
223213

214+
```csharp
215+
// Wait for the agent to finish running
224216
do
225217
{
226-
await Task.Delay(TimeSpan.FromMilliseconds(500));
227-
runResponse = await agentClient.GetRunAsync(thread.Id, runResponse.Value.Id);
218+
Thread.Sleep(TimeSpan.FromMilliseconds(500));
219+
run = agentClient.Runs.GetRun(thread.Id, run.Id);
228220
}
229-
while (runResponse.Value.Status == RunStatus.Queued
230-
|| runResponse.Value.Status == RunStatus.InProgress);
221+
while (run.Status == RunStatus.Queued
222+
|| run.Status == RunStatus.InProgress);
231223

232-
Response<PageableList<ThreadMessage>> afterRunMessagesResponse
233-
= await agentClient.GetMessagesAsync(thread.Id);
234-
IReadOnlyList<ThreadMessage> messages = afterRunMessagesResponse.Value.Data;
224+
// Confirm that the run completed successfully
225+
if (run.Status != RunStatus.Completed)
226+
{
227+
throw new Exception("Run did not complete successfully, error: " + run.LastError?.Message);
228+
}
229+
230+
// Retrieve the messages from the agent client
231+
Pageable<ThreadMessage> messages = agentClient.Messages.GetMessages(
232+
threadId: thread.Id,
233+
order: ListSortOrder.Ascending
234+
);
235235

236-
// Note: messages iterate from newest to oldest, with the messages[0] being the most recent
236+
// Process messages in order
237237
foreach (ThreadMessage threadMessage in messages)
238238
{
239239
Console.Write($"{threadMessage.CreatedAt:yyyy-MM-dd HH:mm:ss} - {threadMessage.Role,10}: ");
240240
foreach (MessageContent contentItem in threadMessage.ContentItems)
241241
{
242242
if (contentItem is MessageTextContent textItem)
243243
{
244-
Console.Write(textItem.Text);
244+
// We need to annotate only Agent messages.
245+
if (threadMessage.Role == MessageRole.Agent && textItem.Annotations.Count > 0)
246+
{
247+
string annotatedText = textItem.Text;
248+
249+
// If we have Text URL citation annotations, reformat the response to show title & URL for citations
250+
foreach (MessageTextAnnotation annotation in textItem.Annotations)
251+
{
252+
if (annotation is MessageTextUrlCitationAnnotation urlAnnotation)
253+
{
254+
annotatedText = annotatedText.Replace(
255+
urlAnnotation.Text,
256+
$" [see {urlAnnotation.UrlCitation.Title}] ({urlAnnotation.UrlCitation.Url})");
257+
}
258+
}
259+
Console.Write(annotatedText);
260+
}
261+
else
262+
{
263+
Console.Write(textItem.Text);
264+
}
245265
}
246266
else if (contentItem is MessageImageFileContent imageFileItem)
247267
{
@@ -250,6 +270,17 @@ foreach (ThreadMessage threadMessage in messages)
250270
Console.WriteLine();
251271
}
252272
}
273+
```
274+
## Step 5: Clean up resources
275+
276+
Clean up the resources from this sample.
277+
278+
```csharp
279+
280+
// Delete thread and agent
281+
agentClient.Threads.DeleteThread(thread.Id);
282+
agentClient.Administration.DeleteAgent(agent.Id);
283+
253284
```
254285

255286
:::zone-end

articles/ai-services/agents/how-to/tools/bing-code-samples.md

Lines changed: 66 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -47,85 +47,96 @@ Use this article to find step-by-step instructions and code samples for Groundin
4747
::: zone pivot="csharp"
4848
## Step 1: Create a project client
4949

50-
Create a client object, which will contain the connection string for connecting to your AI project and other resources.
50+
Create a client object, which will contain the project endpoint for connecting to your AI project and other resources.
5151

5252
```csharp
53+
using Azure;
54+
using Azure.AI.Agents.Persistent;
55+
using Azure.Identity;
56+
using Microsoft.Extensions.Configuration;
5357
using System;
54-
using System.Collections.Generic;
55-
using System.Threading.Tasks;
56-
using Azure.Core;
57-
using Azure.Core.TestFramework;
58-
using NUnit.Framework;
58+
using System.Threading;
5959

60-
var connectionString = System.Environment.GetEnvironmentVariable("PROJECT_CONNECTION_STRING");
61-
var modelDeploymentName = System.Environment.GetEnvironmentVariable("MODEL_DEPLOYMENT_NAME");
62-
var bingConnectionName = System.Environment.GetEnvironmentVariable("BING_CONNECTION_NAME");
60+
// Get Connection information from app configuration
61+
IConfigurationRoot configuration = new ConfigurationBuilder()
62+
.SetBasePath(AppContext.BaseDirectory)
63+
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
64+
.Build();
6365

64-
var projectClient = new AIProjectClient(connectionString, new DefaultAzureCredential());
66+
var projectEndpoint = configuration["ProjectEndpoint"];
67+
var modelDeploymentName = configuration["ModelDeploymentName"];
68+
var bingConnectionId = configuration["BingConnectionId"];
6569

66-
AgentsClient agentClient = projectClient.GetAgentsClient();
70+
// Create the Agent Client
71+
PersistentAgentsClient agentClient = new(projectEndpoint, new DefaultAzureCredential());
6772
```
6873

6974
## Step 2: Create an Agent with the Grounding with Bing search tool enabled
7075

7176
To make the Grounding with Bing search tool available to your agent, use a connection to initialize the tool and attach it to the agent. You can find your connection in the **connected resources** section of your project in the [Azure AI Foundry portal](https://ai.azure.com/).
7277

7378
```csharp
74-
ConnectionResponse bingConnection = projectClient.GetConnectionsClient().GetConnection(bingConnectionName);
75-
var connectionId = bingConnection.Id;
79+
// Create the BingGroundingToolDefinition object used when creating the agent
80+
BingGroundingToolDefinition bingGroundingTool = new BingGroundingToolDefinition(
81+
new BingGroundingSearchConfigurationList(
82+
[
83+
new BingGroundingSearchConfiguration(bingConnectionId)
84+
]
85+
)
86+
);
7687

77-
ToolConnectionList connectionList = new()
78-
{
79-
ConnectionList = { new ToolConnection(connectionId) }
80-
};
81-
BingGroundingToolDefinition bingGroundingTool = new(connectionList);
82-
83-
Agent agent = agentClient.CreateAgent(
84-
model: modelDeploymentName,
85-
name: "my-assistant",
86-
instructions: "You are a helpful assistant.",
87-
tools: [bingGroundingTool]);
88+
// Create the Agent
89+
PersistentAgent agent = agentClient.Administration.CreateAgent(
90+
model: modelDeploymentName,
91+
name: "my-agent",
92+
instructions: "You are a helpful agent.",
93+
tools: [bingGroundingTool]
94+
);
8895
```
8996

90-
## Step 3: Create a thread
97+
## Step 3: Create a thread and run
9198

9299
```csharp
93-
AgentThread thread = agentClient.CreateThread();
100+
PersistentAgentThread thread = agentClient.Threads.CreateThread();
94101

95-
// Create message to thread
96-
ThreadMessage message = agentClient.CreateMessage(
102+
// Create message and run the agent
103+
ThreadMessage message = agentClient.Messages.CreateMessage(
97104
thread.Id,
98105
MessageRole.User,
99106
"How does wikipedia explain Euler's Identity?");
100-
```
101107

102-
## Step 4: Create a run and check the output
108+
ThreadRun run = agentClient.Runs.CreateRun(thread, agent);
103109

104-
Create a run and observe that the model uses the Grounding with Bing Search tool to provide a response to the user's question.
110+
```
105111

112+
## Step 4: Wait for the agent to complete and print the output
113+
114+
Wait for the agent to complete the run and print output to console. Observe that the model uses the Grounding with Bing Search tool to provide a response to the user's question.
106115

107116
```csharp
108117

109-
// Run the agent
110-
ThreadRun run = agentClient.CreateRun(thread, agent);
118+
// Wait for the agent to finish running
111119
do
112120
{
113121
Thread.Sleep(TimeSpan.FromMilliseconds(500));
114-
run = agentClient.GetRun(thread.Id, run.Id);
122+
run = agentClient.Runs.GetRun(thread.Id, run.Id);
115123
}
116124
while (run.Status == RunStatus.Queued
117125
|| run.Status == RunStatus.InProgress);
118126

119-
Assert.AreEqual(
120-
RunStatus.Completed,
121-
run.Status,
122-
run.LastError?.Message);
127+
// Confirm that the run completed successfully
128+
if (run.Status != RunStatus.Completed)
129+
{
130+
throw new Exception("Run did not complete successfully, error: " + run.LastError?.Message);
131+
}
123132

124-
PageableList<ThreadMessage> messages = agentClient.GetMessages(
133+
// Retrieve all messages from the agent client
134+
Pageable<ThreadMessage> messages = agentClient.Messages.GetMessages(
125135
threadId: thread.Id,
126136
order: ListSortOrder.Ascending
127137
);
128138

139+
// Process messages in order
129140
foreach (ThreadMessage threadMessage in messages)
130141
{
131142
Console.Write($"{threadMessage.CreatedAt:yyyy-MM-dd HH:mm:ss} - {threadMessage.Role,10}: ");
@@ -134,13 +145,16 @@ foreach (ThreadMessage threadMessage in messages)
134145
if (contentItem is MessageTextContent textItem)
135146
{
136147
string response = textItem.Text;
148+
149+
// If we have Text URL citation annotations, reformat the response to show title & URL for citations
137150
if (textItem.Annotations != null)
138151
{
139152
foreach (MessageTextAnnotation annotation in textItem.Annotations)
140153
{
141154
if (annotation is MessageTextUrlCitationAnnotation urlAnnotation)
142155
{
143-
response = response.Replace(urlAnnotation.Text, $" [{urlAnnotation.UrlCitation.Title}]({urlAnnotation.UrlCitation.Url})");
156+
response = response.Replace(urlAnnotation.Text,
157+
$" [{urlAnnotation.UrlCitation.Title}]({urlAnnotation.UrlCitation.Url})");
144158
}
145159
}
146160
}
@@ -154,8 +168,18 @@ foreach (ThreadMessage threadMessage in messages)
154168
}
155169
}
156170

157-
agentClient.DeleteThread(threadId: thread.Id);
158-
agentClient.DeleteAgent(agentId: agent.Id);
171+
```
172+
173+
## Step 5: Clean up resources
174+
175+
Clean up the resources from this sample.
176+
177+
```csharp
178+
179+
// Delete thread and agent
180+
agentClient.Threads.DeleteThread(threadId: thread.Id);
181+
agentClient.Administration.DeleteAgent(agentId: agent.Id);
182+
159183
```
160184

161185
::: zone-end

0 commit comments

Comments
 (0)