إنشاء منشئ اختبارات باستخدام الذكاء الاصطناعي التوليدي وCloud Run

1. مقدمة

سوف تنشئ في هذا التمرين المعملي خدمة ويب لإنشاء اختبارات المعلومات العامة ودمجها في تطبيق ممتع وقابل للعمل. ستستخدم لغة برمجة مختلفة عن تلك التي كنت تستخدمها من قبل: الإنجليزية!

الإجراءات التي ستنفّذها

  • عليك صياغة مطالبة تنشئ اختبار معلومات عامة وفقًا لمجموعة من المعايير.
  • ستنشئ تطبيق ويب بسيطًا وتتحقق من تشغيله على النحو المتوقع في بيئة التطوير.
  • سيكون عليك إضافة منطق إلى تطبيق الويب بشكل تدريجي لتحويله إلى خادم واجهة برمجة تطبيقات ينشئ الاختبارات وفقًا لمجموعة من مَعلمات الإدخال.
  • ستتعرف على مدى سهولة نشر خدمة إنشاء الاختبارات على السحابة الإلكترونية باستخدام Google Cloud Run.
  • أخيرًا، ستقوم بتهيئة تطبيق حقيقي ( quizaic.com) لاستخدام خدمة إنشاء الاختبارات التي تم نشرها وستتمكن من تشغيل اختبارات مباشرة بناءً على النتيجة.

المعلومات التي ستطّلع عليها:

  • طريقة إنشاء طلب نموذجي لنموذج لغوي كبير (LLM)
  • كيفية إنشاء تطبيق بسيط لخادم الويب في Python.
  • كيفية إتاحة النموذج اللغوي الكبير من Google في تطبيق الويب الخاص بك
  • طريقة نشر تطبيقك على السحابة الإلكترونية ليتمكّن أي شخص من تجربة تصميمك الجديد
  • كيفية دمج منشئ الاختبارات في تطبيق أكبر.

المتطلبات...

  • متصفّح الويب Chrome
  • حساب Google
  • مشروع على Google Cloud تم تفعيل الفوترة فيه

يستهدف هذا التمرين المعملي المطوّرين من جميع المستويات، بما في ذلك المبتدئين. على الرغم من أنّك ستستخدم Python، ليس من الضروري أن تكون على دراية ببرمجة Python لفهم ما يحدث لأننا سنشرح كل الرموز التي ستراها.

2. ضبط إعدادات الجهاز

a08aa5878e36b60c.png

يتناول هذا القسم كل الإجراءات المطلوبة للبدء في هذا التمرين.

إعداد بيئة ذاتية

  1. سجِّل الدخول إلى Google Cloud Console وأنشئ مشروعًا جديدًا أو أعِد استخدام مشروع حالي. إذا لم يكن لديك حساب على Gmail أو Google Workspace، عليك إنشاء حساب.

fbef9caa1602edd0.png

a99b7ace416376c4.png

5e3ff691252acf41.png

  • اسم المشروع هو الاسم المعروض للمشاركين في هذا المشروع. وهي سلسلة أحرف لا تستخدمها Google APIs. ويمكنك تعديلها في أي وقت.
  • يكون رقم تعريف المشروع فريدًا في جميع مشاريع Google Cloud وغير قابل للتغيير (لا يمكن تغييره بعد تحديده). تنشئ Cloud Console سلسلة فريدة تلقائيًا. فعادةً لا تهتم بما هو. في معظم الدروس التطبيقية حول الترميز، يجب الإشارة إلى رقم تعريف المشروع (الذي يتم تحديده عادةً على أنّه PROJECT_ID). وإذا لم يعجبك رقم التعريف الذي تم إنشاؤه، يمكنك إنشاء رقم تعريف عشوائي آخر. ويمكنك بدلاً من ذلك تجربة طلبك الخاص ومعرفة ما إذا كان متاحًا. ولا يمكن تغييره بعد هذه الخطوة ويبقى طوال مدة المشروع.
  • لمعلوماتك، هناك قيمة ثالثة، وهي رقم المشروع، الذي تستخدمه بعض واجهات برمجة التطبيقات. اطّلِع على مزيد من المعلومات حول هذه القيم الثلاث في المستندات.
  1. بعد ذلك، عليك تفعيل الفوترة في Cloud Console لاستخدام الموارد/واجهات برمجة التطبيقات في Cloud. لن يؤدي إكمال هذا الدرس التطبيقي حول الترميز إلى فرض أي تكاليف، إن وُجدت. لإيقاف تشغيل الموارد لتجنب تحمُّل الفواتير إلى ما هو أبعد من هذا البرنامج التعليمي، يمكنك حذف الموارد التي أنشأتها أو حذف المشروع. يكون مستخدمو Google Cloud الجدد مؤهَّلون للانضمام إلى برنامج فترة تجريبية مجانية بقيمة 300 دولار أمريكي.

بدء Cloud Shell

ستعمل في هذا التمرين المعملي في جلسة Cloud Shell، وهي عبارة عن مترجم أوامر يستضيفه جهاز افتراضي يعمل على السحابة الإلكترونية من Google. كان بإمكانك تشغيل هذا القسم محليًا بسهولة على جهاز الكمبيوتر، ولكن استخدام Cloud Shell يمنح الجميع إمكانية الوصول إلى تجربة قابلة للتكرار في بيئة متسقة. بعد انتهاء التمرين المعملي، يمكنك إعادة محاولة استخدام هذا القسم على جهاز الكمبيوتر.

4a95152439f0159b.png

تفعيل Cloud Shell

  1. من Cloud Console، انقر على تفعيل Cloud Shell 853e55310c205094.png.

3c1dabeca90e44e5.png

إذا كانت هذه هي المرة الأولى التي تبدأ فيها Cloud Shell، ستظهر لك شاشة وسيطة تصف ماهيتها. إذا ظهرت لك شاشة وسيطة، انقر على متابعة.

9c92662c6a846a5c.png

من المفترَض أن تستغرق عملية توفير المتطلبات اللازمة والاتصال بخدمة Cloud Shell بضع دقائق فقط.

9f0e51b578fecce5.png

يتم تحميل هذا الجهاز الافتراضي مع جميع أدوات التطوير اللازمة. وتوفّر هذه الشبكة دليلاً رئيسيًا دائمًا بسعة 5 غيغابايت ويتم تشغيله في Google Cloud، ما يحسّن بشكل كبير من أداء الشبكة والمصادقة. يمكنك تنفيذ معظم عملك، إن لم يكن كلّه، في هذا الدرس التطبيقي حول الترميز باستخدام متصفّح.

بعد الربط بخدمة Cloud Shell، من المفترض أن تتأكّد من أنّه تمّت مصادقتك وأنّ المشروع مضبوط على رقم تعريف مشروعك.

  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].

تفعيل بعض واجهات برمجة التطبيقات

في الخطوات اللاحقة، ستظهر لك الحاجة إلى هذه الخدمات (وسبب ذلك)، ولكن في الوقت الحالي، عليك تنفيذ هذا الأمر لمنح مشروعك إذن الوصول إلى 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- مطالبة - البرمجة باللغة الطبيعية

92f630373224ead8.png

سنبدأ بتعلّم كيفية إعداد طلب لنموذج لغوي كبير. الانتقال إلى Google Cloud Console > Vertex AI > Vertex AI Studio (اللغة) يُفترض أن تظهر لك صفحة على النحو التالي:

bfe5706041ae6454.png

من Generate Text، انقر على الزرّ Text Prompt. في مربع الحوار التالي، أدخل مطالبة تعتقد أنها قد تكون فعالة لإنشاء اختبار معلومات عامة وفقًا للمتطلبات التالية:

  • الموضوع: تاريخ العالم
  • عدد الأسئلة: 5
  • مستوى الصعوبة: متوسط
  • اللغة: الإنجليزية

انقر فوق الزر "Submit" (إرسال) للاطلاع على الناتج.

كما هو موضح في لقطة الشاشة التالية، تمنحك اللوحة اليمنى إمكانية تحديد النموذج الذي تريد استخدامه وضبط بعض الإعدادات:

8aa89a1970ea9335.png

تتوفر الإعدادات التالية:

  • المنطقة هي المكان الذي يجب تنفيذ طلب الإنشاء فيه.
  • يحدد النموذج النموذج اللغوي الكبير الذي تريد استخدامه. في هذا الدرس التطبيقي حول الترميز، يجب استخدام "gemini-1.0-pro-001".
  • يتحكّم خيار "درجة الحرارة" في درجة العشوائية عند اختيار الرمز المميّز. يساعد انخفاض درجات الحرارة في تقديم ردود على الطلبات التي تتوقّع الحصول على إجابة صحيحة أو صحيحة، بينما يؤدي ارتفاع درجات الحرارة إلى نتائج أكثر تنوعًا أو غير متوقّع.
  • يحدّد حدّ الرموز المميّزة الحدّ الأقصى للمخرجات النصية الناتجة من طلب واحد. يتكون الرمز المميز من أربعة أحرف تقريبًا. القيمة التلقائية هي 1024.
  • يُغيِّر عمود Top-k كيفية اختيار النموذج للرموز المميّزة للمخرجات. يعني ظهور رمز الحرف العلوي 1 أن الرمز المميّز الذي تم اختياره هو الأكثر احتمالاً بين كل الرموز المميّزة في مفردات النموذج (ويُسمّى أيضًا فكّ الترميز الجشع)، في حين يشير الحرف العلوي 3 إلى أنّه تم اختيار الرمز المميّز التالي من بين الرموز الثلاثة الأكثر احتمالاً (باستخدام درجة الحرارة). قيمة أعلى كيلوبايت التلقائية هي 40.
  • يغيّر الجزء العلوي p طريقة اختيار النموذج للرموز المميّزة للمخرجات. يتم اختيار الرموز المميّزة من الأكثر ترجيحًا إلى الأقل إلى أن يساوي مجموع احتمالاتها القيمة ذات الأولوية P.
  • الحدّ الأقصى للردود هو الحد الأقصى لعدد ردود النموذج التي يتم إنشاؤها لكل طلب.
  • تسلسل محطة التوقّف هو سلسلة من الأحرف (بما فيها المسافات) التي تتوقف عن إنشاء الردّ إذا صادفه النموذج.
  • يحدد البث المباشر الردود ما إذا كان يجب طباعة الردود عند إنشائها أو حفظها، ويتم عرضها عند اكتمالها.
  • يعمل الحد الأدنى لفلتر الأمان على تعديل مدى احتمال رؤيتك للردود التي قد تكون ضارة.

عندما يظهر لك طلب يبدو أنّه يؤدي إلى إنشاء اختبار معقول وفقًا للمتطلبات المذكورة أعلاه، يمكننا تحليل هذا الاختبار باستخدام رمز مخصّص، ولكن ألن يكون من الأفضل أن ينشئ النموذج اللغوي الكبير الاختبار بتنسيق منظَّم يمكننا تحميله مباشرةً إلى برنامجنا. ومن المتوقّع أن يتم التعبير عن الاختبارات بتنسيق 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 في أعلى يسار الصفحة للاطّلاع على رمز لغة Python الذي يمكنك استخدامه لإرسال طلبك آليًا إلى Vertex AI LLM. إذا كنت مهتمًا باستخدام لغة برمجة أخرى غير Python، يمكنك الاطّلاع على https://cloud.google.com/vertex-ai/docs/samples?text=generative.

4. إنشاء خادم ويب بسيط

c73008bb8a72b57b.png

الآن بعد أن أصبح لديك مطالبة تعمل، نريد دمجها في تطبيق أكبر. بالطبع، يمكننا تضمين طلبك في رمز المصدر الخاص بالتطبيق الأكبر حجمًا، ولكنّنا نريد أن يعمل منشئك كخدمة مصغّرة توفّر خدمة إنشاء الاختبارات للتطبيقات الأخرى. ولتحقيق ذلك، سنحتاج إلى إنشاء خادم ويب بسيط وجعله متاحًا للجميع. سنقوم بذلك في الخطوات التالية.

يمكنك البدء بالنقر على الزر Open Editor أعلى لوحة Cloud Shell. تبدو هكذا:

e2a06b5304079efc.png

ستجد بعد ذلك في بيئة IDE مشابهة لـ Visual Studio Code، حيث يمكنك إنشاء مشاريع وتعديل رمز المصدر وتشغيل برامجك وما إلى ذلك.

إذا كانت شاشتك ضيقة جدًا، فيمكنك توسيع أو تقليص الخط الفاصل بين وحدة التحكم ونافذة التعديل/الطرف الطرفي عن طريق سحب الشريط الأفقي بين هاتين المنطقتين، المحدد هنا:

8dea35450851af53.png

يمكنك التبديل بين المحرر والمحطة الطرفية من خلال النقر على الزرين Open Editor وOpen Terminal على التوالي. حاول التبديل بين هاتين البيئتين الآن.

بعد ذلك، أنشئ مجلدًا لتخزين عملك ضمن هذا التمرين بالنقر على زر إضافة مجلد 5f4e64909bc15e30.png ثم أدخل quiz-generator ثم اضغط على Enter. وستجري في هذا المجلد جميع الملفات التي تنشئها في هذا التمرين وكل الأعمال التي تنفذها في Cloud Shell.

يمكنك الآن إنشاء ملف requirements.txt. ويخبر ذلك Python بالمكتبات التي يعتمد عليها تطبيقك. في تطبيق الويب البسيط هذا، ستستخدم وحدة Python شائعة لإنشاء خوادم ويب تُسمى Flask, مكتبة برامج google-cloud-aiplatform، وإطار عمل لخادم الويب يُسمى gunicorn. في مساحة الروابط، انقر بزر الماوس الأيمن على مجلد quiz-generator وحدد عنصر القائمة New file، كما يلي:

613eb3de4b9b750a.png

عندما يُطلب منك إدخال اسم الملف الجديد، أدخِل requirements.txt واضغط على مفتاح Enter. تأكد من أن الملف الجديد ينتهي به الأمر في مجلد مشروع quiz-generator.

ألصِق السطور التالية في الملف الجديد لتحديد أن تطبيقك يعتمد على حزمة flask في بايثون وخادم الويب gunicorn ومكتبة عملاء 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 preview ثم على عنصر القائمة Preview on Port 8080 على النحو التالي:

7f938c0bc1b4154c.png

سيؤدي ذلك إلى فتح علامة تبويب متصفّح ويب للوصول إلى التطبيق قيد التشغيل، والذي من المفترض أن يبدو على النحو التالي:

aaaf366f9bf74a28.png

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). حاول إضافة معلمتين إضافيتين من خلال إلحاق السلسلة "`&param1=val1&param2=val2`" إلى نهاية عنوان URL في شريط عناوين المتصفح، فأعد تحميل الصفحة، ومن المفترض أن يظهر لك ما يلي:

6e223ca358e4e009.png

الآن وبعد أن عرضنا كيفية إرسال معلَمات طلب البحث وتحليلها على عنوان 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)

يمكنك الآن إعادة تحميل علامة تبويب متصفّح الويب للاطّلاع على النتائج. من المفترض أن يظهر لك محتوى كصفحة الويب التالية:

15eed60f6a805212.png

جرِّب تغيير عنوان URL لضبط قيم لمعلَمات متنوعة. على سبيل المثال، يمكنك تجربة استخدام اللاحقة "?authuser=0&topic=Literature&num_q=10&diff=easy&lang=French" في نهاية عنوان URL في شريط العناوين:

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.png

جرِّب تعديل عنوان URL لتغيير تلك المعلمات الأربعة.

7. إضافة مكتبة برامج Vertex AI

نحن الآن جاهزون لاستخدام مكتبة برامج Vertex AI Python لإنشاء الاختبار. سيؤدي هذا الإجراء إلى برمجة الطلب التفاعلي الذي أجريته في الخطوة رقم 3 ومنح خدمة المنشئ إمكانية الوصول الآلي إلى إمكانات النماذج اللغوية الكبيرة (LLM) من Google. عدِّل ملف main.py على النحو التالي:

التأكّد من استبدال "YOUR_PROJECT" برقم تعريف مشروعك الفعلي

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

حاوِل تغيير عنوان URL لطلب محتوى اختبار مختلف وعدد الأسئلة ومستوى الصعوبة.

وبهذا، تكون قد انتهيت من خدمتك المصغَّرة - تهانينا! ستتعلم في الخطوة التالية كيفية نشر خدمتك في السحابة الإلكترونية حتى يتمكن أي شخص من الوصول إليها من أي مكان.

8. إلى السحابة الإلكترونية!

67c99bf45a7b7805.png

الآن وبعد أن أنشأت أداة إنشاء الاختبارات الخاصة بك، عليك مشاركة هذه الفكرة الرائعة مع بقية العالم، لذا حان الوقت لنشره على السحابة. ولكنك ترغب حقًا في القيام بأكثر من مجرد مشاركته. يجب التأكّد من أنّه:

  • يعمل بشكل موثوق - فأنت تتخطى الأخطاء تلقائيًا في حالة تعطُّل جهاز كمبيوتر يعمل بتطبيقك
  • يتطور تلقائيًا - سيواكب تطبيقك مستويات هائلة من الزيارات، ويقلل تلقائيًا من بصمته عند عدم استخدامه.
  • إلى خفض التكاليف، من خلال عدم تحصيل رسوم منك مقابل الموارد التي لا تستخدمها، بل يتم تحصيل رسوم منك فقط مقابل الموارد المستهلكة أثناء الاستجابة للزيارات
  • يمكن الوصول إليها عبر اسم مجال خاص - يمكنك الوصول إلى حل بنقرة واحدة لتعيين اسم مجال خاص لخدمتك
  • وقت استجابة ممتاز - عمليات التشغيل على البارد سريعة الاستجابة بشكل معقول ولكن يمكنك تحسين ذلك من خلال تحديد تهيئة الحد الأدنى للمثيل
  • يتوافق مع التشفير التام بين الأطراف باستخدام أمان الويب العادي من خلال طبقة المقابس الآمنة (SSL)/بروتوكول أمان طبقة النقل (TLS)، فعند نشر إحدى الخدمات، تحصل على تشفير الويب العادي، والشهادات المطلوبة المقابلة، مجانًا وتلقائيًا.

من خلال نشر تطبيقك على Google Cloud Run، يمكنك الاستفادة من كل ما سبق والمزيد. تعتبر الوحدة الأساسية لمشاركة تطبيقك مع Cloud Run هي الحاوية.

تتيح لنا الحاويات إنشاء مربع وحدات يمكن فيه تشغيل تطبيق مع تجميع جميع ملحقاته معًا. ونظرًا لأنه يمكن استخدام الحاويات على أي خادم افتراضي أو حقيقي تقريبًا، فإن ذلك يمنحنا طريقة لنشر تطبيقك في أي مكان تريده، من داخل الشركة إلى السحابة، وحتى نقل تطبيقك من مقدم خدمة إلى آخر.

للمزيد من المعلومات عن الحاويات وكيفية عملها في Google Cloud Run، يمكنك الاطّلاع على الدرس التطبيقي حول الترميز تطوير البرامج في ثلاث خطوات سهلة باستخدام Cloud Run.

نشر تطبيقك في تشغيل السحابة الإلكترونية

Cloud Run هي خدمة إقليمية، ما يعني أنّ البنية الأساسية التي تدير خدمات Cloud Run تقع في منطقة محدّدة وتديرها Google لتكون متاحة بشكلٍ متكرّر في جميع المناطق ضمن تلك المنطقة. ولتبسيط الأمر، سنستخدم منطقة الترميز الثابت us-central1 في هذا التمرين المعملي.

سنستخدم أداة تسمى Buildpack لإنشاء حاويتك تلقائيًا. أنشئ ملفًا جديدًا باسم "Procfile" في Cloud Editor وأدرِج هذا السطر من النص:

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 بأنّك تريد أن يستخدم الإصدار حزم التطبيقات لإنشاء صورة الحاوية استنادًا إلى الملفات المصدر التي يعثر عليها في الدليل الحالي (اختصارًا dot في --source . للدليل الحالي). بما أنّ الخدمة تعتني بصورة الحاوية بشكل ضمني، لن تحتاج إلى تحديد صورة في الأمر 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

هذا الرابط هو عنوان URL مخصَّص لخدمة "تشغيل السحابة الإلكترونية" مع أمان بروتوكول أمان طبقة النقل (TLS). هذا الرابط دائم (طالما لم يتم إيقاف الخدمة) وقابل للاستخدام في أي مكان على الإنترنت. ولا يستخدم آلية الخادم الوكيل لـ Cloud Shell المذكورة سابقًا، والتي كانت تعتمد على جهاز افتراضي عابر.

انقر على Service URL المميّز لفتح علامة تبويب في متصفّح الويب للوصول إلى تطبيقك قيد التشغيل. تحقَّق من أن النتيجة مماثلة لما رأيته في بيئة التطوير. تأكَّد أيضًا من أنّه يمكنك تعديل الاختبار الذي تم إنشاؤه من خلال توفير معلَمات في نهاية عنوان URL.

تهانينا! يتم تشغيل تطبيقك الآن على السحابة الإلكترونية من Google. وبدون الحاجة إلى التفكير في الأمر، سيكون تطبيقك متاحًا للجميع، ومزودًا بتشفير TLS (HTTPS)، بالإضافة إلى إمكانية التوسيع التلقائي لمستويات زيارات مذهلة.

9. وضع كل القطع معًا

9927db1725bcd5d6.png

في هذه الخطوة الأخيرة، نحن جاهزون لتشغيل منشئ الاختبار الخاص بك كجزء من تطبيق Quiaic. انتقل إلى عنوان URL المميز، وسجّل الدخول إلى حسابك في Google، ثم انتقل إلى علامة التبويب Create Quiz. اختَر نوع المنشئ Custom، والصِق عنوان URL لتشغيل Cloud في حقل عنوان URL، واملأ الحقول الأخرى المطلوبة، ثم أرسِل النموذج.

328ee05579ea05f9.png

بعد بضع لحظات، سيكون لديك اختبار جديد (راجِع "اختباري الجديد" في الصورة أدناه) يتضمّن صورة مصغّرة من إنشاء الذكاء الاصطناعي يمكنك تعديلها أو تشغيلها أو استنساخها أو حذفها من خلال الأزرار المناسبة. تم إنشاء هذا الاختبار الجديد باستخدام خدمة الويب التي نشرتها للتو بناءً على طلبك النموذجي.

1719169140978b63.png

10. التنظيف

c1592d590c563428.png

على الرغم من أنه لا يتم تحصيل رسوم عند استخدام الخدمة عندما لا تكون الخدمة قيد الاستخدام، قد يستمر تحصيل رسوم منك مقابل تخزين صورة الحاوية التي تم إنشاؤها.

يمكنك حذف مشروع Google Cloud Platform لتجنُّب تحمُّل الرسوم، ما سيؤدي إلى إيقاف الفوترة لجميع الموارد المستخدَمة ضمن هذا المشروع، أو حذف صورة الحاوية باستخدام هذا الأمر:

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.png

لقد نجحت في إعداد طلب نموذج لغوي كبير (LLM) ونشر خدمة مصغّرة في السحابة الإلكترونية باستخدام هذا الطلب. يمكنك الآن البرمجة بلغة طبيعية ومشاركة إبداعاتك مع العالم!

أودّ أن أطرح عليك سؤالاً مهمًا:

بعد تشغيل التطبيق في بيئة المطوِّر، كم عدد أسطر الرمز البرمجي التي اضطررت إلى تعديلها لنشره على السحابة الإلكترونية، مع جميع سمات مستوى الإنتاج التي يوفّرها تشغيل Cloud Run؟

الإجابة بالطبع هي صفر. :)

يمكنك الاطّلاع على دروس تطبيقية أخرى حول الترميز...

المستندات المرجعية...

12. الحث على اتخاذ إجراء

إذا استمتعت بهذا الدرس التطبيقي ومن المرجح أن تقضي وقتًا أطول في التدريب على Google Cloud، ننصحك بالانضمام إلى Google Cloud Innovants اليوم.

498cab7d87ec12d3.png

خدمة Google Cloud Innovions مجانية وتشمل ما يلي:

  • لقاءات مباشرة ونقاشات وجلسات تفصيلية حول وضع خرائط الطريق للتعرّف على آخر الأخبار مباشرةً من موظفي Google
  • آخر أخبار Google Cloud مباشرةً في بريدك الوارد
  • شارة رقمية وخلفية اجتماع الفيديو
  • 500 وحدة دراسية من المختبرات والتعلُّم في "منصة تعزيز المهارات"

انقر هنا للتسجيل.