你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

将 Azure Functions 与 Foundry 智能体服务结合使用

了解如何使用基于队列的工具方法将 Azure Functions 与 Microsoft Foundry 代理集成。 本文介绍如何构建智能体的 Foundry 模型可以通过 Azure 队列存储异步调用的自定义无服务器工具。 通过此方法,你的智能体可以访问企业系统和复杂业务逻辑,并采用缩放到零定价模式。

Foundry 代理通过使用 AzureFunctionsTool 提供的工具定义直接连接到由 Azure Functions 监视的输入队列。 当代理需要使用这个托管在 Azure Functions 的工具时,它使用工具定义将消息放置在由 Azure Functions 的函数应用监控的输入队列中。 Azure 存储队列触发器调用函数代码来处理消息并通过输出队列绑定返回结果。 代理从输出队列中读取消息以继续聊天。

Functions 提供了多个托管计划。 弹性消耗计划非常适合托管自定义工具,因为它提供:

  • 支持缩放到零无服务器托管,基于消耗量定价。
  • 对Azure中的资源的基于标识的访问,包括虚拟网络中的资源。
  • 通过 输入/输出绑定进行声明性数据源连接。

使用支持

下表显示了 SDK 和设置支持。

Microsoft Foundry 支持 Python SDK C# SDK JavaScript SDK Java SDK REST API 基本代理设置 标准代理设置
✔️ ✔️ ✔️ ✔️ ✔️ ✔️ - ✔️

先决条件

代码示例

以下代码示例演示如何定义一个Azure函数工具,该工具使用基于队列的集成获取指定位置的天气信息。

安装这个软件包

安装 Azure AI Projects 客户端库:

pip install "azure-ai-projects>=2.0.0"

定义该工具并创建代理

from azure.identity import DefaultAzureCredential
from azure.ai.projects import AIProjectClient
from azure.ai.projects.models import (
    AzureFunctionBinding,
    AzureFunctionDefinition,
    AzureFunctionStorageQueue,
    AzureFunctionDefinitionFunction,
    AzureFunctionTool,
    PromptAgentDefinition,
)

# Format: "https://resource_name.ai.azure.com/api/projects/project_name"
PROJECT_ENDPOINT = "your_project_endpoint"
STORAGE_QUEUE_ENDPOINT = "your_storage_queue_service_endpoint"

# Create clients to call Foundry API
project = AIProjectClient(
    endpoint=PROJECT_ENDPOINT,
    credential=DefaultAzureCredential(),
)
openai = project.get_openai_client()

# Define the Azure Function tool
tool = AzureFunctionTool(
    azure_function=AzureFunctionDefinition(
        input_binding=AzureFunctionBinding(
            storage_queue=AzureFunctionStorageQueue(
                queue_name="get-weather-input-queue",
                queue_service_endpoint=STORAGE_QUEUE_ENDPOINT,
            )
        ),
        output_binding=AzureFunctionBinding(
            storage_queue=AzureFunctionStorageQueue(
                queue_name="get-weather-output-queue",
                queue_service_endpoint=STORAGE_QUEUE_ENDPOINT,
            )
        ),
        function=AzureFunctionDefinitionFunction(
            name="GetWeather",
            description="Get the weather in a location.",
            parameters={
                "type": "object",
                "properties": {
                    "location": {
                        "type": "string",
                        "description": "The location to look up.",
                    }
                },
            },
        ),
    )
)

# Create the agent with the Azure Function tool
agent = project.agents.create_version(
    agent_name="azure-function-agent-get-weather",
    definition=PromptAgentDefinition(
        model="gpt-5.1",
        instructions="You are a helpful support agent. Answer the user's questions to the best of your ability.",
        tools=[tool],
    ),
)
print(f"Agent created (id: {agent.id}, name: {agent.name}, version: {agent.version})")

创建响应

response = openai.responses.create(
    input="What is the weather in Seattle, WA?",
    extra_body={"agent_reference": {"name": agent.name, "type": "agent_reference"}},
)

print(f"Response: {response.output_text}")

清理

project.agents.delete_version(agent_name=agent.name, agent_version=agent.version)
print("Agent deleted")

编写 Azure 函数

前面的代码示例演示如何在代理端定义Azure函数工具。 还需要编写处理队列消息的函数。 该函数从输入队列接收输入,运行自定义逻辑,并通过输出队列返回结果。

以下示例展示了一个由队列触发的函数,用于获取某个位置的天气信息。 该函数会解析传入的消息,提取函数参数,并返回一个包含CorrelationId的响应,代理通过该响应将结果与原始请求匹配。

import azure.functions as func
import logging
import json

app = func.FunctionApp()


# Queue trigger receives agent tool calls from the input queue
# and returns results through the output queue binding
@app.queue_trigger(
    arg_name="msg",
    queue_name="get-weather-input-queue",
    connection="STORAGE_CONNECTION",
)
@app.queue_output(
    arg_name="outputQueue",
    queue_name="get-weather-output-queue",
    connection="STORAGE_CONNECTION",
)
def queue_trigger(
    msg: func.QueueMessage, outputQueue: func.Out[str]
):
    try:
        # Parse the incoming message from the agent
        messagepayload = json.loads(
            msg.get_body().decode("utf-8")
        )
        logging.info("Received: %s", json.dumps(messagepayload))

        # Extract the function arguments
        function_args = messagepayload.get("function_args", {})
        location = function_args.get("location")

        # Run your custom logic (replace with real API calls)
        weather_result = (
            f"Weather is {len(location)} degrees "
            f"and sunny in {location}"
        )

        # Return result with the CorrelationId from the request
        response_message = {
            "Value": weather_result,
            "CorrelationId": messagepayload["CorrelationId"],
        }
        outputQueue.set(json.dumps(response_message))

    except Exception as e:
        logging.error("Error processing message: %s", e)

重要

响应消息必须包含原始消息中的 CorrelationId。 代理使用此值将函数输出与正确的工具调用匹配。

有关完整示例,请参阅Azure SDK for Python 存储库中的Azure Functions天气示例

安装这些包

安装 Azure AI Projects 客户端库:

dotnet add package Azure.AI.Projects
dotnet add package Azure.AI.Extensions.OpenAI
dotnet add package Azure.Identity

定义该工具并创建代理

using System;
using System.Text.Json;
using Azure.AI.Projects;
using Azure.AI.Extensions.OpenAI;
using Azure.Identity;

// Format: "https://resource_name.ai.azure.com/api/projects/project_name"
var projectEndpoint = "your_project_endpoint";
var storageQueueUri = "your_storage_queue_service_endpoint";

AIProjectClient projectClient = new(
    endpoint: new Uri(projectEndpoint),
    tokenProvider: new DefaultAzureCredential());

AzureFunctionDefinitionFunction functionDefinition = new(
    name: "GetWeather",
    parameters: BinaryData.FromObjectAsJson(
        new
        {
            Type = "object",
            Properties = new
            {
                location = new
                {
                    Type = "string",
                    Description = "The location to look up.",
                }
            }
        },
        new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }
    )
)
{
    Description = "Get the weather in a location.",
};

AzureFunctionTool azureFnTool = new(
    new AzureFunctionDefinition(
        function: functionDefinition,
        inputBinding: new AzureFunctionBinding(
            new AzureFunctionStorageQueue(
                queueServiceEndpoint: storageQueueUri,
                queueName: "input")),
        outputBinding: new AzureFunctionBinding(
            new AzureFunctionStorageQueue(
                queueServiceEndpoint: storageQueueUri,
                queueName: "output"))
    )
);

DeclarativeAgentDefinition agentDefinition = new(model: "gpt-5-mini")
{
    Instructions = "You are a helpful support agent. Answer the user's questions "
        + "to the best of your ability.",
    Tools = { azureFnTool },
};

AgentVersion agentVersion = await projectClient.AgentAdministrationClient.CreateAgentVersionAsync(
    agentName: "azure-function-agent-get-weather",
    options: new(agentDefinition));
Console.WriteLine($"Agent created (id: {agentVersion.Id}, name: {agentVersion.Name}, "
    + $"version: {agentVersion.Version})");

创建响应

ProjectResponsesClient responseClient =
    projectClient.ProjectOpenAIClient.GetProjectResponsesClientForAgent(agentVersion.Name);

CreateResponseOptions responseOptions = new()
{
    InputItems =
    {
        ResponseItem.CreateUserMessageItem("What is the weather in Seattle, WA?")
    },
};

ResponseResult response = await responseClient.CreateResponseAsync(responseOptions);
Console.WriteLine(response.GetOutputText());

清理

await projectClient.AgentAdministrationClient.DeleteAgentVersionAsync(
    agentName: agentVersion.Name,
    agentVersion: agentVersion.Version);
Console.WriteLine("Agent deleted");

编写 Azure 函数

前面的代码示例演示如何在代理端定义Azure函数工具。 还需要编写处理队列消息的函数。 该函数从输入队列接收输入,运行自定义逻辑,并通过输出队列返回结果。

以下示例展示了一个由队列触发的函数,用于获取某个位置的天气信息。 此示例使用 隔离的工作者模型。 该函数会解析传入的消息,提取函数参数,并返回一个包含CorrelationId的响应,代理通过该响应将结果与原始请求匹配。

using System.Text.Json;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Logging;

public class GetWeather
{
    private readonly ILogger<GetWeather> _logger;

    public GetWeather(ILogger<GetWeather> logger)
    {
        _logger = logger;
    }

    // Queue trigger receives agent tool calls from the input
    // queue and returns results through the output queue
    [Function("GetWeather")]
    [QueueOutput(
        "get-weather-output-queue",
        Connection = "STORAGE_CONNECTION")]
    public string Run(
        [QueueTrigger(
            "get-weather-input-queue",
            Connection = "STORAGE_CONNECTION")]
        string message)
    {
        _logger.LogInformation("Received: {Message}", message);

        // Parse the incoming message from the agent
        var payload = JsonSerializer.Deserialize<JsonElement>(
            message);
        var correlationId = payload
            .GetProperty("CorrelationId").GetString();
        var functionArgs = payload
            .GetProperty("function_args");
        var location = functionArgs
            .GetProperty("location").GetString();

        // Run your custom logic (replace with real API calls)
        var weatherResult =
            $"Weather is {location!.Length} degrees "
            + $"and sunny in {location}";

        // Return result with the CorrelationId from the request
        var response = new
        {
            Value = weatherResult,
            CorrelationId = correlationId,
        };
        return JsonSerializer.Serialize(response);
    }
}

重要

响应消息必须包含原始消息中的 CorrelationId。 代理使用此值将函数输出与正确的工具调用匹配。

安装这个软件包

将 Azure AI 代理依赖项添加到 pom.xml

<dependency>
    <groupId>com.azure</groupId>
    <artifactId>azure-ai-agents</artifactId>
    <version>2.2.0</version>
</dependency>
<dependency>
    <groupId>com.azure</groupId>
    <artifactId>azure-identity</artifactId>
</dependency>

定义该工具并创建代理

import com.azure.ai.agents.*;
import com.azure.ai.agents.models.*;
import com.azure.core.util.BinaryData;
import com.azure.identity.DefaultAzureCredentialBuilder;
import com.openai.models.responses.Response;
import com.openai.models.responses.ResponseCreateParams;

import java.util.*;

// Format: "https://resource_name.ai.azure.com/api/projects/project_name"
String projectEndpoint = "your_project_endpoint";
String storageQueueUri = "your_storage_queue_service_endpoint";

AgentsClientBuilder builder = new AgentsClientBuilder()
    .credential(new DefaultAzureCredentialBuilder().build())
    .endpoint(projectEndpoint)
    .serviceVersion(AgentsServiceVersion.getLatest());

AgentsClient agentsClient = builder.buildAgentsClient();
ResponsesClient responsesClient = builder.buildResponsesClient();

// Define the function parameters
Map<String, BinaryData> parameters = new HashMap<>();
parameters.put("type", BinaryData.fromString("\"object\""));
parameters.put("properties", BinaryData.fromString(
    "{\"location\": {\"type\": \"string\", "
    + "\"description\": \"The location to look up.\"}}"));

AzureFunctionDefinitionDetails function =
    new AzureFunctionDefinitionDetails("GetWeather", parameters)
        .setDescription("Get the weather in a location.");

AzureFunctionTool azureFnTool = new AzureFunctionTool(
    new AzureFunctionDefinition(
        function,
        new AzureFunctionBinding(
            new AzureFunctionStorageQueue(storageQueueUri, "input")),
        new AzureFunctionBinding(
            new AzureFunctionStorageQueue(storageQueueUri, "output"))
    )
);

PromptAgentDefinition agentDefinition = new PromptAgentDefinition("gpt-5.1")
    .setInstructions("You are a helpful support agent. Answer the user's "
        + "questions to the best of your ability.")
    .setTools(Collections.singletonList(azureFnTool));

AgentVersionDetails agent = agentsClient.createAgentVersion(
    "azure-function-agent-get-weather", agentDefinition);
System.out.printf("Agent created (id: %s, name: %s, version: %s)%n",
    agent.getId(), agent.getName(), agent.getVersion());

创建响应

AgentReference agentReference = new AgentReference(agent.getName())
    .setVersion(agent.getVersion());

Response response = responsesClient.createAzureResponse(
    new AzureCreateResponseOptions().setAgentReference(agentReference),
    ResponseCreateParams.builder()
        .input("What is the weather in Seattle, WA?"));

System.out.println("Response: " + response.output());

清理

agentsClient.deleteAgentVersion(agent.getName(), agent.getVersion());
System.out.println("Agent deleted");

编写 Azure 函数

前面的代码示例演示如何在代理端定义Azure函数工具。 还需要编写处理队列消息的函数。 该函数从输入队列接收输入,运行自定义逻辑,并通过输出队列返回结果。

以下示例展示了一个由队列触发的函数,用于获取某个位置的天气信息。 该函数会解析传入的消息,提取函数参数,并返回一个包含CorrelationId的响应,代理通过该响应将结果与原始请求匹配。

import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.microsoft.azure.functions.*;
import com.microsoft.azure.functions.annotation.*;

import java.util.logging.Logger;

public class GetWeather {

    // Queue trigger receives agent tool calls from the input
    // queue and returns results through the output queue
    @FunctionName("GetWeather")
    @QueueOutput(
        name = "output",
        queueName = "get-weather-output-queue",
        connection = "STORAGE_CONNECTION")
    public String run(
            @QueueTrigger(
                name = "msg",
                queueName = "get-weather-input-queue",
                connection = "STORAGE_CONNECTION")
            String message,
            final ExecutionContext context) {

        Logger logger = context.getLogger();
        logger.info("Received: " + message);

        // Parse the incoming message from the agent
        JsonObject payload =
            JsonParser.parseString(message)
                .getAsJsonObject();
        String correlationId =
            payload.get("CorrelationId").getAsString();
        JsonObject functionArgs =
            payload.getAsJsonObject("function_args");
        String location =
            functionArgs.get("location").getAsString();

        // Run your custom logic (replace with real API calls)
        String weatherResult =
            "Weather is " + location.length()
            + " degrees and sunny in " + location;

        // Return result with the CorrelationId
        JsonObject response = new JsonObject();
        response.addProperty("Value", weatherResult);
        response.addProperty(
            "CorrelationId", correlationId);
        return response.toString();
    }
}

重要

响应消息必须包含原始消息中的 CorrelationId。 代理使用此值将函数输出与正确的工具调用匹配。

安装这些包

安装 Azure AI Projects 客户端库:

npm install @azure/ai-projects @azure/identity

定义该工具并创建代理

import { AIProjectClient } from "@azure/ai-projects";
import { DefaultAzureCredential } from "@azure/identity";

// Format: "https://resource_name.ai.azure.com/api/projects/project_name"
const PROJECT_ENDPOINT = "your_project_endpoint";
const STORAGE_QUEUE_ENDPOINT = "your_storage_queue_service_endpoint";

// Create clients to call Foundry API
const project = new AIProjectClient(PROJECT_ENDPOINT, new DefaultAzureCredential());
const openai = project.getOpenAIClient();

const agent = await project.agents.createVersion(
  "azure-function-agent-get-weather",
  {
    kind: "prompt",
    model: "gpt-5.1",
    instructions:
      "You are a helpful support agent. Answer the user's questions to the best of your ability.",
    tools: [
      {
        type: "azure_function",
        azure_function: {
          function: {
            name: "GetWeather",
            description: "Get the weather in a location.",
            parameters: {
              type: "object",
              properties: {
                location: {
                  type: "string",
                  description: "The location to look up.",
                },
              },
            },
          },
          input_binding: {
            type: "storage_queue",
            storage_queue: {
              queue_service_endpoint: STORAGE_QUEUE_ENDPOINT,
              queue_name: "get-weather-input-queue",
            },
          },
          output_binding: {
            type: "storage_queue",
            storage_queue: {
              queue_service_endpoint: STORAGE_QUEUE_ENDPOINT,
              queue_name: "get-weather-output-queue",
            },
          },
        },
      },
    ],
  },
);
console.log(`Agent created (id: ${agent.id}, name: ${agent.name}, version: ${agent.version})`);

创建响应

const response = await openai.responses.create(
  {
    input: "What is the weather in Seattle, WA?",
  },
  {
    body: {
      agent: { name: agent.name, type: "agent_reference" },
    },
  },
);
console.log(`Response: ${response.output_text}`);

清理

await project.agents.deleteVersion(agent.name, agent.version);
console.log("Agent deleted");

编写 Azure 函数

前面的代码示例演示如何在代理端定义Azure函数工具。 还需要编写处理队列消息的函数。 该函数从输入队列接收输入,运行自定义逻辑,并通过输出队列返回结果。

以下示例展示了一个由队列触发的函数,用于获取某个位置的天气信息。 此示例使用 v4 编程模型。 该函数会解析传入的消息,提取函数参数,并返回一个包含CorrelationId的响应,代理通过该响应将结果与原始请求匹配。

import {
  app,
  InvocationContext,
  output,
} from "@azure/functions";

// Define the output queue binding
const queueOutput = output.storageQueue({
  queueName: "get-weather-output-queue",
  connection: "STORAGE_CONNECTION",
});

interface AgentMessage {
  CorrelationId: string;
  function_args: { location: string };
}

// Queue trigger receives agent tool calls from the input
// queue and returns results through the output queue
async function getWeather(
  message: unknown,
  context: InvocationContext
): Promise<void> {
  const payload = message as AgentMessage;
  context.log("Received:", JSON.stringify(payload));

  // Extract the function arguments
  const location = payload.function_args.location;

  // Run your custom logic (replace with real API calls)
  const weatherResult =
    `Weather is ${location.length} degrees ` +
    `and sunny in ${location}`;

  // Return result with the CorrelationId from the request
  const response = {
    Value: weatherResult,
    CorrelationId: payload.CorrelationId,
  };
  context.extraOutputs.set(queueOutput, response);
}

// Register the queue trigger function
app.storageQueue("getWeather", {
  queueName: "get-weather-input-queue",
  connection: "STORAGE_CONNECTION",
  extraOutputs: [queueOutput],
  handler: getWeather,
});

重要

响应消息必须包含原始消息中的 CorrelationId。 代理使用此值将函数输出与正确的工具调用匹配。

创建代理版本

使用 Azure 函数工具定义创建代理版本。

curl --request POST \
  --url $FOUNDRY_PROJECT_ENDPOINT/agents/azure-function-agent-get-weather/versions?api-version=$API_VERSION \
  -H "Authorization: Bearer $AGENT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "description": "Agent with Azure Function tool",
    "definition": {
      "kind": "prompt",
      "model": "gpt-5.1",
      "instructions": "You are a helpful support agent. Answer the user's questions to the best of your ability.",
      "tools": [
        { 
          "type": "azure_function",
          "azure_function": {
              "function": {
                  "name": "GetWeather",
                  "description": "Get the weather in a location.",
                  "parameters": {
                      "type": "object",
                      "properties": {
                          "location": {"type": "string", "description": "The location to look up."}
                      },
                      "required": ["location"]
                  }
              },
              "input_binding": {
                  "type": "storage_queue",
                  "storage_queue": {
                      "queue_service_endpoint": "https://storageaccount.queue.core.windows.net",
                      "queue_name": "input"
                  }
              },
              "output_binding": {
                  "type": "storage_queue",
                  "storage_queue": {
                      "queue_service_endpoint": "https://storageaccount.queue.core.windows.net",
                      "queue_name": "output"
                  }
              }
          }
        }
      ]
    }
  }'

创建响应

创建使用代理版本的响应来获取天气信息。

curl --request POST \
  --url $FOUNDRY_PROJECT_ENDPOINT/openai/responses?api-version=$API_VERSION \
  -H "Authorization: Bearer $AGENT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "input": "What is the weather in Seattle, WA?",
    "agent": {
      "name": "azure-function-agent-get-weather",
      "type": "agent_reference"
    }
  }'

编写 Azure 函数

REST API 示例演示如何配置Azure函数工具定义。 Azure函数本身是使用受支持的 Functions 语言编写的服务器端代码。 选择其他语言(Python、C#、Java或 TypeScript)以查看函数实现。

何时使用 Azure Functions 与函数调用

虽然 函数调用使你能够定义使用代理代码进行进程内运行的工具,但在需要时在 Azure Functions 上托管自定义工具可提供额外的企业功能:

  • 分离关注点:将业务逻辑与代理代码隔离,以便可以独立开发、测试和部署。
  • 集中管理:创建多个代理、应用程序或团队可以使用的可重用工具。
  • 安全隔离:将代理对工具的访问与工具对企业资源的访问分开控制。 此方法意味着你只能分配代理来调用该工具所需的特定权限,而无需提供对基础数据库、API 或网络的直接访问。
  • 外部依赖项:使用非Microsoft库、特别的运行时环境或遗留系统集成。
  • 复杂操作:处理多步骤工作流和数据转换,或卸载计算密集型操作。
  • 异步处理:使用重试功能和弹性消息处理执行长时间运行的操作。

集成选项

Foundry 代理服务为代理提供两种主要方法来访问Azure Functions托管的工具:

功能 模型上下文协议 (MCP) 服务器 Azure基于队列存储的工具
它的工作原理是什么? 代理使用 MCP 协议连接到Azure中的函数应用。 函数应用本身充当自定义 MCP 服务器,将单个函数公开为工具。 自定义 MCP 服务器从代理项目中抽象化托管和公开工具的复杂性,并提升代码的可重用性。 在 Azure 的函数应用中,代理通过将消息放入队列存储,与工具代码进行通信,从而触发工具代码的执行。 函数应用侦听输入队列,异步处理消息,并返回对第二个队列的响应。
何时使用它? ✔ 最适合利用行业标准协议进行代理工具集成。
✔ 提供实时同步交互,并即时响应。
✔ 最适合不需要实时响应的异步工作流。
✔ 非常适合使用重试功能进行后台处理和可靠的消息传递。
SDK 配置 通用 MCP 工具 具体(请参阅上面的 代码示例
入门 如何在 MCP 中使用Azure Functions 请参阅上面的 代码示例

对于 HTTP 触发器函数,还可以通过在代理配置中使用 OpenAPI 工具 将函数描述为可调用的工具并将其注册为可调用工具,从而集成。 此方法为现有的基于 HTTP 的函数提供了灵活性,但它需要额外的设置来定义 API 规范。

支持的模型

若要使用函数调用的所有功能(包括并行函数),请使用在 2023 年 11 月 6 日之后发布的模型。

创建和部署基于队列的工具集成示例

若要使用 Azure Developer CLI (azd) 示例,该示例使用 Functions 配置代理以支持代理的基于队列的工具集成,请执行以下步骤:

注意

有关如何将基于 Functions 的工具定义并承载为 MCP 服务器的详细说明,请参阅在 Azure Functions 中托管 MCP 服务器

初始化项目模板

此项目使用 azd 简化创建Azure资源和部署代码。 此部署遵循当前安全且可缩放的 Functions 部署的最佳做法。 可以在 GitHub 上找到此处使用的模板和代码。

  1. azd init在终端窗口中运行以下命令,从 azd 模板初始化项目:

    azd init --template azure-functions-ai-services-agent-python
    

出现提示时,请提供环境名称,例如 ai-services-agent-python。 在 azd 中,环境为你的应用维护一个独特的部署上下文,你可以定义多个。 环境名称还用于资源组的名称和在Azure中创建的其他资源。

  1. 运行以下命令以允许本地安装脚本成功运行,具体取决于本地操作系统:

    chmod +x ./infra/scripts/*.sh 
    

配置资源

运行 azd provision 命令,在Azure中创建所需的资源:

azd provision

出现提示时,请提供以下所需的部署参数:

提示 描述
选择要使用的 Azure 订阅 请选择要用于创建资源的订阅。
位置 部署参数 Azure区域以创建包含新Azure资源的资源组。 仅显示当前支持 Flex 消耗计划的区域。
vnetEnabled 部署参数 虽然模板支持在虚拟网络中创建资源,但选择 False 简化部署和测试。

azd读取 main.bicep 部署文件,并使用它在Azure中创建这些资源:

  • Flex 消耗计划和函数应用
  • Foundry 中的代理平台,包括:
    • 服务帐户
    • 模型部署
    • 项目
    • 代理
    • 搜寻
    • Azure Cosmos DB 帐户(供搜索使用)
  • Azure 存储(Azure Functions 和 AI 代理需要)和 Application Insights(推荐)
  • 帐户访问策略和角色
  • 使用托管标识的服务到服务连接(而不是使用存储的连接字符串)

预配后脚本还会创建一个本地运行所需的 local.settings.json 文件,这对于 Functions 来说是必须的。 生成的文件应如下所示:

{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "UseDevelopmentStorage=true",
    "FUNCTIONS_WORKER_RUNTIME": "python",
    "STORAGE_CONNECTION__queueServiceUri": "https://<storageaccount>.queue.core.windows.net",
    "PROJECT_CONNECTION_STRING": "<project connnection for AI Project>"
    }
}

在 Visual Studio Code 中运行应用

  1. 在新终端中打开文件夹。
  2. 运行 code . 命令以在 Visual Studio Code 中打开项目。
  3. 在命令面板(F1)中,键入 Azurite: Start。 此操作允许使用 Functions 运行时的本地存储进行调试。
  4. Run/Debug (F5) 运行调试器。 如果系统提示本地模拟器未运行,请选择仍然调试
  5. 使用 HTTP 测试工具分别向 prompt 终结点发送 POST 请求。 如果已安装 RestClient 扩展,可以直接从 test.http 项目文件执行请求。

部署到 Azure 云服务

运行此 azd deploy 命令,将项目代码发布到刚刚预配的函数应用和相关Azure资源:

azd deploy

成功完成发布后,azd 会提供新函数的 URL 终结点,但不包括访问终结点所需的函数键值。 可以将 Azure Functions Core Tools 命令 func azure functionapp list-functions--show-keys 选项一起使用,以获取函数终结点的密钥。 有关详细信息,请参阅 在 Azure Functions 中使用访问密钥。

重新部署代码

根据需要多次运行 azd up 命令,以便预配Azure资源并将代码更新部署到函数应用。

注意

最新发布的部署包始终覆盖已部署的代码文件。

清理资源

使用完函数应用和相关资源后,请使用此命令从Azure中删除函数应用及其相关资源,并避免产生任何进一步的成本。 --purge 选项不会对 AI 资源进行软删除并恢复你的配额:

azd down --purge