Агенты, размещенные на платформе Foundry

Hosted agents в службе агентов Microsoft Foundry позволяют развертывать агентов Agent Framework в качестве контейнерных приложений на инфраструктуре, управляемой Microsoft. Платформа обрабатывает масштабирование, сохраняемость состояния сеанса, безопасность и управление жизненным циклом, чтобы сосредоточиться на логике агента. Microsoft Foundry Hosted Agents стали общедоступны.

Благодаря интеграции размещения в Agent Framework вы можете предоставить Agent, в том числе рабочий процесс, обернутый в Workflow.as_agent(), через протокол Foundry Responses или Invocations, написав минимальный объем кода.

Когда следует использовать размещенные агенты

Выберите размещенные агенты Foundry, если требуется:

  • Управляемая инфраструктура — не нужно настраивать контейнеры, веб-серверы или правила масштабирования самостоятельно.
  • Встроенное управление сеансами — платформа сохраняет и загруженные файлы между циклами взаимодействия и в периодах простоя.
  • Удостоверение выделенного агента — каждый развернутый агент получает собственное удостоверение Entra для безопасного доступа к моделям, средствам и подчиненным службам.
  • Конечные точки, совместимые с OpenAI , — клиенты могут взаимодействовать с агентом с помощью любого пакета SDK, совместимого с OpenAI, через протокол Responses.

Замечание

Интеграция Python agent-framework-foundry-hosting находится в предварительной версии. Размещённые агенты Microsoft Foundry, сервис управляемого хостинга, стали общедоступными.

Prerequisites

  • подписка Azure
  • Интерфейс командной строки разработчика Azure (azd) с расширением для агента ИИ:

Для локального тестирования также требуется:

Установите пакет 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 является рекомендуемой отправной точкой для большинства агентов. Она предоставляет конечную точку, совместимую /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" использует настроенный поставщик ответов Agent Server в качестве источника истории модели. Хост не позволяет нисходящему сервису модели сохранять вторую копию, когда клиент по умолчанию хранит историю.

Не объединяйте источник журнала по умолчанию с HistoryProvider, у которого есть load_messages=True. Кроме того, не задавайте параметры продолжения для нисходящего сервиса conversation_id, previous_response_id или conversation. Хост отклоняет эти конфигурации, чтобы предотвратить дублирование истории.

Используйте ResponsesHostServer(agent, history_source="agent"), когда поставщик истории агента или нижележащая служба модели должны управлять историей беседы. Этот режим передает только текущие входные данные запроса с сервера агента и сохраняет журнал агента и поведение хранилища служб. Пользовательские SupportsAgentRun реализации должны использовать этот режим. Параметр store остаётся отдельным: он выбирает поставщика ответов, который сохраняет входные и выходные данные Responses API в обоих режимах.

Хост является владельцем предоставленного агента и может добавлять поставщиков контекста, специфичных для хостинга. Не используйте агент повторно с другим хостом и не вызывайте его напрямую после создания хоста.

Сохранять состояние и обрабатывать длительные диалоги

ResponsesHostServer настраивает хранилища с поддержкой Foundry по умолчанию. Для агентов, не относящихся к рабочим процессам, AgentSessionStoreProvider предоставляет FoundryAgentSessionStore. Для агентов рабочего процесса CheckpointStoreProvider предоставляет FoundryCheckpointStore. FunctionApprovalStoreProvider предоставляет FoundryFunctionApprovalStore для ожидающих утверждения. Эти хранилища используют Foundry State Store при размещении в облаке, а при локальном запуске — локальное состояние сервера агента.

С history_source="agent" настроенное хранилище сеансов сохраняет состояние провайдера, передаваемое через AgentSession, включая сообщения из InMemoryHistoryProvider.

Чтобы настроить хранилище, передайте StoreProvider в agent_session_store_provider или function_approval_store_provider. Передайте ContextScopedStoreProvider в checkpoint_store_provider. Например, реализуйте SessionStore и StoreProvider[SessionStore] так, чтобы использовать собственное хранилище сеансов агента, не связанное с рабочим процессом.

Импортируйте azure.ai.agentserver.responses из ResponsesServerOptions и передайте его в options через параметр ResponsesHostServer. Доступные варианты длительных диалогов зависят от типа агента:

Функциональность Тип агента Требования и поведение
Устойчивые фоновые ответы Только рабочий процесс Задайте ResponsesServerOptions(resilient_background=True). Отправьте запрос Responses с store=true и background=true. После перезапуска хост возобновляет выполнение с последней контрольной точки отказоустойчивого рабочего процесса или повторно воспроизводит исходные входные данные, если контрольная точка отсутствует. Не настраивайте хранилище контрольных точек в рабочем процессе, так как хост управляет им. Сделайте внешние побочные эффекты идемпотентными, так как выполненная после последней сохранённой контрольной точки работа может быть повторена.
Управляемые беседы Только нерабочие процессы Задайте ResponsesServerOptions(steerable_conversations=True) и отправляйте запросы Responses с помощью store=true. Сохраняйте ходы в одной линейной цепочке, повторно используя одно и то же значение conversation. В качестве альтернативы отправьте непосредственно предшествующее previous_response_id и сохраните разрешённое agent_session_id. Хост отклоняет устаревшие предшественники, которые привели бы к форку.

ResponsesHostServer выдает RuntimeError, если включены устойчивые фоновые ответы для агента, не относящегося к рабочему процессу, или управляемые беседы для агента рабочего процесса. См. полные реализации в примерах пользовательского хранилища, отказоустойчивого длительно выполняющегося рабочего процесса и управляемого длительно работающего агента.

Если для средства MCP, размещенного в Foundry, требуется согласие пользователя, ResponsesHostServer возвращает неполный ответ с выходным элементом oauth_consent_request . Покажите пользователю его consent_link, а затем используйте идентификатор неполного ответа в качестве previous_response_id после того, как пользователь даст согласие. Хост сохраняет сеанс агента при этой повторной попытке и предоставляет только абсолютные HTTPS-ссылки для согласия.

Протокол вызовов

Протокол вызовов обеспечивает полный контроль над HTTP-запросом и ответом. Используйте его, если вам нужны нестандартные полезные нагрузки, не требующие обработки разговоров, или протоколы потоковой передачи, не совместимые с OpenAI.

С помощью протокола Invocations в C#вы реализуете пользовательский 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 регистрирует службы протокола Invocations. Вы реализуете 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()

Предупреждение

Хранилище сеансов в памяти в примере пользовательского обработчика теряется при перезапуске. Используйте устойчивое хранилище (например, Cosmos DB) в рабочей среде.

Полный пример развертывания Invocations см. в примере Telegram, размещённом в Foundry. Решение размещает API Management перед вебхуком размещённого агента и использует управляемые удостоверения, Key Vault и Cosmos DB для долговременного хранения истории диалогов.

Замечание

Скоро появится поддержка Go для размещенных агентов Foundry. Сведения о последнем состоянии см. в репозитории Agent Framework Go .

Tip

Можно ознакомиться с примерами проектов размещенного агента на языке Python или C#. Или используйте команду azd ai agent init, чтобы создать структуру проекта нового размещенного агента с нуля. В этом кратком руководстве приведены пошаговые инструкции.

Запуск на локальной машине

Интерфейс командной строки разработчика Azure (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

Развертывание в Foundry

После локальной проверки агента разверните его в Microsoft Foundry:

  1. Подготовка ресурсов (если у вас еще нет проекта Foundry):

    azd provision
    

    При этом создается группа ресурсов с экземпляром Foundry, проектом, развертыванием модели, Application Insights и реестром контейнеров.

  2. Разверните агент:

    azd deploy
    

    Это упаковывает ваш агент в виде образа контейнера, отправляет его в Реестр контейнеров Azure и развертывает в службе Foundry Agent Service.

Инфраструктура размещения Foundry автоматически внедряет следующие переменные среды в контейнер агента во время выполнения:

Variable Описание
FOUNDRY_PROJECT_ENDPOINT URL-адрес конечной точки для проекта Foundry.
AZURE_AI_MODEL_DEPLOYMENT_NAME Имя развертывания модели (настроено во время azd ai agent init).
APPLICATIONINSIGHTS_CONNECTION_STRING Строка подключения Application Insights для телеметрии.

После развертывания ваш агент доступен через выделенную конечную точку Foundry и его также можно протестировать на портале Foundry.

Дальнейшие действия