משרטטים אתר: אפשר להפוך את הדמיון לאתר בעזרת מודלים של Gemini!

1. מבוא

בעולם פיתוח האתרים, התהליך של הפיכת קונספט עיצובי לאתר פונקציונלי יכול להיות מורכב ולגזול זמן רב. עם זאת, עם התפתחות מודלים של AI גנרטיבי כמו Gemini, התהליך הזה הופך ליעיל ונגיש יותר ויותר. אנחנו נבנה פתרון שמתמחה בהמרת מסגרות אתרים שצויירו ביד לקוד אתר. הכלי העוצמתי הזה מאפשר למעצבים ולמפתחים להגשים את החזון שלהם לגבי האתר בקלות וביעילות חסרות תקדים.

בשיעור ה-Lab הזה ניצור אפליקציית אינטרנט שמאפשרת למשתמשים ליצור קוד לאתר (html,‏ css ו-JavaScript) משרטוטים ומנחיות שהמשתמש מזין באמצעות מודלים של AI גנרטיבי של Vertex AI (Gemini 1.5 Flash,‏ Gemini 1.5 Pro וכו'). האפליקציה תיבנה באמצעות Flask, מסגרת אינטרנט פופולרית של Python, ותשתמש בספריית הלקוח של Vertex AI כדי ליצור אינטראקציה עם שירות המודלים הגנרטיביים.

מה תפַתחו

בסוף שיעור Lab הזה, יהיה לכם אפליקציית אינטרנט פעילה שיכולה ליצור תמונות משרטוטים ומבקשות. בנוסף, תקבלו הבנה טובה יותר של אופן השימוש במודלים של AI גנרטיבי ב-Vertex AI.

אפליקציית האינטרנט תיראה כך:

5bccb261882c1bf0.png

איך האפליקציה פועלת

  1. העלאת מסגרת חוטים שצוירה ביד: המשתמשים יכולים להעלות לאפליקציה תמונה של מסגרת חוטים שצוירה ביד.
  2. בחירת מודל: האפליקציה מספקת מבחר של מודלים מאומנים מראש של Gemini שעברו אופטימיזציה לסגנונות עיצוב שונים.
  3. הזנת הנחיה: המשתמשים יכולים להזין הנחיית טקסט כדי להנחות את יצירת התמונה על ידי המודל.
  4. יצירת קוד לאתר: האפליקציה שולחת את מסגרת התצוגה ואת ההנחיה ל-Gemini, שיוצר את קוד האתר המתאים.
  5. הצגת התוצאה: הקוד שנוצר מוצג בדף התשובה של האפליקציה.

נתחיל בהסבר על היסודות של מסגרות תיל ומנחי טקסט, ואיך אפשר להשתמש בהם כדי ליצור קוד לאתר. לאחר מכן נסביר איך לבנות את אפליקציית האינטרנט, כולל איך לטפל בקלט של משתמשים, ליצור תשובה ולהציג את התוצאות.

‫2. לפני שמתחילים

  1. ב-מסוף Google Cloud, בדף לבחירת הפרויקט, בוחרים או יוצרים פרויקט ב-Google Cloud.
  2. מוודאים שהחיוב מופעל בפרויקט בענן שלכם ב-Google Cloud. כך בודקים אם החיוב מופעל בפרויקט
  3. תשתמשו ב-Cloud Shell, סביבת שורת פקודה שפועלת ב-Google Cloud. כדי לגשת אליו, לוחצים על Activate Cloud Shell (הפעלת Cloud Shell) בחלק העליון של מסוף Google Cloud.

1829c3759227c19b.png

  1. אחרי שמתחברים ל-Cloud Shell, אפשר לבדוק שכבר בוצע אימות ושהפרויקט מוגדר למזהה הפרויקט שלכם באמצעות הפקודה הבאה:
gcloud auth list
  1. מריצים את הפקודה הבאה ב-Cloud Shell כדי לוודא שפקודת gcloud מכירה את הפרויקט.
gcloud config list project
  1. אם הפרויקט לא מוגדר, משתמשים בפקודה הבאה כדי להגדיר אותו:
gcloud config set project <YOUR_PROJECT_ID>
  1. מוודאים שממשקי ה-API הבאים מופעלים:
  • Cloud Run
  • Vertex AI

אפשרות נוספת היא להשתמש במסוף דרך הקישור הזה במקום להשתמש בפקודת gcloud. אפשר לעיין במאמרי העזרה בנושא פקודות gcloud ושימוש בהן.

3. שלב 1: אתחול של אפליקציית אינטרנט ב-Python Cloud Run

קודם ניצור את תבנית אפליקציית האינטרנט של Python Cloud Run מ-Cloud Shell.

עוברים אל Cloud Shell Terminal ולוחצים על הלחצן Open Editor (פתיחת העורך). b16d56e4979ec951.png

מוודאים שהפרויקט ב-Cloud Code מוגדר בפינה הימנית התחתונה (סרגל הסטטוס) של העורך ב-Cloud Shell, כפי שמודגש בתמונה שלמטה, ושהוא מוגדר לפרויקט הפעיל ב-Google Cloud שבו החיוב מופעל. אם מתבקשים, לוחצים על Authorize (אישור).

f5003b9c38b43262.png

לוחצים על הפרויקט הפעיל בסרגל הסטטוס ומחכים עד שייפתח החלון הקופץ של Cloud Code. בחלון הקופץ, בוחרים באפשרות 'אפליקציה חדשה'. 70f80078e01a02d8.png

ברשימת האפליקציות, בוחרים באפשרות Cloud Run Application (אפליקציית Cloud Run):

39abad102a72ae74.png

בדף 2 מתוך 2, בוחרים בתבנית Python Flask:

a78b3a0311403ad.png

מזינים את שם הפרויקט הרצוי (למשל, amazing-gemini-app) ולוחצים על OK (אישור):

4d8f77279d9509cb.png

הפעולה הזו תפתח את התבנית של הפרויקט החדש שהגדרתם.

e85a020a20d38e17.png

כך אפשר להפעיל אפליקציית אינטרנט בקלות באמצעות Google Cloud Shell.

4. שלב 2: בניית חזית האתר

לשם כך, נדרוש דף HTML. הדף הזה יכיל את הקוד שמגדיר את ממשק המשתמש של אפליקציית האינטרנט. הוא כולל טופס שמאפשר למשתמשים להעלות תמונה של מסגרת (wireframe) שצוירה ביד, לבחור מודל גנרטיבי ולספק הנחיית טקסט. אחרי ששולחים את הטופס, התוצאה מוצגת בכרטיסייה אחרת.

מעתיקים את הקוד שלמטה ומחליפים את הקובץ index.html בתיקייה templates:

<!DOCTYPE html>
<html>
<head>
   <title>Draw a Website</title>
   <style>
       body {
           font-family: sans-serif;
           display: flex;
           justify-content: center;
           align-items: center;
           min-height: 100vh; /* Ensure form is centered vertically */
           background-color: #f4f4f4;
       }
       .container {
           background-color: white;
           padding: 30px;
           border-radius: 8px;
           box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
           text-align: center;
       }
       h2 {
           text-align: center;
           margin-bottom: 20px;
       }
       input[type="file"], textarea, select {
           width: 100%;
           padding:10px;
           margin-bottom: 15px;
           border: 1px solid #ccc;
           border-radius: 4px;
           box-sizing: border-box;
       }
       button {
           background-color: #4CAF50;
           color: white;
           padding: 12px 20px;
           border: none;
           border-radius: 4px;
           cursor: pointer;
       }
   </style>
</head>
<body>
   <div class="container">
       <h2>Draw a Website</h2>
       <form action="/response" target="_blank" method="post" enctype="multipart/form-data">
           <input type="file" id="image-upload" name="image-upload" accept=".png, .jpg, .jpeg">
           <select name="model">
               <option value="gemini-1.5-flash-001">Gemini 1.5 Flash</option>
               <option value="gemini-1.5-pro-001">Gemini 1.5 Pro</option>
               <option value="gemini-1.0-pro-vision-001">Gemini 1.0 Pro Vision</option>
               </select>
           <textarea name="prompt" placeholder="Write your prompt here. For example: 'Convert this drawing into an html page'">Convert this drawing into an html page</textarea>
           <button type="submit">Submit</button>
       </form>
   </div>
</body>
</html>

כשמשתמש מקיים אינטראקציה עם האפליקציה, מתרחשות הפעולות הבאות:

  1. המשתמש בוחר תמונה של מסגרת תיל, בוחר מודל ומזין הנחיה.
  2. כשהמשתמש לוחץ על הלחצן 'שליחה', נתוני הטופס (תמונה, מודל והנחיה) נשלחים לכתובת ה-URL ‏ /response באמצעות שיטת HTTP POST.
  3. הקוד בצד השרת (שמוטמע בקובץ app.py) מעבד את נתוני הטופס ויוצר את התשובה באמצעות המודל וההנחיה שצוינו.
  4. התשובה שנוצרה מוצגת בכרטיסייה החדשה.

סיימנו את החלק של חזית האתר באפליקציית האינטרנט.

5. שלב 3: בניית הקצה העורפי (AI גנרטיבי)

עכשיו נכתוב את החלק העיקרי של אפליקציית האינטרנט הזו. קובץ app.py שמקבל תמונת קלט של משתמשים, את המודל שנבחר ואת ההנחיה, וממיר אותם לקוד של אתר.

מעתיקים את הקוד המלא של app.py:

# Import the necessary libraries.
import os
import random
from flask import (
    Flask,
    render_template,
    request,
    redirect
)

import vertexai
from vertexai.generative_models import (
    GenerativeModel,
    Image
)

# Initialize the Flask app.
app = Flask(__name__)
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024  # 16 MB per image

# TODO: Replace "YOUR_PROJECT_ID" before running
# Initialize the Vertex AI client library.
vertexai.init(project="YOUR_PROJECT_ID", location="us-central1")

# Define a function to generate response from a wireframe and a prompt.
def generate(wireframe, model, prompt):
    '''Generates a response from a wireframe and a prompt.
    Args:
    wireframe: The wireframe image.
    model: The generative model to use.
    prompt: The prompt to use.
    Returns:The generated response.
    '''
    # Create a GenerativeModel object.
    model = GenerativeModel(model)

    # Create a list of contents to pass to the model.
    contents = [
        wireframe,
        prompt
    ]
   
    # Generate the response.
    responses = model.generate_content(
        contents=contents,
        stream=True,
    )

    # Concatenate the response text.
    response = ""
    for res in responses:
        response += res.text.strip()
   
    # Return the generated response.
    return response

# Define the home page route.
@app.route('/', methods=['GET'])
def index():
    '''Renders the home page.
    Returns:The rendered template.
    '''
    return render_template('index.html')

# Define the response route.
@app.route('/response', methods=['GET', 'POST'])
def response():
    '''Handles the response to the user's input.
    Returns:The rendered template.
    '''
    # If the request is a POST request, process the form data.
    if request.method == 'POST':
        # Get the uploaded image from the request.
        uploaded_image = request.files['image-upload']
       
        # Convert the uploaded image to a wireframe image.
        wireframe = Image.from_bytes(uploaded_image.read())

        # Get the model and prompt from the request.
        model = request.form['model']
        prompt = request.form['prompt']
       
        # Generate the response and render the response.
        try:
            response = generate(wireframe, model, prompt)
            response = response.replace("```html", "").replace("```", "").strip()
            return response
        except ValueError as e:
            raise e
   
    # If the request is a GET request, redirect to the home page.
    else:
        return redirect('/')

# Run the app.
if __name__ == '__main__':
    # Get the server port from the environment variables.
    server_port = os.environ.get('PORT', '8080')

    # Run the app.
    app.run(debug=False, port=server_port, host='0.0.0.0')

הקוד מבצע את הפעולות הבאות:

  1. הקוד הזה מייבא את הספריות הנדרשות לאפליקציה:

Flask: מסגרת אינטרנט קלה ל-Python.

‫os: לאינטראקציה עם מערכת ההפעלה.

random: ליצירת מספרים אקראיים.

vertexai: ספריית הלקוח של Vertex AI.

‫GenerativeModel ו-Image: מחלקות מספריית המודלים הגנרטיביים של Vertex AI.

  1. אתחול אפליקציית Flask:

לאחר מכן, הוא מאתחל את אפליקציית Flask ומגדיר את הגודל המקסימלי המותר לתמונות שהועלו ל-16MB.

  1. אתחול הלקוח של Vertex AI

הפקודה מאתחלת את ספריית הלקוח של Vertex AI עם מזהה הפרויקט והמיקום שצוינו. חשוב להחליף את YOUR_PROJECT_ID במזהה הפרויקט שלכם.

  1. הגדרת הפונקציה generate

הפונקציה הזו מקבלת כקלט תמונה של מסגרת, מודל גנרטיבי והנחיה. לאחר מכן, הוא יוצר את קוד ה-HTML של האתר באמצעות המודל וההנחיה שצוינו. התשובה שנוצרה מוחזרת כמחרוזת.

  1. הגדרת המסלול לדף הבית

הפונקציה הזו מגדירה את המסלול לדף הבית. הפונקציה הזו מופעלת כשמשתמש מבקר בכתובת ה-URL הבסיסית של האפליקציה. הוא מעבד את התבנית index.html, שהיא דף הבית של האפליקציה.

  1. הגדרת נתיב התגובה

הפונקציה הזו מגדירה את נתיב התגובה. הפונקציה הזו מופעלת כשמשתמש שולח את הטופס בדף הבית. הוא מעבד את התמונה, המודל וההנחיה שהועלו, ואז יוצר את קוד האתר. התשובה שנוצרה מוצגת בכרטיסייה החדשה.

  1. הפעלת האפליקציה

החלק הזה של הקוד בודק אם הסקריפט מופעל כתוכנית הראשית. אם כן, המערכת מקבלת את יציאת השרת ממשתני הסביבה ומריצה את האפליקציה ביציאה שצוינה.

6. שלב 4: הכנת יחסי תלות ו-Dockerfile

מוודאים שקובץ requirements.txt כולל את התלות הבאה:

Flask==2.3.3
requests==2.31.0
debugpy # Required for debugging.
google-cloud-aiplatform>=1.38

מחליפים את התוכן של Dockerfile בתוכן הבא:

# Python image to use.
FROM python:3.11-slim

# Set the working directory to /app
WORKDIR /app

# copy the requirements file used for dependencies
COPY requirements.txt .

# Install any needed packages specified in requirements.txt
RUN pip install -r requirements.txt

# Copy the rest of the working directory contents into the container at /app
COPY . .

# Run app.py when the container launches
ENTRYPOINT ["python", "app.py"]

7. שלב 5: פריסת אפליקציית האינטרנט

אחרי שיצרנו את רכיבי האפליקציה, אפשר לפרוס את האפליקציה.

עוברים אל הטרמינל של Cloud Shell ומוודאים שהפרויקט הנוכחי מוגדר לפרויקט הפעיל שלכם. אם לא, צריך להשתמש בפקודה gcloud configure כדי להגדיר את מזהה הפרויקט:

gcloud config set project [PROJECT_ID]

לאחר מכן מזינים את הפקודות הבאות לפי הסדר:

cd draw-a-website
gcloud run deploy --source .

תתבקשו להזין שם לשירות, למשל draw-website. בוחרים את המספר המתאים לאזור us-central1. אומרים y כשנשאלים אם רוצים לאפשר הפעלות לא מאומתות. שימו לב שאנחנו מאפשרים כאן גישה לא מאומתת כי זו אפליקציית הדגמה. מומלץ להשתמש באימות מתאים לאפליקציות הארגוניות ולאפליקציות הייצור.

אחרי שהפריסה תושלם, תקבלו קישור שדומה לקישור שבהמשך:

**https://draw-website-*****eua-uc.a.run.app/

אפשר לבדוק את האפליקציה:

6ca7b67b7fce97de.png

8. הסרת המשאבים

כדי לא לצבור חיובים לחשבון Google Cloud על המשאבים שבהם השתמשתם ב-Code Lab הזה:

  1. במסוף Google Cloud, עוברים לדף Manage resources.
  2. ברשימת הפרויקטים, בוחרים את הפרויקט שרוצים למחוק ולוחצים על Delete.
  3. כדי למחוק את הפרויקט, כותבים את מזהה הפרויקט בתיבת הדו-שיח ולוחצים על Shut down.
  4. לחלופין, אפשר לעבור אל Cloud Run במסוף, לבחור את השירות שפרסתם ולמחוק אותו.

9. מזל טוב

מעולה! יצרתם בהצלחה אפליקציית אינטרנט מהירה ב-Python Flask שנפרסה ב-Cloud Run וממירה ציורים לאתרים. המאגר המלא זמין כאן. אפליקציית draw-a-website ממחישה את הכוח המהפכני של Gemini בייעול תהליך פיתוח האתרים. באמצעות AI, אנחנו יכולים לעזור למעצבים ולמפתחים ליצור אתרים במהירות, בדיוק וביצירתיות רבה יותר. מודלים של AI גנרטיבי ממשיכים להתפתח, ולכן אפשר לצפות לעוד יישומים פורצי דרך בעתיד.