Галоўная / Артыкулы

Навучаем уласную мадэль у Azure ML і выклікаем яе з агента Foundry

Навучаем, рэгіструем і разгортваем мадэль адтоку кліентаў на кіраваным endpoint Azure ML, а потым даём яе агенту Foundry як FunctionTool — з аўтэнтыфікацыяй і нататкамі для прадакшну.

Выдавец: REACTAPP.TOP7 хв чытання1652 слоў

Крыніцы: 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.
  • Foundry FunctionTool. эта ўстановка служыць мостам. Foundry не ведае і не цікавіцца тым, што функцыя, якая працюе за допамогай цьего інструмента, вызывае канцэнтры Azure ML. Для агента гэта проста назва, схема і рэзультат.
  • Пярэшкоды

    1. Рабочая зона Azure ML і праект Foundry. Яны можаць знаходзіцца ў тых жа або разных групах рысакоў, таму што нічога тут не выкалікае патрэбы ў спяльнай інфраструктурэ.
    2. 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 для адпаведзяў — усё залежыць толькі ад таго, што функцыя рабіць у сэрварных умовах. Яна можа запытваць базу дадзенаў, вызываць функцыю 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 у месцы, якое можна будзе пераглядзець, і рэгулярна перазьвяртайцеся да дадзеных для трэніравання, а не толькі пасля таго, як прыказанні стануць візуабельна гorsымі.
  • Выбор правай платформы

    Для большайшай часткі правакаў з генератыўнага ІІ Foundry-ў каталазе ёсць правы інструмент, а команды, якія не маюць власных дадзенаў для навчання, можаць ніколі не патрабаваць чагось большога. Калі задача ператвараецца на прагнозаванне паведання власных кліяў на аднойчынай історыі, тады Azure ML ёсць лепшы выбар. У іншым случае мовны мадэль выкарыстоўваецца для задачы, якой яна не была створана, альбо інфраструктура для обслугавання будуе створана вручную. Усё цэўна прыкрэпляецца за дапамогою адной задачы навчання, аднаго зарэгістраванага мадэлю, аднаго кераванага канцэнтра і адного FunctionTool. Платформы застаюцца окрэмымі, кожная віконвае тое, у чаму яна супэрнай.