Skip to content

Commit 9c0a3d0

Browse files
authored
Merge pull request #4144 from aahill/custom-bing
Custom bing search
2 parents dc16b84 + 5fbd11e commit 9c0a3d0

File tree

5 files changed

+528
-1
lines changed

5 files changed

+528
-1
lines changed
Lines changed: 374 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,374 @@
1+
---
2+
title: 'How to use the Custom Bing Search with Azure AI Agent Service tool'
3+
titleSuffix: Azure OpenAI
4+
description: Find samples to ground Azure AI Agents using Custom Bing Search results.
5+
services: cognitive-services
6+
manager: nitinme
7+
ms.service: azure-ai-agent-service
8+
ms.topic: how-to
9+
ms.date: 04/15/2025
10+
author: aahill
11+
ms.author: aahi
12+
ms.custom: azure-ai-agents
13+
zone_pivot_groups: selection-bing-custom-grounding
14+
---
15+
16+
# How to use Grounding with Bing Custom Search
17+
18+
19+
::: zone pivot="portal"
20+
21+
22+
1. Navigate to the Create and debug screen for your agent in the [Azure AI Foundry portal](https://ai.azure.com/), scroll down the Setup pane on the right to **knowledge**. Then select **Add**.
23+
24+
:::image type="content" source="../../media/tools/knowledge-tools.png" alt-text="A screenshot of the agents screen in the AI Foundry portal.":::
25+
26+
1. Select the **Grounding with Bing Custom Search** tool.
27+
28+
1. Select to create a new connection, or use an existing connection
29+
30+
1. For a new connection, select your Grounding with Bing Custom Search resource.
31+
32+
1. Once you have connected to a resource, select the configuration name.
33+
34+
1. Save the tool and start chatting with your agent.
35+
36+
:::zone-end
37+
38+
::: zone pivot="csharp"
39+
40+
## Step 1: Create a project client
41+
42+
Create a client object, which will contain the connection string for connecting to your AI project and other resources.
43+
44+
```csharp
45+
using System;
46+
using System.Collections.Generic;
47+
using System.Threading.Tasks;
48+
using Azure.Core;
49+
using Azure.Core.TestFramework;
50+
using NUnit.Framework;
51+
52+
var connectionString = System.Environment.GetEnvironmentVariable("PROJECT_CONNECTION_STRING");
53+
var modelDeploymentName = System.Environment.GetEnvironmentVariable("MODEL_DEPLOYMENT_NAME");
54+
var bingConnectionName = System.Environment.GetEnvironmentVariable("BING_CONNECTION_NAME");
55+
56+
var projectClient = new AIProjectClient(connectionString, new DefaultAzureCredential());
57+
58+
AgentsClient agentClient = projectClient.GetAgentsClient();
59+
```
60+
61+
## Step 2: Create an Agent with the Grounding with Bing search tool enabled
62+
63+
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/).
64+
65+
```csharp
66+
AgentsClient agentClient = projectClient.GetAgentsClient();
67+
ConnectionResponse bingConnection = await projectClient.GetConnectionsClient().GetConnectionAsync(bingConnectionName);
68+
var connectionId = bingConnection.Id;
69+
var instanceName = "<your_config_instance_name>";
70+
71+
SearchConfigurationList searchConfigurationList = new SearchConfigurationList(
72+
new List<SearchConfiguration>
73+
{
74+
new SearchConfiguration(connectionId, instanceName)
75+
});
76+
77+
BingCustomSearchToolDefinition bingGroundingTool = new(searchConfigurationList);
78+
Agent agent = await agentClient.CreateAgentAsync(
79+
model: modelDeploymentName,
80+
name: "my-assistant",
81+
instructions: "You are a helpful assistant.",
82+
tools: [ bingGroundingTool ]);
83+
```
84+
85+
## Step 3: Create a thread
86+
87+
```csharp
88+
AgentThread thread = agentClient.CreateThread();
89+
90+
// Create message to thread
91+
ThreadMessage message = agentClient.CreateMessage(
92+
thread.Id,
93+
MessageRole.User,
94+
"How does wikipedia explain Euler's Identity?");
95+
```
96+
97+
## Step 4: Create a run and check the output
98+
99+
Create a run and observe that the model uses the Grounding with Bing Search tool to provide a response to the user's question.
100+
101+
102+
```csharp
103+
104+
// Run the agent
105+
ThreadRun run = agentClient.CreateRun(thread, agent);
106+
do
107+
{
108+
Thread.Sleep(TimeSpan.FromMilliseconds(500));
109+
run = agentClient.GetRun(thread.Id, run.Id);
110+
}
111+
while (run.Status == RunStatus.Queued
112+
|| run.Status == RunStatus.InProgress);
113+
114+
Assert.AreEqual(
115+
RunStatus.Completed,
116+
run.Status,
117+
run.LastError?.Message);
118+
119+
PageableList<ThreadMessage> messages = agentClient.GetMessages(
120+
threadId: thread.Id,
121+
order: ListSortOrder.Ascending
122+
);
123+
124+
foreach (ThreadMessage threadMessage in messages)
125+
{
126+
Console.Write($"{threadMessage.CreatedAt:yyyy-MM-dd HH:mm:ss} - {threadMessage.Role,10}: ");
127+
foreach (MessageContent contentItem in threadMessage.ContentItems)
128+
{
129+
if (contentItem is MessageTextContent textItem)
130+
{
131+
string response = textItem.Text;
132+
if (textItem.Annotations != null)
133+
{
134+
foreach (MessageTextAnnotation annotation in textItem.Annotations)
135+
{
136+
if (annotation is MessageTextUrlCitationAnnotation urlAnnotation)
137+
{
138+
response = response.Replace(urlAnnotation.Text, $" [{urlAnnotation.UrlCitation.Title}]({urlAnnotation.UrlCitation.Url})");
139+
}
140+
}
141+
}
142+
Console.Write($"Agent response: {response}");
143+
}
144+
else if (contentItem is MessageImageFileContent imageFileItem)
145+
{
146+
Console.Write($"<image from ID: {imageFileItem.FileId}");
147+
}
148+
Console.WriteLine();
149+
}
150+
}
151+
152+
agentClient.DeleteThread(threadId: thread.Id);
153+
agentClient.DeleteAgent(agentId: agent.Id);
154+
```
155+
156+
:::zone-end
157+
158+
::: zone pivot="javascript"
159+
160+
## Step 1: Create a project client
161+
162+
Create a client object, which will contain the connection string for connecting to your AI project and other resources.
163+
164+
```javascript
165+
const { AIProjectsClient, ToolUtility, isOutputOfType } = require("@azure/ai-projects");
166+
const { delay } = require("@azure/core-util");
167+
const { DefaultAzureCredential } = require("@azure/identity");
168+
169+
require("dotenv/config");
170+
171+
const connectionString =
172+
process.env["AZURE_AI_PROJECTS_CONNECTION_STRING"] || "<project connection string>";
173+
174+
// Create an Azure AI Client from a connection string, copied from your AI Foundry project.
175+
// At the moment, it should be in the format "<HostName>;<AzureSubscriptionId>;<ResourceGroup>;<HubName>"
176+
// Customer needs to login to Azure subscription via Azure CLI and set the environment variables
177+
const client = AIProjectsClient.fromConnectionString(
178+
connectionString || "",
179+
new DefaultAzureCredential(),
180+
);
181+
```
182+
183+
184+
## Step 2: Create an Agent with the Grounding with Bing search tool enabled
185+
186+
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/).
187+
188+
```javascript
189+
const bingCustomSearchConnection = await client.connections.getConnection(
190+
process.env["BING_CUSTOM_SEARCH"] || "<connection-name>",
191+
);
192+
console.log(`Bing custom search connection ID:`, bingCustomSearchConnection.id);
193+
194+
// Initialize agent bing custom search tool with the connection id
195+
const bingCustomSearchTool = ToolUtility.createBingCustomSearchTool([
196+
{
197+
connectionId: bingCustomSearchConnection.id,
198+
instanceName: bingCustomSearchConnection.name,
199+
},
200+
]);
201+
202+
// Create agent with the bing tool and process assistant run
203+
const agent = await client.agents.createAgent("gpt-4o", {
204+
name: "my-agent",
205+
instructions:
206+
"You are a customer support chatbot. Use the tools provided and your knowledge base to best respond to customer queries",
207+
tools: [bingCustomSearchTool.definition]
208+
});
209+
console.log(`Created agent, agent ID : ${agent.id}`);
210+
```
211+
212+
## Step 3: Create a thread
213+
214+
```javascript
215+
// create a thread
216+
const thread = await client.agents.createThread();
217+
218+
// add a message to thread
219+
await client.agents.createMessage(
220+
thread.id, {
221+
role: "user",
222+
content: "What is the weather in Seattle?",
223+
});
224+
```
225+
226+
## Step 4: Create a run and check the output
227+
228+
Create a run and observe that the model uses the Grounding with Bing Search tool to provide a response to the user's question.
229+
230+
231+
```javascript
232+
233+
// create a run
234+
const streamEventMessages = await client.agents.createRun(thread.id, agent.id).stream();
235+
236+
for await (const eventMessage of streamEventMessages) {
237+
switch (eventMessage.event) {
238+
case RunStreamEvent.ThreadRunCreated:
239+
break;
240+
case MessageStreamEvent.ThreadMessageDelta:
241+
{
242+
const messageDelta = eventMessage.data;
243+
messageDelta.delta.content.forEach((contentPart) => {
244+
if (contentPart.type === "text") {
245+
const textContent = contentPart;
246+
const textValue = textContent.text?.value || "No text";
247+
}
248+
});
249+
}
250+
break;
251+
252+
case RunStreamEvent.ThreadRunCompleted:
253+
break;
254+
case ErrorEvent.Error:
255+
console.log(`An error occurred. Data ${eventMessage.data}`);
256+
break;
257+
case DoneEvent.Done:
258+
break;
259+
}
260+
}
261+
262+
// Print the messages from the agent
263+
const messages = await client.agents.listMessages(thread.id);
264+
265+
// Messages iterate from oldest to newest
266+
// messages[0] is the most recent
267+
for (let i = messages.data.length - 1; i >= 0; i--) {
268+
const m = messages.data[i];
269+
if (isOutputOfType<MessageTextContentOutput>(m.content[0], "text")) {
270+
const textContent = m.content[0];
271+
console.log(`${textContent.text.value}`);
272+
console.log(`---------------------------------`);
273+
}
274+
}
275+
```
276+
277+
:::zone-end
278+
279+
::: zone pivot="python"
280+
281+
## Step 1: Create a project client
282+
283+
Create a client object, which will contain the connection string for connecting to your AI project and other resources.
284+
285+
```python
286+
287+
import os
288+
from azure.ai.projects import AIProjectClient
289+
from azure.ai.projects.models import MessageRole, BingCustomSearchTool
290+
from azure.identity import DefaultAzureCredential
291+
292+
293+
# Create an Azure AI Client from a connection string, copied from your Azure AI Foundry project.
294+
# At the moment, it should be in the format "<HostName>;<AzureSubscriptionId>;<ResourceGroup>;<HubName>"
295+
# Customer needs to login to Azure subscription via Azure CLI and set the environment variables
296+
297+
project_client = AIProjectClient.from_connection_string(
298+
credential=DefaultAzureCredential(),
299+
conn_str=os.environ["PROJECT_CONNECTION_STRING"],
300+
)
301+
302+
```
303+
304+
305+
## Step 2: Create an Agent with the Grounding with Bing search tool enabled
306+
307+
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/).
308+
309+
```python
310+
bing_custom_connection = project_client.connections.get(connection_name=os.environ["BING_CUSTOM_CONNECTION_NAME"])
311+
conn_id = bing_custom_connection.id
312+
313+
print(conn_id)
314+
315+
# Initialize agent bing custom search tool and add the connection id
316+
bing_custom_tool = BingCustomSearchTool(connection_id=conn_id, instance_name="<config_instance_name>")
317+
318+
# Create agent with the bing custom search tool and process assistant run
319+
with project_client:
320+
agent = project_client.agents.create_agent(
321+
model=os.environ["MODEL_DEPLOYMENT_NAME"],
322+
name="my-agent",
323+
instructions="You are a helpful agent",
324+
tools=bing_custom_tool.definitions
325+
)
326+
print(f"Created agent, ID: {agent.id}")
327+
```
328+
329+
## Step 3: Create a thread
330+
331+
```python
332+
# Create thread for communication
333+
thread = project_client.agents.create_thread()
334+
print(f"Created thread, ID: {thread.id}")
335+
336+
# Create message to thread
337+
message = project_client.agents.create_message(
338+
thread_id=thread.id,
339+
role="user",
340+
content="What is the top news today",
341+
)
342+
print(f"Created message, ID: {message.id}")
343+
```
344+
345+
## Step 4: Create a run and check the output
346+
347+
Create a run and observe that the model uses the Grounding with Bing Search tool to provide a response to the user's question.
348+
349+
350+
```python
351+
# Create and process agent run in thread with tools
352+
run = project_client.agents.create_and_process_run(thread_id=thread.id, agent_id=agent.id)
353+
print(f"Run finished with status: {run.status}")
354+
355+
if run.status == "failed":
356+
print(f"Run failed: {run.last_error}")
357+
358+
# Delete the assistant when done
359+
project_client.agents.delete_agent(agent.id)
360+
print("Deleted agent")
361+
362+
# Print the Agent's response message with optional citation
363+
response_message = project_client.agents.list_messages(thread_id=thread.id).get_last_message_by_role(
364+
MessageRole.AGENT
365+
)
366+
if response_message:
367+
for text_message in response_message.text_messages:
368+
print(f"Agent response: {text_message.text.value}")
369+
for annotation in response_message.url_citation_annotations:
370+
print(f"URL Citation: [{annotation.url_citation.title}]({annotation.url_citation.url})")
371+
```
372+
373+
374+
:::zone-end

0 commit comments

Comments
 (0)