שימוש בהגדרת תצורה מרחוק בצד השרת עם Cloud Functions ו-Agent Platform

במדריך הזה מוסבר איך להתחיל להשתמש ב-Cloud Functions מהדור השני עם Remote Config בצד השרת כדי לבצע קריאות בצד השרת אל Agent Platform Gemini API (formerly Vertex AI).

במדריך הזה תוסיפו את Remote Config לפונקציה דמוית צ'אט בוט שמשתמשת במודל Gemini כדי לענות על שאלות של משתמשים. ‫Remote Config ינהל את הקלטים של Gemini API (כולל פרומפט שתוסיפו בתחילת השאילתות הנכנסות של המשתמשים), ותוכלו לעדכן את הקלטים האלה על פי דרישה ממסוף Firebase. בנוסף, תשתמשו ב-Firebase Local Emulator Suite כדי לבדוק את הפונקציה ולנפות באגים, ואחרי שתוודאו שהיא פועלת, תפרסו ותבדקו אותה ב-Google Cloud.

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

המדריך הזה מניח שאתם יודעים להשתמש ב-JavaScript כדי לפתח אפליקציות.

הגדרת פרויקט ב-Firebase

אם עדיין אין לכם פרויקט ב-Firebase:

  1. נכנסים למסוף Firebase.

  2. לוחצים על Create project ובוחרים באחת מהאפשרויות הבאות:

    • אפשרות 1: יוצרים פרויקט Firebase חדש (והפרויקט הבסיסי ב-Google Cloud נוצר באופן אוטומטי) על ידי הזנת שם פרויקט חדש בשלב הראשון של תהליך העבודה "יצירת פרויקט".
    • אפשרות 2: "הוספת Firebase" לפרויקט קיים ב-Google Cloud. כדי לעשות את זה, בוחרים את שם הפרויקט ב-Google Cloud מהתפריט הנפתח בשלב הראשון של תהליך העבודה "יצירת פרויקט".
  3. כשמוצגת בקשה, לא צריך להגדיר את Google Analytics כדי להשתמש בפתרון הזה.

  4. ממשיכים לפעול לפי ההוראות במסך כדי ליצור את הפרויקט.

אם כבר יש לכם פרויקט ב-Firebase:

עוברים לקטע הגדרת סביבת הפיתוח.

הגדרת סביבת הפיתוח

כדי לכתוב פונקציות, צריך סביבת Node.js, וכדי לפרוס פונקציות בסביבת זמן הריצה של Cloud Functions, צריך את ה-CLI של Firebase.

  1. מתקינים את Node.js ואת npm.

    כדי להתקין את Node.js ו-npm, מומלץ להשתמש ב-Node Version Manager.

  2. מתקינים את ה-CLI של Firebase בשיטה שמעדיפים. לדוגמה, כדי להתקין את ה-CLI באמצעות npm, מריצים את הפקודה הבאה:

    npm install -g firebase-tools@latest
    

    הפקודה הזו מתקינה את הפקודה firebase שזמינה באופן גלובלי. אם הפקודה נכשלת, יכול להיות שצריך לשנות את ההרשאות של npm.

    כדי לעדכן לגרסה העדכנית של firebase-tools, מריצים שוב את אותה פקודה.

  3. מתקינים את firebase-functions ואת firebase-admin ומשתמשים ב---save כדי לשמור אותם ב-package.json:

    npm install firebase-functions@latest firebase-admin@latest --save
    

עכשיו אתם מוכנים להטמיע את הפתרון הזה.

הטמעה

כדי ליצור, לבדוק ולפרוס פונקציית Cloud Functions מהדור השני באמצעות Remote Config ו-Agent Platform:

  1. מפעילים Agent Platform ממשקי API מומלצים בGoogle Cloudמסוף.
  2. מאתחלים את הפרויקט ומתקינים את יחסי התלות של Node.
  3. מגדירים הרשאות IAM לחשבון השירות של Admin SDK ושומרים את המפתח.
  4. ‫יוצרים את הפונקציה.
  5. יוצרים תבנית Remote Config ספציפית לשרת.
  6. פורסים את הפונקציה ובודקים אותה ב-Firebase Local Emulator Suite.
  7. פורסים את הפונקציה ב-Google Cloud.

שלב 1: מפעילים Agent Platform ממשקי API מומלצים במסוף Google Cloud

  1. פותחים את מסוף Google Cloud, וכשמוצגת בקשה, בוחרים את הפרויקט.
  2. בשדה Search שבחלק העליון של המסוף, מזינים Agent Platform ומחכים ש-Agent Platform יופיע בתוצאות.
  3. לוחצים על Agent Platform. מופיע מרכז הבקרה של Agent Platform.
  4. לוחצים על הפעלת כל ממשקי ה-API המומלצים.

    יכול להיות שיעברו כמה רגעים עד שה-API יופעל. צריך להשאיר את הדף פתוח ופעיל עד שההפעלה תסתיים.

  5. אם החיוב לא מופעל, תתבקשו להוסיף או לקשר חשבון Cloud Billing. אחרי שמפעילים חשבון לחיוב, חוזרים למרכז הבקרה של Agent Platform ומוודאים שכל ממשקי ה-API המומלצים מופעלים.

‫שלב 2: מאתחלים את הפרויקט ומתקינים את יחסי התלות של Node

  1. פותחים טרמינל במחשב ועוברים לספרייה שבה רוצים ליצור את הפונקציה.
  2. מתחברים ל-Firebase:

    firebase login
    
  3. מריצים את הפקודה הבאה כדי לאתחל את Cloud Functions for Firebase:

    firebase init functions
    
  4. בוחרים באפשרות שימוש בפרויקט קיים ומציינים את מזהה הפרויקט.

  5. כשמופיעה בקשה לבחור את השפה שבה רוצים להשתמש, בוחרים באפשרות JavaScript ומקישים על Enter.

  6. בכל שאר האפשרויות, בוחרים את ברירות המחדל.

    ספרייה בשם functions נוצרת בספרייה הנוכחית. בתוך התיקייה יש קובץ index.js שמשמש ליצירת הפונקציה, ספריית node_modules שמכילה את יחסי התלות של הפונקציה וקובץ package.json שמכיל את יחסי התלות של החבילה.

  7. מוסיפים את החבילות Admin SDK ו-Agent Platform באמצעות הפקודות הבאות, ומשתמשים ב---save כדי לוודא שהן נשמרות בקובץ package.json:

    cd functions
    npm install firebase-admin@latest @google-cloud/vertexai --save
    

עכשיו הקובץ functions/package.json אמור להיראות כך, עם הגרסאות העדכניות שצוינו:

  {
    "name": "functions",
    "description": "Cloud Functions for Firebase",
    "scripts": {
      "serve": "firebase emulators:start --only functions",
      "shell": "firebase functions:shell",
      "start": "npm run shell",
      "deploy": "firebase deploy --only functions",
      "logs": "firebase functions:log"
    },
    "engines": {
      "node": "20"
    },
    "main": "index.js",
    "dependencies": {
      "@google-cloud/vertexai": "^1.1.0",
      "firebase-admin": "^12.1.0",
      "firebase-functions": "^5.0.0"
    },
    "devDependencies": {
      "firebase-functions-test": "^3.1.0"
    },
    "private": true
  }

שימו לב שאם אתם משתמשים ב-ESLint, תראו בית שכולל אותו. בנוסף, ודאו שגרסת מנוע הצומת תואמת לגרסה המותקנת של Node.js ולגרסה שאתם מריצים בסופו של דבר ב-Google Cloud. לדוגמה, אם הבית engines בקובץ package.json מוגדר לגרסה 18 של Node ואתם משתמשים ב-Node.js 20, צריך לעדכן את הקובץ לגרסה 20:

  "engines": {
    "node": "20"
  },

שלב 3: מגדירים הרשאות IAM לחשבון השירות של Admin SDK ושומרים את המפתח

בפתרון הזה, תשתמשו בחשבון השירות Admin SDK של Firebase כדי להריץ את הפונקציה.

  1. במסוף Google Cloud, פותחים את הדף IAM & Admin ומאתרים את חשבון השירות של Admin SDK (בשם firebase-adminsdk).
  2. בוחרים את החשבון ולוחצים על Edit principal. הדף גישת עריכה מופיע.
  3. לוחצים על Add another role ובוחרים באפשרות Remote Config Viewer.
  4. לוחצים על Add another role ובוחרים את התפקיד AI platform developer.
  5. לוחצים על הוספת תפקיד ובוחרים באפשרות משתמש Agent Platform.
  6. לוחצים על Add another role ובוחרים את התפקיד Cloud Run Invoker.
  7. לוחצים על שמירה.

בשלב הבא, מייצאים את פרטי הכניסה של חשבון השירות Admin SDK ושומרים אותם במשתנה הסביבה GOOGLE_APPLICATION_CREDENTIALS.

  1. פותחים את הדף Credentials במסוף Google Cloud.
  2. לוחצים על חשבון השירות Admin SDK כדי לפתוח את הדף Details.
  3. לוחצים על Keys.
  4. לוחצים על Add key ואז על Create new key.
  5. מוודאים שהאפשרות JSON נבחרה בתור Key type ולוחצים על Create.
  6. מורידים את המפתח למקום בטוח במחשב.
  7. בטרמינל, מייצאים את המפתח כמשתנה סביבה:

    export GOOGLE_APPLICATION_CREDENTIALS="/path/to/your/service-account-key.json"
    

שלב 4: יוצרים את הפונקציה

בשלב הזה, תבנו פונקציה שמטפלת בקלט של המשתמש ויוצרת תשובות מבוססות-AI. תשלבו כמה קטעי קוד כדי ליצור פונקציה מקיפה שמפעילה את Admin SDK ו-Agent Platform Gemini API (formerly Vertex AI), מגדירה פרמטרים של ברירת מחדל באמצעות Remote Config, מאחזרת את הפרמטרים העדכניים ביותר של Remote Config, מעבדת את הקלט של המשתמש ומעבירה תשובה למשתמש.

  1. בבסיס הקוד, פותחים את functions/index.js בכלי לעריכת טקסט או ב-IDE.
  2. מוחקים את התוכן הקיים ומוסיפים את Admin SDK, Remote Config ו-Agent Platform SDK, ומפעילים את האפליקציה על ידי הדבקת הקוד הבא בקובץ:

    const { onRequest } = require("firebase-functions/https");
    const { requiresRole, requiresAPI } = require("firebase-functions");
    const logger = require("firebase-functions/logger");
    
    const { initializeApp } = require("firebase-admin/app");
    const { VertexAI } = require('@google-cloud/vertexai');
    const { getRemoteConfig } = require("firebase-admin/remote-config");
    
    requiresRole("roles/aiplatform.user");
    requiresRole("roles/cloudconfig.viewer");
    requiresAPI("aiplatform.googleapis.com", "Needed to query Vertex AI Gemini models");
    requiresAPI("firebaseremoteconfig.googleapis.com", "Needed to fetch server-side Remote Config templates");
    
    // Set and check environment variables.
    const project = process.env.GCLOUD_PROJECT;
    
    // Initialize Firebase.
    const app = initializeApp();
    
  3. מגדירים ערכי ברירת מחדל שהפונקציה תשתמש בהם אם היא לא תצליח להתחבר לשרת Remote Config. הפתרון הזה מגדיר את textModel,‏ generationConfig,‏ safetySettings,‏ textPrompt ו-location כפרמטרים של Remote Config שתואמים לפרמטרים של Remote Config שתגדירו בהמשך המדריך. מידע נוסף על הפרמטרים האלה זמין במאמר לקוח Vertex AI Node.js.

    אפשר גם להגדיר פרמטר כדי לקבוע אם תהיה גישה אל Agent Platform Gemini API (formerly Vertex AI) (בדוגמה הזו, פרמטר שנקרא vertex_enabled). ההגדרה הזו יכולה להיות שימושית כשבודקים את הפונקציה. בקטעי הקוד הבאים, הערך הזה מוגדר כ-false, כדי לדלג על השימוש ב-Agent Platform בזמן שבודקים את פריסת הפונקציה הבסיסית. הגדרה של true תפעיל את Agent Platform Gemini API (formerly Vertex AI).

    // Define default (fallback) parameter values for Remote Config.
    const defaultConfig = {
    
      // Default values for Vertex AI.
      model_name: "gemini-1.5-flash-002",
      generation_config: [{
        "stopSequences": [], "temperature": 0.7,
        "maxOutputTokens": 64, "topP": 0.1, "topK": 20
      }],
      prompt: "I'm a developer who wants to learn about Firebase and you are a \
        helpful assistant who knows everything there is to know about Firebase!",
      safety_settings: [{
        "category":
          "HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT",
        "threshold": "HarmBlockThreshold.BLOCK_MEDIUM_AND_ABOVE"
      }],
      location: 'us-central1',
    
      // Disable Vertex AI Gemini API access for testing.
      vertex_enabled: false
    };
    
  4. יוצרים את הפונקציה ומגדירים את Remote Config בצד השרת:

    // Export the function.
    exports.generateWithVertex = onRequest(async (request, response) => {
    
      try {
    
        // Set up Remote Config.
        const rc = getRemoteConfig(app);
    
        // Get the Remote Config template and assign default values.
        const template = await rc.getServerTemplate({
          defaultConfig: defaultConfig
        });
    
        // Add the template evaluation to a constant.
        const config = template.evaluate();
    
        // Obtain values from Remote Config.
        const textModel = config.getString("model_name") ||
            defaultConfig.model_name;
        const textPrompt = config.getString("prompt") || defaultConfig.prompt;
        const generationConfig = config.getString("generation_config") ||
            defaultConfig.generation_config;
        const safetySettings = config.getString("safety_settings") ||
            defaultConfig.safety_settings;
        const location = config.getString("location") ||
            defaultConfig.location;
        const vertexEnabled = config.getBoolean("is_vertex_enabled") ||
            defaultConfig.vertex_enabled;
    
  5. מגדירים את Agent Platform ומוסיפים את הלוגיקה של הצ'אט והתשובות:

      // Allow user input.
      const userInput = request.query.prompt || '';
    
      // Instantiate Vertex AI.
        const vertex_ai = new VertexAI({ project: project, location: location });
        const generativeModel = vertex_ai.getGenerativeModel({
          model: textModel,
          safety_settings: safetySettings,
          generation_config: generationConfig,
        });
    
        // Combine prompt from Remote Config with optional user input.
        const chatInput = textPrompt + " " + userInput;
    
        if (!chatInput) {
          return res.status(400).send('Missing text prompt');
        }
        // If vertexEnabled isn't true, do not send queries to Vertex AI.
        if (vertexEnabled !== true) {
          response.status(200).send({
            message: "Vertex AI call skipped. Vertex is not enabled."
          });
          return;
        }
    
        logger.log("\nRunning with model ", textModel, ", prompt: ", textPrompt,
          ", generationConfig: ", generationConfig, ", safetySettings: ",
          safetySettings, " in ", location, "\n");
    
        const result = await generativeModel.generateContentStream(chatInput); 
        response.writeHead(200, { 'Content-Type': 'text/plain' });
    
        for await (const item of result.stream) {
          const chunk = item.candidates[0].content.parts[0].text;
          logger.log("Received chunk:", chunk);
          response.write(chunk);
        }
    
        response.end();
    
      } catch (error) {
        logger.error(error);
        response.status(500).send('Internal server error');
      }
    });
    
  6. שומרים וסוגרים את הקובץ.

שלב 5: יוצרים תבנית Remote Config ספציפית לשרת

בשלב הבא, יוצרים תבנית Remote Config בצד השרת ומגדירים פרמטרים וערכים לשימוש בפונקציה. כדי ליצור תבנית Remote Config ספציפית לשרת:

  1. במסוף Firebase, עוברים אל DevOps & Engagement (DevOps ומעורבות) > Remote Config (הגדרת תצורה מרחוק).

  2. בבורר Client/Server שבחלק העליון של הדף, בוחרים באפשרות Server.

    • אם זו הפעם הראשונה שאתם משתמשים ב-Remote Config או בתבניות שרת, לוחצים על Create Configuration (יצירת הגדרה). החלונית Create your first server-side parameter תופיע.
    • אם זו לא הפעם הראשונה שאתם משתמשים בתבניות שרת של Remote Config, לוחצים על Add parameter (הוספת פרמטר).
  3. מגדירים את הפרמטרים הבאים של Remote Config:

    שם הפרמטר תיאור סוג ערך ברירת המחדל
    model_name שם המודל
    כדי לראות רשימות עדכניות של שמות מודלים שאפשר להשתמש בהם בקוד, עיינו במאמר גרסאות ומחזורי חיים של מודלים או במאמר שמות מודלים זמינים.
    מחרוזת gemini-2.0-flash
    prompt הנחיה שתוצג לפני השאילתה של המשתמש. מחרוזת I'm a developer who wants to learn about Firebase and you are a helpful assistant who knows everything there is to know about Firebase!
    generation_config פרמטרים לשליחה למודל JSON [{"stopSequences": ["I hope this helps"],"temperature": 0.7,"maxOutputTokens": 512, "topP": 0.1,"topK": 20}]
    safety_settings הגדרות הבטיחות של Agent Platform JSON [{"category": "HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT", "threshold": "HarmBlockThreshold.BLOCK_LOW_AND_ABOVE"}]
    location המיקום שבו פועלים השירות והמודל של Agent Platform מחרוזת global
    is_vertex_enabled פרמטר אופציונלי שקובע אם השאילתות נשלחות אל Agent Platform. בוליאני true
  4. כשמסיימים להוסיף פרמטרים, בודקים שוב את הפרמטרים ומוודאים שסוגי הנתונים שלהם נכונים. לאחר מכן לוחצים על פרסום השינויים.

שלב 6: פורסים את הפונקציה ובודקים אותה ב-Firebase Local Emulator Suite

עכשיו אפשר לפרוס ולבדוק את הפונקציה באופן מקומי באמצעות Firebase Local Emulator Suite.

  1. חשוב לוודא שהגדרתם את GOOGLE_APPLICATION_CREDENTIALS כמשתנה סביבה, כמו שמתואר בשלב 3: הגדרת הרשאות IAM לחשבון השירות של Admin SDK ושמירת המפתח. אחר כך, מספריית האם של הספרייה functions, פורסים את הפונקציה באמולטור של Firebase:

    firebase emulators:start --project PROJECT_ID --only functions
    
  2. פותחים את דף היומנים של האמולטור. הפעולה הזו אמורה להראות שהפונקציה נטענה.

  3. כדי לגשת לפונקציה, מריצים את הפקודה הבאה, כאשר PROJECT_ID הוא מזהה הפרויקט ו-LOCATION הוא האזור שבו פרסתם את הפונקציה (לדוגמה, us-central1):

    curl http://localhost:5001/PROJECT_ID/LOCATION/generateWithVertex
    
  4. מחכים לתגובה, ואז חוזרים לדף היומנים של Firebase Emulator או למסוף ובודקים אם יש שגיאות או אזהרות.

  5. נסו לשלוח קלט משתמש, ושימו לב שבגלל שהגדרתם את is_vertex_enabled בתבנית השרת של Remote Config, הקלט הזה אמור לגשת למודל Gemini דרך Agent Platform Gemini API (formerly Vertex AI), וזה עלול להיות כרוך בחיובים:

    curl http://localhost:5001/PROJECT_ID/LOCATION/generateWithVertex?prompt=Tell%20me%20everything%20you%20know%20about%20cats
    
  6. מבצעים שינויים בתבנית השרת של Remote Config במסוף של Firebase, ואז ניגשים שוב לפונקציה כדי לראות את השינויים.

שלב 7: פורסים את הפונקציה ב-Google Cloud

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

פריסת הפונקציה

פורסים את הפונקציה באמצעות ה-CLI של Firebase:

firebase deploy --only functions

חסימת גישה לא מאומתת לפונקציה

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

כדי לחסום גישה לא מאומתת לפונקציה:

  1. פותחים את Cloud Run במסוף Google Cloud.

  2. לוחצים על generateWithVertex ואז על הכרטיסייה אבטחה.

  3. מפעילים את האפשרות נדרש אימות ולוחצים על שמירה.

מגדירים את חשבון המשתמש כך שישתמש בפרטי כניסה לחשבון של חשבון השירות Admin SDK

לחשבון השירות Admin SDK יש את כל התפקידים וההרשאות שנדרשים כדי להריץ את הפונקציה ולתקשר עם Remote Config ועם Agent Platform Gemini API (formerly Vertex AI), ולכן כדאי להשתמש בו כדי להריץ את הפונקציה. כדי לעשות זאת, צריכה להיות לכם אפשרות ליצור אסימונים לחשבון מחשבון המשתמש שלכם.

כדי להגדיר את חשבון המשתמש ואת הפונקציה כך שיפעלו עם הרשאות חשבון השירות Admin SDK, צריך לבצע את השלבים הבאים:

  1. במסוף Google Cloud, מפעילים את IAM Service Account Credentials API.
  2. מקצים לחשבון המשתמש את התפקיד יצירת אסימונים בחשבון שירות: במסוף Google Cloud, פותחים את IAM & Admin‏ > IAM, בוחרים את חשבון המשתמש ולוחצים על Edit principal‏ > Add another role.
  3. בוחרים באפשרות Service Account Token Creator ולוחצים על Save.

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

  4. פותחים את הדף Cloud Functions במסוף Google Cloud ולוחצים על הפונקציה generateWithVertex ברשימה Functions.

  5. בוחרים באפשרות Trigger‏ > Edit ומרחיבים את Runtime, build, connections and security settings.

  6. בכרטיסייה Runtime, משנים את Runtime service account ל-Admin SDK account.

  7. לוחצים על הבא ואז על פריסה.

הגדרת ה-CLI של gcloud

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

כדי להפעיל יצירת טוקנים, מתקינים ומגדירים את ה-CLI של gcloud:

  1. אם ה-CLI של gcloud לא מותקן במחשב, מתקינים אותו לפי ההוראות במאמר התקנת ה-CLI של gcloud.

  2. משיגים את פרטי הכניסה לחשבון Google Cloud:

    gcloud auth login
    
  3. מגדירים את מזהה הפרויקט ב-gcloud:

    gcloud config set project PROJECT_ID
    

בדיקת הפונקציה

עכשיו אפשר לבדוק את הפונקציה ב-Google Cloud. כדי לבדוק את הפונקציה, מריצים את הפקודה הבאה:

curl -X POST https://LOCATION-PROJECT_ID.cloudfunctions.net/generateWithVertex \
  -H "Authorization: bearer $(gcloud auth print-identity-token)" \
  -H "Content-Type: application/json"

נסו שוב עם פרטים שהמשתמשים סיפקו:

curl -X POST https://LOCATION-PROJECT_ID.cloudfunctions.net/generateWithVertex?prompt=Tell%20me%20everything%20you%20know%20about%20dogs \
 -H "Authorization: bearer $(gcloud auth print-identity-token)" \
 -H "Content-Type: application/json"

עכשיו אתם יכולים לבצע שינויים בתבנית השרת של Remote Config, לפרסם את השינויים האלה ולבדוק אפשרויות שונות.

השלבים הבאים