1. 소개
이 실습에서는 웹 서비스를 빌드하여 상식 퀴즈를 만들고 재미있고 작동하는 앱에 통합합니다. 영어!
실습할 내용…
- 일련의 기준에 따라 상식 퀴즈를 생성하는 프롬프트를 제작합니다.
- 간단한 웹 앱을 빌드하고 개발 환경에서 예상대로 실행되는지 확인합니다.
- 웹 앱에 점진적으로 로직을 추가하여 입력 매개변수 세트에 따라 퀴즈를 생성하는 API 서버로 전환합니다.
- Google Cloud Run을 사용하여 퀴즈 생성 서비스를 클라우드에 배포하는 방법을 알아봅니다.
- 마지막으로 배포된 퀴즈 생성기 서비스를 사용하도록 실제 앱 ( quizaic.com)을 구성하고 출력을 기반으로 실시간 퀴즈를 재생할 수 있습니다.
학습할 내용…
- 대규모 언어 모델 (LLM)의 템플릿 프롬프트를 만드는 방법
- Python으로 간단한 웹 서버 앱을 만드는 방법
- 웹 앱에 Google LLM 지원을 추가하는 방법
- 누구나 새로 만들어 볼 수 있도록 앱을 클라우드에 배포하는 방법
- 퀴즈 생성기를 더 큰 앱에 통합하는 방법
필요한 항목…
- Chrome 웹브라우저
- Google 계정
- 결제가 사용 설정된 Cloud 프로젝트
이 실습은 초보자를 포함한 모든 수준의 개발자를 대상으로 합니다. Python을 사용하지만 Python 프로그래밍에 익숙하지 않아도 내용을 이해할 수 있습니다. 표시되는 모든 코드가 설명되기 때문입니다.
2. 설정
이 섹션에서는 실습을 시작하는 데 필요한 모든 사항을 다룹니다.
자습형 환경 설정
- Google Cloud Console에 로그인하여 새 프로젝트를 만들거나 기존 프로젝트를 재사용합니다. 아직 Gmail이나 Google Workspace 계정이 없는 경우 계정을 만들어야 합니다.
- 프로젝트 이름은 이 프로젝트 참가자의 표시 이름입니다. 이는 Google API에서 사용하지 않는 문자열이며 언제든지 업데이트할 수 있습니다.
- 프로젝트 ID는 모든 Google Cloud 프로젝트에서 고유하며, 변경할 수 없습니다(설정된 후에는 변경할 수 없음). Cloud 콘솔은 고유한 문자열을 자동으로 생성합니다. 일반적으로는 신경 쓰지 않아도 됩니다. 대부분의 Codelab에서는 프로젝트 ID (일반적으로
PROJECT_ID
로 식별됨)를 참조해야 합니다. 생성된 ID가 마음에 들지 않으면 다른 임의 ID를 생성할 수 있습니다. 또는 직접 시도해 보고 사용 가능한지 확인할 수도 있습니다. 이 단계 이후에는 변경할 수 없으며 프로젝트 기간 동안 유지됩니다. - 참고로 세 번째 값은 일부 API에서 사용하는 프로젝트 번호입니다. 이 세 가지 값에 대한 자세한 내용은 문서를 참고하세요.
- 다음으로 Cloud 리소스/API를 사용하려면 Cloud 콘솔에서 결제를 사용 설정해야 합니다. 이 Codelab 실행에는 많은 비용이 들지 않습니다. 이 튜토리얼이 끝난 후에 요금이 청구되지 않도록 리소스를 종료하려면 만든 리소스 또는 프로젝트를 삭제하면 됩니다. Google Cloud 신규 사용자는 300달러(USD) 상당의 무료 체험판 프로그램에 참여할 수 있습니다.
Cloud Shell 시작
이 실습에서는 Google의 클라우드에서 실행되는 가상 머신이 호스팅하는 명령어 인터프리터인 Cloud Shell 세션에서 작업합니다. 이 섹션은 사용자의 컴퓨터에서 로컬로 쉽게 실행할 수도 있지만, Cloud Shell을 사용하면 모든 사람이 일관되고 재현 가능한 환경에 액세스할 수 있습니다. 실습을 마치고 로컬 컴퓨터에서 이 섹션을 다시 시도하셔도 됩니다.
Cloud Shell 활성화
- Cloud Console에서 Cloud Shell 활성화를 클릭합니다.
Cloud Shell을 처음 시작하는 경우 Cloud Shell에 대한 설명이 포함된 중간 화면이 표시됩니다. 중간 화면이 표시되면 계속을 클릭합니다.
Cloud Shell을 프로비저닝하고 연결하는 데 몇 분 정도만 걸립니다.
이 가상 머신에는 필요한 모든 개발 도구가 로드되어 있습니다. 영구적인 5GB 홈 디렉터리를 제공하고 Google Cloud에서 실행되므로 네트워크 성능과 인증이 크게 개선됩니다. 이 Codelab에서 대부분의 작업은 브라우저만으로도 수행할 수 있습니다.
Cloud Shell에 연결되면 인증이 완료되었고 프로젝트가 해당 프로젝트 ID로 설정된 것을 확인할 수 있습니다.
- Cloud Shell에서 다음 명령어를 실행하여 인증되었는지 확인합니다.
gcloud auth list
명령어 결과
Credentialed Accounts ACTIVE ACCOUNT * <my_account>@<my_domain.com> To set the active account, run: $ gcloud config set account `ACCOUNT`
- Cloud Shell에서 다음 명령어를 실행하여 gcloud 명령어가 프로젝트를 알고 있는지 확인합니다.
gcloud config list project
명령어 결과
[core] project = <PROJECT_ID>
또는 다음 명령어로 설정할 수 있습니다.
gcloud config set project <PROJECT_ID>
명령어 결과
Updated property [core/project].
일부 API 사용 설정
이후 단계에서는 이러한 서비스가 필요한 위치와 이유를 설명하겠지만, 지금은 다음 명령어를 실행하여 프로젝트에 Cloud Build, Artifact Registry, Vertex AI, Cloud Run에 대한 액세스 권한을 부여합니다.
gcloud services enable cloudbuild.googleapis.com \ artifactregistry.googleapis.com \ aiplatform.googleapis.com \ run.googleapis.com
그러면 다음과 비슷한 성공 메시지가 표시될 것입니다.
Operation "operations/acf.cc11852d-40af-47ad-9d59-477a12847c9e" finished successfully.
3. 메시지 표시 - 자연어 프로그래밍
먼저 대규모 언어 모델의 프롬프트를 개발하는 방법을 알아보겠습니다. Google Cloud 콘솔 > Vertex AI > Vertex AI Studio (언어)로 이동합니다. 다음과 같은 페이지가 표시됩니다.
Generate Text
에서 Text Prompt
버튼을 클릭합니다. 다음 대화상자에서 다음 요구사항에 따라 퀴즈를 생성하는 데 효과적일 수 있다고 생각되는 프롬프트를 입력합니다.
- 주제: 세계사
- 질문 수: 5개
- 난이도: 중급
- 언어: 영어
제출 버튼을 클릭하여 출력을 확인합니다.
다음 스크린샷과 같이 오른쪽 패널에서는 사용할 모델을 선택하고 일부 설정을 미세 조정할 수 있습니다.
사용 가능한 설정은 다음과 같습니다.
- 리전은 생성 요청이 실행되어야 하는 위치입니다.
- 모델은 사용할 대규모 언어 모델을 선택합니다. 이 Codelab에서는 'gemini-1.0-pro-001'을 사용하세요.
- 강도는 토큰 선택의 무작위성 수준을 제어합니다. 강도가 낮을수록 참 또는 정답이 예상되는 프롬프트에 적합한 반면, 강도가 높을수록 보다 다양하거나 예기치 않은 결과가 발생할 수 있습니다.
- 토큰 한도는 프롬프트 1개의 최대 텍스트 출력량을 결정합니다. 토큰 1개는 약 4자(영문 기준)입니다. 기본값은 1024입니다.
- Top-K는 모델이 출력용 토큰을 선택하는 방식을 변경합니다. Top-K가 1이면 선택된 토큰이 모델의 어휘에 포함된 모든 토큰 중에서 가장 확률이 높다는 의미입니다('그리디 디코딩'이라고도 함). 반면에 Top-K가 3이면 온도를 사용하여 가장 확률이 높은 토큰 3개 중에서 다음 토큰이 선택된다는 의미입니다. 기본 최상위 K 값은 40입니다.
- Top-P는 모델이 출력용 토큰을 선택하는 방식을 변경합니다. 토큰의 확률 합계가 Top-P 값과 같아질 때까지 확률이 가장 높은 순에서 낮은 순으로 토큰이 선택됩니다.
- 최대 응답 수는 프롬프트당 생성되는 최대 모델 응답 수입니다.
- 중지 시퀀스는 모델에서 응답이 발생할 경우 응답 생성을 중지하는 일련의 문자(공백 포함)입니다.
- 응답 스트리밍은 응답이 생성될 때 인쇄할지 아니면 저장했다가 완료되면 표시할지 선택합니다.
- 안전 필터 기준점은 유해할 수 있는 응답이 표시될 가능성을 조정합니다.
위에 언급된 요구사항에 따라 합당한 퀴즈를 생성하는 것으로 보이는 프롬프트가 있으면 커스텀 코드를 사용하여 이 퀴즈를 파싱할 수 있지만 LLM이 프로그램에 직접 로드할 수 있는 구조화된 형식으로 퀴즈를 생성하는 것이 더 좋지 않을까요? 이 실습의 뒷부분에서 생성기를 호출하는 데 사용할 프로그램에서는 퀴즈가 구조화된 데이터를 나타내는 데 널리 사용되는 언어 간 형식인 JSON으로 표현되어야 합니다.
이 실습의 퀴즈는 각 객체에 질문, 해당 질문에 대한 가능한 답변 배열, 정답이 포함된 객체 배열로 표현됩니다. 다음은 이 실습의 퀴즈에 관한 JSON 인코딩입니다.
[ { "question": "Who was the first person to walk on the moon?", "responses": [ "Neil Armstrong", "Buzz Aldrin", "Michael Collins", "Yuri Gagarin" ], "correct": "Neil Armstrong" }, { "question": "What was the name of the war that took place between the British and the French in North America from 1754 to 1763??", "responses": [ "The French and Indian War", "The Seven Years' War", "The War of the Austrian Succession", "The Great War" ], "correct": "The French and Indian War" }, ... ]
이제 프롬프트를 수정하여 퀴즈를 필수 JSON 형식으로 출력할 수 있는지 확인합니다.
- 찾고 있는 정확한 형식을 단어로 지정합니다 (예: 위의 기울임꼴 문장).
- 원하는 JSON 형식의 예시를 프롬프트에 포함합니다.
원하는 사양에 따라 퀴즈를 생성하는 프롬프트를 만들었다면 페이지 오른쪽 상단의 GET CODE
버튼을 클릭하여 프롬프트를 프로그래매틱 방식으로 Vertex AI LLM에 제출하는 데 사용할 수 있는 Python 코드를 확인합니다. Python 이외의 프로그래밍 언어를 사용하고 싶다면 https://cloud.google.com/vertex-ai/docs/samples?text=generative를 확인하세요.
4. 간단한 웹 서버 빌드
이제 작동하는 프롬프트를 만들었으므로 더 큰 앱에 통합해 보겠습니다. 물론 프롬프트를 더 큰 앱의 소스 코드에 삽입할 수도 있지만, 생성기를 다른 앱에 퀴즈 생성 서비스를 제공하는 마이크로서비스로 작동하도록 하는 것이 좋습니다. 이렇게 하려면 간단한 웹 서버를 만들어 공개적으로 제공해야 합니다. 다음 단계에서 이를 수행합니다.
먼저 Cloud Shell 패널 상단의 Open Editor
버튼을 클릭합니다. 상태 메시지가 표시됩니다.
그러면 Visual Studio Code와 유사한 IDE 환경으로 이동하게 되며, 여기에서 프로젝트를 만들고, 소스 코드를 수정하고, 프로그램을 실행할 수 있습니다.
화면이 너무 좁은 경우 여기에 강조표시된 두 영역 사이의 가로 막대를 드래그하여 콘솔과 수정/터미널 창 사이의 구분선을 확장하거나 축소할 수 있습니다.
Open Editor
및 Open Terminal
버튼을 각각 클릭하여 편집기와 터미널 간에 전환할 수 있습니다. 이제 두 환경 간에 전환해 보세요.
그런 다음 폴더 추가 버튼 를 클릭하고 quiz-generator
을 입력한 후 Enter 키를 눌러 이 실습의 작업을 저장할 폴더를 만듭니다. 이 실습에서 만든 모든 파일과 Cloud Shell에서 수행하는 모든 작업이 이 폴더에 저장됩니다.
이제 requirements.txt
파일을 만듭니다. 이는 앱이 사용하는 라이브러리를 Python에 알려줍니다. 이 간단한 웹 앱에서는 웹 서버를 빌드하는 데 사용되는 인기 있는 Python 모듈인 Flask,
, google-cloud-aiplatform
클라이언트 라이브러리, gunicorn
웹 서버 프레임워크를 사용합니다. 파일 탐색 창에서 quiz-generator
폴더를 마우스 오른쪽 버튼으로 클릭하고 다음과 같이 New file
메뉴 항목을 선택합니다.
새 파일의 이름을 입력하라는 메시지가 표시되면 requirements.txt
를 입력하고 Enter 키를 누릅니다. 새 파일이 quiz-generator
프로젝트 폴더에 있는지 확인합니다.
다음 줄을 새 파일에 붙여넣어 앱이 Python flask 패키지, gunicorn 웹 서버, google-cloud-aiplatform 클라이언트 라이브러리와 각 제품의 관련 버전에 종속된다는 것을 지정합니다.
flask==3.0.0 gunicorn==21.2.0 google-cloud-aiplatform==1.47.0
Cloud 편집기에서 변경사항을 자동으로 저장하므로 이 파일을 명시적으로 저장할 필요가 없습니다.
동일한 기법을 사용하여 main.py
라는 새 파일을 만듭니다. 이 파일이 앱의 기본 (유일한) Python 소스 파일이 됩니다. 새 파일이 quiz-generator
폴더에 있는지 다시 확인합니다.
다음 코드를 이 파일에 삽입합니다.
from flask import Flask
import os
app = Flask(__name__) # Create a Flask object.
PORT = os.environ.get("PORT") # Get PORT setting from environment.
if not PORT:
PORT = 8080
# The app.route decorator routes any GET requests sent to the root path
# to this function, which responds with a "Hello world!" HTML document.
@app.route("/", methods=["GET"])
def say_hello():
html = "<h1>Hello world!</h1>"
return html
# This code ensures that your Flask app is started and listens for
# incoming connections on the local interface and port 8080.
if __name__ == "__main__":
app.run(host="0.0.0.0", port=PORT)
터미널로 다시 전환하고 다음 명령어를 사용하여 프로젝트 폴더로 변경합니다.
cd quiz-generator
다음 명령어를 실행하여 프로젝트 종속 항목을 설치합니다.
pip3 install -r requirements.txt
종속 항목을 설치한 후 다음과 같이 끝나는 출력이 표시됩니다.
Successfully installed flask-3.0.0
이제 터미널에서 다음 명령어를 실행하여 앱을 실행합니다.
flask --app main.py --debug run --port 8080
이 시점에서 앱은 Cloud Shell 세션 전용 가상 머신에서 실행됩니다. Cloud Shell에는 전역 인터넷 어디에서나 가상 머신에서 실행되는 웹 서버 (예: 방금 시작한 서버)에 액세스할 수 있는 프록시 메커니즘이 포함되어 있습니다.
web preview
버튼을 클릭한 다음 Preview on Port 8080
메뉴 항목을 클릭합니다.
그러면 실행 중인 앱의 웹브라우저 탭이 열리고 다음과 같이 표시됩니다.
5. 매개변수 파싱이 포함된 생성 메서드 추가
이제 generate
라는 새 메서드의 필드 지원을 추가하려고 합니다. 가져오기 문을 추가하여 HTTP 요청을 조작하고 다음과 같이 기본 경로를 수정하여 이 요청을 파싱하고 매개변수를 출력하면 됩니다.
from flask import Flask
from flask import request #<-CHANGED
import os
app = Flask(__name__) # Create a Flask object.
PORT = os.environ.get("PORT") # Get PORT setting from environment.
if not PORT:
PORT = 8080
# The app.route decorator routes any GET requests sent to the /generate
# path to this function, which responds with "Generating:" followed by
# the body of the request.
@app.route("/", methods=["GET"]) #<-CHANGED
def generate(): #<-CHANGED
params = request.args.to_dict() #<-CHANGED
html = f"<h1>Quiz Generator</h1>" #<-CHANGED
for param in params: #<-CHANGED
html += f"<br>{param}={params[param]}" #<-CHANGED
return html #<-CHANGED
# This code ensures that your Flask app is started and listens for
# incoming connections on the local interface and port 8080.
if __name__ == "__main__":
app.run(host="0.0.0.0", port=PORT)
이제 기존 웹브라우저 탭을 새로고침하여 결과를 확인합니다. 이번에는 '퀴즈 생성기'와 함께 URL에 자동으로 추가된 쿼리 매개변수 (authuser
)가 표시됩니다. 브라우저의 주소 표시줄에 있는 URL 끝에 '`¶m1=val1¶m2=val2`" 문자열을 추가하여 매개변수를 두 개 더 추가해 보고 페이지를 새로고침하면 다음과 같은 내용이 표시됩니다.
이제 URL에서 쿼리 매개변수를 전송하고 파싱하는 방법을 살펴봤으므로 다음과 같이 퀴즈 생성기를 전송할 특정 매개변수에 대한 지원을 추가해 보겠습니다.
topic
- 원하는 퀴즈 주제num_q
- 원하는 질문 수diff
- 원하는 난이도 (쉬움, 중간, 어려움)lang
- 원하는 퀴즈 언어
from flask import Flask
from flask import request
import os
# Default quiz settings #<-CHANGED
TOPIC = "History" #<-CHANGED
NUM_Q = "5" #<-CHANGED
DIFF = "intermediate" #<-CHANGED
LANG = "English" #<-CHANGED
app = Flask(__name__) # Create a Flask object.
PORT = os.environ.get("PORT") # Get PORT setting from environment.
if not PORT:
PORT = 8080
# This function takes a dictionary, a name, and a default value.
# If the name exists as a key in the dictionary, the corresponding
# value is returned. Otherwise, the default value is returned.
def check(args, name, default): #<-CHANGED
if name in args: #<-CHANGED
return args[name] #<-CHANGED
return default #<-CHANGED
# The app.route decorator routes any GET requests sent to the /generate
# path to this function, which responds with "Generating:" followed by
# the body of the request.
@app.route("/", methods=["GET"])
# This function generates a quiz using Vertex AI.
def generate():
args = request.args.to_dict() #<-CHANGED
topic = check(args, "topic", TOPIC) #<-CHANGED
num_q = check(args, "num_q", NUM_Q) #<-CHANGED
diff = check(args, "diff", DIFF) #<-CHANGED
lang = check(args, "lang", LANG) #<-CHANGED
html = f"""
<h1>Quiz Generator</h1><br>
{topic=}<br>
{num_q=}<br>
{diff=}<br>
{lang=}""" #<-CHANGED
return html
# This code ensures that your Flask app is started and listens for
# incoming connections on the local interface and port 8080.
if __name__ == "__main__":
app.run(host="0.0.0.0", port=PORT)
이제 기존 웹브라우저 탭을 새로고침하여 결과를 확인합니다. 다음과 같은 웹페이지가 표시됩니다.
URL을 변경하여 다양한 매개변수의 값을 설정해 보세요. 예를 들어 주소 표시줄의 URL 끝에 접미사 '?authuser=0&topic=Literature&num_q=10&diff=easy&lang=French
'를 사용해 보세요.
6. 프롬프트 추가 및 서식 지정
다음으로 퀴즈 생성기에 전송할 특정 매개변수에 관한 지원을 추가합니다. 다음과 같습니다.
topic
- 원하는 퀴즈 주제num_q
- 원하는 질문 수diff
- 원하는 난이도 (쉬움, 중간, 어려움)lang
- 원하는 퀴즈 언어
이전 단계에서 Vertex Generative AI Studio로 개발한 프롬프트를 복사하되 주제, 질문 수, 난이도의 하드 코딩 값을 다음 문자열로 변경합니다.
- {topic}
- {num_q}
- {diff}
- {lang}
from flask import Flask
from flask import request
import os
# Default quiz settings
TOPIC = "History"
NUM_Q = 5
DIFF = "intermediate"
LANG = "English"
PROMPT = """
Generate a quiz according to the following specifications:
- topic: {topic}
- num_q: {num_q}
- diff: {diff}
- lang: {lang}
Output should be (only) an unquoted json array of objects with keys:
"Question", "responses", and "correct".
""" #<-CHANGED
app = Flask(__name__) # Create a Flask object.
PORT = os.environ.get("PORT") # Get PORT setting from environment.
if not PORT:
PORT = 8080
# This function takes a dictionary, a name, and a default value.
# If the name exists as a key in the dictionary, the corresponding
# value is returned. Otherwise, the default value is returned.
def check(args, name, default):
if name in args:
return args[name]
return default
# The app.route decorator routes any GET requests sent to the /generate
# path to this function, which responds with "Generating:" followed by
# the body of the request.
@app.route("/", methods=["GET"])
# This function generates a quiz using Vertex AI.
def generate():
args = request.args.to_dict()
topic = check(args, "topic", TOPIC)
num_q = check(args, "num_q", NUM_Q)
diff = check(args, "diff", DIFF)
lang = check(args, "lang", LANG)
prompt = PROMPT.format(topic=topic, num_q=num_q, diff=diff, lang=lang) #<-CHANGED
html = f"<h1>Prompt:</h1><br><pre>{prompt}</pre>" #<-CHANGED
return html
# This code ensures that your Flask app is started and listens for
# incoming connections on the local interface and port 8080.
if __name__ == "__main__":
app.run(host="0.0.0.0", port=PORT)
이제 기존 웹브라우저 탭을 새로고침하여 결과를 확인합니다. 다음과 같은 웹페이지가 표시됩니다.
URL을 수정하여 매개변수 4개를 변경해 보세요.
7. Vertex AI 클라이언트 라이브러리 추가
이제 Vertex AI Python 클라이언트 라이브러리를 사용하여 퀴즈를 생성할 준비가 되었습니다. 이렇게 하면 3단계에서 수행한 대화형 프롬프트가 자동화되고 생성기 서비스가 Google의 LLM 기능에 프로그래매틱 방식으로 액세스할 수 있습니다. 다음과 같이 main.py
파일을 업데이트합니다.
'YOUR_PROJECT'를 실제 프로젝트 ID로 바꿔야 합니다.
from flask import Flask
from flask import request
from flask import Response #<-CHANGED
import os
import vertexai
from vertexai.generative_models import GenerativeModel #<-CHANGED
# Default quiz settings
TOPIC = "History"
NUM_Q = 5
DIFF = "intermediate"
LANG = "English"
MODEL = "gemini-1.0-pro" #<-CHANGED
PROMPT = """
Generate a quiz according to the following specifications:
- topic: {topic}
- num_q: {num_q}
- diff: {diff}
- lang: {lang}
Output should be (only) an unquoted json array of objects with keys "question", "responses", and "correct".
"""
app = Flask(__name__) # Create a Flask object.
PORT = os.environ.get("PORT") # Get PORT setting from environment.
if not PORT:
PORT = 8080
# Initialize Vertex AI access.
vertexai.init(project="YOUR_PROJECT", location="us-central1") #<-CHANGED
parameters = { #<-CHANGED
"candidate_count": 1, #<-CHANGED
"max_output_tokens": 1024, #<-CHANGED
"temperature": 0.5, #<-CHANGED
"top_p": 0.8, #<-CHANGED
"top_k": 40, #<-CHANGED
} #<-CHANGED
model = GenerativeModel(MODEL) #<-CHANGED
# This function takes a dictionary, a name, and a default value.
# If the name exists as a key in the dictionary, the corresponding
# value is returned. Otherwise, the default value is returned.
def check(args, name, default):
if name in args:
return args[name]
return default
# The app.route decorator routes any GET requests sent to the /generate
# path to this function, which responds with "Generating:" followed by
# the body of the request.
@app.route("/", methods=["GET"])
# This function generates a quiz using Vertex AI.
def generate():
args = request.args.to_dict()
topic = check(args, "topic", TOPIC)
num_q = check(args, "num_q", NUM_Q)
diff = check(args, "diff", DIFF)
lang = check(args, "lang", LANG)
prompt = PROMPT.format(topic=topic, num_q=num_q, diff=diff, lang=lang)
response = model.generate_content(prompt, generation_config=parameters) #<-CHANGED
print(f"Response from Model: {response.text}") #<-CHANGED
html = f"{response.text}" #<-CHANGED
return Response(html, mimetype="application/json") #<-CHANGED
# This code ensures that your Flask app is started and listens for
# incoming connections on the local interface and port 8080.
if __name__ == "__main__":
app.run(host="0.0.0.0", port=PORT)
이제 기존 웹브라우저 탭을 새로고침하여 결과를 확인합니다. 이제 실제로 LLM 요청을 하게 되므로 몇 초 정도 걸릴 수 있습니다. 다음과 같은 웹페이지가 표시됩니다.
URL을 변경하여 다른 퀴즈 주제, 질문 수, 난이도 수준을 요청해 보세요.
이제 마이크로서비스가 완성되었습니다. 축하합니다. 다음 단계에서는 누구나 어디서나 액세스할 수 있도록 클라우드에 서비스를 배포하는 방법을 알아봅니다.
8. 클라우드로 이동하세요.
이제 직접 퀴즈 생성기를 빌드했으므로 이 멋진 도구를 전 세계와 공유하고자 할 것입니다. 이제 Cloud에 배포할 차례입니다. 하지만 단순히 공유하는 것 이상의 일을 하고 싶습니다. 다음 사항을 확인해야 합니다.
- 안정적으로 실행됨 - 앱을 실행하는 컴퓨터가 비정상 종료되는 경우 자동 내결함성이 제공됩니다.
- 자동 확장 - 앱이 대규모 트래픽을 처리하고 사용하지 않을 때는 자동으로 풋프린트를 줄입니다.
- 사용하지 않는 리소스에 대해 비용을 청구하지 않으므로, 트래픽에 응답하는 동안 사용한 리소스에 대해서만 비용이 청구되므로 비용이 최소화됩니다.
- 맞춤 도메인 이름을 통해 액세스할 수 있습니다. 원클릭 솔루션을 통해 서비스에 맞춤 도메인 이름을 할당할 수 있습니다.
- 뛰어난 응답 시간을 제공합니다. 콜드 스타트는 응답 속도가 합리적이지만 최소 인스턴스 구성을 지정하여 이를 세부적으로 조정할 수 있습니다.
- 표준 SSL/TLS 웹 보안을 사용하여 엔드 투 엔드 암호화를 지원합니다. 서비스를 배포할 때 표준 웹 암호화와 이에 상응하는 필수 인증서가 무료로 자동 제공됩니다.
Google Cloud Run에 앱을 배포하면 위의 모든 기능을 사용할 수 있습니다. Cloud Run과 앱을 공유하기 위한 기본 구성요소는 컨테이너입니다.
컨테이너를 사용하면 모든 종속 항목이 번들로 포함된 애플리케이션을 실행할 수 있는 모듈식 박스를 만들 수 있습니다. 컨테이너는 거의 모든 가상 또는 실제 서버에서 사용할 수 있으므로 온프레미스에서 클라우드로 애플리케이션을 배포하거나 한 서비스 제공업체에서 다른 서비스 제공업체로 애플리케이션을 이동할 수도 있습니다.
컨테이너 및 Google Cloud Run에서의 작동 방식에 대해 자세히 알아보려면 Cloud Run을 사용한 간단한 3단계로 개발 환경에서 프로덕션으로 이동 Codelab을 확인하세요.
Cloud Run에 앱 배포
Cloud Run은 리전별 서비스입니다. 즉, Cloud Run 서비스를 실행하는 인프라가 특정 리전에 위치해 있으며, 해당 리전 내의 모든 영역에서 중복으로 사용할 수 있도록 Google에서 관리합니다. 편의상 이 실습에서는 하드코딩된 리전 us-central1
를 사용합니다.
빌드팩이라는 것을 사용하여 컨테이너를 자동으로 생성하겠습니다. Cloud 편집기에서 Procfile
이라는 새 파일을 만들고 다음과 같은 텍스트 한 줄을 삽입합니다.
web: gunicorn --bind :$PORT --workers 1 --threads 8 --timeout 0 main:app
이렇게 하면 자동 생성된 컨테이너에서 앱을 실행하는 방법을 빌드팩 시스템에 알립니다. 그런 다음 Cloud Shell 터미널 (quiz-generator
디렉터리)에서 다음 명령어를 실행합니다.
gcloud run deploy quiz-generator \ --source . \ --region us-central1 \ --allow-unauthenticated
이렇게 하면 gcloud
명령어에 현재 디렉터리에서 찾은 소스 파일을 기반으로 빌드팩을 사용하여 컨테이너 이미지를 만들라고 지시합니다. --source .
의 dot
는 현재 디렉터리의 약어입니다. 서비스에서 컨테이너 이미지를 암시적으로 처리하므로 이 gcloud
명령어에서 이미지를 지정할 필요가 없습니다.
그런 다음 배포가 완료될 때까지 잠시 기다립니다. 성공하면 gcloud
명령어에 새 서비스의 URL이 표시됩니다.
Building using Buildpacks and deploying container to Cloud Run service [quiz-generator] in project [YOUR_PROJECT] region [YOUR_REGION] OK Building and deploying new service... Done. OK Creating Container Repository... OK Uploading sources... OK Building Container... Logs are available at [https://console.cloud.google.com/cloud-build/builds/0cf1383f-35db-412d -a973-557d5e2cd4a4?project=780573810218]. OK Creating Revision... OK Routing traffic... OK Setting IAM Policy... Done. Service [quiz-generator] revision [quiz-generator-00001-xnr] has been deployed and is serving 100 percent of traffic. Service URL: https://quiz-generator-co24gukjmq-uc.a.run.app
다음 명령어를 사용하여 서비스 URL을 검색할 수도 있습니다.
gcloud run services describe quiz-generator \ --region us-central1 \ --format "value(status.url)"
다음과 같이 표시됩니다.
https://quiz-generator-co24gukjmq-uc.a.run.app
이 링크는 Cloud Run 서비스의 TLS 보안 전용 URL입니다. 이 링크는 서비스를 사용 중지하지 않는 한 영구적이며 인터넷 어디서나 사용할 수 있습니다. 일시적인 가상 머신에 종속된 앞에서 언급한 Cloud Shell의 프록시 메커니즘을 사용하지 않습니다.
강조 표시된 Service URL
를 클릭하여 실행 중인 앱의 웹브라우저 탭을 엽니다. 결과가 개발 환경에서 보았던 것과 동일한지 확인합니다. 또한 URL 끝에 매개변수를 제공하여 생성된 퀴즈를 조정할 수 있는지 확인합니다.
축하합니다. 이제 앱이 Google Cloud에서 실행됩니다. 별도로 생각할 필요 없이 앱을 공개적으로 제공하고 TLS (HTTPS) 암호화와 엄청난 수준의 트래픽에 맞게 자동으로 확장할 수 있습니다.
9. 모든 요소를 종합
이 마지막 단계에서는 quizaic 앱의 일부로 퀴즈 생성기를 실행할 준비가 됩니다. quizaic URL로 이동하여 Google 계정에 로그인하고 Create Quiz
탭으로 이동합니다. 생성기 유형 Custom
를 선택하고 Cloud Run URL을 URL 필드에 붙여넣고 다른 필수 필드를 작성한 후 양식을 제출합니다.
잠시 후 AI가 생성한 썸네일 이미지가 포함된 새 퀴즈 (아래 이미지의 '새 퀴즈' 참고)가 표시됩니다. 이 퀴즈는 해당 버튼을 통해 수정, 재생, 클론 또는 삭제할 수 있습니다. 이 새 퀴즈는 방금 템플릿 프롬프트를 기반으로 배포한 웹 서비스를 사용하여 만들어졌습니다.
10. 삭제
Cloud Run에서는 서비스를 사용하지 않을 때 비용이 청구되지 않지만 빌드된 컨테이너 이미지를 저장하는 데 요금이 부과될 수 있습니다.
GCP 프로젝트를 삭제하여 요금이 청구되지 않도록 하거나, 해당 프로젝트 내에서 사용된 모든 리소스에 대한 청구가 중지되도록 하거나, 다음 명령어를 사용하여 컨테이너 이미지를 삭제할 수 있습니다.
gcloud config set artifacts/repository cloud-run-source-deploy gcloud config set artifacts/location us-central1 gcloud artifacts docker images list # Note image tag for resulting list gcloud artifacts docker images delete <IMAGE-TAG>
Cloud Run 서비스를 삭제하려면 다음 명령어를 사용합니다.
gcloud run services delete quiz-generator --region us-central1 --quiet
11. 완료되었습니다.
LLM 프롬프트를 만들고 이 프롬프트를 사용하여 Cloud Run 마이크로서비스를 배포했습니다. 이제 자연어로 프로그래밍하고 전 세계와 창작물을 공유할 수 있습니다.
한 가지 중요한 질문을 하겠습니다.
앱이 개발자 환경에서 작동하도록 한 후 Cloud Run에서 제공하는 모든 프로덕션 등급 속성을 포함하여 클라우드에 배포하기 위해 몇 줄의 코드를 수정해야 했나요?
답은 당연히 0입니다. :)
살펴볼 다른 Codelab...
- Cloud Run으로 간단한 3단계로 개발부터 프로덕션까지
- Vertex AI 및 Svelte Kit를 사용한 텍스트 요약 도구 앱
- Cloud Run에서 PaLM API를 사용하는 채팅 앱
- PaLM Text Bison 모델을 래핑하는 Cloud Functions
- Spanner 및 Vertex AI Imagen API를 사용한 생성형 AI 데이터
참조 문서…
12. 액션 유도하기
이 Codelab이 만족스러웠고 Google Cloud를 실습하는 시간이 더 길다면 지금 바로 Google Cloud Innovators에 가입해 보세요.
Google Cloud Innovators는 무료이며 다음을 포함합니다.
- 실시간 토론, AMA, 로드맵 세션에 참여하여 Google 직원이 직접 전하는 최신 소식 알아보기
- 최신 Google Cloud 소식을 이메일로 받아보세요.
- 디지털 배지 및 화상 회의 배경
- 실습 및 Skills Boost 학습 500크레딧 제공
여기를 클릭하여 등록하세요.