你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
使用 Microsoft Agent Framework 托管包,使 Agent Framework 代理能够通过适用于 Foundry 托管代理的协议进行公开。 托管套餐让你能够将代理逻辑保留在代码中,而由 Foundry 负责管理托管运行时、会话、扩缩容、身份管理和协议端点。
在本文中,你将创建一个最小的 Agent Framework 代理,通过响应或调用协议公开它,通过 HTTP 对其进行测试,并使用Azure开发人员 CLI 将其部署到 Foundry。
先决条件
- 一份 Azure 订阅。 免费创建一个。
- Foundry 项目。
- 已部署的聊天模型,例如
gpt-4.1或gpt-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_ENDPOINT 和 AZURE_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.created, response.output_text.delta和 response.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 查询参数和响应标头管理每会话状态。
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调用示例。
测试调用端点
将请求发送到本地服务器:
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_id 或 conversation ID。
对于调用协议,平台不会存储对话历史记录。
使用 agent_session_id 查询参数将后续调用路由到同一个托管沙盒。
协议版本不匹配
如果在升级后请求失败,请确认清单和托管包都使用协议版本 2.0.0。 协议版本 1.0.0 和 2.0.0 不兼容。