SDK 개발 Level 300 · 45분
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 엔드포인트를 사용합니다!

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 윈도우가 새롭게 시작합니다. 작성자를 신뢰하는지 확인하는 메시지가 뜰 수 있습니다.

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

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

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
)
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)
9. 로그인 후 실행해 보기
- 코드 파일 변경 사항을 저장합니다. 그런 다음 터미널에서 다음 명령으로 Azure에 로그인합니다(여러 테넌트에 구독이 있다면 --tenant 매개변수로 테넌트를 지정해야 할 수도 있습니다).
az login
10. 첫 실행 테스트
- 메시지가 표시되면 안내에 따라 Azure에 로그인합니다. 그런 다음 명령줄에서 로그인 과정을 완료하며 Foundry 리소스가 포함된 구독의 세부 정보를 확인(필요하면 확인)합니다.
- 로그인 후 다음 명령으로 애플리케이션을 실행합니다. 프로그램이 터미널에서 실행되어야 합니다(그렇지 않다면 오류를 해결하고 다시 시도하세요).
python chat-app.py11. 프롬프트 테스트하기
- 메시지가 표시되면 'ELIZA 챗봇에 대해 설명해.'을 입력합니다. 잠시 후 앱이 1960년대 만들어진 ELIZA 챗봇에 대한 정보로 응답해야 합니다.
- 'quit'을 입력해 애플리케이션을 종료합니다.

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)
13. 맥락이 끊기는 문제 확인하기
- 코드 변경을 저장하고 터미널에서 애플리케이션을 다시 실행합니다(python chat-app.py). 이전과 같은 프롬프트 'ELIZA 챗봇에 대해 알려줘.'을 입력하면 다시 ELIZA 챗봇에 대한 정보로 응답합니다.
- 대화를 이어가려고 '이 챗봇은 현대 LLM과 비교하면 어때?'라는 프롬프트를 입력합니다. 앱은 '이 챗봇'이 무엇을 가리키는지 이해하지 못하는 응답을 보여야 합니다 - 대화 맥락이 사라진 것입니다. 이 문제를 곧 해결합니다.
- 'quit'을 입력해 애플리케이션을 종료합니다.
14. 대화 맥락 추적 코드 추가하기
- 대화 맥락을 유지하려면 각 새 요청에 이전 응답에 대한 참조를 포함해야 합니다.
- main 함수에서 'Loop until the user wants to quit' 주석을 찾아, 그 위(루프 시작 전)에 다음 코드를 추가합니다.
# Track responses
last_response_id = None
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
16. 맥락 유지 테스트하기
- 코드 변경을 저장하고 애플리케이션을 다시 실행합니다(python chat-app.py). 'ELIZA 챗봇에 대해 알려줘.'을 입력해 응답을 확인합니다.
- '이 챗봇과 현대 LLM과 비교하면 어때?'라는 프롬프트를 입력합니다. 이번에는 앱이 ELIZA 챗봇과 현대 LLM을 비교하는 응답을 줍니다. 응답이 꽤 길 수 있고, 앱은 모델로부터 전체 텍스트를 다 받을 때까지 기다렸다가 표시하므로 응답이 없는 것처럼 느껴질 수 있습니다 - 다음에 이 문제를 해결합니다!
- 'quit'을 입력해 애플리케이션을 종료합니다.

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'을 입력해 애플리케이션을 종료합니다.

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.py22. 비동기 앱 테스트 및 마무리
- 메시지가 표시되면 '튜링 테스트에 대해 알려줘.'를 입력합니다. 잠시 후 앱이 튜링 테스트에 대한 정보로 응답해야 합니다.
- 'quit'을 입력해 애플리케이션을 종료합니다.

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