שימוש בחיפוש מבוסס-Vertex AI בקובצי PDF (נתונים לא מובנים) ב-Cloud Storage משירות Cloud Run

1. מבוא

סקירה כללית

חיפוש ושיחות על בסיס Vertex AI (לשעבר Generative AI App Builder) מאפשר למפתחים לנצל את העוצמה של מודלים בסיסיים של Google, את המומחיות שלה בחיפוש ואת טכנולוגיות ה-AI בממשק שיחה שלה כדי ליצור אפליקציות AI גנרטיבי ברמת הארגון. ב-Codelab הזה נתמקד בשימוש בחיפוש מבוסס-Vertex AI, שמאפשר לכם ליצור אפליקציית חיפוש באיכות של Google על בסיס הנתונים שלכם ולהטמיע סרגל חיפוש בדפי האינטרנט או באפליקציה.

Cloud Run היא פלטפורמת מחשוב מנוהלת שמאפשרת להריץ קונטיינרים ישירות על גבי התשתית הניתנת להתאמה של Google. אפשר לפרוס ב-Cloud Run קוד שנכתב בכל שפת תכנות (שניתן להכניס לקונטיינר) באמצעות האפשרות פריסה מבוססת-מקור.

ב-Codelab הזה תיצרו שירות Cloud Run באמצעות פריסה מבוססת-מקור כדי לאחזר תוצאות חיפוש של תוכן לא מובנה בקובצי PDF בקטגוריה של Cloud Storage. מידע נוסף על הטמעה של תוכן לא מובנה

מה תלמדו

  • איך יוצרים אפליקציית חיפוש מבוסס-Vertex AI לנתונים לא מובְנים בתור קובצי PDF שמוזנים מקטגוריה של Cloud Storage
  • איך יוצרים נקודת קצה (endpoint) של HTTP באמצעות פריסה מבוססת-מקור ב-Cloud Run
  • איך יוצרים חשבון שירות לפי העיקרון של הרשאות מינימליות בשביל שירות Cloud Run יוכל להשתמש בו כדי לשלוח שאילתות לאפליקציית חיפוש מבוסס-Vertex AI
  • איך מפעילים את שירות Cloud Run כדי לשלוח שאילתה לאפליקציית חיפוש מבוסס-Vertex AI

2. הגדרה ודרישות

דרישות מוקדמות

הפעלת Cloud Shell

  1. ב-Cloud Console, לוחצים על Activate Cloud Shell d1264ca30785e435.png.

cb81e7c8e34bc8d.png

אם זו הפעם הראשונה שאתם מפעילים את Cloud Shell, יוצג לכם מסך ביניים עם תיאור של השירות. אם הוצג לכם מסך ביניים, לוחצים על המשך.

d95252b003979716.png

הקצאת המשאבים והחיבור ל-Cloud Shell נמשכים רק כמה רגעים.

7833d5e1c5d18f54.png

במכונה הווירטואלית הזו טעונים כל הכלים הדרושים למפתחים. יש בה ספריית בית בנפח מתמיד של 5GB והיא פועלת ב-Google Cloud, מה שמשפר מאוד את הביצועים והאימות של הרשת. אפשר לבצע את רוב העבודה ב-codelab הזה, אם לא את כולה, באמצעות דפדפן.

אחרי שמתחברים ל-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].

3. הפעלת ממשקי ה-API

לפני שמתחילים להשתמש בחיפוש מבוסס-Vertex AI, צריך להפעיל כמה ממשקי API.

קודם כל, כדי לבצע את ה-Codelab הזה צריך להשתמש בממשקי ה-API של חיפוש ושיחות על בסיס Vertex AI,‏ BigQuery ו-Cloud Storage. כאן אפשר להפעיל את ממשקי ה-API האלה.

בשלב השני, מפעילים את חיפוש ושיחות על בסיס Vertex AI API:

  1. במסוף Google Cloud, עוברים אל מסוף החיפוש והשיחות על בסיס Vertex AI.
  2. קוראים את התנאים וההגבלות ומסכימים להם, ואז לוחצים על Continue (המשך) ומפעילים את ה-API.

4. יצירת אפליקציית חיפוש לנתונים לא מובנים מ-Cloud Storage

  1. במסוף Google Cloud, נכנסים אל הדף 'חיפוש ושיחה'. לוחצים על אפליקציה חדשה.
  2. בחלונית בחירת סוג האפליקציה, בוחרים באפשרות חיפוש.
  3. כדי לקבל תשובות שמבוססות על ציטוטים מדויקים מהמסמכים, צריך לוודא שתכונות Enterprise מופעלות.
  4. כדי לקבל סיכום של תוצאות החיפוש, צריך לוודא שהאפשרות תכונות מתקדמות של LLM מופעלת.
  5. בשדה App name, מזינים שם לאפליקציה. מזהה האפליקציה מופיע מתחת לשם האפליקציה.
  6. בוחרים באפשרות גלובלי (Global) בתור המיקום של האפליקציה ולוחצים על המשך.
  7. בחלונית מאגרי נתונים, לוחצים על יצירת מאגר נתונים חדש.
  8. בחלונית בחירת מקור נתונים, בוחרים באפשרות Cloud Storage.
  9. בחלונית Import data from GCS (ייבוא נתונים מ-GCS), מוודאים שהאפשרות Folder (תיקייה) מסומנת.
  10. בשדה gs://‎, מזינים את הערך הבא: cloud-samples-data/gen-app-builder/search/stanford-cs-224 קטגוריה של Cloud Storage זו מכילה קובצי PDF מתיקיית Cloud Storage שזמינה לציבור, למטרות בדיקה.
  11. בוחרים באפשרות מסמכים לא מובנים ולוחצים על המשך.
  12. בחלונית Configure your data store, בוחרים באפשרות global (Global) בתור המיקום של מאגר הנתונים.
  13. מזינים שם למאגר הנתונים. תשתמשו בשם הזה בהמשך ה-Codelab הזה, כשתיצרו את שירות Cloud Run. לוחצים על יצירה.
  14. בחלונית מאגרי נתונים, בוחרים את מאגר הנתונים החדש ולוחצים על יצירה.
  15. בדף נתונים של מאגר הנתונים, לוחצים על הכרטיסייה פעילות כדי לראות את הסטטוס של הטמעת הנתונים. הסטטוס פעולת הייבוא הושלמה מוצג בעמודה 'סטטוס' כשתהליך הייבוא מסתיים.
  16. לוחצים על הכרטיסייה מסמכים כדי לראות את מספר המסמכים שיובאו.
  17. בתפריט הניווט, לוחצים על תצוגה מקדימה כדי לבדוק את אפליקציית החיפוש.
  18. בסרגל החיפוש, מזינים final lab due date ואז מקישים על Enter כדי לראות את התוצאות.

5. יצירת שירות Cloud Run

בקטע הזה, תיצרו שירות Cloud Run שמקבל מחרוזת שאילתה של מונחי החיפוש. השירות הזה ישתמש בספריות הלקוח של Python ל-Discovery Engine API. כאן אפשר לראות רשימה של סביבות זמן ריצה נתמכות אחרות.

יצירת קוד המקור של הפונקציה

קודם יוצרים ספרייה ועוברים אליה באמצעות הפקודה cd.

mkdir docs-search-service-python && cd $_

לאחר מכן, יוצרים קובץ requirements.txt עם התוכן הבא:

blinker==1.6.3
cachetools==5.3.1
certifi==2023.7.22
charset-normalizer==3.3.0
click==8.1.7
Flask==3.0.0
google-api-core==2.12.0
google-auth==2.23.3
google-cloud-discoveryengine==0.11.2
googleapis-common-protos==1.61.0
grpcio==1.59.0
grpcio-status==1.59.0
idna==3.4
importlib-metadata==6.8.0
itsdangerous==2.1.2
Jinja2==3.1.2
MarkupSafe==2.1.3
numpy==1.26.1
proto-plus==1.22.3
protobuf==4.24.4
pyasn1==0.5.0
pyasn1-modules==0.3.0
requests==2.31.0
rsa==4.9
urllib3==2.0.7
Werkzeug==3.0.1
zipp==3.17.0

לאחר מכן, יוצרים קובץ מקור main.py עם התוכן הבא:

from typing import List
import json
import os
from flask import Flask
from flask import request

app = Flask(__name__)

from google.api_core.client_options import ClientOptions
from google.cloud import discoveryengine_v1 as discoveryengine

project_id = os.environ.get('PROJECT_ID')
location = "global"  # Values: "global", "us", "eu"
data_store_id = os.environ.get('SEARCH_ENGINE_ID')

print(project_id)
print(data_store_id)

@app.route("/")
def search_storage():

    search_query = request.args.get("searchQuery")

    result = search_sample(project_id, location, data_store_id, search_query)
    return result

def search_sample(
    project_id: str,
    location: str,
    data_store_id: str,
    search_query: str,
) -> str:
    #  For more information, refer to:
    # https://cloud.google.com/generative-ai-app-builder/docs/locations#specify_a_multi-region_for_your_data_store
    client_options = (
        ClientOptions(api_endpoint=f"{location}-discoveryengine.googleapis.com")
        if location != "global"
        else None
    )

    # Create a client
    client = discoveryengine.SearchServiceClient(client_options=client_options)

    # The full resource name of the search engine serving config
    # e.g. projects/{project_id}/locations/{location}/dataStores/{data_store_id}/servingConfigs/{serving_config_id}
    serving_config = client.serving_config_path(
        project=project_id,
        location=location,
        data_store=data_store_id,
        serving_config="default_config",
    )

    # Optional: Configuration options for search
    # Refer to the `ContentSearchSpec` reference for all supported fields:
    # https://cloud.google.com/python/docs/reference/discoveryengine/latest/google.cloud.discoveryengine_v1.types.SearchRequest.ContentSearchSpec
    content_search_spec = discoveryengine.SearchRequest.ContentSearchSpec(
        # For information about snippets, refer to:
        # https://cloud.google.com/generative-ai-app-builder/docs/snippets
        snippet_spec=discoveryengine.SearchRequest.ContentSearchSpec.SnippetSpec(
            return_snippet=True
        ),
        # For information about search summaries, refer to:
        # https://cloud.google.com/generative-ai-app-builder/docs/get-search-summaries
        summary_spec=discoveryengine.SearchRequest.ContentSearchSpec.SummarySpec(
            summary_result_count=5,
            include_citations=True,
            ignore_adversarial_query=True,
            ignore_non_summary_seeking_query=True,
        ),
    )


    # Refer to the `SearchRequest` reference for all supported fields:
    # https://cloud.google.com/python/docs/reference/discoveryengine/latest/google.cloud.discoveryengine_v1.types.SearchRequest
    request = discoveryengine.SearchRequest(
        serving_config=serving_config,
        query=search_query,
        page_size=10,
        content_search_spec=content_search_spec,
        query_expansion_spec=discoveryengine.SearchRequest.QueryExpansionSpec(
            condition=discoveryengine.SearchRequest.QueryExpansionSpec.Condition.AUTO,
        ),
        spell_correction_spec=discoveryengine.SearchRequest.SpellCorrectionSpec(
            mode=discoveryengine.SearchRequest.SpellCorrectionSpec.Mode.AUTO
        ),
    )

    response = client.search(request)

    return response.summary.summary_text

if __name__ == "__main__":
    app.run(debug=True, host="0.0.0.0", port=int(os.environ.get("PORT", 8080)))

הגדרה של משתני סביבה

בקוד הזה, תיצרו כמה משתני סביבה כדי לשפר את הקריאות של הפקודות gcloud שמשמשות ב-codelab הזה.

PROJECT_ID=$(gcloud config get-value project)

SERVICE_NAME="search-storage-pdfs-python"
SERVICE_REGION="us-central1"

# update with your data store name
SEARCH_ENGINE_ID=<your-data-store-name>

יצירת חשבון שירות

ב-Codelab הזה נסביר איך ליצור חשבון שירות לשירות Cloud Run כדי להשתמש בו לגישה אל חיפוש מבוסס-Vertex AI API.

SERVICE_ACCOUNT="cloud-run-vertex-ai-search"
SERVICE_ACCOUNT_ADDRESS=$SERVICE_ACCOUNT@$PROJECT_ID.iam.gserviceaccount.com

gcloud iam service-accounts create $SERVICE_ACCOUNT \
  --display-name="Cloud Run Vertex AI Search service account"

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member serviceAccount:$SERVICE_ACCOUNT_ADDRESS \
  --role='roles/discoveryengine.editor'

פריסת שירות Cloud Run

עכשיו אפשר להשתמש בפריסה מבוססת-מקור כדי להכניס את שירות Cloud Run לקונטיינר באופן אוטומטי.

gcloud run deploy $SERVICE_NAME \
--region=$SERVICE_REGION \
--source=. \
--service-account $SERVICE_ACCOUNT \
--update-env-vars SEARCH_ENGINE_ID=$SEARCH_ENGINE_ID,PROJECT_ID=$PROJECT_ID \
--no-allow-unauthenticated

אחר כך אפשר לשמור את כתובת ה-URL של Cloud Run כמשתנה סביבה לשימוש מאוחר יותר.

ENDPOINT_URL="$(gcloud run services describe $SERVICE_NAME --region=$SERVICE_REGION --format='value(status.url)')"

6. קריאה לשירות Cloud Run

עכשיו אפשר להתקשר לשירות Cloud Run עם מחרוזת שאילתה כדי לשאול את What is the final lab due date?.

curl -H "Authorization: bearer $(gcloud auth print-identity-token)" "$ENDPOINT_URL?searchQuery=what+is+the+final+lab+due+date"

התוצאות שלכם אמורות להיות דומות לפלט לדוגמה שבהמשך:

The final lab is due on Tuesday, March 21 at 4:30 PM [1].

7. מעולה!

כל הכבוד, סיימתם את ה-Codelab!

מומלץ לעיין במסמכי התיעוד בנושא חיפוש מבוסס-Vertex AI ו-Cloud Run.

מה נכלל

  • איך יוצרים אפליקציית חיפוש מבוסס-Vertex AI לנתונים לא מובְנים בתור קובצי PDF שמוזנים מקטגוריה של Cloud Storage
  • איך יוצרים נקודת קצה (endpoint) של HTTP באמצעות פריסה מבוססת-מקור ב-Cloud Run
  • איך ליצור חשבון שירות לפי העיקרון של הרשאות מינימליות, כדי ששירות Cloud Run יוכל להשתמש בו לשליחת שאילתות לאפליקציית חיפוש מבוסס-Vertex AI.
  • איך מפעילים את שירות Cloud Run כדי לשלוח שאילתה לאפליקציית חיפוש מבוסס-Vertex AI

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

כדי להימנע מחיובים לא מכוונים (לדוגמה, אם הפונקציה של Cloud Functions מופעלת בטעות יותר פעמים מההקצאה החודשית של הפעלות Cloud Functions בחשבון בחינם), אפשר למחוק את הפונקציה של Cloud Functions או למחוק את הפרויקט שיצרתם בשלב 2.

כדי למחוק את הפונקציה ב-Cloud Functions, נכנסים ל-Cloud Console של Cloud Functions בכתובת https://console.cloud.google.com/functions/ ומוחקים את הפונקציה imagen_vqa (או את $FUNCTION_NAME אם השתמשתם בשם אחר).

אם אתם רוצים למחוק את הפרויקט כולו, אתם יכולים להיכנס לכתובת https://console.cloud.google.com/cloud-resource-manager, לבחור את הפרויקט שיצרתם בשלב 2 וללחוץ על 'מחיקה'. אם תמחקו את הפרויקט, תצטרכו לשנות את הפרויקטים ב-Cloud SDK. כדי לראות את רשימת כל הפרויקטים הזמינים, מריצים את הפקודה gcloud projects list.