使用生成式 AI 和 Cloud Run 构建测验生成器

1. 简介

在本实验中,您将构建一个 Web 服务来生成知识问答,并将其集成到一个有趣的应用中。您将使用与以前不同的编程语言:English!

实践内容…

  • 您需要编写一个提示,根据一组条件生成知识问答。
  • 您将构建一个简单的 Web 应用,并验证该应用在开发环境中是否按预期运行。
  • 您将逐步向 Web 应用添加逻辑,使其变为根据一组输入参数生成测验的 API 服务器。
  • 您将了解使用 Google Cloud Run 将测验生成服务部署到云端有多么容易。
  • 最后,您将配置一个真实应用 ( quizaic.com) 以使用您部署的测验生成器服务,您将能够根据输出结果播放实时测验。

学习内容…

  • 如何为大型语言模型 (LLM) 创建模板化提示。
  • 如何使用 Python 创建简单的 Web 服务器应用。
  • 如何在 Web 应用中添加对 Google LLM 的支持。
  • 如何将应用部署到云端,以便任何人都可以试用您的新构建。
  • 如何将测验生成器集成到较大的应用中。

所需条件…

  • Chrome 网络浏览器
  • Google 账号
  • 启用了结算功能的 Cloud 项目

本实验的适用对象为各种水平的开发者,包括新手。尽管您将使用 Python,但您无需熟悉 Python 编程就能理解代码内容,因为我们将为您介绍所有代码。

2. 设置

a08aa5878e36b60c.png

本部分涵盖了开始此实验所需执行的所有操作。

自定进度的环境设置

  1. 登录 Google Cloud 控制台,然后创建一个新项目或重复使用现有项目。如果您还没有 Gmail 或 Google Workspace 账号,则必须创建一个

fbef9caa1602edd0.png

a99b7ace416376c4.png

5e3ff691252acf41.png

  • 项目名称是此项目参与者的显示名称。它是 Google API 尚未使用的字符串。您可以随时对其进行更新。
  • 项目 ID 在所有 Google Cloud 项目中是唯一的,并且是不可变的(一经设置便无法更改)。Cloud 控制台会自动生成一个唯一字符串;通常情况下,您无需关注该字符串。在大多数 Codelab 中,您都需要引用项目 ID(通常用 PROJECT_ID 标识)。如果您不喜欢生成的 ID,可以再随机生成一个 ID。或者,您也可以尝试自己的项目 ID,看看是否可用。完成此步骤后便无法更改该 ID,并且此 ID 在项目期间会一直保留。
  • 此外,还有第三个值,即部分 API 使用的项目编号,供您参考。如需详细了解所有这三个值,请参阅文档
  1. 接下来,您需要在 Cloud 控制台中启用结算功能,以便使用 Cloud 资源/API。运行此 Codelab 应该不会产生太多的费用(如果有的话)。若要关闭资源以避免产生超出本教程范围的结算费用,您可以删除自己创建的资源或删除项目。Google Cloud 新用户符合参与 300 美元免费试用计划的条件。

启动 Cloud Shell

在本实验中,您将使用 Cloud Shell 会话,这是一个由在 Google 云中运行的虚拟机托管的命令解释器。您可以在自己的计算机本地轻松运行此部分,但借助 Cloud Shell,每个人都可以在一致的环境中获得可重现的体验。完成实验后,您可以在自己的计算机上重试本部分。

4a95152439f0159b

激活 Cloud Shell

  1. 在 Cloud Console 中,点击激活 Cloud Shell853e55310c205094

3c1dabeca90e44e5

如果这是您第一次启动 Cloud Shell,系统会显示一个中间屏幕,说明它是什么。如果您看到中间屏幕,请点击继续

9c92662c6a846a5c

预配和连接到 Cloud Shell 只需花几分钟时间。

9f0e51b578fecce5

这个虚拟机装有所需的所有开发工具。它提供了一个持久的 5 GB 主目录,并在 Google Cloud 中运行,大大增强了网络性能和身份验证功能。您在此 Codelab 中的大部分(即使不是全部)工作都可以通过浏览器完成。

在连接到 Cloud Shell 后,您应该会看到自己已通过身份验证,并且相关项目已设为您的项目 ID。

  1. 在 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`
  1. 在 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. 提示 - Natural Language 编程

92f630373224ead8

首先,我们将学习如何为大型语言模型开发提示。前往 Google Cloud 控制台 >Vertex AI >Vertex AI Studio(Language)。您应该会看到如下页面:

bfe5706041ae6454.png

Generate Text 下,点击 Text Prompt 按钮。在下一个对话框中,根据以下要求输入您认为可能有助于生成知识问答题的提示:

  • 主题:世界史
  • 题目数量:5
  • 难度等级:中等
  • 语言:英语

点击“提交”按钮查看输出。

如以下屏幕截图所示,您可以通过右侧面板选择要使用的模型,并微调某些设置:

8aa89a1970ea9335

您可以使用以下设置:

  • 区域是指应运行生成请求的区域。
  • Model 选择您要使用的大型语言模型。对于此 Codelab,请坚持使用“gemini-1.0-pro-001”。
  • 温度可以控制词元选择的随机性。较低的温度适合希望获得真实或正确回答的提示,而较高的温度可能会引发更加多样化或意想不到的结果。
  • 词元限制决定了一条提示的最大文本输出量。词元约为 4 个字符。默认值为 1024。
  • Top-k 可更改模型选择输出词元的方式。如果 Top-k 设为 1,表示所选词元是模型词汇表的所有词元中概率最高的词元(也称为贪心解码)。如果 Top-k 设为 3,则表示系统将从 3 个概率最高的词元(通过温度确定)中选择下一个词元。Top-k 的默认值为 40。
  • Top-p 可更改模型选择输出词元的方式。系统会按照概率从最高到最低的顺序选择词元,直到所选词元的概率总和等于 Top-p 的值。
  • 响应数量上限是指每个提示生成的模型响应数量上限。
  • 停止序列是一连串字符(包括空格),如果模型遇到停止序列,则会停止生成回答。
  • 逐字逐句给出回答,您可以选择是在生成回答时输出结果,还是在完成回答后进行保存和显示。
  • 安全过滤器阈值用于调整您看到有害响应的可能性。

看到根据上述要求生成合理测验的提示后,我们可以使用自定义代码解析此测验。但如果让 LLM 以结构化格式直接加载到程序中来生成测验,是不是更好?在本实验的后面部分,我们将使用以下程序来调用您的生成器,要求测验以 JSON 格式表示。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 格式输出测验。

  1. 用字词指明您要查找的确切格式(例如,上面的斜体句子)。
  2. 在提示中添加所需 JSON 格式的示例。

提示根据所需规范生成测验后,点击页面右上角的 GET CODE 按钮,查看可用于以编程方式将提示提交到 Vertex AI LLM 的 Python 代码。如果您对使用 Python 以外的编程语言感兴趣,请访问 https://cloud.google.com/vertex-ai/docs/samples?text=generative

4. 构建简单的 Web 服务器

c73008bb8a72b57b.png

现在,您已经有了有效的提示,我们希望将其集成到一个更大的应用中。当然,我们可以将您的提示嵌入到大型应用的源代码中,但我们希望您的生成器作为一个微服务来运行,以便为其他应用提供测验生成服务。为此,我们需要创建一个简单的网络服务器,并将其公开。我们将在后续步骤中执行此操作。

首先,点击 Cloud Shell 面板顶部的 Open Editor 按钮。如下所示:

e2a06b5304079efc.png

然后,您会进入一个类似于 Visual Studio Code 的 IDE 环境中,您可以在其中创建项目、修改源代码、运行程序等。

如果屏幕太狭窄,您可以拖动控制台和编辑/终端窗口之间的水平栏,以扩大或缩小这两个区域之间的分界线,如下图中突出显示:

8dea35450851af53

您可以通过分别点击 Open EditorOpen Terminal 按钮,在编辑器和终端之间来回切换。现在,请尝试在这两种环境之间来回切换。

接下来,创建一个文件夹来存储本实验中的工作内容,方法是点击“添加文件夹”按钮 5f4e64909bc15e30,输入 quiz-generator 并按 Enter 键。您在本实验中创建的所有文件,以及在 Cloud Shell 中执行的所有工作,都将在此文件夹中进行。

现在,创建一个 requirements.txt 文件。这会告知 Python 您的应用依赖于哪些库。对于这个简单的 Web 应用,您将使用一个热门的 Python 模块来构建名为 Flask,google-cloud-aiplatform 客户端库)的 Web 服务器,以及一个名为 gunicorn 的 Web 服务器框架。在文件导航窗格中,右键点击 quiz-generator 文件夹,然后选择 New file 菜单项,如下所示:

613eb3de4b9b750a

当系统提示您输入新文件的名称时,输入 requirements.txt 并按 Enter 键。确保新文件最终位于 quiz-generator 项目文件夹中。

将以下行粘贴到新文件中,以指定您的应用依赖于 Python flask 软件包、gunicorn Web 服务器、google-cloud-aiplatform 客户端库,以及每个软件包的关联版本。

flask==3.0.0
gunicorn==21.2.0
google-cloud-aiplatform==1.47.0

您无需明确保存此文件,因为 Cloud Editor 会自动为您保存更改。

使用相同的方法,创建另一个名为 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 服务器(比如您刚刚启动的网络服务器)。

点击 web preview 按钮,然后点击 Preview on Port 8080 菜单项,如下所示:

7f938c0bc1b4154c

这将打开您正在运行的应用的网络浏览器标签页,如下所示:

aaaf366f9bf74a28.png

5. 添加了包含参数解析的 generate 方法

现在,我们需要添加对字段化名为 generate 的新方法的支持。为此,您可以添加一个 import 语句来操作 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)

现在,重新加载现有的网络浏览器标签页以查看结果。这一次,您应该会看到“测验生成器”,以及一个自动添加到您的网址的查询参数 (authuser)。请尝试附加字符串“`&param1=val1&param2=val2`”,以添加另外两个参数附加到浏览器地址栏中网址的末尾,重新加载页面,然后您应该会看到如下所示的内容:

6e223ca358e4e009

现在,我们已经了解了如何在网址上发送和解析查询参数,接下来我们将添加对要发送测验生成器的特定参数的支持,如下所示:

  • 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)

现在,重新加载现有的网络浏览器标签页以查看结果。您应该会看到类似如下网页的内容:

15eed60f6a805212

请尝试更改网址,以设置各种参数的值。例如,您可以尝试使用后缀“?authuser=0&topic=Literature&num_q=10&diff=easy&lang=French”:

f629dba5fa207cef.png

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)

现在,重新加载现有的网络浏览器标签页以查看结果。您应该会看到类似如下网页的内容:

3c2b9dfcfba86b7a

请尝试修改网址,以更改这四个参数。

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 请求。您应该会看到类似如下网页的内容:

f43d3ba5102857b8.png

请尝试更改网址,以请求不同的测验主题、题目数量和难度级别。

至此,您的微服务就完成了。恭喜!在下一步中,您将学习如何在云端部署服务,以便任何人都可以随时随地访问。

8. 迁移到云端!

67c99bf45a7b7805

现在,您已经构建了自己的测验生成器,接下来希望与全世界分享这些高级功能,是时候将其部署到云端了。但你确实希望能做的不仅仅是分享。您希望确保:

  • 运行可靠 - 在运行您应用的计算机崩溃时,您具备自动容错能力
  • 自动扩缩 - 您的应用可以跟上巨大的流量水平,并且在不使用时会自动减少其占用空间
  • 可最大限度地降低费用,因为它不会针对未使用的资源向您收费 - 您只需为响应流量时消耗的资源付费
  • 可通过自定义域名访问 - 您可以使用一键式解决方案为您的服务分配自定义域名
  • 响应时间极短,冷启动的响应速度比较快,但您可以通过指定实例数下限配置进行微调
  • 支持使用标准 SSL/TLS 网络安全的端到端加密。部署服务时,免费且自动地获得标准网络加密以及所需的相应证书

将应用部署到 Google Cloud Run 后,您可以获享上述所有优势及其他优势。与 Cloud Run 共享应用的基本构建块是一个容器。

容器让我们能够创建一个模块化盒子,在其中运行捆绑在一起所有依赖项的应用。由于容器几乎可以在任何虚拟或真实服务器上使用,这使我们能够在任何您喜欢的地方(从本地到云端)部署您的应用,甚至可以将您的应用从一个服务提供商迁移到另一个服务提供商。

如需详细了解容器及其在 Google Cloud Run 中的工作原理,请查看使用 Cloud Run 完成三个简单步骤从开发到生产 Codelab。

将应用部署到 Cloud Run

Cloud Run 是一项区域级服务,这意味着运行 Cloud Run 服务的基础架构位于特定区域并由 Google 托管,以便在该区域内的所有可用区以冗余方式提供。为简单起见,在本实验中,我们将使用硬编码区域 us-central1

我们将使用名为 buildpack 的工具来自动生成容器。在 Cloud Editor 中创建一个名为 Procfile 的新文件,并插入下面一行文本:

web: gunicorn --bind :$PORT --workers 1 --threads 8 --timeout 0 main:app

这会告知 Buildpack 系统如何在自动生成的容器中运行您的应用。接下来,在 Cloud Shell 终端(从同一 quiz-generator 目录)中运行以下命令:

gcloud run deploy quiz-generator  \
    --source .                    \
    --region us-central1          \
    --allow-unauthenticated

这会告知 gcloud 命令,您希望它根据在当前目录中找到的源文件(--source . 中的 dot 是当前目录的简写形式)使用 buildpack 创建容器映像。由于该服务隐式处理容器映像,因此您无需在此 gcloud 命令中指定映像。

等待部署完成。 成功后,gcloud 命令会显示新服务的网址:

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

您还可以使用以下命令检索服务网址:

gcloud run services describe quiz-generator  \
  --region us-central1                       \
  --format "value(status.url)"

显示的内容应如下所示:

https://quiz-generator-co24gukjmq-uc.a.run.app

此链接是您的 Cloud Run 服务的专用网址,其中包含 TLS 安全性。此链接是永久性的(只要您未停用服务),可在互联网的任何地方使用。它并不使用前面提到的 Cloud Shell 的代理机制,该机制依赖于临时虚拟机。

点击突出显示的 Service URL,打开一个网络浏览器标签页,跳转到正在运行的应用。验证结果是否与您在开发环境中看到的结果相同。此外,验证您是否可以通过在网址末尾提供参数来调整生成的测验。

恭喜!您的应用现在正在 Google 的云中运行。无需费心考虑,您的应用便已公开发布,支持 TLS (HTTPS) 加密,并且能够自动扩缩到令人难以置信的流量水平。

9. 将各部分整合在一起

9927db1725bcd5d6

在这最后一步中,我们可以运行测验生成器作为测验应用的一部分了。访问 quizaic 网址,登录您的 Google 账号,然后导航至“Create Quiz”标签。选择生成器类型 Custom,将您的 Cloud Run 网址粘贴到网址字段中,填写其他必填字段,然后提交表单。

328ee05579ea05f9

稍后,你应该会有一个新测验(请见下图中的“我的新测验”)和一张 AI 生成的缩略图,你可以通过相应按钮编辑、播放、复制或删除该图片。这个新测验是使用您刚刚根据模板化提示部署的 Web 服务创建的!

1719169140978b63

10. 清理

c1592d590c563428.png

虽然 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. 您做到了!

910162be58c0f6d6

恭喜 - 您已成功编写 LLM 提示,并使用该提示部署了 Cloud Run 微服务。现在,您可以使用自然语言进行编程,并与全世界分享您的创作!

我想给大家留下一个重要的问题:

让您的应用在开发者环境中运行后,要使用 Cloud Run 提供的所有生产级属性,您必须修改多少行代码才能将其部署到云端?

答案当然是零。:)

可查看其他 Codelab...

参考文档…

12. 号召性用语

如果您喜欢此 Codelab,并且可能会花更多时间亲自体验 Google Cloud,那么真正应该加入 Google Cloud Innovators 计划

498cab7d87ec12d3

Google Cloud Innovators 完全免费,包含以下内容:

  • 通过实时讨论、AMA 和路线图会议,直接向 Google 员工学习最新动态
  • 最新的 Google Cloud 资讯直接送到您的收件箱
  • 数字徽章和视频会议背景
  • 价值 500 积分的 Skills Boost 实验和学习积分

点击此处报名!