Размещайте агентов Microsoft Agent Framework как агентов, размещенных в Foundry

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

В этой статье вы создадите минимальный агент Agent Framework, предоставите его через протокол "Ответы" или "Вызовы", протестируйте его по протоколу HTTP и разверните его в Foundry с помощью интерфейса командной строки разработчика Azure.

Навык Microsoft Foundry может помочь реализовать адаптер, протестировать протоколы и выполнить развертывание с помощью azd.

Необходимые условия

  • 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 для конечной точки, совместимой /responses с OpenAI.
  • 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

Для протокола вызовов также добавьте пакет сервера вызовов:

dotnet add package Azure.AI.AgentServer.Invocations

Эти пакеты предоставляют расширения узла для протоколов Foundry:

  • AddFoundryResponses и MapFoundryResponses для конечной точки, совместимой /responses с OpenAI.
  • AddInvocationsServer и MapInvocationsServer для универсальной /invocations конечной точки.

Выбор протокола размещения

Размещённые агенты могут поддерживать один или несколько протоколов. Начните с Responses для большинства разговорных агентов.

Protocol Endpoint Используйте, если
Responses /responses Вам нужны чат, совместимый с OpenAI, потоковая передача, история ответов и ветвление бесед.
Инвокации /invocations Вам нужны пользовательская структура JSON, эндпоинт в стиле вебхука или недиалоговая обработка.

Общие сведения о поведении и сеансах протокола см. в разделе "Размещенные агенты " и "Управление размещенными сеансами агента".

Настройка переменных среды

Задайте имя конечной точки проекта и развертывания модели для локальной разработки:

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, с потоковой передачей, журналом ответов и потоком беседы.

Создание узла ответов

Создайте файл main.py с минимальным агентом Agent Framework, использующим модель Foundry.

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()

Что делает этот фрагмент кода: Создает агента фреймворка Agent Framework на основе модели Foundry через FoundryChatClient, а затем передает агента в ResponsesHostServer. Хост запускает HTTP-сервер и открывает доступ к агенту через POST /responses. По умолчанию сервер привязывается к порту 8088.

Справка: Документация по Microsoft Agent Framework

Запустите приложение локально:

python main.py

Program.cs Создайте файл с минимальным агентом Agent Framework, использующим модель Foundry с помощью протокола Responses.

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();

Что делает этот фрагмент кода: Создает AIAgent из клиента проекта Foundry, регистрирует его как узел Foundry Responses с помощью AddFoundryResponses и сопоставляет конечную точку POST /responses с помощью MapFoundryResponses. По умолчанию узел обслуживается через порт 8088.

Справочник: AIProjectClient | DefaultAzureCredential

Запустите приложение локально:

dotnet run

Проверка конечной точки ответов

Отправьте на локальный сервер запрос Responses без потоковой передачи.

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"

Сервер отвечает с помощью объекта JSON, содержащего текст ответа и идентификатор ответа. Для потоковых ответов задайте значение streamtrue. Хост генерирует server-sent events Responses API, такие как response.created, response.output_text.delta и response.completed.

Многоэтапные диалоги

Чтобы продолжить беседу, передайте предыдущий идентификатор ответа в previous_response_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. Дополнительные сведения см. в разделе "Управление размещенными сеансами агента".

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

Используйте протокол Invocations, если вызывающая сторона не может использовать формат запросов API Responses или если ваш сценарий не является чатом. Узел Invocations управляет состоянием сеанса через параметр запроса agent_session_id и заголовок ответа.

Создание узла вызовов

Используйте ту же конфигурацию агента, что и в примере 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()

Что делает этот фрагмент кода: Размещает агент Agent Framework через POST /invocations. Хост управляет состоянием каждого сеанса с помощью параметра запроса agent_session_id и заголовка ответа.

Справка: Документация по Microsoft Agent Framework

Протокол вызовов использует 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();

Что делает этот фрагмент кода: Регистрирует службы сервера Invocations и вашу реализацию 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, чтобы направлять последующие вызовы в ту же размещённую песочницу.

Deploy

Развертывание с помощью интерфейса командной строки разработчика Azure (azd). Поток использует примеры azure.yaml файлов и Docker для создания образа контейнера агента и его развертывания в среде выполнения размещенного агента Foundry.

Для развертывания размещенного агента требуется роль Foundry Project Manager в проекте. Дополнительные сведения см. в разделе "Развертывание размещенного агента".

Установите расширение Azure Developer CLI

Установите расширение ИИ-агента и войдите, прежде чем инициализировать пример:

azd ext install azure.ai.agents
azd auth login

Docker должен работать локально, так как azd ai agent run создает образ контейнера, объявленный в файле Dockerfile примера. Подробные сведения о команде см. в справочнике по Azure Developer CLI.

Инициализация из примера манифеста

Создайте новую папку и инициализируйте ее, используя azure.yaml из примера. Эти команды инициализируют текущий каталог и выбирают вариант развертывания в контейнере, чтобы соответствовать этому пошаговому руководству.

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

azd ai agent init -t https://github.com/microsoft-foundry/foundry-samples/blob/main/samples/python/hosted-agents/agent-framework/responses/01-basic/azure.yaml --src . --deploy-mode container
mkdir my-agent-framework-agent
cd my-agent-framework-agent

azd ai agent init -t https://github.com/microsoft/agent-framework/blob/main/dotnet/samples/04-hosting/FoundryHostedAgents/responses/Hosted-ChatClientAgent-Dockerfile/azure.yaml --src . --deploy-mode container

Следуйте инструкциям из azd ai agent init. Пример Python может создать проект Foundry и развертывание модели. Для примера C# требуются существующий проект 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: URL-адрес конечной точки для проекта Foundry, в котором развернут агент.
  • 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 в последующих запросах.

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

Несоответствие версии протокола

Если запросы завершаются сбоем после обновления, убедитесь, что манифест и пакет размещения используют протокол 2.0.0. Протокол версии 1.0.0 больше не поддерживается.

Следующий шаг