← 문서 목록으로 돌아가기

Microsoft Foundry·Azure OpenAI API 연결 안내

배포, v1 엔드포인트와 권한을 확인하고 최소 호출, 스트림과 사용량을 검증합니다.

적용 범위와 사전 조건

권한이 있는 Azure 구독, 자원과 모델 배포가 준비된 상태에서 시작합니다. OpenAI Python SDK로 Microsoft v1 채팅 API를 호출하며, 자원을 만들거나 모든 모델이 같은 기능을 지원한다고 가정하지 않습니다. 포털에서 자원명, 실제 모델 버전, 배포명, 배포 유형, 할당량과 네트워크 접근 방식을 기록하세요. model에는 다른 공급사의 목록에서 추측한 모델명이 아닌 자신의 배포명을 넣습니다.

Chat Completions와 예제의 max_completion_tokens를 지원하는 배포를 선택하세요. Responses, 도구, 이미지, 추론 매개변수와 스트리밍은 각각 확인해야 합니다. Responses를 지원하지 않는 배포는 URL을 바꿔 반복 호출해도 지원되지 않습니다. Azure OpenAI와 Foundry의 비 OpenAI 모델은 기능과 권한이 다르며 프로젝트 관리 엔드포인트는 추론용 주소가 아닙니다.

엔드포인트와 권한 확인

v1 base_url은 자원의 /openai/v1/ 경로를 사용합니다. 해당 services.ai.azure.com 자원 호스트 형식도 지원됩니다. 포털의 실제 설정을 복사하고 프로젝트 URL이나 이전 /deployments/... 경로와 섞지 마세요. v1에는 날짜 형식 api-version이 필요 없지만 이전 API의 버전 요건은 별개입니다.

처리 위치는 배포 유형에 따라 달라집니다. 자원명만 보고 Global, Data Zone 또는 지역 배포의 경계를 판단하면 안 됩니다. 관리자가 필요한 자원 범위에 추론 권한을 할당해야 합니다. Azure OpenAI는 Cognitive Services OpenAI User, 비 OpenAI Foundry 모델은 해당 문서의 Cognitive Services User 요건을 확인하세요. 구독 Owner나 Contributor가 곧 추론 권한은 아닙니다. 프록시, 프라이빗 엔드포인트, DNS와 방화벽도 확인하세요.

설치와 최소 요청

python3 -m venv .venv
. .venv/bin/activate
python -m pip install --upgrade openai

자리표시자를 실제 자원과 배포로 바꾸세요. AZURE_OPENAI_API_KEY는 승인된 서버 실행 환경에서 안전하게 주입합니다. 브라우저 코드, 저장소나 공유하는 터미널 기록에 키를 넣지 마세요.

export AZURE_OPENAI_BASE_URL='https://YOUR-RESOURCE.openai.azure.com/openai/v1/'
export AZURE_OPENAI_DEPLOYMENT='YOUR-DEPLOYMENT-NAME'

아래를 azure_chat.py로 저장하고 비용과 테스트 권한을 확인한 뒤 python azure_chat.py를 실행하세요. 출력 상한128과 클라이언트 제한 시간30초는 예제의 제어값이며 플랫폼 할당량이나 지원 보장이 아닙니다. 처음에는 SDK 자동 재시도를0으로 두어 원래 오류를 쉽게 확인합니다.

import os
from openai import OpenAI

client = OpenAI(
    base_url=os.environ["AZURE_OPENAI_BASE_URL"],
    api_key=os.environ["AZURE_OPENAI_API_KEY"],
    timeout=30.0,
    max_retries=0,
)
request = {
    "model": os.environ["AZURE_OPENAI_DEPLOYMENT"],
    "messages": [{"role": "user", "content": "Reply with one short greeting."}],
    "max_completion_tokens": 128,
}
answer = client.chat.completions.create(**request)
if not answer.choices:
    raise RuntimeError("No completion choice returned")
print(answer.choices[0].message.content or "")
print(answer.usage.model_dump() if answer.usage else "usage unavailable")

Entra ID로 정적 키 대체하기

서버 애플리케이션은 관리 ID나 승인된 Entra 자격 증명 체인을 사용할 수 있습니다. 의존 패키지를 설치하고 앞의 client 초기화를 다음 코드로 바꾸세요. 먼저 역할을 할당하고 실제 실행 ID를 검증합니다. 액세스 토큰을 출력하지 마세요. 현재 공식 v1 예제의 scope는 https://ai.azure.com/.default입니다.

python -m pip install --upgrade azure-identity
from azure.identity import DefaultAzureCredential, get_bearer_token_provider

token_provider = get_bearer_token_provider(
    DefaultAzureCredential(), "https://ai.azure.com/.default"
)
client = OpenAI(
    base_url=os.environ["AZURE_OPENAI_BASE_URL"],
    api_key=token_provider,
    timeout=30.0,
    max_retries=0,
)

스트림과 오류 처리

배포가 스트리밍 채팅을 지원하면 비스트리밍 호출을 다음으로 바꿉니다. 인덱스를 읽기 전에 choices를 확인하고 텍스트 증분을 처리하세요. usage가 있으면 별도로 저장합니다. 일부 배포는 지원하는 사용량 옵션이 있어야 반환하므로 usage 누락을 요금0으로 해석하면 안 됩니다. Responses는 이벤트 구조가 달라 별도 파서가 필요합니다.

usage = None
with client.chat.completions.create(**request, stream=True) as events:
    for part in events:
        if part.usage is not None:
            usage = part.usage
        if not part.choices:
            continue
        text = part.choices[0].delta.content
        if text:
            print(text, end="", flush=True)
print()
print(usage.model_dump() if usage else "usage unavailable")
  • 401/403: 인증 출처, 자원 범위, 역할과 네트워크 정책을 확인하고 키나 토큰은 기록하지 않습니다.
  • 404: 호스트, v1 경로와 배포명을 점검하고 관리 주소와 혼동하지 않습니다.
  • 400: 모델의 API, 매개변수와 콘텐츠 제한을 확인하며 선택 매개변수를 줄여 원인을 찾습니다.
  • 429: 할당량과 동시 실행을 확인하고 응답의 대기 안내와 제한된 백오프를 적용합니다. 시간 초과나5xx를 무한 재시도하지 않습니다.

검수, 비용과 데이터 처리

민감 정보를 제거한 요청 식별자, 모델·배포 버전, finish reason, 소요 시간과 사용량을 남겨 Azure 청구와 대조합니다. 출력 잘림, 거부와 스트림 중단도 각각 검증하세요. 출력, 캐시, 배포 용량과 제삼자 서비스 요금은 실제 과금 방식에 맞춰 확인하고 다른 경로의 단가를 가져오지 마세요.

보관, 콘텐츠 안전 처리와 Global 배포의 처리 범위는 적용 약관으로 확인합니다. 애플리케이션 로그와 접근도 따로 통제하세요. 이 예제는 오프라인 구문 검사만 거쳤습니다. 구독 사용, 비밀 읽기나 실제 모델 호출은 하지 않았으므로 계정 접근, 품질과 비용은 승인된 환경에서 검증해야 합니다.

Claude: 네이티브 API와 구매 자격 확인

Claude는 별도의 Messages API를 사용합니다. AnthropicFoundry에 리소스의 https://YOUR-RESOURCE.services.ai.azure.com/anthropic을 기본 URL로 지정하며, HTTP Messages 대상 경로는 /anthropic/v1/messages입니다. 요청의 model에는 실제 배포 이름을 넣어야 합니다. 이 이름은 카탈로그의 모델 ID와 다를 수 있습니다. 앞의 OpenAI v1 예제는 해당 API를 명시적으로 지원하는 배포에 적용됩니다. Foundry 프로젝트 관리 URL, OpenAI v1 경로, Claude 네이티브 경로는 용도가 서로 다릅니다. 파트너 모델 카탈로그에 포함되어 있다는 사실만으로 OpenAI API 호환성을 판단할 수 없습니다.

클라이언트를 설정하기 전에 다음 순서로 확인하세요.

  1. 자격을 갖춘 Azure 유료 구독인지, 청구 국가가 지원되는지, Marketplace 제품을 구매할 권한이 있는지 확인합니다. 현재 Microsoft Claude 문서는 Cloud Solution Provider(CSP) 구독을 지원하지 않는다고 명시합니다. 다른 구독 제한도 있으므로 Azure 계정이 있다는 사실만으로 구매 자격이 확인되지는 않습니다.
  2. 모델 카드와 배포 세부 정보에서 모델, 호스팅 버전, 배포 유형, 현재 지원되는 배포 지역을 기록합니다. 버전 1은 Anthropic 인프라에서 실행되고 버전 2는 Azure에서 호스팅됩니다. 둘 다 Global Standard를 제공하며, Data Zone Standard(US)는 일부 Azure 호스팅 모델 버전만 지원합니다. 리소스가 속한 국가로 추정하지 말고 정확한 모델·버전·유형 조합을 확인합니다.
  3. 네이티브 엔드포인트와 배포 이름을 복사합니다. Entra 추론에는 Foundry 리소스 범위의 Cognitive Services User 역할과 실제 실행 ID를 확인합니다. Azure OpenAI 전용 역할이나 리소스 관리 역할로 이 확인을 대신할 수 없습니다. 네트워크 접근도 별도로 확인합니다.
  4. 배포가 지원하는 인증 방식, Messages 매개변수, 스트리밍과 할당량을 확인합니다. 접근이 제한된 일부 모델은 Entra ID만 허용합니다. Files, Skills, 도구 등의 고급 기능은 호스팅 및 모델 버전에 따라 다르므로 다른 Claude 배포의 매개변수를 그대로 사용하지 마세요.

Anthropic에서 호스팅하는 v1 요청은 Azure와 선택한 Azure 지역 밖에서 처리될 수 있습니다. Azure에서 호스팅하는 v2도 Global 또는 Data Zone의 처리 범위와 저장 데이터의 위치를 구분해 검토해야 합니다. 두 구성 모두 Anthropic이 판매자이자 운영자이며, 프롬프트와 출력의 독립적인 데이터 처리자입니다. Claude Marketplace 및 데이터 처리 약관을 적용하세요. Azure OpenAI의 보존 기간이나 SLA 설명이 Claude에 자동으로 적용되지는 않습니다.

Claude: API 키를 사용하는 독립적인 최소 요청

API 키를 허용하는 배포라면 승인된 서버에 패키지를 설치하고 다음 자리표시자를 설정합니다. 키는 안전한 서버 비밀 환경에서 제공하며 브라우저 코드나 복사하는 예제에 넣지 마세요. 다음 Python 코드는 별도의 Claude 예제로 저장합니다. 이번에는 오프라인 검사만 수행했으며 패키지 설치나 클라우드 요청을 실행하지 않았습니다. 출력 한도와 타임아웃은 예시 제어값이고 SDK 자동 재시도는 비활성화되어 있습니다.

아래 API 키 방식과 Entra 방식은 모두 base_url을 명시합니다. SDK는 ANTHROPIC_FOUNDRY_RESOURCE도 자동으로 읽으므로 설정 전에 이 환경 변수를 해제하세요. 대신 resource로 초기화한다면 base_url을 전달하지 않고 자동으로 읽는 ANTHROPIC_FOUNDRY_BASE_URL도 해제합니다.

python -m pip install --upgrade anthropic azure-identity
# Explicit base_url must not be combined with the SDK resource-name fallback.
unset ANTHROPIC_FOUNDRY_RESOURCE
# Copy both values from your actual Foundry deployment in the console.
export FOUNDRY_CLAUDE_BASE_URL='https://YOUR-RESOURCE.services.ai.azure.com/anthropic'
export FOUNDRY_CLAUDE_DEPLOYMENT='YOUR-CLAUDE-DEPLOYMENT-NAME'
# Supply FOUNDRY_CLAUDE_API_KEY through the approved server secret environment.
import os
from anthropic import AnthropicFoundry

client = AnthropicFoundry(
    base_url=os.environ["FOUNDRY_CLAUDE_BASE_URL"],
    api_key=os.environ["FOUNDRY_CLAUDE_API_KEY"],
    timeout=30.0,
    max_retries=0,
)
message = client.messages.create(
    model=os.environ["FOUNDRY_CLAUDE_DEPLOYMENT"],
    max_tokens=128,
    messages=[{"role": "user", "content": "Reply with one short greeting."}],
)
for block in message.content:
    if block.type == "text":
        print(block.text)
print(message.stop_reason)
print(message.usage.model_dump())

응답은 형식이 지정된 content 블록을 반환합니다. 텍스트 블록만 출력하고 stop_reason과 usage를 확인한 뒤 결과를 검수하세요. 네이티브 HTTP는 x-api-key와 anthropic-version: 2023-06-01을 사용하며 OpenAI의 choices 응답 구조를 사용하지 않습니다. thinking이나 도구 매개변수는 배포가 지원하는 조합을 확인한 후 추가합니다.

Claude: API 키를 Entra ID로 대체하기

앞 예제의 import os, AnthropicFoundry, Messages 요청은 유지하고 클라이언트 초기화만 다음 코드로 바꿉니다. 승인된 자격 증명 체인을 사용하고 가능하면 애플리케이션의 관리 ID를 선택하며 리소스 역할을 먼저 확인하세요. azure_ad_token_provider는 https://ai.azure.com/.default 범위의 토큰을 가져옵니다. 네이티브 HTTP에서는 Authorization: Bearer ...에 해당합니다. 인증 방식은 하나만 지정하세요. 이 provider를 사용할 때는 명시적인 API 키와 SDK가 자동으로 읽는 ANTHROPIC_FOUNDRY_API_KEY 설정을 제거하고 토큰을 출력하지 마세요.

from azure.identity import DefaultAzureCredential, get_bearer_token_provider

token_provider = get_bearer_token_provider(
    DefaultAzureCredential(), "https://ai.azure.com/.default"
)
client = AnthropicFoundry(
    base_url=os.environ["FOUNDRY_CLAUDE_BASE_URL"],
    azure_ad_token_provider=token_provider,
    timeout=30.0,
    max_retries=0,
)

Claude: 스트리밍, 오류와 검수

지원되는 배포에서 Messages에 stream=True를 지정하면 SSE를 수신합니다. 네이티브 이벤트는 message_start, 인덱스가 있는 content_block_start / content_block_delta / content_block_stop, 이어서 message_delta와 message_stop 순서로 진행됩니다. 텍스트 델타는 delta.type == "text_delta"를 사용하며 도구와 thinking은 다른 블록 형식을 사용합니다. ping, 알 수 없는 이벤트, 오류를 따로 처리하고 최종 사용량과 중지 정보를 보관하세요. 완료 전에 연결이 끊긴 스트림은 미완료로 표시합니다. OpenAI의 choices[].delta나 Responses 이벤트 파서로는 이 프로토콜을 파싱할 수 없습니다. HTTP 상태가 성공이어도 스트림이 정상적으로 완료된다는 보장은 없습니다.

Claude의 401/403은 선택한 인증 방식, 토큰 범위, 리소스 역할을 확인합니다. 404는 /anthropic과 정확한 배포 이름을 확인합니다. 400은 지원하지 않는 매개변수나 특정 모델의 데이터 보존 요구 사항 때문일 수 있으며, 후자는 적용 약관에 따라 검토해야 합니다. 구매 또는 지역 오류는 구독 자격과 모델 버전의 가용성을 확인합니다. 429는 구독·모델·버전별 할당량을 확인하고 재시도 횟수를 제한합니다. 다른 지역에 리소스를 만들어도 동일한 Global 할당량 풀을 공유할 수 있습니다. 앞의 OpenAI 배포 요금을 적용하지 말고 실제 Marketplace Claude Consumption Unit(CCU) 미터, 입력·출력과 캐시 사용량을 청구 내역과 대조하세요. 승인된 환경에서 민감한 내용이 없는 정상 출력, 출력 잘림, 스트림 연결 끊김을 각각 확인한 뒤 연동을 검수합니다.

공식 자료

확인일: 2026-10-17. 사용 전에 현재 문서와 포털을 다시 확인하세요.