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

1. مقدمه

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

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

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

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

2. فراخوانی تابع Gemini

Gemini Function Calling در عصر Generative AI متمایز است زیرا به شما امکان می دهد انعطاف پذیری مدل های زبان مولد را با دقت برنامه نویسی سنتی ترکیب کنید.

در اینجا کارهایی که برای اجرای فراخوانی تابع 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

چیزی که خواهی ساخت

شما یک Java Cloud Function ایجاد و مستقر خواهید کرد که کارهای زیر را انجام می دهد:

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

3. الزامات

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

5. تابع Cloud را اجرا کنید

  1. Cloud Shell Editor را اجرا کنید .
  2. روی Cloud Code کلیک کنید و سپس بخش Cloud Functions را گسترش دهید.
  3. روی نماد Create Function (+) کلیک کنید.
  4. در گفتگوی Create New Application ، گزینه Java: Hello World را انتخاب کنید.
  5. نامی برای پروژه در مسیر پروژه ارائه کنید، مانند GeminiFunctionCalling .
  6. برای مشاهده ساختار پروژه روی Explorer کلیک کنید و سپس فایل pom.xml را باز کنید. تصویر زیر ساختار پروژه را نشان می دهد:

bdf07515f413dd9e.png

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

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

ورودی سریع

در این مثال، اعلان ورودی زیر است: آدرس مقدار latlong 40.714224,-73.961452 چیست .

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

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

مشخصات API

در این مثال از Reverse Geocoding API استفاده شده است. مشخصات 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 Function Calling با استفاده از حالت استانداردسازی آدرس چگونه کار می کند، می توانید ادامه دهید و تابع Cloud را اجرا کنید.

7. مستقر و آزمایش کنید

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

8. پاکسازی کنید

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

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

9. تبریک می گویم

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