Hosted agents 在 Foundry Agent Service 中Microsoft允許您將 Agent Framework 代理部署為容器化應用程式,部署至 Microsoft 管理的基礎設施。 該平台處理擴展性、會話狀態持久性、安全性與生命週期管理,讓您能專注於代理程式的邏輯。 Microsoft Foundry 託管代理程式已普遍提供。
透過 Agent Framework 的託管整合,你只需少量程式碼,即可透過 Foundry Responses 或 Invocations 通訊協定公開 Agent,其中包括以 Workflow.as_agent() 包裝的工作流程。
何時使用託管代理
選擇 Foundry 託管代理,當您希望達成以下目的時:
- 託管基礎設施 ——無需自行配置容器、網頁伺服器或擴展規則。
-
內建會話管理 — 平台能
$HOME在回合與閒置期間持續存檔並上傳檔案。 - 專用代理身份 — 每個部署的代理都會擁有自己的 Entra 身份,以確保對模型、工具及下游服務的安全存取。
- OpenAI 相容端點 — 客戶端可透過 Responses 協議,使用任何 OpenAI 相容 SDK 與您的客服人員互動。
備註
Python agent-framework-foundry-hosting 整合目前是預發布狀態。 Microsoft Foundry 託管代理服務,作為託管主機服務,已普遍提供。
Prerequisites
- Azure 訂用帳戶
-
Azure 開發者 CLI(
azd) 搭配 AI 代理擴充功能:azd ext install azure.ai.agents
本地測試,你還需要:
- 一個Microsoft Foundry專案,包含模型部署(例如
gpt-4o) - 已安裝並驗證 Azure CLI (
az login)
- .NET 10 SDK 或更新版本
安裝主機 NuGet 套件:
dotnet add package Microsoft.Agents.AI.Foundry.Hosting --prerelease
dotnet add package Azure.AI.Projects --prerelease
- Python 3.10 或更新版本
安裝預發布的主機套件、Foundry 客戶端和 Azure 認證套件:
pip install --pre agent-framework-foundry agent-framework-foundry-hosting azure-identity
在 Foundry 中,平台提供呼叫者的使用者上下文與通話上下文;主機基礎設施利用這些工具來隔離每位使用者的狀態,並將請求上下文轉發給 Foundry 服務。 在本機執行時不會收到該平台的情境資訊,因此應用程式必須在需要時自行提供身分識別與狀態控管機制。
回應協定
回應協議是大多數代理人的推薦起點。 它提供一個相容 /responses OpenAI 的端點,平台自動管理對話歷史、串流和會話生命週期。
using Azure.AI.AgentServer.Core;
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";
AIAgent agent = new AIProjectClient(projectEndpoint, new DefaultAzureCredential())
.AsAIAgent(
model: deployment,
instructions: "You are a helpful AI assistant.",
name: "my-agent");
var builder = AgentHost.CreateBuilder(args);
builder.Services.AddFoundryResponses(agent);
builder.RegisterProtocol("responses", endpoints => endpoints.MapFoundryResponses());
var app = builder.Build();
app.Run();
AgentHost.CreateBuilder會為 Foundry 主機環境預先設定一個應用程式主機。
AddFoundryResponses會將您的代理程式註冊到 Responses 協定處理器,並MapFoundryResponses/responses映射 HTTP 端點。
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
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 helpful AI assistant.",
)
server = ResponsesHostServer(agent)
server.run()
ResponsesHostServer 包裹你的代理,並透過 Foundry Responses 協定將其公開。 對於非工作流程代理,預設 history_source="agent_server" 會使用已設定的代理伺服器回應提供者作為模型的歷史來源。 當客戶端預設儲存歷史時,主機會阻止下游模型服務保留第二個副本。
不要將預設歷程來源與帶有 load_messages=True 的 HistoryProvider 結合。 也不要設定 conversation_id、 或 previous_response_idconversation 下游服務延續選項。 主機會拒絕這些設定,以避免產生重複的歷程記錄。
當客服人員的歷史提供者或下游模型服務必須管理通話歷史時,請使用 ResponsesHostServer(agent, history_source="agent") 。 此模式僅傳遞來自代理伺服器的當前請求輸入,並保留代理的歷史與服務儲存行為。 自訂 SupportsAgentRun 實作必須使用此模式。
store參數保持獨立:它選擇能在兩種模式下持續執行回應 API 輸入與輸出的回應提供者。
主機擁有所提供的代理,並可能新增主機專用的上下文提供者。 不要在其他主機重複使用代理,或是在主機建置後直接呼叫。
持續狀態並處理長時間對話
ResponsesHostServer 預設會設定以 Foundry 為後端的存放區。 對於非工作流程代理程式,AgentSessionStoreProvider 會提供 FoundryAgentSessionStore。 對工作流程代理而言,CheckpointStoreProvider 提供了一個 FoundryCheckpointStore。
FunctionApprovalStoreProvider 提供用於待核准項目的 FoundryFunctionApprovalStore。 這些存放區在託管環境中會使用 Foundry State Store,而在本機執行時則會使用本機 Agent Server 狀態。
使用 history_source="agent" 時,已設定的工作階段儲存區會持久保存由 AgentSession 攜帶的提供者狀態,包括來自 InMemoryHistoryProvider 的訊息。
若要自訂儲存空間,請傳遞 a StoreProvider 到 agent_session_store_provider 或 function_approval_store_provider。 將 ContextScopedStoreProvider 傳遞給 checkpoint_store_provider。 例如,實作 SessionStore 和 StoreProvider[SessionStore],以使用你自己的非工作流程代理程式工作階段儲存區。
從 azure.ai.agentserver.responses 匯入 ResponsesServerOptions,並透過 ResponsesHostServer 參數將其傳遞給 options。 可用的長時間對話選項依代理類型而異:
| 能力 | 代理人類型 | 需求與行為 |
|---|---|---|
| 具韌性的背景回應 | 僅工作流程 | 設定 ResponsesServerOptions(resilient_background=True)。 請傳送含有 store=true 和 background=true 的 Responses 要求。 重新啟動後,主機會繼續執行最新的持久性工作流程檢查點;如果沒有檢查點,則會重新播放原始輸入。 不要在工作流程中設定檢查點儲存體,因為這是由主機管理的。 請確保外部副作用具備冪等性,因為最後一個持久性檢查點之後的工作可能會被重複執行。 |
| 可引導的對話 | 僅適用於非工作流程 | 設定 ResponsesServerOptions(steerable_conversations=True),並使用 store=true 傳送 Responses 請求。 透過重複使用相同的 conversation 值,讓各輪次維持在同一條線性鏈中。 或者,傳送緊接在前的 previous_response_id,並保留已解析的 agent_session_id。 主機拒絕那些會造成分支的陳舊前任。 |
ResponsesHostServer 會引發 RuntimeError,如果您為非工作流程代理程式啟用韌性背景回應,或為工作流程代理程式啟用可引導式對話。 完整實作請參閱 自訂儲存、 韌性長期執行工作流程,以及 可導引的長期執行代理 樣本。
處理 OAuth 同意申請
當 Foundry 託管的 MCP 工具需要使用者同意時,會 ResponsesHostServer 回傳一個不完整的回應並附帶 oauth_consent_request 輸出項目。 先把它 consent_link 呈現給使用者,然後在使用者完成同意後繼續使用不完整的回應的 ID previous_response_id 。 主機會保留代理會話以供此重試使用,並只公開絕對的 HTTPS 同意連結。
呼叫協定
Invocations 協定讓你能完全控制 HTTP 請求與回應。 當你需要自訂有效載荷、非對話式處理,或是不支援 OpenAI 的串流協定時,才會使用它。
使用 C# 中的 Invocations 協定,您可以實現一個自訂 InvocationHandler 来處理來的請求:
using Azure.AI.AgentServer.Core;
using Azure.AI.AgentServer.Invocations;
using Microsoft.Agents.AI;
var builder = AgentHost.CreateBuilder(args);
builder.Services.AddSingleton<AIAgent, MyAgent>();
builder.Services.AddInvocationsServer();
builder.Services.AddScoped<InvocationHandler, MyInvocationHandler>();
builder.RegisterProtocol("invocations", endpoints => endpoints.MapInvocationsServer());
var app = builder.Build();
app.Run();
此 AddInvocationsServer 方法會註冊呼叫協定服務。 你實作 InvocationHandler 來定義代理如何處理每個請求。
想要輕量化的配置,請使用 InvocationsHostServer 套件中的 agent_framework_foundry_hosting。 它會將您的代理類似於 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
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()
為了完全控制請求處理,請直接使用來自InvocationAgentServerHost套件的azure.ai.agentserver.invocations,並實作您自己的呼叫處理器:
import os
from collections.abc import AsyncGenerator
from agent_framework import Agent, AgentSession
from agent_framework.foundry import FoundryChatClient
from azure.ai.agentserver.invocations import InvocationAgentServerHost
from azure.identity import DefaultAzureCredential
from starlette.requests import Request
from starlette.responses import JSONResponse, Response, StreamingResponse
_sessions: dict[str, AgentSession] = {}
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},
)
app = InvocationAgentServerHost()
@app.invoke_handler
async def handle_invoke(request: Request):
"""Handle streaming multi-turn chat."""
data = await request.json()
session_id = request.state.session_id
stream = data.get("stream", False)
user_message = data.get("message", None)
if user_message is None:
return Response(content="Missing 'message' in request", status_code=400)
session = _sessions.setdefault(session_id, AgentSession(session_id=session_id))
if stream:
async def stream_response() -> AsyncGenerator[str]:
async for update in agent.run(user_message, session=session, stream=True):
yield update.text
return StreamingResponse(
stream_response(),
media_type="text/event-stream",
headers={"Cache-Control": "no-cache", "Connection": "keep-alive"},
)
response = await agent.run([user_message], session=session, stream=stream)
return JSONResponse({"response": response.text})
if __name__ == "__main__":
app.run()
Warning
自訂處理器範例中的記憶體會話儲存會在重新啟動時遺失。 在生產環境中使用耐用儲存(例如 Cosmos DB)。
完整的 Invocations 部署,請參閱 Foundry 託管的 Telegram 範例。 它將 API 管理置於託管代理 webhook 前方,並使用受管理身份、金鑰保存庫 與 Cosmos DB 來保存持久的對話歷史。
備註
Go 對 Foundry 託管代理的支援即將推出。 最新狀態請參閱 Agent Framework Go 倉庫 。
Tip
參考 Python 樣本 或 C# 樣本 以了解託管代理專案的範例。 或者用這個 azd ai agent init 指令從零開始搭建新的託管代理專案。 請參閱這份 快速入門指南 ,了解逐步說明。
在本機執行
Azure 開發者 CLI(azd)提供了最簡單的本地運行與測試主機代理的方式。
初始化專案
建立一個新資料夾,並從範例清單初始化:
mkdir my-hosted-agent && cd my-hosted-agent
azd ai agent init -m <path-to-agent.manifest.yaml>
Tip
清單可以是本地 YAML 檔案的路徑,或是遠端清單的 URL。
設定環境變數
export FOUNDRY_PROJECT_ENDPOINT="https://<account>.services.ai.azure.com/api/projects/<project>"
export AZURE_AI_MODEL_DEPLOYMENT_NAME="<your-model-deployment>"
執行代理主機
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!"}'
或者用 PowerShell 來做:
(Invoke-WebRequest -Uri http://localhost:8088/responses -Method POST -ContentType "application/json" -Body '{"input": "Hello!"}').Content
部署至鑄造廠
一旦你在本地驗證了代理程式,就部署到 Microsoft Foundry:
資源配置 (如果你還沒有 Foundry 專案):
azd provision這會建立一個資源群組,包含 Foundry 實例、專案、模型部署、應用洞察以及容器登錄檔。
部署代理:
azd deploy這會將你的代理程式打包成容器映像,推送到 Azure Container Registry,然後部署到 Foundry Agent Service。
Foundry 的主機架構會在執行時自動將以下環境變數注入你的代理容器:
| Variable | 說明 |
|---|---|
FOUNDRY_PROJECT_ENDPOINT |
Foundry 專案的端點網址。 |
AZURE_AI_MODEL_DEPLOYMENT_NAME |
模型部署名稱(在 azd ai agent init 設定時配置)。 |
APPLICATIONINSIGHTS_CONNECTION_STRING |
Application Insights 的遙測連線字串。 |
部署完成後,代理程式可透過其專用的 Foundry 端點存取,並可從 Foundry 入口網站進行測試。