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 โดดเด่นในยุค Generative AI เนื่องจากช่วยให้คุณผสมผสานความยืดหยุ่นของโมเดลภาษา Generative เข้ากับความแม่นยำของการเขียนโปรแกรมแบบเดิมได้

คุณต้องทํางานต่อไปนี้ให้เสร็จสมบูรณ์เพื่อใช้การเรียกใช้ฟังก์ชันของ 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

สิ่งที่คุณจะสร้าง

คุณจะสร้างและทำให้ Cloud Function ของ Java ใช้งานได้ ซึ่งจะทำสิ่งต่อไปนี้

  • รับพิกัดละติจูดและลองจิจูด
  • เรียก 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 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 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 ด้วยคีย์ Geocoding API และรหัสโปรเจ็กต์ Google Cloud ตามลำดับ

6. ทำความเข้าใจการเรียกใช้ฟังก์ชันโดยใช้คลาส HelloWorld.java

อินพุตของพรอมต์

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