الذكاء الاصطناعي التوليدي مع Gemini يطلب البيانات من خلال وظيفة في Java

1. مقدمة

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

يوضّح هذا الدرس التطبيقي حول الترميز هذا المفهوم من خلال حالة استخدام إكمال العناوين وتوحيدها. لذلك، سننشئ دالة Java على Cloud تنفّذ المهام التالية:

  1. تأخذ إحداثيات خط العرض وخط الطول
  2. يطلب البيانات من Google Maps Geocoding API للحصول على العناوين المطابقة
  3. يستخدم ميزة "استدعاء الدوال" في Gemini 1.0 Pro لتوحيد هذه العناوين وتلخيصها بشكل حتمي بتنسيق محدّد نحتاجه

لنبدأ!

2. استدعاء الدالة في Gemini

تبرز ميزة "استدعاء الدوال" في Gemini في عصر الذكاء الاصطناعي التوليدي لأنّها تتيح لك الجمع بين مرونة النماذج اللغوية التوليدية ودقة البرمجة التقليدية.

في ما يلي المهام التي عليك إكمالها لتنفيذ ميزة "استدعاء الدوال البرمجية" في Gemini:

  1. تحديد الدوال: يجب وصف الدوال بوضوح. يجب أن تتضمّن الأوصاف المعلومات التالية:
  • اسم الدالة، مثل getAddress
  • المَعلمات التي تتوقّعها الدالة، مثل latlng كسلسلة
  • نوع البيانات التي تعرضها الدالة، مثل قائمة بسلاسل العناوين
  1. إنشاء أدوات لـ Gemini: يمكنك تجميع أوصاف الوظائف في شكل مواصفات واجهة برمجة التطبيقات (API) في أدوات. يمكنك اعتبار الأداة بمثابة صندوق أدوات متخصص يمكن أن يستخدمه Gemini لفهم وظيفة واجهة برمجة التطبيقات.
  2. تنظيم واجهات برمجة التطبيقات باستخدام Gemini: عندما ترسل طلبًا إلى Gemini، يمكنه تحليل طلبك والتعرّف على الأماكن التي يمكنه فيها استخدام الأدوات التي قدّمتها. بعد ذلك، يعمل Gemini كمنسّق ذكي من خلال تنفيذ المهام التالية:
  • تنشئ هذه الأداة مَعلمات واجهة برمجة التطبيقات اللازمة لاستدعاء الدوال المحدّدة. لا يطلب Gemini واجهة برمجة التطبيقات نيابةً عنك. يجب طلب البيانات من واجهة برمجة التطبيقات استنادًا إلى المَعلمات والتوقيع اللذين أنشأتهما لك ميزة "طلب البيانات من الدوال" في Gemini.
  • يعالج Gemini النتائج من خلال إعادة إدخالها من طلبات البيانات من واجهة برمجة التطبيقات إلى عملية الإنشاء، ويدمج المعلومات المنظَّمة في الردّ النهائي. يمكنك معالجة هذه المعلومات بالطريقة التي تريدها لتطبيقك.

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

b9a39f55567072d3.png

ما ستنشئه

ستنشئ دالة Java Cloud Function وتنفّذها، وتؤدي هذه الدالة ما يلي:

  • تأخذ إحداثيات خطوط الطول والعرض.
  • يطلب البيانات من Google Maps Geocoding API للحصول على العناوين المطابقة.
  • يستخدم ميزة استدعاء الدوال في Gemini 1.0 Pro لتوحيد هذه العناوين وتلخيصها بشكل حتمي بتنسيق معيّن.

3- المتطلبات

  • متصفّح، مثل Chrome أو Firefox
  • مشروع Google Cloud تم تفعيل الفوترة فيه

4. قبل البدء

  1. في Google Cloud Console، ضمن صفحة اختيار المشروع، اختَر مشروعًا على Google Cloud أو أنشِئه.
  2. تأكَّد من تفعيل الفوترة لمشروعك على Google Cloud. تعرَّف على كيفية التحقّق مما إذا كانت الفوترة مفعَّلة في مشروع.
  3. فعِّل Cloud Shell من "وحدة تحكّم Google Cloud". لمزيد من المعلومات، راجِع استخدام Cloud Shell.
  4. إذا لم يتم ضبط مشروعك، استخدِم الأمر التالي لضبط مشروعك:
gcloud config set project <YOUR_PROJECT_ID>
  1. في Cloud Shell، اضبط متغيّرات البيئة التالية:
export GCP_PROJECT=<YOUR_PROJECT_ID>
export GCP_REGION=us-central1
  1. فعِّل واجهات Google Cloud APIs اللازمة من خلال تنفيذ الأوامر التالية في Cloud Shell:
gcloud services enable cloudbuild.googleapis.com cloudfunctions.googleapis.com run.googleapis.com logging.googleapis.com storage-component.googleapis.com cloudaicompanion.googleapis.com aiplatform.googleapis.com
  1. افتح Cloud Shell Editor، وانقر على الإضافات، ثم ثبِّت إضافة Gemini + Google Cloud Code.

5- تنفيذ Cloud Function

  1. تشغيل "محرّر Cloud Shell"
  2. انقر على رمز Cloud، ثم وسِّع قسم وظائف Cloud.
  3. انقر على رمز إنشاء دالة (+).
  4. في مربّع الحوار إنشاء تطبيق جديد، اختَر الخيار Java: Hello World.
  5. قدِّم اسمًا للمشروع في مسار المشروع، مثل GeminiFunctionCalling.
  6. انقر على Explorer لعرض بنية المشروع، ثم افتح ملف pom.xml. تعرض الصورة التالية بنية المشروع:

bdf07515f413dd9e.png

  1. أضِف الاعتماديات اللازمة ضمن العلامة <dependencies>... </dependencies> في ملف pom.xml. يمكنك الوصول إلى pom.xml بالكامل من مستودع هذا المشروع على GitHub. انسخ ملف pom.xml من هناك إلى ملف pom.xml في مشروعك الحالي الذي تعدّله.
  2. انسخ HelloWorld.java الفئة من الرابط GeminiFunctionCalling github. يجب تعديل API_KEY وproject_id باستخدام مفتاح واجهة برمجة التطبيقات للترميز الجغرافي ورقم تعريف مشروع Google Cloud على التوالي.

6. فهم ميزة "استدعاء الدوال" باستخدام فئة HelloWorld.java

إدخال الطلب

في هذا المثال، يكون طلب الإدخال كما يلي: ما هو عنوان قيمة خطوط الطول والعرض 40.714224,-73.961452؟

في ما يلي مقتطف الرمز البرمجي الذي يتوافق مع طلب الإدخال في الملف:

String promptText = "What's the address for the latlong value '" + latlngString + "'?"; //40.714224,-73.961452

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

يتم استخدام Reverse Geocoding API في هذا المثال. في ما يلي مواصفات واجهة برمجة التطبيقات:

/* Declare the function for the API to invoke (Geo coding API) */ 
FunctionDeclaration functionDeclaration =
    FunctionDeclaration.newBuilder()
        .setName("getAddress")
        .setDescription("Get the address for the given latitude and longitude value.")
        .setParameters(
            Schema.newBuilder()
                .setType(Type.OBJECT)
                .putProperties(
                    "latlng",
                    Schema.newBuilder()
                        .setType(Type.STRING)
                        .setDescription("This must be a string of latitude and longitude coordinates separated by comma")
                        .build())
                .addRequired("latlng")
                .build())
        .build();

تنسيق الطلب باستخدام Gemini

يتم إرسال الطلب ومواصفات واجهة برمجة التطبيقات إلى Gemini:

// Add the function to a "tool"
Tool tool = Tool.newBuilder()
.addFunctionDeclarations(functionDeclaration)
.build();

// Invoke the Gemini model with the use of the tool to generate the API parameters from the prompt input.
GenerativeModel model = GenerativeModel.newBuilder()
.setModelName(modelName)
.setVertexAi(vertexAI)
.setTools(Arrays.asList(tool))
.build();
GenerateContentResponse response = model.generateContent(promptText);
Content responseJSONCnt = response.getCandidates(0).getContent();

الاستجابة من هذا هي JSON للمَعلمات المنسَّقة إلى واجهة برمجة التطبيقات. في ما يلي مثال على الناتج:

role: "model"
parts {
 function_call {
   name: "getAddress"
   args {
     fields {
       key: "latlng"
       value {
         string_value: "40.714224,-73.961452"
       }
     }
   }
 }
}

نقِّل المَعلمة التالية إلى واجهة برمجة التطبيقات Reverse Geocoding: "latlng=40.714224,-73.961452"

طابِق النتيجة المنسَّقة مع التنسيق "latlng=VALUE".

استدعاء واجهة برمجة التطبيقات

في ما يلي قسم الرمز الذي يستدعي واجهة برمجة التطبيقات:

// Create a request
     String url = API_STRING + "?key=" + API_KEY + params;
     java.net.http.HttpRequest request = java.net.http.HttpRequest.newBuilder()
         .uri(URI.create(url))
         .GET()
         .build();
     // Send the request and get the response
     java.net.http.HttpResponse<String> httpresponse = client.send(request, java.net.http.HttpResponse.BodyHandlers.ofString());
     // Save the response
     String jsonResult =  httpresponse.body().toString();

يحتوي السلسلة jsonResult على الردّ من واجهة برمجة التطبيقات "عكس الترميز الجغرافي". في ما يلي نسخة منسَّقة من الناتج:

"...277 Bedford Ave, Brooklyn, NY 11211, USA; 279 Bedford Ave, Brooklyn, NY 11211, USA; 277 Bedford Ave, Brooklyn, NY 11211, USA;..."

معالجة الردّ من واجهة برمجة التطبيقات وإعداد الطلب

تعالج التعليمة البرمجية التالية الردّ من واجهة برمجة التطبيقات وتعدّ الطلب مع تعليمات حول كيفية معالجة الردّ:

// Provide an answer to the model so that it knows what the result
     // of a "function call" is.
     String promptString =
     "You are an AI address standardizer for assisting with standardizing addresses accurately. Your job is to give the accurate address in the standard format as a JSON object containing the fields DOOR_NUMBER, STREET_ADDRESS, AREA, CITY, TOWN, COUNTY, STATE, COUNTRY, ZIPCODE, LANDMARK by leveraging the address string that follows in the end. Remember the response cannot be empty or null. ";

Content content =
         ContentMaker.fromMultiModalData(
             PartMaker.fromFunctionResponse(
                 "getAddress",
                 Collections.singletonMap("address", formattedAddress)));
     String contentString = content.toString();
     String address = contentString.substring(contentString.indexOf("string_value: \"") + "string_value: \"".length(), contentString.indexOf('"', contentString.indexOf("string_value: \"") + "string_value: \"".length()));

     List<SafetySetting> safetySettings = Arrays.asList(
       SafetySetting.newBuilder()
           .setCategory(HarmCategory.HARM_CATEGORY_HATE_SPEECH)
           .setThreshold(SafetySetting.HarmBlockThreshold.BLOCK_ONLY_HIGH)
           .build(),
       SafetySetting.newBuilder()
           .setCategory(HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT)
           .setThreshold(SafetySetting.HarmBlockThreshold.BLOCK_ONLY_HIGH)
           .build()
   );

استدعاء Gemini وعرض العنوان الموحّد

ينقل الرمز التالي الناتج المعالَج من الخطوة السابقة كطلب إلى Gemini:

GenerativeModel modelForFinalResponse = GenerativeModel.newBuilder()
     .setModelName(modelName)
     .setVertexAi(vertexAI)
     .build();
     GenerateContentResponse finalResponse = modelForFinalResponse.generateContent(promptString + ": " + address, safetySettings);
      System.out.println("promptString + content: " + promptString + ": " + address);
       // See what the model replies now
       System.out.println("Print response: ");
       System.out.println(finalResponse.toString());
       String finalAnswer = ResponseHandler.getText(finalResponse);
       System.out.println(finalAnswer);

يحتوي المتغيّر finalAnswer على العنوان الموحّد بتنسيق JSON. في ما يلي مثال على الناتج:

{"replies":["{ \"DOOR_NUMBER\": null, \"STREET_ADDRESS\": \"277 Bedford Ave\", \"AREA\": \"Brooklyn\", \"CITY\": \"New York\", \"TOWN\": null, \"COUNTY\": null, \"STATE\": \"NY\", \"COUNTRY\": \"USA\", \"ZIPCODE\": \"11211\", \"LANDMARK\": null} null}"]}

بعد أن فهمت كيفية عمل ميزة "استدعاء الدوال" في Gemini مع حالة استخدام توحيد تنسيق العناوين، يمكنك المتابعة وتفعيل "دالة السحابة".

7. النشر والاختبار

  1. إذا سبق لك إنشاء مشروع GeminiFunctionCalling وتنفيذ Cloud Function، انتقِل إلى الخطوة 2. إذا لم تكن قد أنشأت المشروع، انتقِل إلى نافذة Cloud Shell الطرفية واستنسِخ هذا المستودع: git clone https://github.com/AbiramiSukumaran/GeminiFunctionCalling
  2. انتقِل إلى مجلد المشروع: cd GeminiFunctionCalling
  3. نفِّذ العبارة التالية لإنشاء Cloud Function ونشرها:
gcloud functions deploy gemini-fn-calling --gen2 --region=us-central1 --runtime=java11 --source=. --entry-point=cloudcode.helloworld.HelloWorld --trigger-http

في ما يلي تنسيق عنوان URL بعد النشر: https://us-central1-YOUR_PROJECT_ID.cloudfunctions.net/gemini-fn-calling

  1. اختبِر Cloud Function من خلال تنفيذ الأمر التالي من الوحدة الطرفية:
gcloud functions call gemini-fn-calling --region=us-central1 --gen2 --data '{"calls":[["40.714224,-73.961452"]]}'

في ما يلي ردّ على طلب عيّنة عشوائية: '{"replies":["{ "DOOR_NUMBER": "277", "STREET_ADDRESS": "Bedford Ave", "AREA": null, "CITY": "Brooklyn", "TOWN": null, "COUNTY": "Kings County", "STATE": "NY", "COUNTRY": "USA", "ZIPCODE": "11211", "LANDMARK": null}}```"]}'

8. تَنظيم

لتجنُّب تحمّل رسوم في حسابك على Google Cloud مقابل الموارد المستخدَمة في هذه المشاركة، اتّبِع الخطوات التالية:

  1. في Google Cloud Console، انتقِل إلى صفحة إدارة الموارد.
  2. في قائمة المشاريع، اختَر المشروع الذي تريد حذفه، ثم انقر على "حذف".
  3. في مربّع الحوار، اكتب رقم تعريف المشروع، ثم انقر على "إيقاف" لحذف المشروع.
  4. إذا كنت تريد الاحتفاظ بمشروعك، تخطَّ الخطوات أعلاه واحذف Cloud Function من خلال الانتقال إلى Cloud Functions، ثم ضَع علامة في المربّع بجانب الدالة التي تريد حذفها من قائمة الدوال وانقر على DELETE.

9- تهانينا

تهانينا! لقد استخدمت بنجاح ميزة "استدعاء الدوال" في Gemini ضمن تطبيق Java وحوّلت مهمة الذكاء الاصطناعي التوليدي إلى عملية حتمية وموثوقة. لمزيد من المعلومات عن النماذج المتاحة، راجِع مستندات منتج النماذج اللغوية الكبيرة في Vertex AI.