การสร้างข้อความ Generative AI ใน Java ด้วย PaLM และ LangChain4J

1. บทนำ

อัปเดตล่าสุด: 27-11-2023

Generative AI คืออะไร

Generative AI หรือปัญญาประดิษฐ์เชิงสร้างสรรค์หมายถึงการใช้ AI เพื่อสร้างเนื้อหาใหม่ๆ เช่น ข้อความ รูปภาพ เพลง เสียง และวิดีโอ

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

Generative AI ทำงานอย่างไร

Generative AI ทำงานโดยใช้โมเดล ML (แมชชีนเลิร์นนิง) เพื่อเรียนรู้รูปแบบและความสัมพันธ์ในชุดข้อมูลเนื้อหาที่มนุษย์สร้างขึ้น จากนั้นจะใช้รูปแบบที่ได้เรียนรู้มาเพื่อสร้างเนื้อหาใหม่

วิธีที่พบบ่อยที่สุดในการฝึกโมเดล Generative AI คือการใช้การเรียนรู้แบบมีผู้สอน โดยระบบจะให้ชุดเนื้อหาที่มนุษย์สร้างขึ้นและป้ายกำกับที่เกี่ยวข้องแก่โมเดล จากนั้นจะเรียนรู้การสร้างเนื้อหาที่คล้ายกับเนื้อหาที่มนุษย์สร้างขึ้นและติดป้ายกำกับเดียวกัน

แอปพลิเคชัน Generative AI ที่ใช้กันทั่วไปมีอะไรบ้าง

Generative AI ประมวลผลเนื้อหาจำนวนมากเพื่อสร้างข้อมูลเชิงลึกและคำตอบผ่านข้อความ รูปภาพ และรูปแบบที่ใช้งานง่าย Generative AI สามารถใช้เพื่อวัตถุประสงค์ต่อไปนี้

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

Google Cloud มีข้อเสนอ Generative AI อะไรบ้าง

Vertex AI ช่วยให้คุณโต้ตอบ ปรับแต่ง และฝังโมเดลพื้นฐานลงในแอปพลิเคชันได้โดยไม่ต้องมีความเชี่ยวชาญด้าน ML มากนัก เข้าถึงโมเดลพื้นฐานใน Model Garden ปรับแต่งโมเดลผ่าน UI ที่ใช้งานง่ายใน Generative AI Studio หรือใช้โมเดลใน Notebook ของ Data Science

Vertex AI Search and Conversation ช่วยให้นักพัฒนาแอปสร้างเครื่องมือค้นหาและแชทบอทที่ทำงานด้วย Generative AI ได้อย่างรวดเร็วที่สุด

และ Duet AI คือผู้ช่วยที่ทำงานร่วมกันด้วยระบบ AI ซึ่งพร้อมให้บริการใน Google Cloud และ IDE เพื่อช่วยให้คุณทำงานได้มากขึ้นและเร็วขึ้น

Codelab นี้มุ่งเน้นที่อะไร

โค้ดแล็บนี้มุ่งเน้นที่โมเดลภาษาขนาดใหญ่ (LLM) PaLM 2 ซึ่งโฮสต์อยู่ใน Vertex AI ของ Google Cloud ที่ครอบคลุมผลิตภัณฑ์และบริการแมชชีนเลิร์นนิงทั้งหมด

คุณจะใช้ Java เพื่อโต้ตอบกับ PaLM API ร่วมกับตัวจัดระเบียบเฟรมเวิร์ก LLM ของ LangChain4J คุณจะได้ดูตัวอย่างที่ชัดเจนต่างๆ เพื่อใช้ประโยชน์จาก LLM ในการตอบคำถาม การระดมความคิด การแยกเอนทิตีและเนื้อหาที่มีโครงสร้าง และการสรุป

ขอข้อมูลเพิ่มเติมเกี่ยวกับเฟรมเวิร์ก LangChain4J หน่อย

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

c6d7f7c3fd0d2951.png

สิ่งที่คุณจะได้เรียนรู้

  • วิธีตั้งค่าโปรเจ็กต์ Java เพื่อใช้ PaLM และ LangChain4J
  • วิธีเรียกใช้โมเดลข้อความ PaLM เป็นครั้งแรกเพื่อสร้างเนื้อหาและตอบคำถาม
  • วิธีดึงข้อมูลที่เป็นประโยชน์จากเนื้อหาที่ไม่มีโครงสร้าง (การดึงเอนทิตีหรือคีย์เวิร์ด, เอาต์พุตใน JSON)
  • วิธีแยกประเภทเนื้อหาหรือวิเคราะห์ความรู้สึกด้วยการแจ้งแบบ Few-Shot

สิ่งที่คุณต้องมี

  • ความรู้เกี่ยวกับภาษาโปรแกรม Java
  • โปรเจ็กต์ Google Cloud
  • เบราว์เซอร์ เช่น Chrome หรือ Firefox

2. การตั้งค่าและข้อกำหนด

การตั้งค่าสภาพแวดล้อมแบบเรียนรู้ด้วยตนเอง

  1. ลงชื่อเข้าใช้ Google Cloud Console แล้วสร้างโปรเจ็กต์ใหม่หรือใช้โปรเจ็กต์ที่มีอยู่ซ้ำ หากยังไม่มีบัญชี Gmail หรือ Google Workspace คุณต้องสร้างบัญชี

295004821bab6a87.png

37d264871000675d.png

96d86d3d5655cdbe.png

  • ชื่อโปรเจ็กต์คือชื่อที่แสดงสำหรับผู้เข้าร่วมโปรเจ็กต์นี้ ซึ่งเป็นสตริงอักขระที่ Google APIs ไม่ได้ใช้ คุณอัปเดตได้ทุกเมื่อ
  • รหัสโปรเจ็กต์จะไม่ซ้ำกันในโปรเจ็กต์ Google Cloud ทั้งหมดและเปลี่ยนแปลงไม่ได้ (เปลี่ยนไม่ได้หลังจากตั้งค่าแล้ว) Cloud Console จะสร้างสตริงที่ไม่ซ้ำกันโดยอัตโนมัติ ซึ่งโดยปกติแล้วคุณไม่จำเป็นต้องสนใจว่าสตริงนั้นคืออะไร ใน Codelab ส่วนใหญ่ คุณจะต้องอ้างอิงรหัสโปรเจ็กต์ (โดยทั่วไปจะระบุเป็น PROJECT_ID) หากไม่ชอบรหัสที่สร้างขึ้น คุณอาจสร้างรหัสแบบสุ่มอีกรหัสหนึ่งได้ หรือคุณอาจลองใช้ชื่อของคุณเองและดูว่ามีชื่อนั้นหรือไม่ คุณจะเปลี่ยนแปลงรหัสนี้หลังจากขั้นตอนนี้ไม่ได้ และรหัสจะคงอยู่ตลอดระยะเวลาของโปรเจ็กต์
  • โปรดทราบว่ายังมีค่าที่ 3 ซึ่งคือหมายเลขโปรเจ็กต์ที่ API บางตัวใช้ ดูข้อมูลเพิ่มเติมเกี่ยวกับค่าทั้ง 3 นี้ได้ในเอกสารประกอบ
  1. จากนั้นคุณจะต้องเปิดใช้การเรียกเก็บเงินใน Cloud Console เพื่อใช้ทรัพยากร/API ของ Cloud การทำตาม Codelab นี้จะไม่มีค่าใช้จ่ายมากนัก หรืออาจไม่มีค่าใช้จ่ายเลย หากต้องการปิดทรัพยากรเพื่อหลีกเลี่ยงการเรียกเก็บเงินนอกเหนือจากบทแนะนำนี้ คุณสามารถลบทรัพยากรที่สร้างขึ้นหรือลบโปรเจ็กต์ได้ ผู้ใช้ Google Cloud รายใหม่มีสิทธิ์เข้าร่วมโปรแกรมช่วงทดลองใช้ฟรีมูลค่า$300 USD

เริ่มต้น Cloud Shell

แม้ว่าคุณจะใช้งาน Google Cloud จากแล็ปท็อประยะไกลได้ แต่ใน Codelab นี้คุณจะใช้ Cloud Shell ซึ่งเป็นสภาพแวดล้อมบรรทัดคำสั่งที่ทำงานในระบบคลาวด์

เปิดใช้งาน Cloud Shell

  1. จาก Cloud Console ให้คลิกเปิดใช้งาน Cloud Shell d1264ca30785e435.png

cb81e7c8e34bc8d.png

หากคุณเริ่มใช้ Cloud Shell เป็นครั้งแรก คุณจะเห็นหน้าจอระดับกลางที่อธิบายว่า Cloud Shell คืออะไร หากเห็นหน้าจอระดับกลาง ให้คลิกต่อไป

d95252b003979716.png

การจัดสรรและเชื่อมต่อกับ Cloud Shell จะใช้เวลาไม่นาน

7833d5e1c5d18f54.png

เครื่องเสมือนนี้โหลดเครื่องมือพัฒนาซอฟต์แวร์ทั้งหมดที่จำเป็นไว้แล้ว โดยมีไดเรกทอรีหลักแบบถาวรขนาด 5 GB และทำงานใน Google Cloud ซึ่งช่วยเพิ่มประสิทธิภาพเครือข่ายและการตรวจสอบสิทธิ์ได้อย่างมาก คุณสามารถทำงานส่วนใหญ่หรือทั้งหมดในโค้ดแล็บนี้ได้ด้วยเบราว์เซอร์

เมื่อเชื่อมต่อกับ Cloud Shell แล้ว คุณควรเห็นว่าคุณได้รับการตรวจสอบสิทธิ์และระบบได้ตั้งค่าโปรเจ็กต์เป็นรหัสโปรเจ็กต์ของคุณ

  1. เรียกใช้คำสั่งต่อไปนี้ใน Cloud Shell เพื่อยืนยันว่าคุณได้รับการตรวจสอบสิทธิ์แล้ว
gcloud auth list

เอาต์พุตของคำสั่ง

 Credentialed Accounts
ACTIVE  ACCOUNT
*       <my_account>@<my_domain.com>

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. เรียกใช้คำสั่งต่อไปนี้ใน Cloud Shell เพื่อยืนยันว่าคำสั่ง gcloud รู้จักโปรเจ็กต์ของคุณ
gcloud config list project

เอาต์พุตของคำสั่ง

[core]
project = <PROJECT_ID>

หากไม่ได้ตั้งค่าไว้ คุณตั้งค่าได้ด้วยคำสั่งนี้

gcloud config set project <PROJECT_ID>

เอาต์พุตของคำสั่ง

Updated property [core/project].

3. การเตรียมความพร้อมสภาพแวดล้อมในการพัฒนา

ในโค้ดแล็บนี้ คุณจะได้ใช้เทอร์มินัล Cloud Shell และโปรแกรมแก้ไขโค้ดเพื่อพัฒนาโปรแกรม Java

เปิดใช้ Vertex AI API

  1. ในคอนโซล Google Cloud ให้ตรวจสอบว่าชื่อโปรเจ็กต์แสดงอยู่ที่ด้านบนของคอนโซล Google Cloud หากไม่ใช่ ให้คลิกเลือกโปรเจ็กต์เพื่อเปิดเครื่องมือเลือกโปรเจ็กต์ แล้วเลือกโปรเจ็กต์ที่ต้องการ
  2. หากไม่ได้อยู่ในส่วน Vertex AI ของคอนโซล Google Cloud ให้ทำดังนี้
  3. ในค้นหา ให้ป้อน Vertex AI แล้วกด Return
  4. ในผลการค้นหา ให้คลิก Vertex AI แดชบอร์ด Vertex AI จะปรากฏขึ้น
  5. คลิกเปิดใช้ API ที่แนะนำทั้งหมดในแดชบอร์ด Vertex AI

การดำเนินการนี้จะเปิดใช้ API หลายรายการ แต่ API ที่สำคัญที่สุดสำหรับ Codelab คือ aiplatform.googleapis.com ซึ่งคุณยังเปิดใช้ได้ในบรรทัดคำสั่งในเทอร์มินัล Cloud Shell โดยเรียกใช้คำสั่งต่อไปนี้

$ gcloud services enable aiplatform.googleapis.com

การสร้างโครงสร้างโปรเจ็กต์ด้วย Gradle

หากต้องการสร้างตัวอย่างโค้ด Java คุณจะต้องใช้เครื่องมือบิลด์ Gradle และ Java เวอร์ชัน 17 หากต้องการตั้งค่าโปรเจ็กต์ด้วย Gradle ให้สร้างไดเรกทอรี (ในที่นี้คือ palm-workshop) ในเทอร์มินัล Cloud Shell แล้วเรียกใช้คำสั่ง gradle init ในไดเรกทอรีนั้น

$ mkdir palm-workshop
$ cd palm-workshop

$ gradle init

Select type of project to generate:
  1: basic
  2: application
  3: library
  4: Gradle plugin
Enter selection (default: basic) [1..4] 2

Select implementation language:
  1: C++
  2: Groovy
  3: Java
  4: Kotlin
  5: Scala
  6: Swift
Enter selection (default: Java) [1..6] 3

Split functionality across multiple subprojects?:
  1: no - only one application project
  2: yes - application and library projects
Enter selection (default: no - only one application project) [1..2] 1

Select build script DSL:
  1: Groovy
  2: Kotlin
Enter selection (default: Groovy) [1..2] 1

Generate build using new APIs and behavior (some features may change in the next minor release)? (default: no) [yes, no] 

Select test framework:
  1: JUnit 4
  2: TestNG
  3: Spock
  4: JUnit Jupiter
Enter selection (default: JUnit Jupiter) [1..4] 4

Project name (default: palm-workshop): 
Source package (default: palm.workshop): 

> Task :init
Get more help with your project: https://docs.gradle.org/7.4/samples/sample_building_java_applications.html

BUILD SUCCESSFUL in 51s
2 actionable tasks: 2 executed

คุณจะสร้างแอปพลิเคชัน (ตัวเลือกที่ 2) โดยใช้ภาษา Java (ตัวเลือกที่ 3) โดยไม่ต้องใช้โปรเจ็กต์ย่อย (ตัวเลือกที่ 1) โดยใช้ไวยากรณ์ Groovy สำหรับไฟล์บิลด์ (ตัวเลือกที่ 1) ไม่ต้องใช้ฟีเจอร์บิลด์ใหม่ (ตัวเลือกที่ 0) สร้างการทดสอบด้วย JUnit Jupiter (ตัวเลือกที่ 4) และสำหรับชื่อโปรเจ็กต์ คุณสามารถใช้ palm-workshop และในทำนองเดียวกันสำหรับแพ็กเกจแหล่งที่มา คุณสามารถใช้ palm.workshop

โครงสร้างโปรเจ็กต์จะมีลักษณะดังนี้

├── gradle 
│   └── ...
├── gradlew 
├── gradlew.bat 
├── settings.gradle 
└── app
    ├── build.gradle 
    └── src
        ├── main
        │   └── java 
        │       └── palm
        │           └── workshop
        │               └── App.java
        └── test
            └── ...

มาอัปเดตไฟล์ app/build.gradle เพื่อเพิ่มทรัพยากร Dependency ที่จำเป็นกัน คุณสามารถนำการขึ้นต่อกัน guava ออกได้หากมีอยู่ แล้วแทนที่ด้วยการขึ้นต่อกันสำหรับโปรเจ็กต์ LangChain4J และไลบรารีบันทึกเพื่อหลีกเลี่ยงข้อความแจ้งเตือนว่าไม่มีเครื่องบันทึก

dependencies {
    // Use JUnit Jupiter for testing.
    testImplementation 'org.junit.jupiter:junit-jupiter:5.8.1'

    // Logging library
    implementation 'org.slf4j:slf4j-jdk14:2.0.9'

    // This dependency is used by the application.
    implementation 'dev.langchain4j:langchain4j-vertex-ai:0.24.0'
    implementation 'dev.langchain4j:langchain4j:0.24.0'
}

LangChain4J มีทรัพยากร Dependency 2 รายการ ได้แก่

  • หนึ่งในโปรเจ็กต์หลัก
  • และอีก 1 รายการสำหรับโมดูล Vertex AI โดยเฉพาะ

หากต้องการใช้ Java 17 ในการคอมไพล์และเรียกใช้โปรแกรม ให้เพิ่มบล็อกต่อไปนี้ใต้บล็อก plugins {}

java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(17)
    }
}

อีกอย่างที่ต้องเปลี่ยนคือ อัปเดตบล็อก application ของ app/build.gradle เพื่อให้ผู้ใช้ลบล้างคลาสหลักเพื่อเรียกใช้ในบรรทัดคำสั่งได้เมื่อเรียกใช้เครื่องมือบิลด์

application {
    mainClass = providers.systemProperty('javaMainClass')
                         .orElse('palm.workshop.App')
}

หากต้องการตรวจสอบว่าไฟล์บิลด์พร้อมที่จะเรียกใช้แอปพลิเคชันแล้ว คุณสามารถเรียกใช้คลาสหลักเริ่มต้นซึ่งจะพิมพ์ข้อความ Hello World! อย่างง่ายได้ดังนี้

$ ./gradlew run -DjavaMainClass=palm.workshop.App

> Task :app:run
Hello World!

BUILD SUCCESSFUL in 3s
2 actionable tasks: 2 executed

ตอนนี้คุณก็พร้อมที่จะเขียนโปรแกรมด้วยโมเดลข้อความภาษาขนาดใหญ่ PaLM โดยใช้โปรเจ็กต์ LangChain4J แล้ว

เพื่อเป็นข้อมูลอ้างอิง ตอนนี้ไฟล์บิลด์ app/build.gradle แบบเต็มควรมีลักษณะดังนี้

plugins {
    // Apply the application plugin to add support for building a CLI application in Java.
    id 'application'
}

java {
    toolchain {
        // Ensure we compile and run on Java 17
        languageVersion = JavaLanguageVersion.of(17)
    }
}

repositories {
    // Use Maven Central for resolving dependencies.
    mavenCentral()
}

dependencies {
    // Use JUnit Jupiter for testing.
    testImplementation 'org.junit.jupiter:junit-jupiter:5.8.1'

    // This dependency is used by the application.
    implementation 'dev.langchain4j:langchain4j-vertex-ai:0.24.0'
    implementation 'dev.langchain4j:langchain4j:0.24.0'
    implementation 'org.slf4j:slf4j-jdk14:2.0.9'
}

application {
    mainClass = providers.systemProperty('javaMainClass').orElse('palm.workshop.App')
}

tasks.named('test') {
    // Use JUnit Platform for unit tests.
    useJUnitPlatform()
}

4. การเรียกใช้โมเดลข้อความของ PaLM เป็นครั้งแรก

เมื่อตั้งค่าโปรเจ็กต์อย่างถูกต้องแล้ว ก็ถึงเวลาเรียกใช้ PaLM API

สร้างคลาสใหม่ชื่อ TextPrompts.java ในไดเรกทอรี app/src/main/java/palm/workshop (ข้างคลาส App.java เริ่มต้น) แล้วพิมพ์เนื้อหาต่อไปนี้

package palm.workshop;

import dev.langchain4j.model.output.Response;
import dev.langchain4j.model.vertexai.VertexAiLanguageModel;

public class TextPrompts {
    public static void main(String[] args) {
        VertexAiLanguageModel model = VertexAiLanguageModel.builder()
            .endpoint("us-central1-aiplatform.googleapis.com:443")
            .project("YOUR_PROJECT_ID")
            .location("us-central1")
            .publisher("google")
            .modelName("text-bison@001")
            .maxOutputTokens(500)
            .build();

        Response<String> response = model.generate("What are large language models?");

        System.out.println(response.content());
    }
}

ในตัวอย่างแรกนี้ คุณต้องนำเข้าคลาส Response และโมเดลภาษา Vertex AI สำหรับ PaLM

จากนั้นในเมธอด main คุณจะต้องกำหนดค่าโมเดลภาษาโดยใช้เครื่องมือสร้างสำหรับ VertexAiLanguageModel เพื่อระบุสิ่งต่อไปนี้

  • อุปกรณ์ปลายทาง
  • โปรเจ็กต์
  • ภูมิภาค
  • ผู้เผยแพร่โฆษณา
  • และชื่อของโมเดล (text-bison@001)

เมื่อโมเดลภาษาพร้อมแล้ว คุณจะเรียกใช้เมธอด generate() และส่ง "พรอมต์" (เช่น คำถามหรือคำสั่งที่จะส่งไปยัง LLM) ได้ ในที่นี้ คุณถามคำถามง่ายๆ เกี่ยวกับ LLM แต่คุณสามารถเปลี่ยนพรอมต์นี้เพื่อลองถามคำถามหรือทำงานอื่นๆ ได้

หากต้องการเรียกใช้คลาสนี้ ให้เรียกใช้คำสั่งต่อไปนี้ในเทอร์มินัล Cloud Shell

./gradlew run -DjavaMainClass=palm.workshop.TextPrompts

คุณควรเห็นเอาต์พุตที่คล้ายกับเอาต์พุตนี้

Large language models (LLMs) are artificial intelligence systems that can understand and generate human language. They are trained on massive datasets of text and code, and can learn to perform a wide variety of tasks, such as translating languages, writing different kinds of creative content, and answering your questions in an informative way.

LLMs are still under development, but they have the potential to revolutionize many industries. For example, they could be used to create more accurate and personalized customer service experiences, to help doctors diagnose and treat diseases, and to develop new forms of creative expression.

However, LLMs also raise a number of ethical concerns. For example, they could be used to create fake news and propaganda, to manipulate people's behavior, and to invade people's privacy. It is important to carefully consider the potential risks and benefits of LLMs before they are widely used.

Here are some of the key features of LLMs:

* They are trained on massive datasets of text and code.
* They can learn to perform a wide variety of tasks, such as translating languages, writing different kinds of creative content, and answering your questions in an informative way.
* They are still under development, but they have the potential to revolutionize many industries.
* They raise a number of ethical concerns, such as the potential for fake news, propaganda, and invasion of privacy.

VertexAILanguageModelเครื่องมือสร้างช่วยให้คุณกำหนดพารามิเตอร์ที่ไม่บังคับซึ่งมีค่าเริ่มต้นอยู่แล้วบางค่าที่คุณลบล้างได้ ตัวอย่างเช่น

  • .temperature(0.2) เพื่อกำหนดระดับความสร้างสรรค์ของคำตอบ (0 คือระดับความสร้างสรรค์ต่ำและมักจะอิงตามข้อเท็จจริงมากกว่า ส่วน 1 คือระดับความสร้างสรรค์สูงกว่า)
  • .maxOutputTokens(50) — ในตัวอย่างนี้ มีการขอโทเค็น 500 รายการ (โทเค็น 3 รายการเทียบเท่ากับคำ 4 คำโดยประมาณ) ทั้งนี้ขึ้นอยู่กับความยาวของคำตอบที่ต้องการ
  • .topK(20) — เพื่อเลือกคำแบบสุ่มจากจำนวนคำที่เป็นไปได้สูงสุดสำหรับการเติมข้อความ (ตั้งแต่ 1 ถึง 40)
  • .topP(0.95) — เพื่อเลือกคำที่เป็นไปได้ซึ่งมีความน่าจะเป็นรวมกันเท่ากับจำนวนทศนิยมนั้น (ระหว่าง 0 ถึง 1)
  • .maxRetries(3) — ในกรณีที่คุณเรียกใช้เกินโควต้าคำขอต่อเวลา คุณสามารถให้โมเดลลองเรียกใช้ซ้ำ 3 ครั้งได้ เช่น

โมเดลภาษาขนาดใหญ่มีประสิทธิภาพสูงมาก สามารถตอบคำถามที่ซับซ้อน และรับมือกับงานที่น่าสนใจได้หลากหลาย ในส่วนถัดไป เราจะมาดูงานที่มีประโยชน์ นั่นคือการแยกข้อมูลที่มีโครงสร้างจากข้อความ

5. การดึงข้อมูลจากข้อความแบบไม่มีโครงสร้าง

ในส่วนก่อนหน้า คุณได้สร้างเอาต์พุตข้อความบางส่วน ซึ่งก็ใช้ได้หากคุณต้องการแสดงเอาต์พุตนี้ต่อผู้ใช้ปลายทางโดยตรง แต่หากต้องการดึงข้อมูลที่กล่าวถึงในเอาต์พุตนี้ คุณจะดึงข้อมูลดังกล่าวจากข้อความที่ไม่มีโครงสร้างได้อย่างไร

สมมติว่าคุณต้องการดึงชื่อและอายุของบุคคลจากประวัติหรือคำอธิบายของบุคคลนั้น คุณสามารถสั่งให้โมเดลภาษาขนาดใหญ่สร้างโครงสร้างข้อมูล JSON ได้โดยการปรับพรอมต์ดังนี้ (โดยทั่วไปเรียกว่า"การออกแบบพรอมต์")

Extract the name and age of the person described below.

Return a JSON document with a "name" and an "age" property, 
following this structure: {"name": "John Doe", "age": 34}
Return only JSON, without any markdown markup surrounding it.

Here is the document describing the person:
---
Anna is a 23 year old artist based in Brooklyn, New York. She was 
born and raised in the suburbs of Chicago, where she developed a 
love for art at a young age. She attended the School of the Art 
Institute of Chicago, where she studied painting and drawing. 
After graduating, she moved to New York City to pursue her art career. 
Anna's work is inspired by her personal experiences and observations 
of the world around her. She often uses bright colors and bold lines 
to create vibrant and energetic paintings. Her work has been 
exhibited in galleries and museums in New York City and Chicago.
---

JSON: 

แก้ไขmodel.generate()การเรียกใช้ในคลาส TextPrompts เพื่อส่งพรอมต์ข้อความทั้งหมดด้านบน

Response<String> response = model.generate("""
    Extract the name and age of the person described below.
    Return a JSON document with a "name" and an "age" property, \
    following this structure: {"name": "John Doe", "age": 34}
    Return only JSON, without any markdown markup surrounding it.
    Here is the document describing the person:
    ---
    Anna is a 23 year old artist based in Brooklyn, New York. She was born and 
    raised in the suburbs of Chicago, where she developed a love for art at a 
    young age. She attended the School of the Art Institute of Chicago, where 
    she studied painting and drawing. After graduating, she moved to New York 
    City to pursue her art career. Anna's work is inspired by her personal 
    experiences and observations of the world around her. She often uses bright 
    colors and bold lines to create vibrant and energetic paintings. Her work 
    has been exhibited in galleries and museums in New York City and Chicago.    
    ---
    JSON: 
    """
);

หากเรียกใช้พรอมต์นี้ในคลาส TextPrompts ของเรา พรอมต์ควรแสดงสตริง JSON ต่อไปนี้ ซึ่งคุณสามารถแยกวิเคราะห์ได้ด้วยโปรแกรมแยกวิเคราะห์ JSON เช่น ไลบรารี GSON

$ ./gradlew run -DjavaMainClass=palm.workshop.TextPrompts

> Task :app:run
{"name": "Anna", "age": 23}

BUILD SUCCESSFUL in 24s
2 actionable tasks: 1 executed, 1 up-to-date

ได้ Anna อายุ 23 ปีแล้ว

6. เทมเพลตพรอมต์และพรอมต์ที่มีโครงสร้าง

นอกเหนือจากการตอบคำถาม

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

  • การแปล - "แปลประโยคต่อไปนี้เป็นภาษาฝรั่งเศส: YOUR_SENTENCE_HERE"
  • การสรุป - "สรุปเอกสารต่อไปนี้: วางเอกสาร"
  • การสร้างครีเอทีฟโฆษณา - "เขียนบทกวีเกี่ยวกับ TOPIC_OF_THE_POEM"
  • การเขียนโปรแกรม - "วิธีเขียนฟังก์ชัน Fibonacci ใน PROGRAMMING_LANGUAGE"

เทมเพลตพรอมต์

หากคุณลองใช้พรอมต์ข้างต้นสำหรับการแปล การสรุป การสร้างครีเอทีฟโฆษณา หรือการเขียนโปรแกรม คุณจะแทนที่ค่าตัวยึดตำแหน่งด้วยไอเดียของคุณเอง แต่คุณยังใช้ประโยชน์จาก"เทมเพลตพรอมต์" ได้ด้วย ซึ่งจะช่วยให้คุณกำหนดค่าตัวยึดตำแหน่งเหล่านั้น และป้อนข้อมูลลงในช่องว่างได้ในภายหลัง

มาดูพรอมต์ที่น่าสนใจและสร้างสรรค์กันโดยแทนที่เนื้อหาทั้งหมดของเมธอด main() ด้วยโค้ดต่อไปนี้

VertexAiLanguageModel model = VertexAiLanguageModel.builder()
            .endpoint("us-central1-aiplatform.googleapis.com:443")
            .project("YOUR_PROJECT_ID")
            .location("us-central1")
            .publisher("google")
            .modelName("text-bison@001")
            .maxOutputTokens(300)
            .build();

PromptTemplate promptTemplate = PromptTemplate.from("""
    Create a recipe for a {{dish}} with the following ingredients: \
    {{ingredients}}, and give it a name.
    """
);

Map<String, Object> variables = new HashMap<>();
variables.put("dish", "dessert");
variables.put("ingredients", "strawberries, chocolate, whipped cream");

Prompt prompt = promptTemplate.apply(variables);

Response<String> response = model.generate(prompt);

System.out.println(response.content());

และเพิ่มการนำเข้าต่อไปนี้

import dev.langchain4j.model.input.Prompt;
import dev.langchain4j.model.input.PromptTemplate;

import java.util.HashMap;
import java.util.Map;

จากนั้นเรียกใช้แอปพลิเคชันอีกครั้ง เอาต์พุตควรมีลักษณะดังนี้

$ ./gradlew run -DjavaMainClass=palm.workshop.TextPrompts

> Task :app:run
**Strawberry Shortcake**

Ingredients:

* 1 pint strawberries, hulled and sliced
* 1/2 cup sugar
* 1/4 cup cornstarch
* 1/4 cup water
* 1 tablespoon lemon juice
* 1/2 cup heavy cream, whipped
* 1/4 cup confectioners' sugar
* 1/4 teaspoon vanilla extract
* 6 graham cracker squares, crushed

Instructions:

1. In a medium saucepan, combine the strawberries, sugar, cornstarch, water, and lemon juice. Bring to a boil over medium heat, stirring constantly. Reduce heat and simmer for 5 minutes, or until the sauce has thickened.
2. Remove from heat and let cool slightly.
3. In a large bowl, combine the whipped cream, confectioners' sugar, and vanilla extract. Beat until soft peaks form.
4. To assemble the shortcakes, place a graham cracker square on each of 6 dessert plates. Top with a scoop of whipped cream, then a spoonful of strawberry sauce. Repeat layers, ending with a graham cracker square.
5. Serve immediately.

**Tips:**

* For a more elegant presentation, you can use fresh strawberries instead of sliced strawberries.
* If you don't have time to make your own whipped cream, you can use store-bought whipped cream.

อร่อย

เทมเพลตพรอมต์ช่วยให้คุณป้อนพารามิเตอร์ที่จำเป็นก่อนเรียกใช้เมธอดการสร้างข้อความได้ ซึ่งเป็นวิธีที่ยอดเยี่ยมในการส่งข้อมูลและปรับแต่งพรอมต์สำหรับค่าต่างๆ ที่ผู้ใช้ระบุ

ดังที่ชื่อของคลาสระบุไว้ คลาส PromptTemplate จะสร้างพรอมต์เทมเพลต และคุณสามารถกำหนดค่าให้กับองค์ประกอบตัวยึดตำแหน่งได้โดยใช้แผนที่ของชื่อและค่าตัวยึดตำแหน่ง

พรอมต์ที่มีโครงสร้าง (ไม่บังคับ)

อีกวิธีในการจัดโครงสร้างพรอมต์คือใช้@StructuredPromptคำอธิบายประกอบ หากต้องการใช้วิธีการที่เน้นออบเจ็กต์มากขึ้น คุณใส่คำอธิบายประกอบในคลาสด้วยคำอธิบายประกอบนี้ และฟิลด์ของคลาสจะสอดคล้องกับตัวยึดตำแหน่งที่กำหนดไว้ในพรอมต์ มาดูการทำงานกัน

ก่อนอื่น เราต้องนำเข้าใหม่ดังนี้

import java.util.Arrays;
import java.util.List;
import dev.langchain4j.model.input.structured.StructuredPrompt;
import dev.langchain4j.model.input.structured.StructuredPromptProcessor;

จากนั้นเราจะสร้างคลาสแบบคงที่ภายในคลาส TextPrompts ซึ่งรวบรวมข้อมูลที่จำเป็นเพื่อส่งในตัวยึดตำแหน่งในพรอมต์ที่อธิบายไว้ในคำอธิบายประกอบ @StructuredPrompt ได้

@StructuredPrompt("Create a recipe of a {{dish}} that can be prepared using only {{ingredients}}")
static class RecipeCreationPrompt {
    String dish;
    List<String> ingredients;
}

จากนั้นสร้างอินสแตนซ์ของคลาสใหม่นั้นและป้อนอาหารและส่วนผสมของสูตรอาหารของเรา สร้างและส่งพรอมต์ไปยังเมธอด generate() เหมือนเดิม

RecipeCreationPrompt createRecipePrompt = new RecipeCreationPrompt();
createRecipePrompt.dish = "salad";
createRecipePrompt.ingredients = Arrays.asList("cucumber", "tomato", "feta", "onion", "olives");
Prompt prompt = StructuredPromptProcessor.toPrompt(createRecipePrompt);

Response<String> response = model.generate(prompt);

คุณสามารถใช้ออบเจ็กต์ Java ที่มีฟิลด์ซึ่ง IDE สามารถเติมข้อความอัตโนมัติได้ในลักษณะที่ปลอดภัยต่อประเภทมากกว่า แทนที่จะเติมช่องว่างผ่านแผนที่

นี่คือโค้ดทั้งหมดหากคุณต้องการวางการเปลี่ยนแปลงเหล่านั้นลงในคลาส TextPrompts ได้ง่ายขึ้น

package palm.workshop;

import java.util.Arrays;
import java.util.List;
import dev.langchain4j.model.input.Prompt;
import dev.langchain4j.model.output.Response;
import dev.langchain4j.model.vertexai.VertexAiLanguageModel;
import dev.langchain4j.model.input.structured.StructuredPrompt;
import dev.langchain4j.model.input.structured.StructuredPromptProcessor;

public class TextPrompts {

    @StructuredPrompt("Create a recipe of a {{dish}} that can be prepared using only {{ingredients}}")
    static class RecipeCreationPrompt {
        String dish;
        List<String> ingredients;
    }
    public static void main(String[] args) {
        VertexAiLanguageModel model = VertexAiLanguageModel.builder()
            .endpoint("us-central1-aiplatform.googleapis.com:443")
            .project("YOUR_PROJECT_ID")
            .location("us-central1")
            .publisher("google")
            .modelName("text-bison@001")
            .maxOutputTokens(300)
            .build();

        RecipeCreationPrompt createRecipePrompt = new RecipeCreationPrompt();
        createRecipePrompt.dish = "salad";
        createRecipePrompt.ingredients = Arrays.asList("cucumber", "tomato", "feta", "onion", "olives");
        Prompt prompt = StructuredPromptProcessor.toPrompt(createRecipePrompt);

        Response<String> response = model.generate(prompt);
        
        System.out.println(response.content());
    }
}

7. การจัดประเภทข้อความและการวิเคราะห์ความรู้สึก

เช่นเดียวกับที่ได้เรียนรู้ในส่วนก่อนหน้า คุณจะได้ค้นพบเทคนิค "การออกแบบพรอมต์" อีกอย่างหนึ่งเพื่อทำให้โมเดล PaLM จัดประเภทข้อความหรือวิเคราะห์ความรู้สึก มาพูดถึง "Few-Shot Prompting" กัน ซึ่งเป็นวิธีปรับปรุงพรอมต์ด้วยตัวอย่างเล็กๆ น้อยๆ ที่จะช่วยนำโมเดลภาษาไปในทิศทางที่คุณต้องการ เพื่อให้เข้าใจความตั้งใจของคุณได้ดียิ่งขึ้น

มาปรับTextPromptsคลาสของเราเพื่อใช้ประโยชน์จากเทมเพลตพรอมต์กัน

package palm.workshop;

import java.util.Map;

import dev.langchain4j.model.output.Response;
import dev.langchain4j.model.vertexai.VertexAiLanguageModel;
import dev.langchain4j.model.input.Prompt;
import dev.langchain4j.model.input.PromptTemplate;

public class TextPrompts {
    public static void main(String[] args) {
        VertexAiLanguageModel model = VertexAiLanguageModel.builder()
            .endpoint("us-central1-aiplatform.googleapis.com:443")
            .project("YOUR_PROJECT_ID")
            .location("us-central1")
            .publisher("google")
            .modelName("text-bison@001")
            .maxOutputTokens(10)
            .build();

        PromptTemplate promptTemplate = PromptTemplate.from("""
            Analyze the sentiment of the text below. Respond only with one word to describe the sentiment.

            INPUT: This is fantastic news!
            OUTPUT: POSITIVE

            INPUT: Pi is roughly equal to 3.14
            OUTPUT: NEUTRAL

            INPUT: I really disliked the pizza. Who would use pineapples as a pizza topping?
            OUTPUT: NEGATIVE

            INPUT: {{text}}
            OUTPUT: 
            """);

        Prompt prompt = promptTemplate.apply(
            Map.of("text", "I love strawberries!"));

        Response<String> response = model.generate(prompt);

        System.out.println(response.content());
    }
}

สังเกตแนวทางการเสนอตัวอย่างอินพุตและเอาต์พุต 2-3 รายการในพรอมต์ นี่คือ "ตัวอย่างเล็กๆ น้อยๆ" ที่ช่วยให้ LLM ทำตามโครงสร้างเดียวกันได้ เมื่อโมเดลได้รับอินพุตแล้ว โมเดลจะต้องการแสดงผลเอาต์พุตที่ตรงกับรูปแบบอินพุต/เอาต์พุต

การเรียกใช้โปรแกรมควรแสดงเฉพาะคำว่า POSITIVE เนื่องจากสตรอว์เบอร์รีก็อร่อยเช่นกัน

$ ./gradlew run -DjavaMainClass=palm.workshop.TextPrompts

> Task :app:run
POSITIVE

การวิเคราะห์ความรู้สึกยังเป็นสถานการณ์การแยกประเภทเนื้อหาด้วย คุณสามารถใช้แนวทาง "การแจ้งแบบไม่กี่นัด" เดียวกันนี้เพื่อจัดหมวดหมู่เอกสารต่างๆ ลงในที่เก็บหมวดหมู่ต่างๆ ได้

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

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

สิ่งต่อไปที่ควรทำ

ลองใช้ Codelab ต่อไปนี้เพื่อดูข้อมูลเพิ่มเติมเกี่ยวกับ PaLM ใน Java

อ่านเพิ่มเติม

เอกสารอ้างอิง