Skip to content

Commit c953771

Browse files
author
Peter Hauge
committed
Update Bing Grounding sample
1 parent 10f39a2 commit c953771

File tree

4 files changed

+416
-2
lines changed

4 files changed

+416
-2
lines changed
Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
# Sample for use of an agent with Bing grounding in Azure.AI.Agents.
2+
3+
To enable your Agent to perform search through Bing search API, you use `BingGroundingToolDefinition` along with a connection.
4+
1. First we need to create an agent and read the environment variables, which will be used in the next steps.
5+
6+
```C# Snippet:AgentsBingGrounding_CreateProject
7+
// Get Connection information from App Configuration
8+
var projectEndpoint = configuration["ProjectEndpoint"];
9+
var modelDeploymentName = configuration["ModelDeploymentName"];
10+
var bingConnectionId = configuration["BingConnectionId"];
11+
12+
// Create the Agent Client
13+
PersistentAgentsClient agentClient = new(projectEndpoint, new DefaultAzureCredential());
14+
```
15+
16+
2. We will use the Bing connection Id to initialize the `BingGroundingToolDefinition`.
17+
18+
```C# Snippet:AgentsBingGrounding_GetConnection
19+
// Create the BingGroundingToolDefinition object used when creating the agent
20+
BingGroundingToolDefinition bingGroundingTool = new BingGroundingToolDefinition(
21+
new BingGroundingSearchConfigurationList(
22+
[
23+
new BingGroundingSearchConfiguration(bingConnectionId)
24+
]
25+
)
26+
);
27+
28+
```
29+
3. We will use the `BingGroundingToolDefinition` during the agent initialization.
30+
31+
Synchronous sample:
32+
```C# Snippet:AgentsBingGrounding_CreateAgent
33+
// Create the Agent
34+
PersistentAgent agent = agentClient.Administration.CreateAgent(
35+
model: modelDeploymentName,
36+
name: "my-agent",
37+
instructions: "You are a helpful agent.",
38+
tools: [bingGroundingTool]
39+
);
40+
```
41+
42+
Asynchronous sample:
43+
```C# Snippet:AgentsBingGroundingAsync_CreateAgent
44+
// Create the Agent
45+
PersistentAgent agent = await agentClient.Administration.CreateAgentAsync(
46+
model: modelDeploymentName,
47+
name: "my-agent",
48+
instructions: "You are a helpful agent.",
49+
tools: [bingGroundingTool]
50+
);
51+
```
52+
53+
4. Now we will create the thread, add the message containing a question for agent and start the run.
54+
55+
Synchronous sample:
56+
```C# Snippet:AgentsBingGrounding_CreateThreadMessage
57+
PersistentAgentThread thread = agentClient.Threads.CreateThread();
58+
59+
// Create message and run the agent
60+
ThreadMessage message = agentClient.Messages.CreateMessage(
61+
thread.Id,
62+
MessageRole.User,
63+
"How does wikipedia explain Euler's Identity?");
64+
ThreadRun run = agentClient.Runs.CreateRun(thread, agent);
65+
66+
// Wait for the agent to finish running
67+
do
68+
{
69+
Thread.Sleep(TimeSpan.FromMilliseconds(500));
70+
run = agentClient.Runs.GetRun(thread.Id, run.Id);
71+
}
72+
while (run.Status == RunStatus.Queued
73+
|| run.Status == RunStatus.InProgress);
74+
75+
// Confirm that the run completed successfully
76+
if (run.Status != RunStatus.Completed)
77+
{
78+
throw new Exception("Run did not complete successfully, error: " + run.LastError?.Message);
79+
}
80+
81+
```
82+
83+
Asynchronous sample:
84+
```C# Snippet:AgentsBingGroundingAsync_CreateThreadMessage
85+
PersistentAgentThread thread = await agentClient.Threads.CreateThreadAsync();
86+
87+
// Create message and run the agent
88+
ThreadMessage message = await agentClient.Messages.CreateMessageAsync(
89+
thread.Id,
90+
MessageRole.User,
91+
"How does wikipedia explain Euler's Identity?");
92+
ThreadRun run = await agentClient.Runs.CreateRunAsync(thread, agent);
93+
94+
// Wait for the agent to finish running
95+
do
96+
{
97+
Thread.Sleep(TimeSpan.FromMilliseconds(500));
98+
run = await agentClient.Runs.GetRunAsync(thread.Id, run.Id);
99+
}
100+
while (run.Status == RunStatus.Queued
101+
|| run.Status == RunStatus.InProgress);
102+
103+
// Confirm that the run completed successfully
104+
if (run.Status != RunStatus.Completed)
105+
{
106+
throw new Exception("Run did not complete successfully, error: " + run.LastError?.Message);
107+
}
108+
```
109+
110+
5. Print the agent messages to console in chronological order (including formatting URL citations).
111+
112+
Synchronous sample:
113+
```C# Snippet:AgentsBingGrounding_Print
114+
// Retrieve all messages from the agent client
115+
Pageable<ThreadMessage> messages = agentClient.Messages.GetMessages(
116+
threadId: thread.Id,
117+
order: ListSortOrder.Ascending
118+
);
119+
120+
// Process messages in order
121+
foreach (ThreadMessage threadMessage in messages)
122+
{
123+
Console.Write($"{threadMessage.CreatedAt:yyyy-MM-dd HH:mm:ss} - {threadMessage.Role,10}: ");
124+
foreach (MessageContent contentItem in threadMessage.ContentItems)
125+
{
126+
if (contentItem is MessageTextContent textItem)
127+
{
128+
string response = textItem.Text;
129+
130+
// If we have Text URL citation annotations, reformat the response to show title & URL for citations
131+
if (textItem.Annotations != null)
132+
{
133+
foreach (MessageTextAnnotation annotation in textItem.Annotations)
134+
{
135+
if (annotation is MessageTextUrlCitationAnnotation urlAnnotation)
136+
{
137+
response = response.Replace(urlAnnotation.Text, $" [{urlAnnotation.UrlCitation.Title}]({urlAnnotation.UrlCitation.Url})");
138+
}
139+
}
140+
}
141+
Console.Write($"Agent response: {response}");
142+
}
143+
else if (contentItem is MessageImageFileContent imageFileItem)
144+
{
145+
Console.Write($"<image from ID: {imageFileItem.FileId}");
146+
}
147+
Console.WriteLine();
148+
}
149+
}
150+
```
151+
152+
Asynchronous sample:
153+
```C# Snippet:AgentsBingGroundingAsync_Print
154+
// Retrieve all messages from the agent client
155+
AsyncPageable<ThreadMessage> messages = agentClient.Messages.GetMessagesAsync(
156+
threadId: thread.Id,
157+
order: ListSortOrder.Ascending
158+
);
159+
160+
// Process messages in order
161+
await foreach (ThreadMessage threadMessage in messages)
162+
{
163+
Console.Write($"{threadMessage.CreatedAt:yyyy-MM-dd HH:mm:ss} - {threadMessage.Role,10}: ");
164+
foreach (MessageContent contentItem in threadMessage.ContentItems)
165+
{
166+
if (contentItem is MessageTextContent textItem)
167+
{
168+
string response = textItem.Text;
169+
170+
// If we have Text URL citation annotations, reformat the response to show title & URL for citations
171+
if (textItem.Annotations != null)
172+
{
173+
foreach (MessageTextAnnotation annotation in textItem.Annotations)
174+
{
175+
if (annotation is MessageTextUrlCitationAnnotation urlAnnotation)
176+
{
177+
response = response.Replace(urlAnnotation.Text, $" [{urlAnnotation.UrlCitation.Title}]({urlAnnotation.UrlCitation.Url})");
178+
}
179+
}
180+
}
181+
Console.Write($"Agent response: {response}");
182+
}
183+
else if (contentItem is MessageImageFileContent imageFileItem)
184+
{
185+
Console.Write($"<image from ID: {imageFileItem.FileId}");
186+
}
187+
Console.WriteLine();
188+
}
189+
}
190+
```
191+
192+
6. Clean up resources by deleting thread and agent.
193+
194+
Synchronous sample:
195+
```C# Snippet:AgentsBingGrounding_Cleanup
196+
// Delete thread and agent
197+
agentClient.Threads.DeleteThread(threadId: thread.Id);
198+
agentClient.Administration.DeleteAgent(agentId: agent.Id);
199+
```
200+
201+
Asynchronous sample:
202+
```C# Snippet:AgentsBingGroundingAsync_Cleanup
203+
// Delete thread and agent
204+
agentClient.Threads.DeleteThread(threadId: thread.Id);
205+
agentClient.Administration.DeleteAgent(agentId: agent.Id);
206+
```
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
using Azure;
2+
using Azure.AI.Agents.Persistent;
3+
using Azure.Identity;
4+
using Microsoft.Extensions.Configuration;
5+
using System;
6+
using System.Threading;
7+
using System.Threading.Tasks;
8+
9+
// Get Connection information from App Configuration
10+
IConfigurationRoot configuration = new ConfigurationBuilder()
11+
.SetBasePath(AppContext.BaseDirectory)
12+
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
13+
.Build();
14+
15+
var projectEndpoint = configuration["ProjectEndpoint"];
16+
var modelDeploymentName = configuration["ModelDeploymentName"];
17+
var bingConnectionId = configuration["BingConnectionId"];
18+
19+
// Create the Agent Client
20+
PersistentAgentsClient agentClient = new(projectEndpoint, new DefaultAzureCredential());
21+
22+
// Create the BingGroundingToolDefinition object used when creating the agent
23+
BingGroundingToolDefinition bingGroundingTool = new BingGroundingToolDefinition(
24+
new BingGroundingSearchConfigurationList(
25+
[
26+
new BingGroundingSearchConfiguration(bingConnectionId)
27+
]
28+
)
29+
);
30+
31+
// Create the Agent
32+
PersistentAgent agent = await agentClient.Administration.CreateAgentAsync(
33+
model: modelDeploymentName,
34+
name: "my-agent",
35+
instructions: "You are a helpful agent.",
36+
tools: [bingGroundingTool]
37+
);
38+
39+
PersistentAgentThread thread = await agentClient.Threads.CreateThreadAsync();
40+
41+
// Create message and run the agent
42+
ThreadMessage message = await agentClient.Messages.CreateMessageAsync(
43+
thread.Id,
44+
MessageRole.User,
45+
"How does wikipedia explain Euler's Identity?");
46+
ThreadRun run = await agentClient.Runs.CreateRunAsync(thread, agent);
47+
48+
// Wait for the agent to finish running
49+
do
50+
{
51+
Thread.Sleep(TimeSpan.FromMilliseconds(500));
52+
run = await agentClient.Runs.GetRunAsync(thread.Id, run.Id);
53+
}
54+
while (run.Status == RunStatus.Queued
55+
|| run.Status == RunStatus.InProgress);
56+
57+
// Confirm that the run completed successfully
58+
if (run.Status != RunStatus.Completed)
59+
{
60+
throw new Exception("Run did not complete successfully, error: " + run.LastError?.Message);
61+
}
62+
63+
// Retrieve all messages from the agent client
64+
AsyncPageable<ThreadMessage> messages = agentClient.Messages.GetMessagesAsync(
65+
threadId: thread.Id,
66+
order: ListSortOrder.Ascending
67+
);
68+
69+
// Process messages in order
70+
await foreach (ThreadMessage threadMessage in messages)
71+
{
72+
Console.Write($"{threadMessage.CreatedAt:yyyy-MM-dd HH:mm:ss} - {threadMessage.Role,10}: ");
73+
foreach (MessageContent contentItem in threadMessage.ContentItems)
74+
{
75+
if (contentItem is MessageTextContent textItem)
76+
{
77+
string response = textItem.Text;
78+
79+
// If we have Text URL citation annotations, reformat the response to show title & URL for citations
80+
if (textItem.Annotations != null)
81+
{
82+
foreach (MessageTextAnnotation annotation in textItem.Annotations)
83+
{
84+
if (annotation is MessageTextUrlCitationAnnotation urlAnnotation)
85+
{
86+
response = response.Replace(urlAnnotation.Text, $" [{urlAnnotation.UrlCitation.Title}]({urlAnnotation.UrlCitation.Url})");
87+
}
88+
}
89+
}
90+
Console.Write($"Agent response: {response}");
91+
}
92+
else if (contentItem is MessageImageFileContent imageFileItem)
93+
{
94+
Console.Write($"<image from ID: {imageFileItem.FileId}");
95+
}
96+
Console.WriteLine();
97+
}
98+
}
99+
100+
// Delete thread and agent
101+
agentClient.Threads.DeleteThread(threadId: thread.Id);
102+
agentClient.Administration.DeleteAgent(agentId: agent.Id);

0 commit comments

Comments
 (0)