Generative AI เชิงกำหนดที่มีการเรียกใช้ฟังก์ชัน Gemini ใน Java

1. บทนำ

โมเดล Generative AI นั้นโดดเด่นในเรื่องการทำความเข้าใจและตอบสนองต่อภาษาที่เป็นธรรมชาติ แต่หากคุณต้องการผลลัพธ์ที่แม่นยำและคาดการณ์ได้สำหรับงานสำคัญๆ เช่น การกำหนดมาตรฐานที่อยู่ บางครั้งโมเดล Generative แบบเดิมจะให้คำตอบที่ต่างกันได้ในช่วงเวลาที่แตกต่างกันสำหรับพรอมต์เดียวกัน ซึ่งอาจทำให้เกิดความไม่สอดคล้องกันได้ และนั่นคือจุดที่ความสามารถในการเรียกใช้ฟังก์ชันของ Gemini โดดเด่น โดยให้คุณควบคุมองค์ประกอบการตอบสนองของ AI ตามที่กำหนดไว้ได้

Codelab นี้แสดงแนวคิดนี้พร้อมกับกรณีการใช้งานการกรอกที่อยู่และการกำหนดมาตรฐาน สำหรับกรณีนี้ เราจะสร้าง Java Cloud Function ที่ทำหน้าที่ต่อไปนี้

  1. ต้องใช้พิกัดละติจูดและลองจิจูด
  2. เรียกใช้ Google Maps Geocoding API เพื่อรับที่อยู่ที่เกี่ยวข้อง
  3. ใช้ฟีเจอร์การเรียกใช้ฟังก์ชัน Gemini 1.0 Pro เพื่อสร้างมาตรฐานและสรุปที่อยู่เหล่านั้นในรูปแบบเฉพาะเจาะจงที่เราต้องการ

ไปดูกันเลย

2. การเรียกใช้ฟังก์ชัน Gemini

Gemini Function Calling นั้นโดดเด่นในยุค Generative AI เนื่องจากให้คุณผสมผสานความยืดหยุ่นของโมเดลภาษาแบบ Generative เข้ากับการเขียนโปรแกรมแบบเดิมๆ ได้อย่างแม่นยำ

คุณต้องทำงานต่อไปนี้เพื่อใช้งานการเรียกใช้ฟังก์ชันของ Gemini

  1. กำหนดฟังก์ชัน: อธิบายฟังก์ชันต่างๆ อย่างชัดเจน คำอธิบายต้องมีข้อมูลต่อไปนี้
  • ชื่อของฟังก์ชัน เช่น getAddress
  • พารามิเตอร์ที่ฟังก์ชันคาดหวัง เช่น latlng เป็นสตริง
  • ประเภทของข้อมูลที่ฟังก์ชันแสดงผล เช่น รายการสตริงที่อยู่
  1. สร้างเครื่องมือสำหรับ Gemini: คำอธิบายฟังก์ชันแพ็กเกจในรูปแบบของข้อกำหนด API ลงในเครื่องมือ ให้คิดว่าเครื่องมือเป็นเหมือนกล่องเครื่องมือพิเศษที่ Gemini ใช้ในการทำความเข้าใจฟังก์ชันการทำงานของ API ได้
  2. จัดการ API โดยใช้ Gemini: เมื่อส่งพรอมต์ไปยัง 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. ข้อกำหนด

  • เบราว์เซอร์ เช่น Chrome หรือ Firefox
  • โปรเจ็กต์ Google Cloud ที่เปิดใช้การเรียกเก็บเงิน

4. ก่อนเริ่มต้น

  1. ในคอนโซล Google Cloud ให้เลือกหรือสร้างโปรเจ็กต์ 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 API ที่จำเป็นโดยเรียกใช้คำสั่งต่อไปนี้ใน 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 Editor
  2. คลิก Cloud Code แล้วขยายส่วน Cloud Functions
  3. คลิกไอคอนสร้างฟังก์ชัน (+)
  4. ในกล่องโต้ตอบสร้างแอปพลิเคชันใหม่ ให้เลือกตัวเลือก Java: Hello World
  5. ระบุชื่อโปรเจ็กต์ในเส้นทางโปรเจ็กต์ เช่น GeminiFunctionCalling
  6. คลิกExplorerเพื่อดูโครงสร้างโปรเจ็กต์แล้วเปิดไฟล์ pom.xml รูปภาพต่อไปนี้แสดงโครงสร้างโปรเจ็กต์

bdf07515f413dd9e.png

  1. เพิ่มทรัพยากร Dependency ที่จำเป็นภายในแท็ก <dependencies>... </dependencies> ในไฟล์ pom.xml คุณสามารถเข้าถึงทั้ง pom.xml ได้จากที่เก็บ GitHub ของโปรเจ็กต์นี้ คัดลอก pom.xml จากไฟล์ไปยังไฟล์ pom.xml ของโปรเจ็กต์ปัจจุบันที่คุณกำลังแก้ไข
  2. คัดลอกคลาส HelloWorld.java จากลิงก์ GeminiFunctionCalling github คุณต้องอัปเดต 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"
       }
     }
   }
 }
}

ส่งพารามิเตอร์ต่อไปนี้ไปยัง Reverse Geocoding API: "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 จะเก็บการตอบกลับจาก Reverse Geocoding API เอาต์พุตในเวอร์ชันต่อไปนี้คือเวอร์ชันที่มีการจัดรูปแบบ

"...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 และส่งคืนที่อยู่มาตรฐาน

โค้ดต่อไปนี้จะส่งเอาต์พุตที่ประมวลผลแล้วจากขั้นตอนก่อนหน้าเป็นพรอมต์ไปยัง 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 ทำงานกับกรณีการใช้งานเรื่องการกำหนดที่อยู่ให้เป็นมาตรฐานเดียวกันแล้ว คุณก็เริ่มทำให้ Cloud Function ใช้งานได้เลย

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 ให้ไปที่หน้าจัดการทรัพยากร
  2. ในรายการโปรเจ็กต์ ให้เลือกโปรเจ็กต์ที่ต้องการลบ แล้วคลิกลบ
  3. ในกล่องโต้ตอบ ให้พิมพ์รหัสโปรเจ็กต์ แล้วคลิกปิดเครื่องเพื่อลบโปรเจ็กต์
  4. หากต้องการเก็บโปรเจ็กต์ไว้ ให้ข้ามขั้นตอนข้างต้นและลบ Cloud Function โดยไปที่ Cloud Functions และจากรายการฟังก์ชัน ให้เลือกฟังก์ชันที่ต้องการลบ แล้วคลิก "ลบ"

9. ขอแสดงความยินดี

ยินดีด้วย คุณได้ใช้ฟีเจอร์การเรียกใช้ฟังก์ชันของ Gemini ในแอปพลิเคชัน Java และเปลี่ยนงาน Generative AI ให้เป็นกระบวนการที่เชื่อถือได้และน่าเชื่อถือเรียบร้อยแล้ว ดูข้อมูลเพิ่มเติมเกี่ยวกับโมเดลที่พร้อมใช้งานได้ที่เอกสารประกอบผลิตภัณฑ์ Vertex AI LLM