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

将 Microsoft Agent Framework 智能体托管为 Foundry 托管智能体

使用 Microsoft Agent Framework 托管包,使 Agent Framework 代理能够通过适用于 Foundry 托管代理的协议进行公开。 托管套餐让你能够将代理逻辑保留在代码中,而由 Foundry 负责管理托管运行时、会话、扩缩容、身份管理和协议端点。

在本文中,你将创建一个最小的 Agent Framework 代理,通过响应或调用协议公开它,通过 HTTP 对其进行测试,并使用Azure开发人员 CLI 将其部署到 Foundry。

先决条件

  • 一份 Azure 订阅。 免费创建一个
  • Foundry 项目
  • 已部署的聊天模型,例如 gpt-4.1gpt-4o
  • 项目上的 Foundry 项目经理角色,用于部署托管智能体。 有关详细信息,请参阅 部署托管代理
  • Azure CLI登录(az login),以便DefaultAzureCredential进行身份验证。
  • Python 3.10 或更高版本。
  • .NET 10 SDK 或更高版本。

安装软件包

安装 Agent Framework 和 Foundry 托管包:

pip install -U agent-framework agent-framework-foundry-hosting azure-identity python-dotenv

agent_framework_foundry_hosting 包为 Foundry 协议提供主机服务器:

  • ResponsesHostServer 用于与 OpenAI 兼容的 /responses 端点。
  • InvocationsHostServer 用于通用 /invocations 端点。

将 Agent Framework 和 Foundry 托管包添加到项目:

dotnet add package Microsoft.Agents.AI
dotnet add package Microsoft.Agents.AI.Foundry.Hosting
dotnet add package Azure.AI.Projects
dotnet add package Azure.Identity

对于 Invocations 协议,还需添加 Invocations 服务器包:

dotnet add package Azure.AI.AgentServer.Invocations

这些包为 Foundry 协议提供主机扩展:

  • AddFoundryResponses 以及 MapFoundryResponses 用于 OpenAI 兼容的 /responses 终结点。
  • AddInvocationsServer 以及 MapInvocationsServer 用于泛型 /invocations 终结点。

选择托管协议

托管代理可以公开一个或多个协议。 从大多数会话代理的响应开始。

Protocol Endpoint 何时使用
Responses /responses 你需要兼容 OpenAI 的聊天、流式输出、响应历史和对话线程功能。
调用 /invocations 需要自定义 JSON 形状、Webhook 样式的终结点或非对话处理。

有关协议行为和会话的背景信息,请参阅 托管代理 和管理 托管代理会话

配置环境变量

设置用于本地开发的项目终结点和模型部署名称:

export FOUNDRY_PROJECT_ENDPOINT="https://<resource>.services.ai.azure.com/api/projects/<project>"
export AZURE_AI_MODEL_DEPLOYMENT_NAME="gpt-4.1"

在 PowerShell 中:

$env:FOUNDRY_PROJECT_ENDPOINT="https://<resource>.services.ai.azure.com/api/projects/<project>"
$env:AZURE_AI_MODEL_DEPLOYMENT_NAME="gpt-4.1"

当同一代码在 Foundry 中作为托管代理运行时,平台会在运行时注入 FOUNDRY_PROJECT_ENDPOINTAZURE_AI_MODEL_DEPLOYMENT_NAME

响应协议

当你需要一个与 OpenAI 兼容的聊天端点,并且支持流式传输、响应历史记录和对话线程时,请使用 Responses 协议。

创建响应主机

创建一个名为 main.py 的文件,其中包含一个使用 Foundry 模型的最简 Agent Framework 代理。

import os

from agent_framework import Agent
from agent_framework.foundry import FoundryChatClient
from agent_framework_foundry_hosting import ResponsesHostServer
from azure.identity import DefaultAzureCredential
from dotenv import load_dotenv

# Load environment variables from a .env file when present.
load_dotenv()


def main() -> None:
    client = FoundryChatClient(
        project_endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"],
        model=os.environ["AZURE_AI_MODEL_DEPLOYMENT_NAME"],
        credential=DefaultAzureCredential(),
    )

    agent = Agent(
        client=client,
        instructions="You are a friendly assistant. Keep your answers brief.",
        # The hosting infrastructure manages conversation history, so the
        # service doesn't need to store it.
        default_options={"store": False},
    )

    server = ResponsesHostServer(agent)
    server.run()


if __name__ == "__main__":
    main()

此代码片段的作用: 通过 FoundryChatClient 创建一个以 Foundry 模型为后端的 Agent Framework 代理,然后将该代理传递给 ResponsesHostServer。 主机启动 HTTP 服务器,并通过 POST /responses公开该代理。 默认情况下,服务器绑定到端口 8088

参考:Microsoft Agent Framework 文档

在本地运行应用:

python main.py

创建一个 Program.cs 文件,其中包含一个最小化的 Agent Framework 代理,该代理通过 Responses 协议使用 Foundry 模型。

using Azure.AI.Projects;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Agents.AI.Foundry.Hosting;

var projectEndpoint = new Uri(
    Environment.GetEnvironmentVariable("FOUNDRY_PROJECT_ENDPOINT")
    ?? throw new InvalidOperationException("FOUNDRY_PROJECT_ENDPOINT is not set."));

var deployment =
    Environment.GetEnvironmentVariable("AZURE_AI_MODEL_DEPLOYMENT_NAME")
    ?? "gpt-4o";

// Create the agent via the AI project client using the Responses API.
AIAgent agent = new AIProjectClient(projectEndpoint, new DefaultAzureCredential())
    .AsAIAgent(
        model: deployment,
        instructions: "You are a friendly assistant. Keep your answers brief.",
        name: "assistant",
        description: "A simple general-purpose AI assistant");

// Host the agent as a Foundry hosted agent using the Responses API.
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddFoundryResponses(agent);

var app = builder.Build();
app.MapFoundryResponses();
app.Run();

此代码片段的作用:从 Foundry 项目客户端创建AIAgent,使用AddFoundryResponses将其注册为 Foundry Responses 主机,并使用MapFoundryResponses映射POST /responses终结点。 默认情况下,主机在端口 8088上提供服务。

参考: AIProjectClient | DefaultAzureCredential

在本地运行应用:

dotnet run

测试响应终结点

将非流式处理响应请求发送到本地服务器。

Bash:

curl -sS -H "Content-Type: application/json" \
  -X POST http://localhost:8088/responses \
  -d '{"input":"Give me one practical tip for testing hosted agents.","stream":false}'

PowerShell

$body = @{
  input  = "Give me one practical tip for testing hosted agents."
  stream = $false
} | ConvertTo-Json

Invoke-RestMethod `
    -Uri http://localhost:8088/responses `
    -Method Post `
    -Body $body `
    -ContentType "application/json"

服务器使用包含响应文本和响应 ID 的 JSON 对象进行响应。 对于流式响应,将 stream 设置为 true。 主机发出响应 API 服务器发送的事件,例如 response.createdresponse.output_text.deltaresponse.completed

多轮次对话

若要继续对话,请在下一个请求的 previous_response_id 字段中传入上一个响应 ID:

curl -sS -H "Content-Type: application/json" \
  -X POST http://localhost:8088/responses \
  -d '{"input":"Can you make that more concise?","previous_response_id":"<previous-response-id>","stream":false}'

在 Foundry 中运行代理时,同一模式通过托管代理响应终结点工作。 如果后续轮次也需要相同的托管沙盒文件系统,请包含 agent_session_id 或使用 conversation ID。 有关详细信息,请参阅 管理托管代理会话

调用协议

当调用方无法使用 Responses API 的请求格式,或者你的场景不是聊天对话时,请使用 Invocations 协议。 调用主机通过 agent_session_id 查询参数和响应标头管理会话状态。

创建 Invocations 主机

使用与 Responses 示例相同的代理设置,但启动 InvocationsHostServer 而不是 ResponsesHostServer

import os

from agent_framework import Agent
from agent_framework.foundry import FoundryChatClient
from agent_framework_foundry_hosting import InvocationsHostServer
from azure.identity import DefaultAzureCredential
from dotenv import load_dotenv

# Load environment variables from a .env file when present.
load_dotenv()


def main() -> None:
    client = FoundryChatClient(
        project_endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"],
        model=os.environ["AZURE_AI_MODEL_DEPLOYMENT_NAME"],
        credential=DefaultAzureCredential(),
    )

    agent = Agent(
        client=client,
        instructions="You are a friendly assistant. Keep your answers brief.",
        default_options={"store": False},
    )

    server = InvocationsHostServer(agent)
    server.run()


if __name__ == "__main__":
    main()

此代码片段的作用: 通过 POST /invocations. 承载 Agent Framework 代理。 主机通过 agent_session_id 查询参数和响应标头管理每会话状态。

参考:Microsoft Agent Framework 文档

Invocations 协议使用由你实现的 InvocationHandler 来处理每个请求。 注册调用服务器和处理程序,然后映射终结点。

using Azure.AI.AgentServer.Invocations;
using Microsoft.Agents.AI;

var builder = WebApplication.CreateBuilder(args);

// Register your agent and the Invocations server services.
builder.Services.AddInvocationsServer();
builder.Services.AddScoped<InvocationHandler, MyInvocationHandler>();

var app = builder.Build();

// Map the Invocations protocol endpoints:
//   POST /invocations              - invoke the agent
//   GET  /invocations/{id}         - get result
//   POST /invocations/{id}/cancel  - cancel
app.MapInvocationsServer();
app.Run();

此代码片段的作用: 注册调用服务器服务和 InvocationHandler 实现,然后映射 /invocations 终结点。 你可以实现MyInvocationHandler,以定义如何处理每个请求。 有关完整的处理程序示例,请参阅.NET调用示例

参考: AddInvocationsServer

测试调用端点

将请求发送到本地服务器:

curl -sS -X POST http://localhost:8088/invocations \
  -H "Content-Type: application/json" \
  -d '{"message":"My name is Alice.","stream":false}'

对于多轮次对话,请在下一个请求中重复使用 agent_session_id 响应标头中的值作为 agent_session_id 查询参数:

curl -sS -X POST "http://localhost:8088/invocations?agent_session_id=<session-id>" \
  -H "Content-Type: application/json" \
  -d '{"message":"What is my name?"}'

平台不会存储调用协议的对话历史记录。 使用 agent_session_id 查询参数将后续调用路由至同一个托管沙盒。

部署

使用Azure开发人员 CLI (azd) 进行部署。 该流使用示例清单和 Docker 生成代理容器映像,并将其推出到 Foundry 托管的代理运行时。

托管智能体部署需要在项目上具有 Foundry 项目管理员角色。 有关详细信息,请参阅 部署托管代理

安装 Azure Developer CLI 扩展

在初始化示例之前安装 AI 代理扩展并登录:

azd ext install azure.ai.agents
azd auth login

Docker 必须在本地运行,因为 azd ai agent run 生成在示例的 Dockerfile 中声明的容器映像。 有关命令详细信息,请参阅 Azure 开发人员 CLI 参考

从示例清单初始化

创建新文件夹,并从示例清单初始化它。 将清单 URL 替换为要使用的示例。

mkdir my-agent-framework-agent
cd my-agent-framework-agent

azd ai agent init -m https://github.com/microsoft/agent-framework/blob/main/python/samples/04-hosting/foundry-hosted-agents/responses/01_basic/agent.manifest.yaml
mkdir my-agent-framework-agent
cd my-agent-framework-agent

azd ai agent init -m https://github.com/microsoft/agent-framework/blob/main/dotnet/samples/04-hosting/FoundryHostedAgents/responses/Hosted-ChatClientAgent/agent.manifest.yaml

按照 azd ai agent init 的提示操作。 如果还没有 Foundry 项目和模型部署,初始化流可以指导你创建它们。

预配 Azure 资源

如果初始化的项目使用新的 Foundry 项目和模型部署,请先预配Azure资源:

azd provision

此命令将创建一个资源组,其中包含其他资源:Foundry 实例、具有模型部署的 Foundry 项目、Application Insights 实例和托管代理映像的容器注册表。

在本地运行容器

通过 azd以下方法在本地运行代理主机:

azd ai agent run

主机在 http://localhost:8088 上提供服务。 在另一个终端中,调用本地协议终结点:

azd ai agent invoke --local "Hello!"

您还可以使用 curl 直接调用该端点:

curl -X POST http://localhost:8088/responses \
  -H "Content-Type: application/json" \
  -d '{"input": "Hello!"}'

部署到 Foundry

部署代理:

azd deploy

部署将代理打包到容器映像中,将其推送到预配的容器注册表,并将其推出到 Foundry 托管代理运行时。

Foundry 托管基础结构将运行时环境变量注入代理,包括:

  • FOUNDRY_PROJECT_ENDPOINT:部署代理的 Foundry 项目的终结点 URL。
  • AZURE_AI_MODEL_DEPLOYMENT_NAME:在azd ai agent init过程中选择的模型部署名称。
  • APPLICATIONINSIGHTS_CONNECTION_STRING:项目的 Application Insights 实例的连接字符串。

有关完整的部署概念、权限和管理详细信息,请参阅 部署托管代理 和管理 托管代理生命周期

Troubleshooting

使用此清单诊断使用 Agent Framework 开发托管代理时的常见问题。

无法在托管容器中访问模型

确认托管代理版本包括 AZURE_AI_MODEL_DEPLOYMENT_NAME,并且代理标识有权调用 Foundry 项目。 平台设置 FOUNDRY_PROJECT_ENDPOINT;代码应在 Foundry 中运行时读取该变量。

对话状态不延续。

对于 Responses 协议,在后续轮次中传入 previous_response_idconversation ID。

对于调用协议,平台不会存储对话历史记录。 使用 agent_session_id 查询参数将后续调用路由到同一个托管沙盒。

协议版本不匹配

如果在升级后请求失败,请确认清单和托管包都使用协议版本 2.0.0。 协议版本 1.0.0 和 2.0.0 不兼容。

后续步骤