1. مقدمة
هل تحب قراءة الكتب ولكنك تشعر بالحيرة بسبب كثرة الخيارات؟ تخيَّل أن لديك تطبيقًا يستند إلى الذكاء الاصطناعي ولا يكتفي باقتراح القراءة المثالية فحسب، بل يقدّم أيضًا ملخّصًا موجزًا استنادًا إلى النوع الذي تختاره، ما يمنحك لمحة عن جوهر الكتاب. في هذا الدرس التطبيقي حول الترميز، سأشرح لك كيفية إنشاء تطبيق من هذا النوع باستخدام BigQuery وCloud Functions المستندَين إلى Gemini.
نظرة عامة على المشروع
تتمحور حالة الاستخدام حول هذه المكوّنات الرئيسية الأربعة:
- قاعدة بيانات الكتب: ستكون مجموعة البيانات العامة الكبيرة في BigQuery الخاصة بكتب "أرشيف الإنترنت" بمثابة فهرس شامل للكتب.
- محرّك التلخيص المستند إلى الذكاء الاصطناعي: ستنشئ "وظائف Google Cloud"، المزوّدة بنموذج اللغة Gemini-Pro، ملخّصات مفيدة مخصّصة لطلبات المستخدمين.
- عملية الدمج مع BigQuery: هي دالة عن بُعد ضمن BigQuery تستدعي Cloud Function لتقديم ملخّصات ومواضيع الكتب عند الطلب.
- واجهة المستخدم: تطبيق ويب مستضاف على Cloud Run يوفّر تطبيق ويب للمستخدمين للاطّلاع على النتائج.
سنقسّم عملية التنفيذ إلى 3 دروس تطبيقية حول الترميز:
الدرس التطبيقي حول الترميز 1: استخدام Gemini لإنشاء دالة Java Cloud Function لتطبيق Gemini
درس تطبيقي حول الترميز 2: استخدام Gemini لإنشاء تطبيقات الذكاء الاصطناعي التوليدي المعدّة فقط بلغة الاستعلامات البنيوية (SQL) باستخدام BigQuery
Codelab 3: استخدام Gemini لإنشاء تطبيق ويب Java Spring Boot يتفاعل مع BigQuery
2. استخدام Gemini لإنشاء خادم تطبيق يعمل بدون خادم للذكاء الاصطناعي التوليدي على Java Cloud Function
ما ستنشئه
ستنشئ
- تطبيق Java Cloud Functions الذي ينفّذ Gemini 1.0 Pro لتلقّي طلب محدّد كإدخال في شكل مصفوفة JSON وعرض استجابة (قيمة JSON مصنّفة على أنّها "ردود").
- ستنفّذ خطوات الإنشاء والنشر بمساعدة Gemini
3- المتطلبات
في ما يلي المتطلبات الأساسية:
إنشاء مشروعك
- في Google Cloud Console، ضمن صفحة اختيار المشروع، اختَر مشروعًا على Google Cloud أو أنشِئه.
- تأكَّد من تفعيل الفوترة لمشروعك على السحابة الإلكترونية. تعرَّف على كيفية التحقّق مما إذا كانت الفوترة مفعَّلة في مشروع.
تفعيل Cloud Shell
- ستستخدم Cloud Shell، وهي بيئة سطر أوامر تعمل في Google Cloud ومحمَّلة مسبقًا بأداة bq:
من Cloud Console، انقر على "تفعيل Cloud Shell" في أعلى يسار الصفحة: 
- بعد الاتصال بـ Cloud Shell، من المفترض أن يظهر لك أنّه تم إثبات هويتك وأنّه تم ضبط المشروع على رقم تعريف مشروعك. نفِّذ الأمر التالي في Cloud Shell للتأكّد من إكمال عملية المصادقة:
gcloud auth list
- نفِّذ الأمر التالي في Cloud Shell للتأكّد من أنّ أمر gcloud يعرف مشروعك
gcloud config list project
- إذا لم يتم ضبط مشروعك، استخدِم الأمر التالي لضبطه:
gcloud config set project <YOUR_PROJECT_ID>
راجِع المستندات لمعرفة أوامر gcloud وطريقة استخدامها.
4. تفعيل "Gemini في Google Cloud" وواجهات برمجة التطبيقات اللازمة
تفعيل Gemini
- انتقِل إلى Gemini في Google Cloud Marketplace لتفعيل واجهة برمجة التطبيقات. يمكنك أيضًا استخدام الأمر التالي:
gcloud services enable cloudaicompanion.googleapis.com --project PROJECT_ID
- انتقِل إلى صفحة Gemini وانقر على "بدء محادثة".
ملاحظة مهمة: اتّبِع الخطوتَين 1 و2 في درس الترميز هذا للبدء باستخدام Gemini وتفعيل Gemini في بيئة Cloud Shell المتكاملة على التوالي.
تفعيل واجهات برمجة التطبيقات الأخرى اللازمة
كيف يمكننا تحقيق ذلك؟ لنسأل Gemini عن ذلك، هل توافق؟ ولكن قبل ذلك، تذكَّر ما يلي:
النماذج اللغوية الكبيرة غير قطعية. لذا، أثناء تجربة هذه الطلبات، قد يختلف الرد الذي تتلقّاه عن الردود الواردة في لقطة الشاشة.
انتقِل إلى وحدة تحكّم محادثة Gemini من خلال النقر على رمز "فتح Gemini" في أعلى يسار الصفحة بجانب شريط البحث في وحدة تحكّم Google Cloud.

اكتب هذا السؤال في قسم "إدخال طلب هنا":
How do I enable the cloud functions api using a gcloud command?
من المفترض أن تتلقّى ردًا مشابهًا لما يلي:
gcloud services enable cloudfunctions.googleapis.com
انسخ هذا الرمز (يمكنك استخدام رمز النسخ في أعلى مقتطف الأمر) ونفِّذه في وحدة Cloud Shell الطرفية لتفعيل Cloud Functions. كرِّر الخطوات نفسها مع Cloud Run لأنّنا نحتاج إلى كليهما لإنشاء دوال Cloud Functions ونشرها:
gcloud services enable \
cloudfunctions.googleapis.com \
aiplatform.googleapis.com \
run.googleapis.com \
cloudbuild.googleapis.com
5- إعداد نموذج Cloud Functions باستخدام Gemini
في هذه المرحلة، أفترض أنّك فعّلت Gemini في بيئة تطوير Cloud Shell المتكاملة.
افتح "محرِّر Cloud Shell" من خلال النقر على رمز "فتح المحرِّر" في أعلى يسار "وحدة Cloud Shell الطرفية" (أفضّل عادةً فتح الوحدة الطرفية والمحرِّر في علامات تبويب منفصلة بالتوازي حتى نتمكّن من كتابة الرمز في إحداهما وإنشائه في الأخرى).

بعد فتح المحرّر، تأكَّد من أنّ شعار Gemini في أسفل يسار نافذة المحرّر مفعّل (وليس مشطوبًا). تأكَّد أيضًا من أنّ مشروع Google Cloud في أسفل يمين الصفحة يشير إلى مشروعك النشط الحالي الذي تريد العمل عليه. إذا كانت غير نشطة، انقر عليها، ثم امنح الإذن، واختَر مشروع Google Cloud الذي تريد أن تشير إليه، ثم فعّلها.
بعد تفعيل كليهما، انقر على اسم المشروع في أسفل يسار الصفحة، وفي القائمة المنبثقة التي تفتح بعنوان "رمز السحابة" (Cloud Code)، انتقِل للأسفل إلى "تطبيق جديد" (New Application).

في تلك القائمة، اختَر تطبيق Cloud Functions. من القائمة المنبثقة، اختَر Java:

في القائمة الناتجة، اكتب اسم المشروع "duetai-gemini-calling" بدلاً من helloworld وانقر على "حسنًا".

رائع! لقد أعددت تطبيقًا بسيطًا لـ "وظائف السحابة الإلكترونية" في Java باستخدام Gemini، ولم تفعل الكثير باستثناء تفعيل الإعدادات وتنشيطها، هل هذا صحيح؟
هذه هي بنية المشروع التي من المفترض أن تظهر لك:

يمكنك الآن نشر الدالة. لكنّ هذا ليس السبب الذي دفعنا إلى إطلاق هذه الميزة. لنبدأ بإنشاء عملية تنفيذ Gemini Pro API في هذه "الدالة السحابية" باستخدام حزمة تطوير البرامج (SDK) للغة Java.
لننشئ الآن الوظيفة الخاصة بحالة الاستخدام، وهي استدعاء نموذج Gemini Pro في Cloud Function هذا. لإجراء ذلك، يمكنك إضافة المزيد من الطلبات وتطوير الرمز بشكل تدريجي باستخدام Gemini أو كتابة المنطق بنفسك. سأستخدم مزيجًا من كليهما.
6. إضافة التبعيات
في وحدة تحكّم محادثة Gemini (التي تظهر ضمن "أداة تعديل Cloud Code" في اللوحة اليمنى)، أدخِل الطلب التالي:
what is the maven dependency for com.google.cloud.vertexai library
السبب الذي يدفعني إلى طلب حزمة com.google.cloud.vertexai تحديدًا هو أنّني أستخدمها في رمز المصدر حيث أطبّق رمز استدعاء Gemini.
ظهرت لي هذه النتيجة:

<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-vertexai</artifactId>
<version>0.1.0</version>
</dependency>
انسخ هذا الرمز والصقه في ملف pom.xml، قبل علامة </dependencies> مباشرةً. استبدِل الإصدار بالرقم 0.1.0 (يمكنك إزالة العلامة <version> إذا كنت تستخدم Spring Cloud GCP BOM لإدارة أرقام إصدارات Spring Cloud GCP).
يجب أن يبدو قسم التبعية على النحو التالي:

تأكَّد من تعديل أرقام الإصدارات، إذا لزم الأمر، لتتطابق مع ما ورد أعلاه. إذا لاحظت، أضفتُ أيضًا تبعية أخرى معها:
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.10</version>
</dependency>
7. تعديل نقطة دخول الدالة واسم الفئة
- انتقِل إلى الملف "launch.json" ضمن المجلد ".vscode". عدِّل اسم الدالة من "function-hello-world" إلى "function-gemini-calling".
- عدِّل قيمة entryPoint من "cloudcode.helloworld.HelloWorld إلى cloudcode.bookshelf.Bookshelf.
- انتقِل الآن إلى ملف فئة Java "HelloWorld.java". غيِّر اسم الحزمة إلى package cloudcode.bookshelf. في الخطأ الذي يظهر، انقر على المصباح الأصفر ثم على الخيار "Move HelloWorld.java" to package cloudcode.bookshelf;.

- عدِّل اسم الفئة إلى Bookshelf، وفي الخطأ الذي يظهر، انقر على المصباح الأصفر الصغير واختَر "إعادة تسمية الملف إلى Bookshelf.java". اختَر ذلك.
8. إنشاء الطريقة التي تستدعي Gemini Pro
لننفّذ هذه الوظيفة في فئة Bookshelf.java. استبدِل ملف Bookshelf.java بالرمز البرمجي أدناه:
package cloudcode.bookshelf;
import java.io.BufferedWriter;
import com.google.cloud.functions.HttpFunction;
import com.google.cloud.functions.HttpRequest;
import com.google.cloud.functions.HttpResponse;
import com.google.cloud.vertexai.VertexAI;
import com.google.cloud.vertexai.api.GenerateContentResponse;
import com.google.cloud.vertexai.api.GenerationConfig;
import com.google.cloud.vertexai.generativeai.preview.GenerativeModel;
import com.google.cloud.vertexai.generativeai.preview.ResponseHandler;
import java.io.IOException;
import java.util.List;
import java.util.Arrays;
import java.util.Map;
import java.util.LinkedHashMap;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.JsonArray;
public class Bookshelf implements HttpFunction {
private static final Gson gson = new Gson();
@Override
public void service(HttpRequest request, HttpResponse response) throws Exception {
BufferedWriter writer = response.getWriter();
// Get the request body as a JSON object.
JsonObject requestJson = new Gson().fromJson(request.getReader(), JsonObject.class);
JsonArray calls_array = requestJson.getAsJsonArray("calls");
JsonArray calls = (JsonArray) calls_array.get(0);
String context = calls.get(0).toString().replace("\"", "");
//Invoke Gemini model
String raw_result = callGemini(context);
raw_result = raw_result.replace("\n","");
String trimmed = raw_result.trim();
List<String> result_list = Arrays.asList(trimmed);
Map<String, List<String>> stringMap = new LinkedHashMap<>();
stringMap.put("replies", result_list);
// Serialization
String return_value = gson.toJson(stringMap);
writer.write(return_value);
}
public String callGemini(String context) throws IOException{
String res = "";
try (VertexAI vertexAi = new VertexAI("REPLACE_WITH_YOUR_PROJECT_ID", "us-central1"); ) {
GenerationConfig generationConfig =
GenerationConfig.newBuilder()
.setMaxOutputTokens(2048)
.setTemperature(0.4F)
.setTopK(32)
.setTopP(1)
.build();
GenerativeModel model = new GenerativeModel("gemini-pro", generationConfig, vertexAi);
GenerateContentResponse response = model.generateContent(context);
res = ResponseHandler.getText(response);
}catch(Exception e){
System.out.println(e);
}
return res;
}
}
يتوقّع هذا الصف إدخالاً في بنية JSON كما هو موضّح أدناه:
{ "calls": [["YOUR_PROMPT_HERE"]] }
تعرض هذه الطريقة استجابة كما هو موضّح أدناه:
(Json) Map<String, List<String>> {"replies": ["response"]}
جرِّب خيار محادثة Gemini من "محرّر Cloud Shell" في اللوحة اليمنى لشرح الرمز. يمكنك بدلاً من ذلك اختيار كل الرمز والنقر على المصباح الأصفر في أعلى يمين الجزء المحدّد واختيار الخيار "شرح هذا الرمز".

9- نشر Cloud Function
بعد أن أصبحت Cloud Function جاهزة، لنطرح على Gemini سؤالاً حول كيفية نشرها. انتقِل إلى محادثة Gemini في "محرّر Cloud Code" وأدخِل ما يلي:
How to deploy this Cloud Function with a gcloud command?
تلقّيتُ الردّ التالي:

أردتُ الآن استكشافها أكثر. لذلك، طلبت من Gemini أن يقدّم لي الأمر الكامل لنشر دوال gcloud. تكون الاستجابة كما هو موضّح أدناه:

لا يمكنني أن أؤكّد لك أنّك ستتلقّى الردّ نفسه، ولكنّني وجدتُ أنّه من المثير للاهتمام أن يضيف بعض التفاصيل الأخرى بشكل مفاجئ، كما هو موضّح في الصورة أدناه:
تنسيق نص الطلب:

و
تنسيق الردّ:

لنبدأ الآن بنشر الدالة من خلال تنفيذ أمر gcloud الذي قدّمه لنا Gemini. لإجراء ذلك، علينا فتح "وحدة Cloud Shell الطرفية". يمكنك فتحه في علامة تبويب جديدة على https://console.cloud.google.com والتأكّد من اختيار المشروع الصحيح. افتح "وحدة Cloud Shell الطرفية" من خلال النقر على رمز "تفعيل Cloud Shell" في أعلى يسار وحدة التحكّم، وتأكَّد من أنّك في مجلد المشروع الصحيح باستخدام الأمر التالي:
cd duetai-gemini-calling
متبوعًا بالأمر أدناه:
gcloud functions deploy bookshelf --runtime java17 --trigger-http --entry-point cloudcode.bookshelf.Bookshelf --allow-unauthenticated
سيُطلب منك الموافقة على "السماح باستدعاءات غير مصادَق عليها للدالة الجديدة [bookshelf]?" اكتب "y" واضغط على Enter. بعد ذلك، سيتم طرح بعض الأسئلة إذا كان ذلك منطبقًا، وسيتم نشر "وظيفة السحابة الإلكترونية" بدون خادم باستخدام عنوان URL الذي تم نشره: https://us-central1-*******.cloudfunctions.net/bookshelf.
لننفّذ الآن وظيفة Cloud Functions التي تم نشرها ونختبرها.
ملاحظة: إذا تخطّيت عن طريق الخطأ السؤال "السماح بعمليات استدعاء غير مصادَق عليها" أو اخترت "لا"، لن تتمكّن من الوصول إلى نتيجة Cloud Functions وسيظهر لك "خطأ في الأذونات" بدون منح إعدادات إضافية في "إدارة الهوية وإمكانية الوصول". لذا، انتبه إلى ذلك.
10. استدعاء دالة Cloud Functions التي تم نشرها
ما رأيك أن نسأل Gemini عن ذلك؟ أدخلتُ الطلب
How to call the deployed cloud function?
حصلتُ على النتيجة أدناه: (قد يظهر لك الردّ نفسه أو لا يظهر، يمكنك تجربة الطلب والاطّلاع على الفرق في الردود).

طرحتُ على المحادثة أسئلة محدّدة حول الطرق البديلة لتفعيل الدالة التي تم نشرها، واستدعاء الدالة باستخدام أمر gcloud وما إلى ذلك. وقد أرسلتُ الطلب التالي:
how to call the deployed cloud function using gcloud
تلقّيتُ الردّ التالي: 
يمكنك استخدام هذا الردّ (الأمر "gcloud functions call") من الوحدة الطرفية مع إجراء تعديلات لجعلها تعمل في السيناريو الخاص بنا (بدلاً من ذلك، جرِّب تمرير المَعلمات في الطلب نفسه ومعرفة ما إذا كان بإمكانك الحصول على تفاصيل الأمر "gcloud functions call" في الردّ):
gcloud functions call bookshelf --region=us-central1 --gen2 --data '{"calls":[["Hello! This is my test prompt."]]}'
إليك النتيجة:

11. تَنظيم
يمكنك حذف دوال Cloud Functions التي أنشأتها سابقًا من خلال النقر على الزرّ DELETE في صفحة التفاصيل الخاصة بدوال Cloud Functions.
12. تهانينا
لقد أنشأت ونشرت واختبرت بنجاح دالة Java Cloud Functions لاستدعاء Gemini 1.0 Pro باستخدام Gemini. يأخذ هذا التطبيق طلب الإدخال المتعلق باقتراح الكتب مع ملخص وموضوع الكتب.