본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 06. 04. 17:26

대규모 AI 에이전트 자동화: Python을 활용한 Azure AI Foundry Routines 심층 분석

요약

Azure AI Foundry Routines를 사용하여 Python 기반의 프로덕션급 AI 에이전트 워크플로를 구축하는 방법을 다룹니다. 스케줄 및 타이머 트리거, 재시도 정책, 실행 관찰성 등 에이전트 오케스트레이션을 자동화하기 위한 핵심 아키텍처를 심층 분석합니다.

핵심 포인트

  • Azure AI Foundry Routines를 통한 에이전트 오케스트레이션 자동화
  • 스케줄 및 타이머 트리거를 활용한 시간 기반 워크플로 구축
  • 재시도 정책 및 디스패치 메커니즘을 통한 안정성 확보
  • 실행 관찰성(Observability)을 통한 에이전트 실행 이력 관리

Meta Description: Azure AI Foundry Routines와 Python을 사용하여 프로덕션 등급의 예약 및 시간 트리거 기반 AI 에이전트 워크플로를 구축하는 방법을 배워보세요. Azure AI 엔지니어를 위한 트리거 유형, 디스패치(Dispatch) 메커니즘, 재시도 정책(Retry policies), 실행 관찰성(Run observability) 및 아키텍처 모범 사례를 심층적으로 다룹니다.

Azure AI agents connected to a central cloud scheduler with calendar and clock icons on a dark azure-blue background

Azure AI Foundry Routines — 사용자의 일정에 따라 오케스트레이션되는 지능형 에이전트

목차

  1. 서론: 에이전트에게 보모가 필요해서는 안 됩니다
  2. Azure AI Foundry Routines란 무엇인가?
  3. 사전 요구 사항 및 환경 설정
  4. 트리거 유형 심층 분석
    • 4.1 스케줄 트리거 (Schedule Trigger) — 반복적인 Cron
    • 4.2 타이머 트리거 (Timer Trigger) — 단발성 실행
  5. 액션 유형: Responses API vs. Invocations API
  6. 루틴 생명주기 관리 (Routine Lifecycle Management)
  7. 수동 디스패치(Manual Dispatch) 및 테스트
  8. 실행 관찰성(Run Observability) 및 이력
  9. 재시도 정책(Retry Policy) 및 디스패치 동작 (전문가 코너)
  10. 프로덕션 모범 사례 및 아키텍처 패턴
  11. 알려진 제한 사항 및 향후 계획
  12. 결론

1. 서론: 에이전트에게 보모가 필요해서는 안 됩니다

Azure AI 엔지니어들에게 너무나 익숙해진 시나리오가 하나 있습니다. 여러분은 강력한 AI 에이전트를 구축했습니다. 이 에이전트는 밤사이의 텔레메트리(Telemetry)를 요약하거나, 주간 컴플라이언스 보고서를 생성하거나, 운영 데이터를 기반으로 문맥에 맞는 알림을 보냅니다. 모델은 견고합니다. 툴링(Tooling)도 연결되어 있습니다. 프롬프트(Prompt)도 완벽합니다. 하지만 매일 아침, 팀의 누군가가 수동으로 이를 실행시켜야 합니다. VM에 붙여놓은 Cron 작업일 수도 있고, 엔드포인트를 호출하는 Function을 호출하는 Logic App일 수도 있으며, 혹은 단순히 오전 7시에 누군가가 채팅 인터페이스에 타이핑을 하는 것일 수도 있습니다. 모든 경우에서 에이전트 자체는 자율적입니다. 하지만 _오케스트레이션(Orchestration)_은 자율적이지 않습니다.

Azure AI Foundry Routines는 그 방정식을 완전히 바꿉니다. Azure AI Foundry 플랫폼의 퍼스트 클래스 프리뷰(first-class preview) 기능으로 도입된 Routines를 사용하면, 외부 스케줄러나 중간 결합 인프라(glue infrastructure), 혹은 관리자(babysitter) 없이도 시간 기반 트리거(time-based trigger)를 에이전트 호출(agent invocation)에 직접 바인딩할 수 있습니다. 사용자는 언제(cron 표현식 또는 일회성 타임스탬프)와 무엇을(어떤 에이전트를 어떤 API 경로를 통해 호출할지) 정의하기만 하면, Foundry가 실행 큐잉(queueing), 상태 추적, 결과 기록, 일시적인 오류 발생 시 재시도(retry) 등 나머지 모든 과정을 처리합니다.

이 포스트는 완전한 L500 수준의 심층 분석(deep dive)입니다. 우리는 루틴을 생성하는

이것은 의미 있는 아키텍처의 변화입니다. 전통적으로 스케줄링된 AI 워크로드(workloads)는 에이전트 호출을 더 큰 워크플로우의 부수 효과(side-effect)로 취급하는 외부 오케스트레이터(Azure Scheduler, Logic Apps, ADF pipelines)를 필요로 했습니다. Routines를 사용하면 스케줄링 기본 요소(scheduling primitive)가 _에이전트 플랫폼 자체와 같은 위치에 배치(colocated)_되므로, 더 긴밀한 통합, 일급 가시성(first-class observability), 그리고 부트스트래핑 오버헤드(bootstrapping overhead) 제로를 의미합니다.

핵심 멘탈 모델 (Key mental model): Routine은 워크플로우 엔진이 아닙니다. 그것은 디스패치 기본 요소(dispatch primitive)입니다. 즉, 시간 신호(time signal)와 에이전트 엔드포인트(agent endpoint) 사이의 경량화되고 내구성이 있는 바인딩(binding)이며, 내장된 재시도 의미론(retry semantics)과 쿼리 가능한 실행 로그(run log)를 갖추고 있습니다.

구성 요소 (Component)설명 (Description)
트리거 (Trigger)실행 시점 — schedule (cron) 또는 timer (one-shot)
...

3. 사전 요구 사항 및 환경 설정 (Prerequisites & Environment Setup)

루틴 코드를 한 줄이라도 작성하기 전에 다음 조건이 충족되었는지 확인하십시오.

지역 가용성 (preview): Routines는 현재 다음 Azure 지역에서만 사용할 수 있습니다:

  • East US / East US 2
  • West US / West US 2 / West Central US / North Central US
  • Sweden Central
  • Japan East

만약 Foundry 프로젝트가 이 지역들 이외의 곳에 프로비저닝(provisioned)되어 있다면, 포털에 Routines 메뉴가 나타나지 않으며 SDK 호출이 실패합니다. 진행하기 전에 프로젝트 지역을 확인하십시오.

RBAC: 사용자의 ID(사용자 또는 서비스 주체(service principal))는 프로젝트 범위에서 Foundry User 역할 또는 그 이상의 권한을 보유해야 합니다. 이 역할은 최근 Azure AI User에서 이름이 변경되었음을 참고하십시오. 역할 ID와 권한은 변경되지 않았으나, 배포 과정 중 포털 표시에는 여전히 이전 이름이 나타날 수 있습니다.

에이전트 ID 요구 사항: 루틴 작업에 바인딩된 모든 에이전트는 구성된 **에이전트 ID (agent identity)**를 가져야 합니다. 프롬프트 전용(Prompt-only) 에이전트는 루틴 생성 시점에 서비스에 의해 명시적으로 거부됩니다. 호출 시점이 아닌 생성 시점에 거부되므로, 이 문제는 조기에 드러납니다.

SDK 설치:

# Azure AI Projects SDK 설치 (루틴 및 기간 약어 사용을 위해 v2.2.0+ 필요)
pip install "azure-ai-projects>=2.2.0"

...

왜 특별히 >=2.2.0 인가요? 버전 2.2.0에서는 client.beta.routines 네임스페이스(namespace)와 타이머 트리거(timer triggers)를 위한 기간 약어 구문("30m", "2h")이 도입되었습니다. 이전 버전의 beta 클라이언트에는 routines 속성이 없습니다.

클라이언트 초기화 (Client initialization):

import os
from azure.identity import DefaultAzureCredential
from azure.ai.projects import AIProjectClient
...

운영 팁 (Production tip): AKS 또는 Azure Container Apps 워크로드에서는 관리 ID(managed identity) 비밀 값을 사용하는 대신 워크로드 ID 페더레이션(workload identity federation)을 사용하세요. DefaultAzureCredential은 워크로드 ID 웹훅(workload identity webhook)에 의해 AZURE_CLIENT_ID 환경 변수가 주입될 때 이를 자동으로 해결합니다.

4. 트리거 유형 심층 분석 (Trigger Types Deep Dive)

Azure AI Foundry Routines는 현재 프리뷰(preview) 단계에서 정확히 두 가지 트리거 유형을 지원합니다. 단순히 구문(syntax)뿐만 아니라 동작 의미론(behavioral semantics)을 이해하는 것이 운영상의 정확성을 위해 매우 중요합니다.

Comparison diagram showing Schedule Trigger with a clock on the left and One-Shot Timer Trigger on the right

스케줄 트리거(Schedule triggers)는 cron 표현식에 따라 무기한 반복되며, 타이머 트리거(timer triggers)는 정확히 한 번 실행됩니다

4.1 스케줄 트리거 (Schedule Trigger) — 반복되는 Cron

schedule 트리거는 5개 필드 cron 표현식을 기반으로 반복해서 실행됩니다. 서비스는 5분의 최소 간격을 엄격하게 적용합니다. 5분 미만의 주기로 해석되는 cron 표현식은 생성 시점에 400 에러와 함께 거부됩니다.

Cron 필드 순서: minute hour day-of-month month day-of-week

Cron 표현식의미
0 7 * * 1-5평일 매일 07:00
...

time_zone 필드는 필수이며, 모든 IANA 시간대 식별자(예: America/Los_Angeles, Europe/Stockholm, Asia/Tokyo) 또는 Windows 시간대 이름을 허용합니다.

시간대 함정 (Timezone pitfall): Foundry 포털은 트리거 시간을 _브라우저의 로컬 시간대_로 해석합니다. 프로덕션(production) 루틴의 경우, 항상 SDK 또는 REST API를 통해 프로그래밍 방식으로 생성하고 time_zone을 IANA 시간대로 명시적으로 설정하십시오. 이렇게 하면 일광 절약 시간제(DST) 전환이나 사용자 로케일(locale)로 인한 모호성을 제거할 수 있습니다.

import os
from azure.identity import DefaultAzureCredential
from azure.ai.projects import AIProjectClient
...

루틴당 하나의 트리거 (preview 제약 사항): V1Preview에서는 triggers 맵이 정확히 하나의 엔트리만 지원합니다. 동일한 에이전트에 대해 여러 스케줄로 팬아웃(fan out)하려면 별도의 루틴을 생성하십시오.

4.2 타이머 트리거 (Timer Trigger) — 단발성 실행

timer 트리거는 미래의 특정 시점에 정확히 한 번 실행됩니다. 이는 출시일 작업, 예정된 데이터 마이그레이션, 알려진 트래픽 급증 전의 모델 웜업(warm-up), 또는 배포 후 지연 실행을 위한 적절한 기본 요소(primitive)입니다.

at 필드는 세 가지 형식을 허용합니다:

형식예시사용 사례
UTC 오프셋이 포함된 ISO 8601"2026-09-01T09:00:00Z"절대 시간, UTC 고정
...
import os
from azure.identity import DefaultAzureCredential
from azure.ai.projects import AIProjectClient
...

중요: 타이머 루틴은 정확히 한 번 실행되며 스스로 재스케줄링되지 않습니다. 트리거가 실행된 후, 루틴은 실행 기록과 함께 시스템에 남아 있지만 다시 실행되지는 않습니다.

5. 액션 유형 (Action Types): Responses API vs. Invocations API

잘못된 액션 유형을 선택하는 것은 Routines를 사용할 때 발생하는 미묘한 프로덕션 실수 중 하나입니다. 두 유형 모두 에이전트를 호출하지만, **상태 모델(state model), 세션 범위(session scope), 그리고 연속성 의미론(continuation semantics)**에서 차이가 있습니다.

차원invoke_agent_responses_apiinvoke_agent_invocations_api
API 경로 (API pathway)Responses APIInvocations API
...
# --- 액션 유형 비교 (Action Type Comparison) ---

# 옵션 A: Responses API — 상태가 없거나(stateless) 대화 스레드가 유지됨(conversation-threaded)
...

의사결정 휴리스틱 (Decision heuristic): 상태가 없거나(stateless) 대화 스레드가 유지되는(conversation-threaded) 워크로드(일일 보고서, 알림, 요약)에는 invoke_agent_responses_api를 사용하세요. 에이전트가 예약된 호출 간에 지속되어야 하는 **세션 범위 메모리(session-scoped memory) 또는 도구 상태(tool state)**에 의존하는 경우에는 invoke_agent_invocations_api를 사용하세요.

6. 루틴 생명주기 관리 (Routine Lifecycle Management)

루틴은 생성(create_or_update를 통해), 일시 중지/재개, 업데이트 및 삭제를 포함한 전체 생명주기를 지원합니다. 프로덕션 환경에서 다수의 루틴(fleet of routines)을 관리할 때는 각 작업의 의미론(semantics)을 이해하는 것이 중요합니다.

import os
from azure.identity import DefaultAzureCredential
from azure.ai.projects import AIProjectClient
...

업데이트 의미론 — 전체 교체 함정 (Update semantics — the full-replace trap): create_or_update는 완전한 교체(complete replacement)를 수행합니다. V1Preview에는 부분적인 PATCH 기능이 없습니다. 업데이트할 때마다 항상 전체 정의를 제공해야 합니다. 일반적인 패턴은 먼저 get()을 호출하여 필요한 필드를 변경(mutate)한 다음, 전체 객체를 다시 전달하는 것입니다.

7. 수동 디스패치 및 테스트 (Manual Dispatch & Testing)

프로덕션에서 예약된 트리거(scheduled triggers)에 의존하기 전에, 루틴이 에이전트에 올바르게 도달하는지 검증하십시오. dispatch 작업은 트리거 일정을 우회하여 즉시 일회성 실행을 큐에 추가합니다.

import os, time
from azure.identity import DefaultAzureCredential
from azure.ai.projects import AIProjectClient

endpoint = os.environ["AZURE_AI_PROJECT_ENDPOINT"]
client = AIProjectClient(endpoint=endpoint, credential=DefaultAzureCredential())

# --- Responses API 루틴을 위한 수동 디스패치 ---
# 페이로드(payload)의 'type'은 루틴의 액션 타입과 정확히 일치해야 합니다
result = client.beta.routines.dispatch(
    routine_name="daily-ops-summary",
    payload={
        "type": "invoke_agent_responses_api",
        # 선택 사항: 이 테스트 실행에 대해서만 루틴에 설정된 프롬프트를 재정의(override)합니다
        "input": "Generate a concise test summary for the last 15 minutes of telemetry.",
    },
)

dispatch()는 즉시 반환됩니다 — 실행이 완료된 것이 아니라 큐(enqueue)에 추가된 상태입니다.

print(f"dispatch_id: {result.dispatch_id}")
print(f"action_correlation_id: {result.action_correlation_id}")
print(f"task_id: {result.task_id}")

--- 실행 완료를 확인하기 위해 실행 이력(run history)을 폴링(Poll)합니다 ---

print("실행이 완료될 때까지 기다리는 중...")
time.sleep(10) # ~를 위한 시간을 허용합니다

AI 자동 생성 콘텐츠

본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0