هوش مصنوعی مولد قطعی با فراخوانی تابع Gemini در جاوا

۱. مقدمه

مدل‌های هوش مصنوعی مولد در درک و پاسخ به زبان طبیعی فوق‌العاده هستند. اما اگر برای وظایف حیاتی مانند استانداردسازی آدرس به خروجی‌های دقیق و قابل پیش‌بینی نیاز داشته باشید، چه؟ مدل‌های مولد سنتی گاهی اوقات می‌توانند در زمان‌های مختلف برای درخواست‌های یکسان، پاسخ‌های متفاوتی ارائه دهند که به طور بالقوه منجر به ناسازگاری می‌شود. اینجاست که قابلیت فراخوانی تابع Gemini می‌درخشد و به شما امکان می‌دهد عناصر پاسخ هوش مصنوعی را به طور قطعی کنترل کنید.

این آزمایشگاه کد، این مفهوم را با استفاده از مورد تکمیل آدرس و استانداردسازی نشان می‌دهد. برای این منظور، ما یک تابع ابری جاوا خواهیم ساخت که وظایف زیر را انجام می‌دهد:

  1. مختصات طول و عرض جغرافیایی را دریافت می‌کند
  2. برای دریافت آدرس‌های مربوطه، API مربوط به Geocoding نقشه‌های گوگل را فراخوانی می‌کند.
  3. از ویژگی فراخوانی تابع Gemini 1.0 Pro برای استانداردسازی قطعی و خلاصه کردن آن آدرس‌ها در قالب خاصی که نیاز داریم، استفاده می‌کند.

بیایید شیرجه بزنیم!

۲. فراخوانی تابع جمینی

فراخوانی تابع Gemini در دوران هوش مصنوعی مولد برجسته است زیرا به شما امکان می‌دهد انعطاف‌پذیری مدل‌های زبان مولد را با دقت برنامه‌نویسی سنتی ترکیب کنید.

در اینجا وظایفی که برای پیاده‌سازی فراخوانی تابع Gemini باید انجام دهید، آورده شده است:

  1. تعریف توابع : توابع را به وضوح شرح دهید. توضیحات باید شامل اطلاعات زیر باشد:
  • نام تابع، مانند getAddress .
  • پارامترهایی که تابع انتظار دارد، مانند latlng به عنوان یک رشته.
  • نوع داده‌ای که تابع برمی‌گرداند، مانند لیستی از رشته‌های آدرس.
  1. ایجاد ابزارها برای Gemini : توصیفات عملکرد را در قالب مشخصات API به ابزارها بسته‌بندی کنید. به یک ابزار به عنوان یک جعبه ابزار تخصصی فکر کنید که Gemini می‌تواند برای درک عملکرد API از آن استفاده کند.
  2. هماهنگ‌سازی APIها با استفاده از Gemini : وقتی درخواستی را به Gemini ارسال می‌کنید، می‌تواند درخواست شما را تجزیه و تحلیل کند و تشخیص دهد که در کجا می‌تواند از ابزارهایی که شما ارائه داده‌اید استفاده کند. سپس Gemini با انجام وظایف زیر به عنوان یک هماهنگ‌کننده هوشمند عمل می‌کند:
  • پارامترهای API لازم برای فراخوانی توابع تعریف شده شما را تولید می‌کند. Gemini از طرف شما API را فراخوانی نمی‌کند. شما باید API را بر اساس پارامترها و امضایی که فراخوانی تابع Gemini برای شما ایجاد کرده است، فراخوانی کنید.
  • Gemini با ارسال نتایج حاصل از فراخوانی‌های API شما به تولید خود، نتایج را پردازش می‌کند و اطلاعات ساختاریافته را در پاسخ نهایی خود لحاظ می‌کند. شما می‌توانید این اطلاعات را به روشی که برای برنامه خود می‌خواهید پردازش کنید.

تصویر زیر جریان داده‌ها، مراحل پیاده‌سازی و مالک هر مرحله، مانند برنامه، LLM یا API را نشان می‌دهد:

b9a39f55567072d3.png

آنچه خواهید ساخت

شما یک تابع ابری جاوا ایجاد و مستقر خواهید کرد که موارد زیر را انجام می‌دهد:

  • مختصات طول و عرض جغرافیایی را دریافت می‌کند.
  • برای دریافت آدرس‌های مربوطه، API مربوط به Geocoding نقشه‌های گوگل را فراخوانی می‌کند.
  • از ویژگی فراخوانی تابع Gemini 1.0 Pro برای استانداردسازی قطعی و خلاصه کردن آن آدرس‌ها در یک قالب خاص استفاده می‌کند.

۳. الزامات

  • یک مرورگر، مانند کروم یا فایرفاکس .
  • یک پروژه گوگل کلود با قابلیت پرداخت.

۴. قبل از شروع

  1. در کنسول گوگل کلود ، در صفحه انتخاب پروژه، یک پروژه گوگل کلود را انتخاب یا ایجاد کنید.
  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. با اجرای دستورات زیر در Cloud Shell، APIهای لازم Google Cloud را فعال کنید:
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 را باز کنید ، روی Extensions کلیک کنید و سپس افزونه Gemini + Google Cloud Code را نصب کنید.

۵. پیاده‌سازی عملکرد ابری

  1. ویرایشگر Cloud Shell را اجرا کنید .
  2. روی Cloud Code کلیک کنید و سپس بخش Cloud Functions را باز کنید.
  3. روی نماد ایجاد تابع (+) کلیک کنید.
  4. در پنجره‌ی «ایجاد برنامه‌ی جدید» ، گزینه‌ی «جاوا: سلام دنیا» را انتخاب کنید.
  5. در مسیر پروژه، یک نام برای پروژه وارد کنید، مانند GeminiFunctionCalling .
  6. برای مشاهده ساختار پروژه، روی Explorer کلیک کنید و سپس فایل pom.xml را باز کنید. تصویر زیر ساختار پروژه را نشان می‌دهد:

bdf07515f413dd9e.png

  1. وابستگی‌های لازم را درون تگ <dependencies>... </dependencies> در فایل pom.xml اضافه کنید. می‌توانید از مخزن گیت‌هاب این پروژه به کل pom.xml دسترسی داشته باشید. pom.xml را از آنجا در فایل pom.xml پروژه فعلی خود که در حال ویرایش آن هستید، کپی کنید.
  2. کلاس HelloWorld.java را از لینک GeminiFunctionCalling در گیت‌هاب کپی کنید. شما باید API_KEY و project_id به ترتیب با کلید API مربوط به geocoding و شناسه پروژه ابری گوگل خود به‌روزرسانی کنید.

۶. درک فراخوانی تابع با استفاده از کلاس HelloWorld.java

ورودی سریع

در این مثال، دستور ورودی به صورت زیر است: آدرس مقدار latlong برابر با 40.714224,-73.961452 چیست؟

قطعه کد مربوط به ورودی در فایل به صورت زیر است:

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

مشخصات API

در این مثال از API مربوط به 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، دستورالعمل را هماهنگ کنید

ورودی اعلان و مشخصات API به 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 برای API است. در اینجا یک مثال از خروجی آورده شده است:

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

پارامتر زیر را به API Reverse Geocoding ارسال کنید: "latlng=40.714224,-73.961452"

نتیجه هماهنگ شده را با فرمت "latlng=VALUE" مطابقت دهید.

فراخوانی API

کد زیر بخشی از کد است که API را فراخوانی می‌کند:

// 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 پاسخ دریافتی از API معکوس Geocoding را در خود نگه می‌دارد. خروجی به صورت فرمت شده در زیر آمده است:

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

پاسخ API را پردازش کرده و اعلان را آماده کنید

کد زیر پاسخ دریافتی از API را پردازش می‌کند و اعلان را به همراه دستورالعمل‌هایی در مورد نحوه پردازش پاسخ آماده می‌کند:

// 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 ارسال می‌کند:

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 چگونه با مورد استفاده استانداردسازی آدرس کار می‌کند، می‌توانید به سراغ پیاده‌سازی تابع ابری بروید.

۷. استقرار و آزمایش

  1. اگر قبلاً پروژه GeminiFunctionCalling را ایجاد کرده و تابع Cloud را پیاده‌سازی کرده‌اید، به مرحله ۲ بروید. اگر پروژه را ایجاد نکرده‌اید، به ترمینال Cloud Shell بروید و این مخزن را کلون کنید: git clone https://github.com/AbiramiSukumaran/GeminiFunctionCalling
  2. به پوشه پروژه بروید: cd GeminiFunctionCalling
  3. برای ساخت و استقرار تابع ابری، دستور زیر را اجرا کنید:
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 را آزمایش کنید:
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}}```"]}'

۸. تمیز کردن

برای جلوگیری از تحمیل هزینه به حساب Google Cloud خود برای منابع استفاده شده در این پست، این مراحل را دنبال کنید:

  1. در کنسول گوگل کلود، به صفحه مدیریت منابع بروید.
  2. در لیست پروژه‌ها، پروژه‌ای را که می‌خواهید حذف کنید انتخاب کنید و سپس روی حذف کلیک کنید.
  3. در کادر محاوره‌ای، شناسه پروژه را تایپ کنید و سپس برای حذف پروژه، روی خاموش کردن کلیک کنید.
  4. اگر می‌خواهید پروژه خود را حفظ کنید، مراحل بالا را رد کنید و با رفتن به Cloud Functions و از لیست توابع، تابع Cloud را که می‌خواهید حذف کنید، حذف کنید و روی DELETE کلیک کنید.

۹. تبریک

تبریک! شما با موفقیت از ویژگی فراخوانی تابع Gemini در یک برنامه جاوا استفاده کردید و یک وظیفه هوش مصنوعی مولد را به یک فرآیند قطعی و قابل اعتماد تبدیل کردید. برای کسب اطلاعات بیشتر در مورد مدل‌های موجود، به مستندات محصول Vertex AI LLM مراجعه کنید.