Практические заметки: создание и запуск пользовательской модели с Azure ML, а затем её подключение
Пошаговое руководство по практическим советам: создание и запуск пользовательской модели с использованием Azure ML, а также инструменты для работы в командах: контракты, проверки и готовые блоки кода для реализации данного подхода.
В этом руководстве пошагово описывается процесс создания системы от сырья до готового решения для следующих задач: построение и запуск пользовательской модели с использованием Azure ML, а затем её интеграция в агента Foundry. Основное внимание уделяется практическим шагам, чётким проверкам и коду, который можно просто добавить в репозиторий без необходимости догадываться о его назначении. На этапе обзора необходимо определить входные данные, ответственного за выполнение шага и критерии завершения перед внесением изменений в код. Операторы должны иметь возможность перезапустить шаг с известной точки контроля, не догадываясь о скрытом состоянии системы. Необходимо одновременно задокументировать успешный и аварийный сценарии работы. Повторные попытки, проверки человеком и обработка ошибок являются неотъемлемой частью продукта, а не элементами последующей доработки.
Сначала ментальная модель
При работе над первым этапом «Ментальной модели» сначала запишите условия работы: необходимые входные данные, сигнал успешного выполнения и действия при частичной неудаче. Такой список поможет сохранять честность при последующих изменениях кода. Предпочитайте небольшие, тестируемые единицы кода вместо обширных скриптов. Если какой-то шаг не сработает, причина должна быть связана с одной конкретной функцией, а не с запутанной цепочкой операций. Храните в кэше стабильные инструкции системы и схемы инструментов. Повторная отправка одинаковых данных — распространенная причина избыточных ресурсов.
Предварительные требования
При работе над этапом предварительных требований сначала запишите контракт: необходимые входные данные, сигнал о успешном выполнении и действия при частичной неудаче. Такой список помогает избегать недостоверных изменений в коде позже. Рассматривайте этот этап как контракт между входными данными и проверенными выходными результатами. Дайте названия элементам, определите критерии успешности и не допускайте молчаливого частичного выполнения задачи. Храните в кэше стабильные инструкции системы и схемы инструментов. Пересылка одинаковых данных является распространенной причиной избыточных ресурсов.
pip install azure-ai-ml azure-ai-projects azure-identity
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>",
)
Шаг 1: обучение модели
При работе над этапом обучения Шаг 1 сначала запишите контракт: необходимые входные данные, сигнал успешного выполнения и действия при частичной неудаче. Такой список помогает сохранять честность при последующих изменениях кода. Записывайте время выполнения и стоимость токенов или запросов рядом с функциональными результатами. Отображение затрат на раннем этапе предотвращает неожиданные счета при переходе от демо-среды к общедоступным средам. Храните в кэше стабильные инструкции системы и схемы инструментов. Повторная отправка одинаковых данных — распространенная причина избыточных затрат. При работе над этапом обучения Шаг 1 сначала запишите контракт: необходимые входные данные, сигнал успешного выполнения и действия при частичной неудаче. Такой список помогает сохранять честность при последующих изменениях кода. Документируйте как успешный путь, так и путь восстановления одновременно. Повторные попытки, проверки человеком и обработка неработающих сообщений являются частью продукта, а не элементами последующей доработки.
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)
Шаг 2: зарегистрируйте обученную модель
Шаг 2, связанный с регистрацией этапов работы, работает наилучшим образом, когда его рассматривают как измеримую поверхность. Соберите один пример успешного выполнения, один случай сбоя и запись о возврате к предыдущему состоянию перед расширением объема работ. Предпочитайте небольшие, тестируемые единицы кода вместо обширных скриптов. Когда происходит сбой на каком-либо этапе, причина должна быть связана с конкретной ответственностью, а не с запутанной цепочкой операций. Установите лимиты на количество токенов за один ход и за сессию. Инструменты агентного типа активно расширяют объем контекста; жесткие ограничения предотвращают появление неожиданных счетов.
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.",
)
)
Шаг 3: разверните его за управляемым конечным пунктом
На этапе 3 развертывания лучше всего работает подход, когда его рассматривают как измеримую среду. Соберите один идеальный пример работы, один случай сбоя и записку о возврате к предыдущему состоянию перед расширением объёма работ. Рассматривайте этот этап как контракт между входными данными и проверенными результатами. Дайте названия создаваемым элементам, определите критерии успеха и не соглашайтесь на молчаливое частичное выполнение задач. Установите лимиты на количество операций за раз и за сессию. Инструменты агентов активно расширяют объём данных; жесткие ограничения предотвращают появление неожиданных счетов.
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()
Шаг 4: убедитесь, что всё работает, прежде чем кто-либо ещё будет с этим работать
На этапе 4 подтверждается, что лучший способ работы с этой средой — рассматривать её как измеримую поверхность. Соберите один идеальный пример работы, один случай сбоя и записку о возврате к предыдущему состоянию перед расширением объёма работ. Записывайте временные показатели, а также стоимость токенов или запросов рядом с функциональными результатами. Отслеживание затрат на раннем этапе предотвращает неожиданные счёты при переходе от демо-среды к общедоступным средам. Установите лимиты на количество токенов за один ход и за сессию. Инструменты агентов активно расширяют контекст; жёсткие ограничения не позволяют демо-версиям превращаться в неожиданные счёты.
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)
На этапе 4 подтверждается, что лучший способ работы с этой средой — рассматривать её как измеримую поверхность. Соберите один идеальный пример работы, один случай сбоя и записку о возврате к предыдущему состоянию перед расширением объёма работ. Документируйте одновременно успешный путь выполнения и путь восстановления. Повторные попытки, проверки человеком и обработка неработающих сообщений являются частью продукта, а не элементами последующей доработки.
Шаг 5: оформление конечной точки в виде функции-инструмента агента Foundry
На шаге 5 необходимо сначала описать этап, определить входные данные, ответственного за выполнение шага и критерии завершения, прежде чем изменять код. Операторы должны иметь возможность перезапустить шаг с известной точки контроля, не догадываясь о скрытом состоянии. Лучше использовать небольшие, тестируемые единицы кода вместо обширных скриптов. При сбое шага он должен указывать на конкретную причину, а не на сложную структуру обработки данных. При следующем шаге, являющемся кодом или вызовом инструмента, предпочтительнее использовать структурированные выходные данные с проверкой соответствия шаблону вместо свободного текста.
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,
),
)
Шаг 6: запустить полностью
На этапе 6 выполнения шага необходимо заранее определить входные данные, ответственного за шаг и критерии завершения перед изменением кода. Операторы должны иметь возможность перезапустить шаг с известной точки контроля, не догадываясь о скрытом состоянии. Рассматривайте этот этап как контракт между входными данными и проверенными выходными результатами. Дайте названия результатам работы, определите критерии успеха и не допускайте молчаливого частичного завершения задачи. При следующем шаге, представляющем собой код или вызов инструмента, отдавайте предпочтение структурированным выходным данным с проверкой по шаблону перед свободным текстовым форматом.
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)
Место этого в общей картине
Чтобы определить место этого шага в процессе, необходимо заранее указать входные данные, ответственного за выполнение шага и критерии завершения перед внесением изменений в код. Операторы должны иметь возможность перезапустить шаг с известной точки контроля, не догадываясь о скрытом состоянии. Регистрируйте время выполнения и стоимость токенов или запросов рядом с функциональными результатами. Отображение стоимости заранее помогает избежать неожиданных счетов при переходе от демо-среды к общедоступным средам. При следующем шаге, представляющем собой код или вызов инструмента, предпочтительнее использовать структурированные выходные данные с проверкой схемы вместо свободного текста. Чтобы определить место этого шага в процессе, необходимо заранее указать входные данные, ответственного за выполнение шага и критерии завершения перед внесением изменений в код. Операторы должны иметь возможность перезапустить шаг с известной точки контроля, не догадываясь о скрытом состоянии. Документируйте как успешный, так и восстановительный сценарии работы. Повторные попытки, проверки человеком и обработка неработающих сообщений являются частью продукта, а не элементами последующей доработки.
Аспекты производства перед запуском
При рассмотрении аспектов производства перед запуском сначала запишите условия контракта: необходимые входные данные, сигнал успешного выполнения и действия при частичной неудаче. Такой список поможет сохранять честность при последующих изменениях кода. Лучше использовать небольшие, тестируемые модули вместо обширных скриптов. При сбое какого-либо шага причина должна быть связана с конкретной функцией, а не с запутанной цепочкой операций. Храните в кэше стабильные инструкции системы и схемы инструментов. Повторная отправка одинаковых данных — распространенная причина избыточных затрат ресурсов.
Что остается после этого
При работе над этапом «Где это приводит к следующему шагу» сначала запишите условия соглашения: необходимые входные данные, сигнал о успешном выполнении и действия при частичной неудаче. Такой список поможет избежать ошибок при последующих изменениях кода. Рассматривайте этот этап как соглашение между входными данными и проверенными выходными результатами. Дайте названия соответствующим элементам, определите критерии успешности и не допускайте молчаливого частичного выполнения задачи. Храните в кэше стабильные инструкции системы и схемы инструментов. Пересылка одинаковых данных является распространенной причиной избыточных ресурсов.
Ссылки
На этапе разработки справочных материалов сначала запишите условия работы: необходимые входные данные, сигнал о успешном выполнении и действия при частичной неудаче. Такой список помогает сохранять честность при последующих изменениях кода. Рядом с функциональными результатами записывайте время выполнения и стоимость токенов или запросов. Отслеживание затрат с самого начала предотвращает неожиданные счета при переходе от демо-среды к общедоступным средам. Храните в кэше стабильные инструкции системы и схемы инструментов. Повторная отправка одинаковых данных — частая причина избыточных затрат. На этапе разработки справочных материалов сначала запишите условия работы: необходимые входные данные, сигнал о успешном выполнении и действия при частичной неудаче. Такой список помогает сохранять честность при последующих изменениях кода. Документируйте как успешный, так и восстановительный пути работы. Повторные попытки, проверки со стороны оператора и обработка некорректных сообщений являются частью продукта, а не элементами последующей доработки.
Чек-лист операционной работы
Этап операционного чек-листа работает наилучшим образом, когда его рассматривают как измеримую основу. Соберите один идеальный пример работы, один случай сбоя и запись о возврате к предыдущему состоянию перед расширением объема работ.
Храните конфигурацию отдельно от кода приложения. Файлы среды, хранилища секретов и флаги функций должны находиться в одном месте, чтобы операторы могли их проверять, не читая всю структуру системы.
Установите лимиты на количество токенов за одну операцию и за сессию. Инструменты с автономным управлением активно расширяют объем данных; жесткие ограничения предотвращают появление неожиданных счетов.
Вводите человеческое утверждение для операций, связанных с тратой денег или изменением производственных данных. Подключение компонентов во время компиляции не гарантирует полноты бизнес-процессов.
Напишите краткий руководство: как заменять ключи, как опустошать очередь задач, как возвращаться к последнему состоянию системы.
Рассматривайте этот этап как контракт между входными данными и проверенными выходными результатами. Дайте названия результатам работы, определите критерии успешности и не соглашайтесь на молчаливое частичное выполнение задачи.
Перед переходом на следующую стадию заморозьте версии, сохраните эталонный отчет для критического пути выполнения и уточните шаги возврата к предыдущему состоянию. В совместных средах необходимы ограничения на частоту запросов, проверки принадлежности пользователя и четко определенный ответственный за обновление секретов. Лучше выбирать надежность, чем креативные одноразовые демонстрации.
Примечание для задачи 2117731bf26b: не храните ключи поставщика в репозитории, установите лимит токенов на сессию и сохраняйте отчеты рядом с фиксами для оценки, чтобы позже можно было сравнивать результаты работы разных моделей.