Навчіть власну модель у Azure ML та викликайте її з агента Foundry
Навчіть, зареєструйте та розгорніть модель втрат клієнтів на керованому кінцевому пункті Azure ML, а потім зробіть її доступною для агента Foundry у вигляді FunctionTool із інформацією про автентифікацію та умови використання в продакшені.
Джерела: Building and Serving a Custom Model with Azure ML, Then Wiring It Into a Foundry Agent
Каталог моделей Foundry є широким, проте деякі завдання залишаються поза ним. Уявіть собі прогнозування відтоку клієнтів на основі власних записів компанії чи оцінку ризиків шахрайства за допомогою власної історії транзакцій. Це звичайні завдання машинного навчання на приватних табличних даних, і рішенням Microsoft для них є Azure Machine Learning — окремий продукт із власним SDK, власним простором роботи та власним способом розгортання моделей.
Наведений нижче процес охоплює всю послідовність дій: навчання моделі за допомогою Azure ML SDK, її реєстрація, надання доступу до неї з керованого кінцевої точки, а потім відкриття цієї кінцевої точки для агента Foundry як інструменту у вигляді функції. Агент може потім викликати цю спеціальну модель під час розмови точно так само, як він би викликав будь-який інший інструмент.
Де зустрічаються ці дві платформи
Ці два продукти працюють під керуванням різних середовищ виконання, але належать до однієї екосистеми, і Microsoft працює над тим, щоб зменшити розрив між ними. Чітке усвідомлення того, де саме він знаходиться, полегшує розуміння процесу створення. У цьому процесі беруть участь чотири компоненти:
- Завдання команди. Тут відбувається навчання. SDK спрямований на скрипт, місце обчислень та певні дані вхіду, і виконує код як задання з можливістю відстеження та повторення.
- Реєстр моделей. Навчена модель перетворюється на об’єкт із назвою та версією, який існує окремо від завдання, що її створило, тож одну версію можна запустити в промисловому середовищі без повторного навчання.
- Керований онлайн-кінець точки. Він надає прогнози з зареєстрованої моделі. Це справжня інфраструктура, яка завжди увімкнена або масштабується автоматично, має власну URL, систему аутентифікації та витрати, і знаходиться всередині робочого простору Azure ML, а не Foundry.
FunctionTool. Це місток. Foundry не знає та не цікавиться тим, що функція, яка знаходиться за інструментом, викликає кінцеву точку Azure ML. Для агента це просто ім’я, схема та результат.Передумови
- Робоче середовище Azure ML та проект Foundry. Вони можуть знаходитися в одних чи різних групах ресурсів, оскільки тут немає потреби у спільній інфраструктурі.
- Python 3.9 або новіша версія з обома SDK:
pip install azure-ai-ml azure-ai-projects azure-identity
MLClient автентифікується та налаштовує робоче простір:
from azure.ai.ml import MLClient
from azure.identity import DefaultAzureCredential
ml_client = MLClient(
DefaultAzureCredential(),
subscription_id="<subscription-id>",
resource_group_name="<resource-group>",
workspace_name="<aml-workspace-name>",
)
Навчання як завдання команди
Крок навчання є завданням команди. Він бере скрипт навчання — у цьому випадку звичайний класифікатор scikit-learn — та виконує його на керованих обчислювальних ресурсах:
from azure.ai.ml import command, Input, Output
train_job = command(
code="./src",
command="python train.py --data ${{inputs.training_data}} --model_output ${{outputs.model_output}}",
inputs={"training_data": Input(type="uri_folder", path="azureml://datastores/workspaceblobstore/paths/churn-training/")},
outputs={"model_output": Output(type="uri_folder")},
environment="azureml://registries/azureml/environments/sklearn-1.5/labels/latest",
compute="cpu-cluster",
display_name="churn-model-training",
)
returned_job = ml_client.jobs.create_or_update(train_job)
ml_client.jobs.stream(returned_job.name)
Виклик ml_client.jobs.stream чекає та виводить журнали поки тренування не завершиться. Краще використовувати його у будь-якому скрипті, який справді буде запущений. Робота, яка мовчки зазнає невдачі на фоні, — це неприємний спосіб дізнатися про пошкодження конвеєра обробки даних.
Реєстрація моделі
Реєстрація перетворює результати роботи на іменований, версіонований артефакт, який можна використовувати окремо:
from azure.ai.ml.entities import Model
from azure.ai.ml.constants import AssetTypes
model = ml_client.models.create_or_update(
Model(
path=f"azureml://jobs/{returned_job.name}/outputs/model_output",
name="churn-classifier",
type=AssetTypes.MLFLOW_MODEL,
description="Customer churn classifier, trained on 18 months of account history.",
)
)
Вибір MLFLOW_MODEL як типу є свідомим рішенням. Якщо скрипт навчання записує модель через автоматичне логування MLflow, керовані ендпоїнти можуть розгорнути її за допомогою вбудованого контейнера оцінки, без необхідності використання спеціального скрипта інференсу score.py. Це економить час у реальному часі, і скрипт навчання краще проектувати з урахуванням цього з самого початку.
Розгортання за допомогою ендпоїнта
Ендпоїнт у поєднанні з процесом розгортання дозволяє опублікувати модель в Інтернеті:
from azure.ai.ml.entities import ManagedOnlineEndpoint, ManagedOnlineDeployment
endpoint = ManagedOnlineEndpoint(name="churn-endpoint", auth_mode="key")
ml_client.online_endpoints.begin_create_or_update(endpoint).result()
deployment = ManagedOnlineDeployment(
name="blue",
endpoint_name="churn-endpoint",
model=model,
instance_type="Standard_DS3_v2",
instance_count=1,
)
ml_client.online_deployments.begin_create_or_update(deployment).result()
endpoint.traffic = {"blue": 100}
ml_client.online_endpoints.begin_create_or_update(endpoint).result()
Ім’я розгортання blue не є обов’язковим, але краще його зберегти, адже це допомагає сформувати корисну звичку під час першої нової версії моделі. Створіть розгортання green поруч із blue, розподіліть трафік між ними та повністю перейдіть на нову версію, коли вона здобуде довіру. Заміна blue та сподівання на краще — це ризикований варіант.
Перш ніж щось ще налаштовувати, отримайте пряме прогнозування:
import json
test_input = {"input_data": {"columns": ["tenure_months", "monthly_spend", "support_tickets"], "data": [[14, 89.50, 3]]}}
response = ml_client.online_endpoints.invoke(
endpoint_name="churn-endpoint",
request_file=None,
deployment_name="blue",
input_data=json.dumps(test_input),
)
print(response)
Виправлення несправного кінцевої точки через цикл викликів функцій агента є набагато складнішим, ніж її виправлення безпосередньо, тому спочатку переконайтеся, що вона працює.
Підключення кінцевої точки до агента Foundry
Агент ніколи не викликає сам Azure ML. Код додатку робить це, коли агент про це просить. У налаштуваннях оголошується FunctionTool, створюється агент та визначається функція, яка надсилає HTTP-запит до кінцевої точки:
import os
import requests
from azure.ai.projects import AIProjectClient
from azure.ai.projects.models import PromptAgentDefinition, Tool, FunctionTool
from azure.identity import DefaultAzureCredential
def get_churn_score(tenure_months: int, monthly_spend: float, support_tickets: int) -> dict:
payload = {"input_data": {"columns": ["tenure_months", "monthly_spend", "support_tickets"], "data": [[tenure_months, monthly_spend, support_tickets]]}}
resp = requests.post(
"https://churn-endpoint.<region>.inference.ml.azure.com/score",
headers={"Authorization": f"Bearer {os.environ['AML_ENDPOINT_KEY']}", "Content-Type": "application/json"},
json=payload,
timeout=10,
)
resp.raise_for_status()
return {"churn_probability": resp.json()[0]}
func_tool = FunctionTool(
name="get_churn_score",
description="Predict churn probability for a customer given tenure, spend, and support ticket history.",
parameters={
"type": "object",
"properties": {
"tenure_months": {"type": "integer", "description": "How many months the customer has been active."},
"monthly_spend": {"type": "number", "description": "Average monthly spend in dollars."},
"support_tickets": {"type": "integer", "description": "Number of support tickets in the last 90 days."},
},
"required": ["tenure_months", "monthly_spend", "support_tickets"],
"additionalProperties": False,
},
strict=True,
)
project = AIProjectClient(endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"], credential=DefaultAzureCredential())
tools: list[Tool] = [func_tool]
agent = project.agents.create_version(
agent_name="retention-agent",
definition=PromptAgentDefinition(
model="gpt-4.1-mini",
instructions="Help the team assess churn risk. Call get_churn_score whenever specific customer numbers are provided.",
tools=tools,
),
)
Потім відбувається розмова, виклик функції моделі переривається, і повертається результат:
import json
from openai.types.responses.response_input_param import FunctionCallOutput
openai_client = project.get_openai_client()
conversation = openai_client.conversations.create()
response = openai_client.responses.create(
input="A customer's been with us 14 months, spends about $90/month, and filed 3 tickets recently. Churn risk?",
conversation=conversation.id,
extra_body={"agent_reference": {"name": agent.name, "type": "agent_reference"}},
)
for item in response.output:
if item.type == "function_call" and item.name == "get_churn_score":
result = get_churn_score(**json.loads(item.arguments))
follow_up = openai_client.responses.create(
input=[FunctionCallOutput(type="function_call_output", call_id=item.call_id, output=json.dumps(result))],
conversation=conversation.id,
extra_body={"agent_reference": {"name": agent.name, "type": "agent_reference"}},
)
print(follow_up.output_text)
Модель вирішує, чи потрібно для запитання викликати функцію get_churn_score. Якщо так, код додатку здійснює HTTP-запит до Azure ML, а результат повертається у ту саму розмову, щоб модель могла завершити свою відповідь. Ніщо у визначенні агента чи у викликах API Responses не залежить від того, що робить функція на задньому плані. Вона може запитувати базу даних, викликати функцію Lambda чи звертатися до іншого робочого простору Azure ML, як це робиться тут.
Два ресурси, два межі автентифікації
Одна деталь залишається непоміченою в документації SDK. Керований кінцевий пункт у Azure ML та проєктний кінцевий пункт у Foundry — це два ресурси, які знаходяться за двома окремими системами автентифікації, і ніщо в цій конфігурації не поєднує їх. Azure ML має власний ключ чи керовану ідентичність для робочого простору, тоді як Foundry використовує інші облікові дані. Оголошення FunctionTool не створює довіри між ними; воно лише надає моделі ім’я та схему для отримання даних від вашого коду. Уся автентифікація щодо Azure ML відбувається всередині вашої власної функції, точно так само, як це було б під час виклику будь-якого іншого зовнішнього API.
Це є перевагою. Частину, пов’язану з Azure ML, можна керувати, захищати та оновлювати незалежно від Foundry, навіть іншою командою, причому жодна зі сторін не потребує прав на запис до ресурсів іншої сторони.
Примітки щодо використання в продакшені
- Виклик функції закінчується через 10 хвилин. Результат має бути надісланий назад у розмову до закриття вікна, інакше виконання зазнає невдачі. Якщо HTTP-запит до Azure ML є повільним, вважайте це жорстким терміном та враховуйте його під час планування.
- Переходьте на керовану ідентичність поза межами прототипу. Ключ, збережений у змінній середовища, підходить для локального використання, але створює ризики у будь-якій ситуації, коли система залишається без нагляду. Надайте ідентичності, яка виконує код інструменту, роль
AzureML Data Scientistабо вужчу користувацьку роль, обмежену цим кінцевим пунктом, а не всією робочою зоною. - Поступово впроваджуйте нові моделі. Запустіть нову версію поруч із існуючою та поступово переносьте трафік на неї. Це єдиний спосіб виявити проблеми під час перенавчання ще до того, як від них залежатимуть реальні запити.
strict=True увімкненим. Суворі схеми запобігають надсиланню моделлю неповних або некоректно сформованих аргументів до get_churn_score, що інакше призвело б до збою всередині вашої функції, а не ще до її виклику.get_churn_score у місце, яке можна буде переглянути, та регулярно перевіряйте дані навчання, а не лише тоді, коли прогнози помітно погіршуються.Вибір правильної платформи
Для більшості завдань у сфері генеративного ШІ каталог Foundry є ідеальним інструментом, а команди без власних даних для навчання, можливо, ніколи не будуть потребувати чогось більшого. Як тільки завдання перетворюється на прогноз щодо ваших власних клієнтів на основі вашого власного досвіду, Azure ML стає кращим вибором. Інакше мовна модель використовується для завдань, для яких вона не була створена, або інфраструктура обслуговування будується вручну. Усе це дуже просто: одна операція навчання, одна зареєстрована модель, один керований ендпоїнт та єдиний FunctionTool. Платформи залишаються окремими, кожна виконує те, у чому вона найкраща.