1. บทนำ
โมเดล Generative AI นั้นโดดเด่นในเรื่องการทำความเข้าใจและตอบสนองต่อภาษาที่เป็นธรรมชาติ แต่หากคุณต้องการผลลัพธ์ที่แม่นยำและคาดการณ์ได้สำหรับงานสำคัญๆ เช่น การกำหนดมาตรฐานที่อยู่ บางครั้งโมเดล Generative แบบเดิมจะให้คำตอบที่ต่างกันได้ในช่วงเวลาที่แตกต่างกันสำหรับพรอมต์เดียวกัน ซึ่งอาจทำให้เกิดความไม่สอดคล้องกันได้ และนั่นคือจุดที่ความสามารถในการเรียกใช้ฟังก์ชันของ Gemini โดดเด่น โดยให้คุณควบคุมองค์ประกอบการตอบสนองของ AI ตามที่กำหนดไว้ได้
Codelab นี้แสดงแนวคิดนี้พร้อมกับกรณีการใช้งานการกรอกที่อยู่และการกำหนดมาตรฐาน สำหรับกรณีนี้ เราจะสร้าง Java Cloud Function ที่ทำหน้าที่ต่อไปนี้
- ต้องใช้พิกัดละติจูดและลองจิจูด
- เรียกใช้ Google Maps Geocoding API เพื่อรับที่อยู่ที่เกี่ยวข้อง
- ใช้ฟีเจอร์การเรียกใช้ฟังก์ชัน Gemini 1.0 Pro เพื่อสร้างมาตรฐานและสรุปที่อยู่เหล่านั้นในรูปแบบเฉพาะเจาะจงที่เราต้องการ
ไปดูกันเลย
2. การเรียกใช้ฟังก์ชัน Gemini
Gemini Function Calling นั้นโดดเด่นในยุค Generative AI เนื่องจากให้คุณผสมผสานความยืดหยุ่นของโมเดลภาษาแบบ Generative เข้ากับการเขียนโปรแกรมแบบเดิมๆ ได้อย่างแม่นยำ
คุณต้องทำงานต่อไปนี้เพื่อใช้งานการเรียกใช้ฟังก์ชันของ Gemini
- กำหนดฟังก์ชัน: อธิบายฟังก์ชันต่างๆ อย่างชัดเจน คำอธิบายต้องมีข้อมูลต่อไปนี้
- ชื่อของฟังก์ชัน เช่น
getAddress
- พารามิเตอร์ที่ฟังก์ชันคาดหวัง เช่น
latlng
เป็นสตริง - ประเภทของข้อมูลที่ฟังก์ชันแสดงผล เช่น รายการสตริงที่อยู่
- สร้างเครื่องมือสำหรับ Gemini: คำอธิบายฟังก์ชันแพ็กเกจในรูปแบบของข้อกำหนด API ลงในเครื่องมือ ให้คิดว่าเครื่องมือเป็นเหมือนกล่องเครื่องมือพิเศษที่ Gemini ใช้ในการทำความเข้าใจฟังก์ชันการทำงานของ API ได้
- จัดการ API โดยใช้ Gemini: เมื่อส่งพรอมต์ไปยัง Gemini Gemini จะวิเคราะห์คำขอและจดจำตำแหน่งที่สามารถใช้เครื่องมือที่คุณให้ไว้ จากนั้น Gemini จะทำหน้าที่เป็นออร์เชสเตอร์อัจฉริยะด้วยการดำเนินการต่อไปนี้
- สร้างพารามิเตอร์ API ที่จำเป็นในการเรียกใช้ฟังก์ชันที่กำหนดไว้ Gemini จะไม่เรียกใช้ API ในนามของคุณ คุณต้องเรียกใช้ API ตามพารามิเตอร์และลายเซ็นที่การเรียกใช้ฟังก์ชัน Gemini สร้างขึ้นสำหรับคุณ
- Gemini จะประมวลผลผลลัพธ์ด้วยการป้อนผลลัพธ์จากการเรียก API ของคุณกลับไปยังการสร้าง และรวมข้อมูลที่มีโครงสร้างลงในคำตอบสุดท้าย โดยประมวลผลข้อมูลนี้ในแบบที่ต้องการ
รูปภาพต่อไปนี้แสดงโฟลว์ข้อมูล ขั้นตอนที่เกี่ยวข้องในการใช้งาน และเจ้าของแต่ละขั้นตอน เช่น แอปพลิเคชัน, LLM หรือ API
สิ่งที่คุณจะสร้าง
คุณจะสร้างและทำให้ Java Cloud Function ใช้งานได้ซึ่งทำสิ่งต่อไปนี้
- ต้องใช้พิกัดละติจูดและลองจิจูด
- เรียกใช้ Google Maps Geocoding API เพื่อรับที่อยู่ที่เกี่ยวข้อง
- ใช้ฟีเจอร์การเรียกใช้ฟังก์ชัน Gemini 1.0 Pro เพื่อสร้างมาตรฐานและสรุปที่อยู่เหล่านั้นในรูปแบบที่เฉพาะเจาะจง
3. ข้อกำหนด
4. ก่อนเริ่มต้น
- ในคอนโซล Google Cloud ให้เลือกหรือสร้างโปรเจ็กต์ Google Cloud ในหน้าตัวเลือกโปรเจ็กต์
- ตรวจสอบว่าเปิดใช้การเรียกเก็บเงินสำหรับโปรเจ็กต์ Google Cloud แล้ว ดูวิธีตรวจสอบว่าเปิดใช้การเรียกเก็บเงินในโปรเจ็กต์แล้ว
- เปิดใช้งาน Cloud Shell จากคอนโซล Google Cloud โปรดดูข้อมูลเพิ่มเติมที่ใช้ Cloud Shell
- หากไม่ได้ตั้งค่าโปรเจ็กต์ไว้ ให้ใช้คำสั่งต่อไปนี้เพื่อตั้งค่าโปรเจ็กต์
gcloud config set project <YOUR_PROJECT_ID>
- ใน Cloud Shell ให้ตั้งค่าตัวแปรสภาพแวดล้อมต่อไปนี้
export GCP_PROJECT=<YOUR_PROJECT_ID>
export GCP_REGION=us-central1
- เปิดใช้ 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
- เปิด Cloud Shell Editor คลิกส่วนขยาย แล้วติดตั้งส่วนขยาย Gemini + Google Cloud Code
5. ใช้งาน Cloud Function
- เปิด Cloud Shell Editor
- คลิก Cloud Code แล้วขยายส่วน Cloud Functions
- คลิกไอคอนสร้างฟังก์ชัน (+)
- ในกล่องโต้ตอบสร้างแอปพลิเคชันใหม่ ให้เลือกตัวเลือก Java: Hello World
- ระบุชื่อโปรเจ็กต์ในเส้นทางโปรเจ็กต์ เช่น GeminiFunctionCalling
- คลิกExplorerเพื่อดูโครงสร้างโปรเจ็กต์แล้วเปิดไฟล์ pom.xml รูปภาพต่อไปนี้แสดงโครงสร้างโปรเจ็กต์
- เพิ่มทรัพยากร Dependency ที่จำเป็นภายในแท็ก
<dependencies>... </dependencies>
ในไฟล์pom.xml
คุณสามารถเข้าถึงทั้งpom.xml
ได้จากที่เก็บ GitHub ของโปรเจ็กต์นี้ คัดลอก pom.xml จากไฟล์ไปยังไฟล์pom.xml
ของโปรเจ็กต์ปัจจุบันที่คุณกำลังแก้ไข - คัดลอกคลาส
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. ทำให้ใช้งานได้และทดสอบ
- หากคุณได้สร้างโปรเจ็กต์ GeminiFunctionCalling และใช้งาน Cloud Function แล้ว ให้ไปยังขั้นตอนที่ 2 หากยังไม่ได้สร้างโปรเจ็กต์ ให้ไปที่เทอร์มินัล Cloud Shell แล้วโคลนที่เก็บนี้:
git clone
https://github.com/AbiramiSukumaran/GeminiFunctionCalling - ไปยังโฟลเดอร์โปรเจ็กต์:
cd GeminiFunctionCalling
- เรียกใช้คำสั่งต่อไปนี้เพื่อสร้างและทำให้ 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
- ทดสอบ 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 สำหรับทรัพยากรที่ใช้ในโพสต์นี้
- ในคอนโซล Google Cloud ให้ไปที่หน้าจัดการทรัพยากร
- ในรายการโปรเจ็กต์ ให้เลือกโปรเจ็กต์ที่ต้องการลบ แล้วคลิกลบ
- ในกล่องโต้ตอบ ให้พิมพ์รหัสโปรเจ็กต์ แล้วคลิกปิดเครื่องเพื่อลบโปรเจ็กต์
- หากต้องการเก็บโปรเจ็กต์ไว้ ให้ข้ามขั้นตอนข้างต้นและลบ Cloud Function โดยไปที่ Cloud Functions และจากรายการฟังก์ชัน ให้เลือกฟังก์ชันที่ต้องการลบ แล้วคลิก "ลบ"
9. ขอแสดงความยินดี
ยินดีด้วย คุณได้ใช้ฟีเจอร์การเรียกใช้ฟังก์ชันของ Gemini ในแอปพลิเคชัน Java และเปลี่ยนงาน Generative AI ให้เป็นกระบวนการที่เชื่อถือได้และน่าเชื่อถือเรียบร้อยแล้ว ดูข้อมูลเพิ่มเติมเกี่ยวกับโมเดลที่พร้อมใช้งานได้ที่เอกสารประกอบผลิตภัณฑ์ Vertex AI LLM