如何使用以 Bing 搜尋為基礎 (傳統)

本文件提及 Microsoft Foundry(經典版)代理程式。

  • 我們建議客戶從具備客服人員 API 的新 網路搜尋工具 開始。 如果您想了解 Web 搜尋工具 與 Grounding with Bing 搜尋工具之間的差異,可在此處深入了解。

🔍 查看新的 Bing 搜尋基礎文件。 Agents(經典版)現已棄用,將於 2027 年 3 月 31 日退役。 請使用普遍可用的 Microsoft Foundry Agents Service 中的新代理。 請依照 遷移指南 更新你的工作負載。

使用本文尋找以 Bing 搜尋為基礎的逐步指示和程式碼範例。

先決條件

  • 已連線的以 Bing 搜尋為基礎的資源
  • 你的連線 ID 格式必須是:/subscriptions/<subscription_id>/resourceGroups/<resource_group_name>/providers/Microsoft.CognitiveServices/accounts/<ai_service_name>/projects/<project_name>/connections/<connection_name>

重要

顯示以 Bing 搜尋為基礎的結果時有相關規定。 詳情請參閱 概述文章

  1. Microsoft Foundry 入口網站 前往 Agents 畫面,尋找你的代理人。 在右側的設定面板中,向下滑動至知識區。 然後選擇 新增

    一張顯示 Foundry 入口中可用工具類別的截圖。

  2. 選擇 「與 Bing 搜尋整合」,然後按照提示添加該工具。 請注意,每位代理人只能新增一個。

    一張顯示 Foundry 入口網站可用知識工具的截圖。

  3. 選擇 新增 以新增連線。 一旦新增連線,你可以直接從現有清單中選擇。

    一張顯示建立新連線按鈕的截圖。

  4. 選擇你想使用的 Bing Grounding 搜尋資源,然後選擇 新增連線

    顯示可用以 Bing 搜尋為基礎連線的螢幕擷取畫面。

建立專案客戶端

建立一個客戶端物件,包含連接 AI 專案及其他資源的端點。

import os
from azure.ai.projects import AIProjectClient
from azure.identity import DefaultAzureCredential
from azure.ai.agents.models import BingGroundingTool

# Create an Azure AI Client from an endpoint, copied from your Foundry project.
# You need to login to Azure subscription via Azure CLI and set the environment variables
project_endpoint = os.environ["PROJECT_ENDPOINT"]  # Ensure the PROJECT_ENDPOINT environment variable is set

# Create an AIProjectClient instance
project_client = AIProjectClient(
    endpoint=project_endpoint,
    credential=DefaultAzureCredential()  # Use Azure Default Credential for authentication
)

啟用 Grounding with Bing 搜尋工具,建立一個客服人員

要讓你的代理程式能使用「Grounding with Bing」搜尋工具,請使用連接來初始化該工具,並將其附加到代理程式。 你可以在 Foundry 入口網站專案連結資源區找到你的連結。

conn_id = os.environ["BING_CONNECTION_NAME"]  # Ensure the BING_CONNECTION_NAME environment variable is set

# Initialize the Bing Grounding tool
bing = BingGroundingTool(connection_id=conn_id)

with project_client:
    # Create an agent with the Bing Grounding tool
    agent = project_client.agents.create_agent(
        model=os.environ["MODEL_DEPLOYMENT_NAME"],  # Model deployment name
        name="my-agent",  # Name of the agent
        instructions="You are a helpful agent",  # Instructions for the agent
        tools=bing.definitions,  # Attach the Bing Grounding tool
    )
    print(f"Created agent, ID: {agent.id}")

建立一個討論串

# Create a thread for communication
thread = project_client.agents.threads.create()
print(f"Created thread, ID: {thread.id}")

# Add a message to the thread
message = project_client.agents.messages.create(
    thread_id=thread.id,
    role="user",  # Role of the message sender
    content="What is the weather in Seattle today?",  # Message content
)
print(f"Created message, ID: {message['id']}")

建立一個執行程序並檢查輸出

建立執行,並觀察模型會使用以 Bing 搜尋為基礎的工具回答使用者的問題。

# Create and process an agent run
run = project_client.agents.runs.create_and_process(
    thread_id=thread.id,
    agent_id=agent.id,
    # tool_choice={"type": "bing_grounding"}  # optional, you can force the model to use Grounding with Bing Search tool
)
print(f"Run finished with status: {run.status}")

# Check if the run failed
if run.status == "failed":
    print(f"Run failed: {run.last_error}")

# Fetch and log all messages
messages = project_client.agents.messages.list(thread_id=thread.id)
for message in messages:
    print(f"Role: {message.role}, Content: {message.content}")

可選擇性地輸出代理所使用的執行步驟

run_steps = project_client.agents.run_steps.list(thread_id=thread.id, run_id=run.id)
for step in run_steps:
    print(f"Step {step['id']} status: {step['status']}")

    # Check if there are tool calls in the step details
    step_details = step.get("step_details", {})
    tool_calls = step_details.get("tool_calls", [])

    if tool_calls:
        print("  Tool calls:")
        for call in tool_calls:
            print(f"    Tool Call ID: {call.get('id')}")
            print(f"    Type: {call.get('type')}")

            function_details = call.get("function", {})
            if function_details:
                print(f"    Function name: {function_details.get('name')}")
    print()  # add an extra newline between steps

完成後刪除代理

project_client.agents.delete_agent(agent.id)
print("Deleted agent")

建立專案客戶端

建立一個客戶端物件,包含專案端點,以便連接你的 AI 專案及其他資源。

using Azure;
using Azure.AI.Agents.Persistent;
using Azure.Identity;

var projectEndpoint = System.Environment.GetEnvironmentVariable("ProjectEndpoint");
var modelDeploymentName = System.Environment.GetEnvironmentVariable("ModelDeploymentName");
var bingConnectionId = System.Environment.GetEnvironmentVariable("BingConnectionId");

// Create the Agent Client
PersistentAgentsClient agentClient = new(projectEndpoint, new DefaultAzureCredential());

啟用 Grounding with Bing 搜尋工具,建立一個客服人員

要讓你的代理程式能使用「Grounding with Bing」搜尋工具,請使用連線來初始化搜尋工具並連接到代理程式。 你可以在 Foundry 入口網站專案連結資源區找到你的連結。


BingGroundingToolDefinition bingGroundingTool = new(
    new BingGroundingSearchToolParameters(
        [new BingGroundingSearchConfiguration(bingConnectionId)]
    )
);

// Create the Agent
PersistentAgent agent = agentClient.Administration.CreateAgent(
    model: modelDeploymentName,
    name: "my-agent",
    instructions: "Use the bing grounding tool to answer questions.",
    tools: [bingGroundingTool]
);

建立一個執行緒並執行

PersistentAgentThread thread = agentClient.Threads.CreateThread();

// Create message and run the agent
PersistentThreadMessage message = agentClient.Messages.CreateMessage(
    thread.Id,
    MessageRole.User,
    "How does wikipedia explain Euler's Identity?");
ThreadRun run = agentClient.Runs.CreateRun(thread, agent);

等代理完成後列印輸出

首先,透過輪詢 Agent 狀態,等候 Agent 完成執行。 該模型使用 Bing Grounding 搜尋工具來回應使用者的問題。

// Wait for the agent to finish running
do
{
    Thread.Sleep(TimeSpan.FromMilliseconds(500));
    run = agentClient.Runs.GetRun(thread.Id, run.Id);
}
while (run.Status == RunStatus.Queued
    || run.Status == RunStatus.InProgress);

// Confirm that the run completed successfully
if (run.Status != RunStatus.Completed)
{
    throw new Exception("Run did not complete successfully, error: " + run.LastError?.Message);
}

接著,從完成的執行中擷取並處理訊息。

// Retrieve all messages from the agent client
Pageable<PersistentThreadMessage> messages = agentClient.Messages.GetMessages(
    threadId: thread.Id,
    order: ListSortOrder.Ascending
);

// Process messages in order
foreach (PersistentThreadMessage threadMessage in messages)
{
    Console.Write($"{threadMessage.CreatedAt:yyyy-MM-dd HH:mm:ss} - {threadMessage.Role,10}: ");
    foreach (MessageContent contentItem in threadMessage.ContentItems)
    {
        if (contentItem is MessageTextContent textItem)
        {
            string response = textItem.Text;

            // If we have Text URL citation annotations, reformat the response to show title & URL for citations
            if (textItem.Annotations != null)
            {
                foreach (MessageTextAnnotation annotation in textItem.Annotations)
                {
                    if (annotation is MessageTextUriCitationAnnotation urlAnnotation)
                    {
                        response = response.Replace(urlAnnotation.Text, $" [{urlAnnotation.UriCitation.Title}]({urlAnnotation.UriCitation.Uri})");
                    }
                }
            }
            Console.Write($"Agent response: {response}");
        }
        else if (contentItem is MessageImageFileContent imageFileItem)
        {
            Console.Write($"<image from ID: {imageFileItem.FileId}");
        }
        Console.WriteLine();
    }
}

可選擇性地輸出代理所使用的執行步驟

// Retrieve the run steps used by the agent and print those to the console
Console.WriteLine("Run Steps used by Agent:");
Pageable<RunStep> runSteps = agentClient.Runs.GetRunSteps(run);

foreach (var step in runSteps)
{
    Console.WriteLine($"Step ID: {step.Id}, Total Tokens: {step.Usage.TotalTokens}, Status: {step.Status}, Type: {step.Type}");

    if (step.StepDetails is RunStepMessageCreationDetails messageCreationDetails)
    {
        Console.WriteLine($"   Message Creation Id: {messageCreationDetails.MessageCreation.MessageId}");
    }
    else if (step.StepDetails is RunStepToolCallDetails toolCallDetails)
    {
        // We know this agent only has the Bing Grounding tool, so we can cast it directly
        foreach (RunStepBingGroundingToolCall toolCall in toolCallDetails.ToolCalls)
        {
            Console.WriteLine($"   Tool Call Details: {toolCall.GetType()}");

            foreach (var result in toolCall.BingGrounding)
            {
                Console.WriteLine($"      {result.Key}: {result.Value}");
            }
        }
    }
}

清理資源

清除本範例中的資源。

// Delete thread and agent
agentClient.Threads.DeleteThread(threadId: thread.Id);
agentClient.Administration.DeleteAgent(agentId: agent.Id);

建立專案客戶端

建立一個客戶端物件,包含連接 AI 專案及其他資源的端點。

const { AgentsClient, ToolUtility, isOutputOfType } = require("@azure/ai-agents");
const { delay } = require("@azure/core-util");
const { DefaultAzureCredential } = require("@azure/identity");

require("dotenv/config");

const projectEndpoint = process.env["PROJECT_ENDPOINT"];

// Create an Azure AI Client
const client = new AgentsClient(projectEndpoint, new DefaultAzureCredential());

啟用 Grounding with Bing 搜尋工具,建立一個客服人員

要讓「Grounding with Bing」搜尋工具可用於您的代理程式,請使用連線來初始化該工具並將其附加到代理程式。 你可以在 Foundry 入口網站專案連結資源區找到你的連結。


const connectionId = process.env["AZURE_BING_CONNECTION_ID"] || "<connection-name>";
// Initialize agent bing tool with the connection id
const bingTool = ToolUtility.createBingGroundingTool([{ connectionId: connectionId }]);

// Create agent with the bing tool and process assistant run
const agent = await client.createAgent("gpt-4o", {
  name: "my-agent",
  instructions: "You are a helpful agent",
  tools: [bingTool.definition],
});
console.log(`Created agent, agent ID : ${agent.id}`);

建立一個討論串

// Create thread for communication
const thread = await client.threads.create();
console.log(`Created thread, thread ID: ${thread.id}`);

// Create message to thread
const message = await client.messages.create(
  thread.id,
  "user",
  "How does wikipedia explain Euler's Identity?",
);
console.log(`Created message, message ID : ${message.id}`);

建立一個執行程序並檢查輸出

建立執行,並觀察模型會使用以 Bing 搜尋為基礎的工具回答使用者的問題。


// Create and process agent run in thread with tools
let run = await client.runs.create(thread.id, agent.id);
while (run.status === "queued" || run.status === "in_progress") {
  await delay(1000);
  run = await client.runs.get(thread.id, run.id);
}
if (run.status === "failed") {
  console.log(`Run failed: ${run.lastError?.message}`);
}
console.log(`Run finished with status: ${run.status}`);

// Delete the assistant when done
await client.deleteAgent(agent.id);
console.log(`Deleted agent, agent ID: ${agent.id}`);

// Fetch and log all messages
const messagesIterator = client.messages.list(thread.id);
console.log(`Messages:`);

// Get the first message
const firstMessage = await messagesIterator.next();
if (!firstMessage.done && firstMessage.value) {
  const agentMessage = firstMessage.value.content[0];
  if (isOutputOfType(agentMessage, "text")) {
    const textContent = agentMessage;
    console.log(`Text Message Content - ${textContent.text.value}`);
  }
}

重要

  1. 此 REST API 讓開發者能透過 Foundry 代理服務呼叫 Grounding with Bing 搜尋工具。 它不會直接向 Grounding with Bing Search API 發送呼叫。

請依照 REST API 快速入門 設定環境變數 AGENT_TOKENAZURE_AI_FOUNDRY_PROJECT_ENDPOINTAPI_VERSION和 的正確值。

啟用 Grounding with Bing 搜尋工具,建立一個客服人員

要讓你的代理程式能使用「Grounding with Bing」搜尋工具,請使用連線來初始化該工具並將其附加到代理程式上。 你可以在 Foundry 入口網站專案連結資源區找到你的連結。

curl --request POST \
  --url $AZURE_AI_FOUNDRY_PROJECT_ENDPOINT/assistants?api-version=$API_VERSION \
  -H "Authorization: Bearer $AGENT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
        "instructions": "You are a helpful agent.",
        "name": "my-agent",
        "model": "gpt-4o",
        "tools": [
          {
            "type": "bing_grounding",
            "bing_grounding": {
                "search_configurations": [
                    {
                        "connection_id": "<your_connection_id>",
                        "count": 7, 
                        "market": "en-US", 
                        "set_lang": "en", 
                        "freshness": "Week",
                    }
                ]
            }
          }
        ]
      }'

建立一個討論串

curl --request POST \
  --url $AZURE_AI_FOUNDRY_PROJECT_ENDPOINT/threads?api-version=$API_VERSION \
  -H "Authorization: Bearer $AGENT_TOKEN" \
  -H "Content-Type: application/json" \
  -d ''

請在討論串中新增用戶問題

curl --request POST \
  --url $AZURE_AI_FOUNDRY_PROJECT_ENDPOINT/threads/thread_abc123/messages?api-version=$API_VERSION \
  -H "Authorization: Bearer $AGENT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
      "role": "user",
      "content": "What is the weather in Seattle?"
    }'

建立一個執行程序並檢查輸出

建立執行,並觀察模型會使用以 Bing 搜尋為基礎的工具回答使用者的問題。

curl --request POST \
  --url $AZURE_AI_FOUNDRY_PROJECT_ENDPOINT/threads/thread_abc123/runs?api-version=$API_VERSION \
  -H "Authorization: Bearer $AGENT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "assistant_id": "asst_abc123",
  }'

取得運行狀態

curl --request GET \
  --url $AZURE_AI_FOUNDRY_PROJECT_ENDPOINT/threads/thread_abc123/runs/run_abc123?api-version=$API_VERSION \
  -H "Authorization: Bearer $AGENT_TOKEN"

取得代理回應

curl --request GET \
  --url $AZURE_AI_FOUNDRY_PROJECT_ENDPOINT/threads/thread_abc123/messages?api-version=$API_VERSION \
  -H "Authorization: Bearer $AGENT_TOKEN"

程式碼範例

package com.example.agents;

import com.azure.ai.agents.persistent.MessagesClient;
import com.azure.ai.agents.persistent.PersistentAgentsAdministrationClient;
import com.azure.ai.agents.persistent.PersistentAgentsClient;
import com.azure.ai.agents.persistent.PersistentAgentsClientBuilder;
import com.azure.ai.agents.persistent.RunsClient;
import com.azure.ai.agents.persistent.ThreadsClient;
import com.azure.ai.agents.persistent.models.BingGroundingSearchConfiguration;
import com.azure.ai.agents.persistent.models.BingGroundingSearchToolParameters;
import com.azure.ai.agents.persistent.models.BingGroundingToolDefinition;
import com.azure.ai.agents.persistent.models.CreateAgentOptions;
import com.azure.ai.agents.persistent.models.CreateRunOptions;
import com.azure.ai.agents.persistent.models.MessageImageFileContent;
import com.azure.ai.agents.persistent.models.MessageRole;
import com.azure.ai.agents.persistent.models.MessageTextContent;
import com.azure.ai.agents.persistent.models.PersistentAgent;
import com.azure.ai.agents.persistent.models.PersistentAgentThread;
import com.azure.ai.agents.persistent.models.RunStatus;
import com.azure.ai.agents.persistent.models.ThreadMessage;
import com.azure.ai.agents.persistent.models.ThreadRun;
import com.azure.ai.agents.persistent.models.MessageContent;
import com.azure.core.http.rest.PagedIterable;
import com.azure.identity.DefaultAzureCredentialBuilder;

import java.util.Arrays;

public class AgentExample {

    public static void main(String[] args) {

        // variables for authenticating requests to the agent service 
        String projectEndpoint = System.getenv("PROJECT_ENDPOINT");
        String modelName = System.getenv("MODEL_DEPLOYMENT_NAME");
        String bingConnectionId = System.getenv("BING_CONNECTION_ID");

        PersistentAgentsClientBuilder clientBuilder = new PersistentAgentsClientBuilder().endpoint(projectEndpoint)
            .credential(new DefaultAzureCredentialBuilder().build());
        PersistentAgentsClient agentsClient = clientBuilder.buildClient();
        PersistentAgentsAdministrationClient administrationClient = agentsClient.getPersistentAgentsAdministrationClient();
        ThreadsClient threadsClient = agentsClient.getThreadsClient();
        MessagesClient messagesClient = agentsClient.getMessagesClient();
        RunsClient runsClient = agentsClient.getRunsClient();

        BingGroundingSearchConfiguration searchConfiguration = new BingGroundingSearchConfiguration(bingConnectionId);
        BingGroundingSearchToolParameters searchToolParameters
            = new BingGroundingSearchToolParameters(Arrays.asList(searchConfiguration));

        BingGroundingToolDefinition bingGroundingTool = new BingGroundingToolDefinition(searchToolParameters);

        String agentName = "bing_grounding_example";
        CreateAgentOptions createAgentOptions = new CreateAgentOptions(modelName)
            .setName(agentName)
            .setInstructions("You are a helpful agent")
            .setTools(Arrays.asList(bingGroundingTool));
        PersistentAgent agent = administrationClient.createAgent(createAgentOptions);

        PersistentAgentThread thread = threadsClient.createThread();
        ThreadMessage createdMessage = messagesClient.createMessage(
            thread.getId(),
            MessageRole.USER,
            "How does wikipedia explain Euler's Identity?");

        try {
            //run agent
            CreateRunOptions createRunOptions = new CreateRunOptions(thread.getId(), agent.getId())
                .setAdditionalInstructions("");
            ThreadRun threadRun = runsClient.createRun(createRunOptions);

            waitForRunCompletion(thread.getId(), threadRun, runsClient);
            printRunMessages(messagesClient, thread.getId());
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } finally {
            //cleanup
            threadsClient.deleteThread(thread.getId());
            administrationClient.deleteAgent(agent.getId());
        }
    }

    // A helper function to print messages from the agent
    public static void printRunMessages(MessagesClient messagesClient, String threadId) {

        PagedIterable<ThreadMessage> runMessages = messagesClient.listMessages(threadId);
        for (ThreadMessage message : runMessages) {
            System.out.print(String.format("%1$s - %2$s : ", message.getCreatedAt(), message.getRole()));
            for (MessageContent contentItem : message.getContent()) {
                if (contentItem instanceof MessageTextContent) {
                    System.out.print((((MessageTextContent) contentItem).getText().getValue()));
                } else if (contentItem instanceof MessageImageFileContent) {
                    String imageFileId = (((MessageImageFileContent) contentItem).getImageFile().getFileId());
                    System.out.print("Image from ID: " + imageFileId);
                }
                System.out.println();
            }
        }
    }

    // a helper function to wait until a run has completed running
    public static void waitForRunCompletion(String threadId, ThreadRun threadRun, RunsClient runsClient)
        throws InterruptedException {

        do {
            Thread.sleep(500);
            threadRun = runsClient.getRun(threadId, threadRun.getId());
        }
        while (
            threadRun.getStatus() == RunStatus.QUEUED
                || threadRun.getStatus() == RunStatus.IN_PROGRESS
                || threadRun.getStatus() == RunStatus.REQUIRES_ACTION);

        if (threadRun.getStatus() == RunStatus.FAILED) {
            System.out.println(threadRun.getLastError().getMessage());
        }
    }
}