03

OpenAI SDK로 생성형 AI 챗 앱 만들기

Visual Studio Code와 Python으로 ChatCompletions API·Responses API를 사용하는 챗 애플리케이션을 직접 코딩하고, 대화 맥락 유지·스트리밍·비동기 처리까지 구현합니다.

실습 준비물

  • 활성 상태의 Azure 구독, Visual Studio Code, Python 3.13.xx(3.14는 일부 의존성 미지원 - 3.13.12로 테스트됨), Git, Azure CLI가 설치되어 있어야 합니다.
  • 참고: 이 실습에서 사용하는 일부 기술은 미리 보기(preview) 또는 활발히 개발 중인 상태입니다. 예상치 못한 동작·경고·오류가 발생할 수 있습니다.

1. Foundry 프로젝트 만들기

  • Microsoft Foundry 포털(https://ai.azure.com)을 열고 Azure 자격 증명으로 로그인합니다. 처음 로그인할 때 나타나는 팁·퀵스타트 창은 닫습니다.
  • New Foundry 옵션이 꺼져 있다면 켜고, 새 프로젝트를 만들며 Advanced options에서 Foundry resource(기본 이름 사용), Subscription, Resource group, Region(권장 리전 목록 중 하나)을 지정합니다.
  • 프로젝트가 생성되기를 기다린 뒤 홈 페이지를 확인합니다.

2. gpt-5.2 모델 배포하기

  • 다음으로 챗 애플리케이션에서 사용할 모델을 배포합니다.
  • Discover 페이지의 Models 탭에서 모델 카탈로그를 봅니다.
  • 모델 카탈로그에서 gpt-5.2를 검색합니다.
  • 모델 카드를 검토한 뒤 기본 설정으로 배포합니다.
  • 모델이 배포되면 모델 플레이그라운드가 열립니다 - 원한다면 그곳에서 테스트해볼 수 있습니다.

3. Azure OpenAI 엔드포인트 확인하기

  • 클라이언트 애플리케이션에서 모델에 연결하려면 엔드포인트가 필요합니다. 이 실습에서는 OpenAI SDK로 모델과 대화하며, Entra ID 인증을 사용하는 Azure OpenAI 엔드포인트로 연결합니다.
  • 참고: Entra ID 인증 대신 프로젝트의 API 키를 사용할 수도 있지만, 가능하면 Entra ID 인증을 사용하는 것이 좋습니다.
  • 메뉴 바에서 Home 페이지를 선택하고, 거기 표시된 Azure OpenAI Endpoint를 기억해 둡니다.
  • TIP: 이 실습에서는 프로젝트 엔드포인트가 아니라 Azure OpenAI 엔드포인트를 사용합니다!
Microsoft Foundry 홈에서 마스킹된 API 키와 프로젝트 및 Azure OpenAI 엔드포인트 확인
Microsoft Foundry 홈에서 마스킹된 API 키와 프로젝트 및 Azure OpenAI 엔드포인트 확인

4. GitHub에서 애플리케이션 파일 가져오기

  • 챗 애플리케이션 개발에 필요한 초기 애플리케이션 파일은 GitHub 저장소에 제공되어 있습니다.
  • Visual Studio Code를 엽니다.
  • 명령 팔레트(Ctrl+Shift+P)를 열고 Git:clone 명령 입력을하면 나오는 Clone from Github 를 클릭합니다. Repository Name을 입력하는 창이 나오면 https://github.com/microsoftlearning/mslearn-ai-studio 를 입력 합니다. 로컬 PC에 클론(복사) 할 수 있는 위치를 지정하라고 나옵니다. 원하는 폴더를 선택 후 저장소를 로컬 폴더(어디든 상관없음)에 저장한 뒤 엽니다. '새로운 New Window에서 열기'를 선택하여 VS Code 윈도우가 새롭게 시작합니다. 작성자를 신뢰하는지 확인하는 메시지가 뜰 수 있습니다.
Visual Studio Code에서 Microsoft Learning의 mslearn-ai-studio GitHub 저장소를 복제하기 위해 주소 입력
Visual Studio Code에서 Microsoft Learning의 mslearn-ai-studio GitHub 저장소를 복제하기 위해 주소 입력

5. Python 환경 준비하기 (Github Copilot을 이용하여 설치할것!)

  • Visual Studio Code에서 Extensions 창을 열어 Python 확장이 설치되어 있지 않다면 설치합니다.
  • 명령 팔레트에서 python:select interpreter 명령을 사용해 Python 3.13 설치를 기반으로 새 Venv 환경을 만듭니다.
  • TIP: 종속성 설치 메시지가 뜨면 /labfiles/foundry-chat/python/chat-app 폴더의 requirements.txt에 있는 것들을 설치해도 되지만, 하지 않아도 괜찮습니다 - 나중에 설치할 것입니다!
  • 탐색기(Explorer) 창에서 /labfiles/foundry-chat/python/chat-app 폴더로 이동합니다. 애플리케이션 파일에는 다음이 포함됩니다: .env(구성 파일) · requirements.txt(패키지 종속성) · chat-app.py(챗 앱 코드) · chat-async.py(비동기 버전 코드).
  • chat-app 폴더를 오른쪽 클릭하고 Open in integrated terminal을 선택합니다(또는 Terminal 메뉴에서 터미널을 열고 해당 폴더로 이동).
  • 참고: Visual Studio Code에서 터미널을 열면 Python 환경이 자동으로 활성화됩니다. 시스템에서 스크립트 실행을 허용해야 할 수도 있습니다.
  • (.venv) 접두사와 함께 터미널이 올바른 폴더에서 열려 있는지 확인한 뒤, 다음 명령으로 OpenAI SDK·Azure Identity 등 필요한 패키지를 설치합니다.
pip install -r requirements.txt
Visual Studio Code 명령 팔레트에서 Python 3.13 인터프리터와 가상 환경 만들기 선택
Visual Studio Code 명령 팔레트에서 Python 3.13 인터프리터와 가상 환경 만들기 선택
Visual Studio Code 탐색기에서 chat-app 폴더의 통합 터미널 열기
Visual Studio Code 탐색기에서 chat-app 폴더의 통합 터미널 열기

6. .env 구성 값 채우기

  • 탐색기 창의 chat-app 폴더에서 .env 파일을 선택해 엽니다. 그런 다음 구성 값을 Azure OpenAI Endpoint와 gpt-5.2 모델 배포에 할당된 이름으로 업데이트합니다.
  • TIP: Foundry 포털의 프로젝트 홈 페이지에서 Azure OpenAI Endpoint(프로젝트 엔드포인트 아님!)를 복사하고, MODEL_DEPLOYMENT 설정에 배포에 할당된 정확한 이름을 입력하세요.
  • 수정한 구성 파일을 저장합니다.
Visual Studio Code의 .env 파일에 Azure OpenAI 엔드포인트와 gpt-5.2 모델 배포 이름 구성
Visual Studio Code의 .env 파일에 Azure OpenAI 엔드포인트와 gpt-5.2 모델 배포 이름 구성

7. ChatCompletions API로 클라이언트 초기화하기

  • ChatCompletions API는 대규모 언어 모델용 클라이언트 애플리케이션을 만드는 잘 정립된 방법으로, 널리 채택되어 있습니다.
  • chat-app 폴더에서 chat-app.py 파일(chat-async.py 아님)을 열고 기존 코드를 검토합니다. OpenAI SDK로 모델에 접근하는 코드를 추가할 것입니다.
  • TIP: 코드를 추가할 때 들여쓰기를 정확히 유지하세요.
  • 코드 파일 상단, 기존 네임스페이스 참조 아래에서 'Import namespaces' 주석을 찾아 다음 코드를 추가합니다. 그런 다음 main 함수에서 'Initialize the OpenAI client' 주석을 찾아 클라이언트를 만드는 코드를 추가합니다.
# import namespaces
from openai import OpenAI
from azure.identity import DefaultAzureCredential, get_bearer_token_provider

# Initialize the OpenAI client
token_provider = get_bearer_token_provider(
    DefaultAzureCredential(), "https://ai.azure.com/.default"
)

openai_client = OpenAI(
    base_url=azure_openai_endpoint,
    api_key=token_provider
)
Visual Studio Code의 chat-app.py에서 Azure 자격 증명 토큰 공급자와 OpenAI 클라이언트 초기화
Visual Studio Code의 chat-app.py에서 Azure 자격 증명 토큰 공급자와 OpenAI 클라이언트 초기화

8. 응답 받기 코드 추가 및 실행하기

  • main 함수에는 사용자가 종료할 때까지 프롬프트를 요청하는 코드가 이미 제공되어 있습니다. 이 루프 안에서 'Get a response' 주석을 찾아 다음 코드를 추가합니다. ChatCompletions API는 대화를 JSON 메시지 모음으로 캡슐화하며, 보통 지침을 담은 시스템 프롬프트와 사용자 입력을 담은 사용자 프롬프트로 구성됩니다.
# Get a response
completion = openai_client.chat.completions.create(
    model=model_deployment,
    messages=[
        {
            "role": "system",
            "content": "You are a helpful AI assistant that answers questions and provides information."
        },
        {
            "role": "user",
            "content": input_text
        }
    ]
)
print(completion.choices[0].message.content)
Visual Studio Code의 chat-app.py에서 ChatCompletions API 응답 생성 코드 추가
Visual Studio Code의 chat-app.py에서 ChatCompletions API 응답 생성 코드 추가

9. 로그인 후 실행해 보기

  • 코드 파일 변경 사항을 저장합니다. 그런 다음 터미널에서 다음 명령으로 Azure에 로그인합니다(여러 테넌트에 구독이 있다면 --tenant 매개변수로 테넌트를 지정해야 할 수도 있습니다).
az login
Visual Studio Code에서 az login 실행 후 Microsoft 회사 또는 학교 계정 선택
Visual Studio Code에서 az login 실행 후 Microsoft 회사 또는 학교 계정 선택

10. 첫 실행 테스트

  • 메시지가 표시되면 안내에 따라 Azure에 로그인합니다. 그런 다음 명령줄에서 로그인 과정을 완료하며 Foundry 리소스가 포함된 구독의 세부 정보를 확인(필요하면 확인)합니다.
  • 로그인 후 다음 명령으로 애플리케이션을 실행합니다. 프로그램이 터미널에서 실행되어야 합니다(그렇지 않다면 오류를 해결하고 다시 시도하세요).
python chat-app.py

11. 프롬프트 테스트하기

  • 메시지가 표시되면 'ELIZA 챗봇에 대해 설명해.'을 입력합니다. 잠시 후 앱이 1960년대 만들어진 ELIZA 챗봇에 대한 정보로 응답해야 합니다.
  • 'quit'을 입력해 애플리케이션을 종료합니다.
Visual Studio Code 터미널에서 ELIZA 챗봇 설명 프롬프트 입력
Visual Studio Code 터미널에서 ELIZA 챗봇 설명 프롬프트 입력

12. Responses API로 전환하기

  • ChatCompletions API가 널리 쓰이지만, 점점 더 새로운 Responses API로 대체되고 있습니다. 코드를 업데이트해 이를 사용해 봅니다.
  • chat-app.py 코드에서 main 함수의 'Get a response' 주석 아래 코드를 다음의 Responses API 코드로 교체합니다. system 메시지가 instructions 매개변수에, 사용자 프롬프트가 input 매개변수에 할당되는 더 단순한 문법에 주목하세요.
# Get a response
response = openai_client.responses.create(
            model=model_deployment,
            instructions="You are a helpful AI assistant that answers questions and provides information.",
            input=input_text
)
print(response.output_text)
Visual Studio Code의 chat-app.py에서 Responses API 호출 코드로 전환
Visual Studio Code의 chat-app.py에서 Responses API 호출 코드로 전환

13. 맥락이 끊기는 문제 확인하기

  • 코드 변경을 저장하고 터미널에서 애플리케이션을 다시 실행합니다(python chat-app.py). 이전과 같은 프롬프트 'ELIZA 챗봇에 대해 알려줘.'을 입력하면 다시 ELIZA 챗봇에 대한 정보로 응답합니다.
  • 대화를 이어가려고 '이 챗봇은 현대 LLM과 비교하면 어때?'라는 프롬프트를 입력합니다. 앱은 '이 챗봇'이 무엇을 가리키는지 이해하지 못하는 응답을 보여야 합니다 - 대화 맥락이 사라진 것입니다. 이 문제를 곧 해결합니다.
  • 'quit'을 입력해 애플리케이션을 종료합니다.

14. 대화 맥락 추적 코드 추가하기

  • 대화 맥락을 유지하려면 각 새 요청에 이전 응답에 대한 참조를 포함해야 합니다.
  • main 함수에서 'Loop until the user wants to quit' 주석을 찾아, 그 위(루프 시작 전)에 다음 코드를 추가합니다.
# Track responses
last_response_id = None
Visual Studio Code의 chat-app.py에서 이전 응답 ID 추적 변수 추가
Visual Studio Code의 chat-app.py에서 이전 응답 ID 추적 변수 추가

15. 이전 응답 ID 전달하기

  • 'Get a response' 아래 코드를 다음 코드로 수정해, 이전 응답 ID를 요청에 전달하고 새 응답 ID를 받아 다음번에 사용할 수 있도록 저장합니다.
  • 이 기법으로 이전 응답의 ID를 전달해 맥락을 유지할 수 있습니다. 더 복잡한 로직을 구현해 이전의 어떤 응답에서든 ID를 전달해 대화를 리디렉션하거나 이전 대화 스레드를 재개할 수도 있습니다.
# Get a response
response = openai_client.responses.create(
            model=model_deployment,
            instructions="You are a helpful AI assistant that answers questions and provides information.",
            input=input_text,
            previous_response_id=last_response_id,
)
print(response.output_text)
last_response_id = response.id
Visual Studio Code의 chat-app.py에서 이전 응답 ID를 전달하고 새 응답 ID 저장
Visual Studio Code의 chat-app.py에서 이전 응답 ID를 전달하고 새 응답 ID 저장

16. 맥락 유지 테스트하기

  • 코드 변경을 저장하고 애플리케이션을 다시 실행합니다(python chat-app.py). 'ELIZA 챗봇에 대해 알려줘.'을 입력해 응답을 확인합니다.
  • '이 챗봇과 현대 LLM과 비교하면 어때?'라는 프롬프트를 입력합니다. 이번에는 앱이 ELIZA 챗봇과 현대 LLM을 비교하는 응답을 줍니다. 응답이 꽤 길 수 있고, 앱은 모델로부터 전체 텍스트를 다 받을 때까지 기다렸다가 표시하므로 응답이 없는 것처럼 느껴질 수 있습니다 - 다음에 이 문제를 해결합니다!
  • 'quit'을 입력해 애플리케이션을 종료합니다.
Visual Studio Code 터미널에서 대화 맥락을 유지해 ELIZA와 현대 LLM 비교 응답 확인
Visual Studio Code 터미널에서 대화 맥락을 유지해 ELIZA와 현대 LLM 비교 응답 확인

17. 스트리밍 응답 구현하기

  • 긴 응답을 처리하려면 스트리밍을 사용해 전체 텍스트가 반환되기 전에 부분 응답 처리를 시작할 수 있습니다.
  • chat-app.py 코드에서 main 함수의 'Get a response' 아래 코드를 다음의 스트리밍 코드로 교체합니다. stream=True 매개변수는 각 새 청크(델타)가 처리 준비될 때마다 이벤트가 발생하는 스트리밍 응답을 만듭니다.
# Get a response
stream = openai_client.responses.create(
            model=model_deployment,
            instructions="You are a helpful AI assistant that answers questions and provides information.",
            input=input_text,
            previous_response_id=last_response_id,
            stream=True
)
for event in stream:
    if event.type == "response.output_text.delta":
        print(event.delta, end="")
    elif event.type == "response.completed":
        last_response_id = event.response.id
print()

18. 스트리밍 결과 확인하기

  • 코드 변경을 저장하고 애플리케이션을 다시 실행합니다(python chat-app.py). 'ELIZA 챗봇에 대해 알려줘.'을 입력하면 응답이 청크 단위로 점진적으로 나타나기 시작해야 합니다.
  • '이 챗봇과 현대 LLM과 비교하면 어때?'라는 프롬프트로 대화를 이어가면, 이번에도 응답이 점진적으로 표시됩니다.
  • 'quit'을 입력해 애플리케이션을 종료합니다.
Visual Studio Code 터미널에서 스트리밍으로 점진적으로 표시되는 ELIZA와 현대 LLM 비교 응답 확인
Visual Studio Code 터미널에서 스트리밍으로 점진적으로 표시되는 ELIZA와 현대 LLM 비교 응답 확인

19. 비동기 API로 전환하기

  • OpenAI SDK는 장시간 실행되는 모델·에이전트 작업을 사용할 때 애플리케이션 응답성을 높일 수 있는 비동기(async) 옵션을 제공합니다.
  • 탐색기 창에서 chat-async.py 파일(chat-app.py 아님)을 열고 기존 코드를 검토합니다. OpenAI SDK의 async API로 모델에 접근하는 코드를 추가할 것입니다.
  • 코드 파일 상단에서 'Import namespaces' 주석을 찾아 다음 코드를 추가합니다. 그런 다음 main 함수에서 'Initialize an async OpenAI client' 주석을 찾아 비동기 클라이언트를 만드는 코드를 추가합니다.
# import namespaces for async
import asyncio
from openai import AsyncOpenAI
from azure.identity.aio import DefaultAzureCredential, get_bearer_token_provider

# Initialize an async OpenAI client
credential = DefaultAzureCredential()
token_provider = get_bearer_token_provider(
    credential, "https://ai.azure.com/.default"
)

async_client = AsyncOpenAI(
    base_url=azure_openai_endpoint,
    api_key=token_provider
)

20. 비동기 응답 대기 코드 추가하기

  • main 함수의 루프 안에서 'Await an asynchronous response' 주석을 찾아 다음 코드를 추가합니다. 이 코드는 모델로부터 비동기 응답을 기다립니다(await)합니다.
  • 그런 다음 main 함수 끝의 finally 블록에서 'Close the async client session' 주석을 찾아 비동기 클라이언트를 닫는 코드를 추가합니다.
# Await an asynchronous response
response = await async_client.responses.create(
            model=model_deployment,
            instructions="You are a helpful AI assistant that answers questions and provides information.",
            input=input_text,
            previous_response_id=last_response_id
)
assistant_text = response.output_text
print("Assistant:", assistant_text)
last_response_id = response.id

# Close the async client session
await credential.close()

21. 비동기 앱 실행 테스트하기

  • 코드 파일 변경 사항을 저장합니다. 그런 다음 터미널에서 다음 명령으로 프로그램을 실행합니다. 프로그램이 터미널에서 실행되어야 합니다(그렇지 않다면 오류를 해결하고 다시 시도하세요).
python chat-async.py

22. 비동기 앱 테스트 및 마무리

  • 메시지가 표시되면 '튜링 테스트에 대해 알려줘.'를 입력합니다. 잠시 후 앱이 튜링 테스트에 대한 정보로 응답해야 합니다.
  • 'quit'을 입력해 애플리케이션을 종료합니다.
Visual Studio Code 터미널에서 비동기 앱으로 튜링 테스트 설명 응답 확인
Visual Studio Code 터미널에서 비동기 앱으로 튜링 테스트 설명 응답 확인

23. 요약 및 정리

  • 이 실습에서는 OpenAI SDK와 ChatCompletions·Responses API를 사용해 Microsoft Foundry 프로젝트에 배포한 생성형 AI 모델용 클라이언트 애플리케이션을 만들었습니다. 대화 맥락을 추적해 모델의 동작을 커스터마이즈하고, 스트리밍을 구현해 응답성 좋은 챗 경험을 제공했습니다.
  • 정리(Clean up): Azure 포털(portal.azure.com)에서 이 실습에 사용한 리소스가 포함된 리소스 그룹을 확인하고, 툴바에서 Delete resource group을 선택한 뒤 이름을 입력해 삭제를 확인합니다.
원문 실습 가이드 보기