ai-agents-for-beginners

Развертывание масштабируемых агентов с Microsoft Foundry

Развертывание масштабируемых агентов

До этого момента в курсе вы создавали агентов, которые работают на вашем ноутбуке, внутри блокнота, управляемые az login и набором переменных окружения. Это именно тот правильный способ учиться. Но это не тот способ, чтобы запускать агента, от которого зависят тысячи клиентов в 3 часа ночи.

Этот урок посвящён разрыву между «у меня работает» и «работает надежно и экономично в продакшене». Мы закрываем этот разрыв с помощью Microsoft Foundry и Microsoft Foundry Agent Service, создавая реального агента поддержки клиентов с инструментами, поиском, памятью, оценкой и мониторингом.

Введение

В этом уроке будет рассмотрено:

Цели обучения

После прохождения этого урока вы будете уметь:

Требования

Предполагается, что вы уже прошли предыдущие уроки и уверенно работаете с:

Также вам понадобятся:

От прототипа к продакшену: что меняется

Прототип агента и продакшен-агент имеют одинаковый основной цикл — размышлять, вызывать инструменты, отвечать. Меняется всё, что оборачивает этот цикл. Модель — это около 20% продакшен-агента; остальные 80% — это операционный каркас.

Аспект Прототип Продакшен
Хостинг Работает в вашем блокноте Работает как размещённый сервис, с версиями и деплоем
Идентичность Ваш токен az login Управляемая идентичность с ограниченным RBAC
Состояние В памяти, теряется при перезапуске Внешнее хранилище (хранилище потоков, сервис памяти)
Сбои Вы видите трассировку ошибок Повторы, резервные варианты, dead-letter, оповещения
Стоимость “Несколько центов” Отслеживается по запросу, маршрутизируется, кэшируется, бюджетируется
Качество Вы оцениваете визуально Автоматическая оценка перед каждым релизом
Доверие Вы одобряете каждое действие Политики + человек в цикле для рискованных действий

Запомните эту таблицу. Каждый следующий раздел соответствует одной из этих строк.

Шаблоны развертывания агентов

Существует три шаблона, которые вы будете использовать часто в комбинации.

1. Агенты, размещённые на клиенте

Объект агента живёт внутри вашего процесса приложения. Ваш код напрямую вызывает провайдера модели; цикл рассуждений запускается в вашем сервисе. Именно так делались агенты в предыдущих уроках.

2. Hosted Agents (Foundry Agent Service)

Агент регистрируется как ресурс в Microsoft Foundry. Foundry хостит цикл рассуждений, хранит потоки, обеспечивает безопасность контента и RBAC, делает агента видимым в портале Foundry. Ваше приложение становится тонким клиентом, который создаёт потоки и читает ответы.

3. Рабочие процессы агента

Несколько агентов (и инструментов) объединяются в граф с явным контролем потока — последовательные шаги, ветвления, узлы одобрения человеком и надёжные чекпойнты, которые можно приостанавливать и возобновлять. Это функция Workflows Microsoft Agent Framework, применённая на масштабе развертывания.

flowchart TB
    subgraph P1[Client-Hosted]
        A1[Your App Process] --> M1[Model Provider]
    end
    subgraph P2[Hosted Agent]
        A2[Thin Client] --> F2[Foundry Agent Service]
        F2 --> M2[Model + Tools + Thread Store]
    end
    subgraph P3[Agent Workflow]
        A3[Orchestrator] --> S1[Triage Agent]
        S1 --> S2[Resolver Agent]
        S2 --> H[Human Approval Node]
        H --> S3[Action Agent]
    end

Жизненный цикл агента в Microsoft Foundry

Развертывание агента — это не разовое push. Это цикл, и он очень похож на цикл релиза ПО, потому что именно это и есть.

flowchart LR
    Create[Create / Author] --> Version[Version]
    Version --> Evaluate[Evaluate offline]
    Evaluate -->|passes gate| Deploy[Deploy hosted]
    Evaluate -->|fails gate| Create
    Deploy --> Observe[Observe online]
    Observe --> Improve[Collect failures]
    Improve --> Create
    Deploy --> Retire[Retire old version]

Ключевая идея, перенесённая из Урока 10: оффлайн-оценка — это ворота, а не последняя мысль. Новая версия агента не выпускается, если она не прошла ваши пороги оценки. Онлайн-наблюдаемость затем возвращает реальные сбои обратно в набор оффлайн-тестов. Вот весь цикл.

Стратегии масштабирования

Масштабирование агента отличается от масштабирования бессостоящего веб-API, потому что каждый запрос может запускать несколько затратных вызовов моделей и инструментов. Четыре техники берут на себя большую часть нагрузки.

Бессостоящая обработка запросов. Не храните состояние пользователя в памяти процесса. Сохраняйте потоки разговоров в хранилище потоков Foundry или сервисе памяти, чтобы любой экземпляр мог обработать любой запрос. Это позволяет масштабировать горизонтально — добавляйте экземпляры, без “липких” сессий.

Маршрутизация моделей. Не каждый запрос требует самой мощной (и самой дорогой) модели. Направляйте простые запросы — классификацию намерений, короткие фактические ответы — на маленькую, быструю модель, а большую модель оставляйте для настоящих рассуждений. Foundry имеет Model Router для этого, или вы можете реализовать простой классификатор самостоятельно. В лаборатории вы создадите именно такую версию.

Кэширование ответов. Многие запросы поддержки почти дублируются (“как сбросить пароль?”). Кэшируйте ответы на частые вопросы и выдавайте их без вызова модели. Даже умеренный уровень попаданий в кэш существенно снижает затраты и задержки.

Параллелизм и управление нагрузкой. У провайдеров моделей есть лимиты на скорость. Ограничивайте параллелизм, используйте повторы с экспоненциальной задержкой и корректно обрабатывайте ошибки (очередной ответ “мы работаем над этим” лучше, чем ошибка 500).

flowchart LR
    Q[User query] --> C{Cache hit?}
    C -->|yes| R[Return cached answer]
    C -->|no| Router{Complexity?}
    Router -->|simple| SLM[Small model]
    Router -->|complex| LLM[Large model]
    SLM --> Out[Response]
    LLM --> Out
    Out --> Store[Cache + trace]

Наблюдаемость в продакшене

Вы не можете управлять тем, чего не видите. Как было рассмотрено в Уроке 10, Microsoft Agent Framework нативно эмитирует OpenTelemetry трейсы — каждый вызов модели, инструмент и шаг оркестрации становится спаном. В продакшене вы экспортируете эти спаны в Microsoft Foundry (или любой совместимый OTel-бэкенд), чтобы:

from agent_framework.observability import get_tracer

tracer = get_tracer()

with tracer.start_as_current_span("support_request") as span:
    span.set_attribute("customer.tier", "enterprise")
    span.set_attribute("routed.model", "gpt-5-nano")
    # agent execution is traced automatically inside this span

Атрибуты вроде customer.tier и routed.model превращают гору трейсов в отвечающие на вопросы данные (“часто ли крупных клиентов направляют на маленькую модель?”).

Оптимизация затрат

В продакшен-агентах стоимость в основном определяется токенами. Три рычага, в порядке влияния:

  1. Правильный размер модели. Маленькая модель, проходящая ворота оценки, почти всегда дешевле большой, которая тоже проходит. Используйте оценку, чтобы доказать, что маленькая модель достаточно хороша, а не выбирайте самую большую из осторожности.
  2. Маршрутизация по сложности. Как выше — платите за большую модель только по запросам, требующим сложных рассуждений.
  3. Агрессивное кэширование. Самый дешёвый вызов модели — это тот, который вы не делаете.

Ворота оценки и контроль затрат — это один и тот же подход с двух сторон: оценка задаёт нижний предел качества, маршрутизация и кэширование удерживают затраты как можно ближе к этому пределу.

Корпоративные требования к развертыванию

Управление. Hosted Agents наследуют RBAC, безопасность контента и ведение аудита Foundry. Дайте каждому агенту управляемую идентичность с минимально необходимыми правами — только чтение базы знаний, ограниченный доступ к API тикетов, ничего лишнего.

Человек в цикле. Некоторые действия слишком важны, чтобы полностью автоматизировать их — возврат денег, удаление аккаунта, эскалация в юридическую команду. Microsoft Agent Framework поддерживает инструменты с требованием одобрения: агент предлагает действие, выполнение приостанавливается, человек одобряет или отклоняет, и рабочий процесс продолжается. Примитив вы видели в Уроке 6; здесь вы его развертываете.

MCP в продакшене. MCP позволяет агенту использовать внешние инструменты через стандартный интерфейс. В продакшене рассматривайте каждый MCP-сервер как недоверенную границу: фиксируйте версию сервера, запускайте с ограниченной идентичностью, проверяйте его выводы и никогда не раскрывайте ему секреты. MCP-сервер — это зависимость, за которой нужно следить, её нужно патчить, аудировать и ограничивать по скорости.

flowchart TB
    subgraph Dev[Development Architecture]
        D1[Notebook] --> D2[Agent Framework]
        D2 --> D3[Model Provider]
        D2 --> D4[Local tools]
    end
    subgraph Deploy[Deployment Architecture]
        E1[CI pipeline] --> E2[Evaluation gate]
        E2 -->|pass| E3[Foundry Agent Service]
        E3 --> E4[Versioned hosted agent]
    end
    subgraph Run[Runtime Architecture]
        F1[Client app] --> F2[Hosted agent]
        F2 --> F3[Model Router]
        F2 --> F4[Azure AI Search RAG]
        F2 --> F5[Memory service]
        F2 --> F6[MCP tools]
        F2 --> F7[OTel -> Foundry tracing]
        F2 --> F8[Human approval]
    end

Эти три диаграммы — разработка, развертывание, исполнение — показывают одного и того же агента на трёх этапах жизни. Следующая лабораторная работа проведёт вас через его создание.

Практическая лабораторная работа: агент поддержки клиентов готовый к продакшену

Откройте code_samples/16-python-agent-framework.ipynb и пройдите её полностью. Вы соберёте агента поддержки клиентов Contoso с учётом всех продакшен-требований:

  1. Вызов инструментов — просмотр статуса заказа и открытие тикетов поддержки.
  2. RAG — ответы на вопросы по политике из базы знаний (Azure AI Search с резервным вариантом в памяти, чтобы блокнот работал без Search-ресурса).
  3. Память — запоминание клиента по ходам разговора.
  4. Маршрутизация моделей — классификатор сложности направляет запрос к маленькой или большой модели.
  5. Кэширование ответов — повторные вопросы обслуживаются из кэша.
  6. Одобрение человеком — возвраты выше порога требуют ручного подтверждения.
  7. Конвейер оценки — маленький оффлайн-набор тестов оценивает агента и служит воротами релиза.
  8. Наблюдаемость — OpenTelemetry трассировка каждого запроса.

Прохождение

Блокнот организован так, что каждая продакшен-задача представляет собой самостоятельный, запускаемый раздел. В его основе — обработчик запросов с маршрутизацией и кэшированием:

async def handle_support_request(query: str, customer_id: str) -> str:
    # 1. Serve from cache when we can.
    cached = response_cache.get(normalize(query))
    if cached:
        return cached

    # 2. Route by complexity to control cost.
    model = "gpt-5-nano" if is_simple(query) else "gpt-5-mini"

    # 3. Run the agent inside a trace span for observability.
    with tracer.start_as_current_span("support_request") as span:
        span.set_attribute("routed.model", model)
        span.set_attribute("customer.id", customer_id)
        response = await support_agent.run(query, model=model)

    # 4. Cache and return.
    response_cache.set(normalize(query), response.text)
    return response.text

Ворота оценки, защищающие релиз, выглядят так:

async def evaluation_gate(agent, test_cases, threshold: float = 0.8) -> bool:
    passed = 0
    for case in test_cases:
        result = await agent.run(case["input"])
        if score_response(result.text, case["expected"]) >= 0.8:
            passed += 1
    pass_rate = passed / len(test_cases)
    print(f"Evaluation pass rate: {pass_rate:.0%} (gate: {threshold:.0%})")
    return pass_rate >= threshold  # only deploy if the gate passes

Читайте каждую строку — блокнот специально сделан с небольшими примитивами, чтобы ничего не скрывалось за вызовом фреймворка.

Валидация развернутого агента с помощью smoke-тестов

Ворота оценки выше запускаются оффлайн по объекту агента. После развертывания агента как Hosted Agent нужен ещё один, ещё более простой чек: фактически отвечает ли развернутый эндпоинт?

Развертывание «успешно» доказывает только, что контрольная плоскость приняла определение — оно не доказывает, что агент отвечает. Отсутствующая зависимость, неправильная маршрутизация модели или истёкшее соединение могут оставить зелёное развертывание, которое ничего не возвращает. smoke-тест ловит это за секунды, при каждом деплое, без затрат полной оценки.

В этом репозитории есть готовый конвейер smoke-тестов, построенный на GitHub Action AI Smoke Test:

- name: Smoke-test hosted agent
  uses: JFolberth/ai-smoketest@v1
  with:
    project_endpoint: $
    agent_name: ContosoSupportAgent
    tests_file: tests/lesson-16-smoke-tests.json

Запустите это с вкладки Actions, когда ваш агент будет развернут, указав конечную точку проекта Foundry и имя агента. Федеративная идентичность должна иметь роль Azure AI User в области проекта Foundry. Представьте слои как пирамиду: дымовые тесты (доступен и отвечает?) запускаются при каждом развертывании, офлайн-оценка (достаточно ли хорош, чтобы отправить?) запускается перед продвижением, а онлайн-оценка (как он работает в реальных условиях?) выполняется непрерывно.

Проверка знаний

Проверьте свои знания перед тем, как перейти к заданию.

1. Примерно какая часть производственного агента — это “модель”, и что остальное?

Ответ Модель — это меньшинство системы — часто говорят около 20%. Остальное — это операционный скелет: размещение и управление версиями, идентификация и RBAC, внешний стейт, обработка сбоев, отслеживание затрат, оценка и управление с участием человека. Переход в продакшн в основном связан с построением всего *вокруг* цикла рассуждения.

2. Когда вы бы выбрали Hosted Agent вместо клиента, размещённого на стороне пользователя?

Ответ Когда вам нужен управляемый рантайм с встроенной надёжностью (потоки, которые сохраняются и могут продолжаться), наблюдаемостью, безопасностью контента и RBAC, и вы готовы пожертвовать частью низкоуровневого контроля цикла рассуждения ради меньшего операционного объёма. Клиентский хостинг предпочтителен, когда нужен полный контроль над циклом или если агент внедряется в существующий бэкенд.

3. Почему масштабируемый агент должен быть без состояния в собственной памяти процесса?

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

4. Какую проблему решает маршрутизация модели и как она связана с оценкой?

Ответ Маршрутизация отправляет простые запросы на небольшую, дешевую и быструю модель и оставляет большую модель для настоящих рассуждений, контролируя задержку и стоимость. Это связано с оценкой, потому что именно оценка *доказывает*, что маленькая модель достаточно хороша для класса запросов — маршрутизация без оценки — это угадывание.

5. Что такое “оценочный шлюз” и где он находится в жизненном цикле?

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

6. Почему MCP сервер должен рассматриваться как ненадёжная граница в продакшене?

Ответ Потому что это внешняя зависимость, к которой обращается ваш агент. Вы должны зафиксировать его версию, запустить с ограниченной идентичностью, проверять его вывод, ограничивать по частоте запросов и никогда не передавать ему секреты — ту же дисциплину, что применяете к любым сторонним зависимостям. Его выводы влияют на рассуждения агента, поэтому непроверенное доверие — это риск безопасности.

7. Какое единственное изменение обычно оказывает наибольшее влияние на стоимость производственного агента, и почему?

Ответ Правильный размер модели — использование самой маленькой модели, которая всё ещё проходит ваш оценочный шлюз. Стоимость в основном определяется токенами, и меньшая модель с нужным качеством почти всегда дешевле большой. Кэширование и маршрутизация дополнительно снижают стоимость, но выбор правильной базовой модели оказывает наибольшее первичное влияние.

8. Какую роль играют атрибуты спанов, такие как customer.tier и routed.model, в наблюдаемости?

Ответ Они превращают сырые трассы в отвечаемые бизнес-вопросы. Без атрибутов у вас стена спанов; с атрибутами можно спросить "часто ли корпоративных клиентов направляют на маленькую модель?" или "какая модель обрабатывает самые медленные запросы?" Атрибуты — это способ разрезать телеметрию по аспектам, важным для вашей эксплуатации.

Задание

Возьмите агента поддержки клиентов из лаборатории и подготовьте его для конкретного сценария: агента поддержки по подписной оплате для SaaS-компании.

Ваше задание должно:

  1. Заменить инструменты на соответствующие биллингу: get_subscription_status, get_invoice и issue_credit (кредиты свыше $50 требуют одобрения человека).
  2. Добавить три документа RAG, охватывающих политику возвратов компании, цикл выставления счетов и политику отмены.
  3. Расширить набор оценочных случаев минимум до восьми, включая как минимум два, которые должны инициировать путь с одобрением человеком, и подтвердить корректность работы оценочного шлюза.
  4. Добавить отчёт о стоимости: после 10 смешанных запросов через агента выведите, сколько запросов было отправлено на маленькую модель, сколько на большую и сколько обслуживалось из кэша.

Напишите короткий абзац (в markdown-клетке), объясняющий, какое правило маршрутизации модели вы выбрали и как вы проверите его на реальном трафике. Единственно правильного ответа нет — вас оценивают по тому, насколько связно учтены производственные аспекты.

Итог

На этом уроке вы перевели агента от прототипа к продакшену с Microsoft Foundry:

Следующий урок совершает обратное путешествие: вместо масштабирования агентов в облако вы перенесёте их на одну машину разработчика и запустите полностью локально.

Дополнительные ресурсы

Предыдущий урок

Создание агентов для использования компьютера (CUA)

Следующий урок

Создание локальных AI агентов


Отказ от ответственности: Этот документ был переведен с использованием сервиса машинного перевода Co-op Translator. Несмотря на наши усилия по обеспечению точности, имейте в виду, что автоматический перевод может содержать ошибки или неточности. Оригинальный документ на его исходном языке следует считать авторитетным источником. Для получения критически важной информации рекомендуется обратиться к профессиональному человеческому переводу. Мы не несем ответственности за любые недоразумения или неправильные толкования, возникшие в результате использования этого перевода.