แชทที่ทำงานด้วยระบบ Generative AI กับผู้ใช้และเอกสารใน Java ด้วย PaLM และ LangChain4J

1. บทนำ

อัปเดตล่าสุด: 05-02-2024

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

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

  • ความรู้เกี่ยวกับภาษาโปรแกรม 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

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

package palm.workshop;

import dev.langchain4j.model.vertexai.VertexAiChatModel;
import dev.langchain4j.chain.ConversationalChain;

public class ChatPrompts {
    public static void main(String[] args) {
        VertexAiChatModel model = VertexAiChatModel.builder()
            .endpoint("us-central1-aiplatform.googleapis.com:443")
            .project("YOUR_PROJECT_ID")
            .location("us-central1")
            .publisher("google")
            .modelName("chat-bison@001")
            .maxOutputTokens(400)
            .maxRetries(3)
            .build();

        ConversationalChain chain = ConversationalChain.builder()
            .chatLanguageModel(model)
            .build();

        String message = "What are large language models?";
        String answer = chain.execute(message);
        System.out.println(answer);

        System.out.println("---------------------------");

        message = "What can you do with them?";
        answer = chain.execute(message);
        System.out.println(answer);

        System.out.println("---------------------------");

        message = "Can you name some of them?";
        answer = chain.execute(message);
        System.out.println(answer);
    }
}

ในตัวอย่างแรกนี้ คุณต้องนำเข้าคลาส VertexAiChatModel และ LangChain4J ConversationalChain เพื่อให้จัดการด้านการสนทนาแบบหลายรอบได้ง่ายขึ้น

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

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

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

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

หากต้องการสนทนาแบบหลายรอบ คุณเพียงแค่เรียกใช้เมธอด execute() ในเชน ระบบจะเพิ่มเมธอดดังกล่าวลงในบริบทของการสนทนา โมเดลแชทจะสร้างคำตอบและเพิ่มลงในประวัติการแชทด้วย

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

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

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

$ ./gradlew run -DjavaMainClass=palm.workshop.ChatPrompts
Starting a Gradle Daemon, 2 incompatible and 2 stopped Daemons could not be reused, use --status for details

> Task :app:run
Large language models (LLMs) are artificial neural networks that are trained on massive datasets of text and code. They are designed to understand and generate human language, and they can be used for a variety of tasks, such as machine translation, question answering, and text summarization.
---------------------------
LLMs can be used for a variety of tasks, such as:

* Machine translation: LLMs can be used to translate text from one language to another.
* Question answering: LLMs can be used to answer questions posed in natural language.
* Text summarization: LLMs can be used to summarize text into a shorter, more concise form.
* Code generation: LLMs can be used to generate code, such as Python or Java code.
* Creative writing: LLMs can be used to generate creative text, such as poems, stories, and scripts.

LLMs are still under development, but they have the potential to revolutionize a wide range of industries. For example, LLMs could be used to improve customer service, create more personalized marketing campaigns, and develop new products and services.
---------------------------
Some of the most well-known LLMs include:

* GPT-3: Developed by OpenAI, GPT-3 is a large language model that can generate text, translate languages, write different kinds of creative content, and answer your questions in an informative way.
* LaMDA: Developed by Google, LaMDA is a large language model that can chat with you in an open-ended way, answering your questions, telling stories, and providing different kinds of creative content.
* PaLM 2: Developed by Google, PaLM 2 is a large language model that can perform a wide range of tasks, including machine translation, question answering, and text summarization.
* T5: Developed by Google, T5 is a large language model that can be used for a variety of tasks, including text summarization, question answering, and code generation.

These are just a few examples of the many LLMs that are currently being developed. As LLMs continue to improve, they are likely to play an increasingly important role in our lives.

BUILD SUCCESSFUL in 25s
2 actionable tasks: 2 executed

PaLM ตอบคำถามที่เกี่ยวข้อง 3 ข้อของคุณแล้ว

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

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

5. แชทบ็อตที่มีประโยชน์และมีบุคลิกภาพ

ในส่วนก่อนหน้านี้ คุณเริ่มถามคำถามแชทบอท LLM ทันทีโดยไม่ได้ให้บริบทใดๆ แต่คุณสามารถปรับแต่งแชทบอทดังกล่าวให้กลายเป็นผู้เชี่ยวชาญในงานหรือหัวข้อใดหัวข้อหนึ่งได้

คุณจะทำได้อย่างไร การวางรากฐาน: โดยการอธิบายงานที่กำลังทำอยู่ บริบท และอาจให้ตัวอย่างเล็กๆ น้อยๆ เกี่ยวกับสิ่งที่ต้องทำ บุคลิกที่ควรมี รูปแบบที่คุณต้องการรับคำตอบ และอาจรวมถึงน้ำเสียง หากต้องการให้แชทบอททำงานในลักษณะใดลักษณะหนึ่ง

บทความเกี่ยวกับการสร้างพรอมต์นี้แสดงให้เห็นถึงแนวทางนี้ได้เป็นอย่างดีด้วยกราฟิกนี้

8a4c67679dcbd085.png

https://medium.com/@eldatero/master-the-perfect-chatgpt-prompt-formula-c776adae8f19

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

มีตัวอย่างหนึ่งในการเปลี่ยนแชทบอท LLM ให้เป็นผู้เล่นหมากรุก มาใช้กันเลย

อัปเดตชั้นเรียน ChatPrompts ดังนี้

package palm.workshop;

import dev.langchain4j.chain.ConversationalChain;
import dev.langchain4j.data.message.SystemMessage;
import dev.langchain4j.memory.chat.MessageWindowChatMemory;
import dev.langchain4j.model.vertexai.VertexAiChatModel;
import dev.langchain4j.store.memory.chat.InMemoryChatMemoryStore;

public class ChatPrompts {
    public static void main(String[] args) {
        VertexAiChatModel model = VertexAiChatModel.builder()
            .endpoint("us-central1-aiplatform.googleapis.com:443")
            .project("YOUR_PROJECT_ID")
            .location("us-central1")
            .publisher("google")
            .modelName("chat-bison@001")
            .maxOutputTokens(7)
            .maxRetries(3)
            .build();

        InMemoryChatMemoryStore chatMemoryStore = new InMemoryChatMemoryStore();

        MessageWindowChatMemory chatMemory = MessageWindowChatMemory.builder()
            .chatMemoryStore(chatMemoryStore)
            .maxMessages(200)
            .build();

        chatMemory.add(SystemMessage.from("""
            You're an expert chess player with a high ELO ranking.
            Use the PGN chess notation to reply with the best next possible move.
            """
        ));


        ConversationalChain chain = ConversationalChain.builder()
            .chatLanguageModel(model)
            .chatMemory(chatMemory)
            .build();

        String pgn = "";
        String[] whiteMoves = { "Nf3", "c4", "Nc3", "e3", "Dc2", "Cd5"};
        for (int i = 0; i < whiteMoves.length; i++) {
            pgn += " " + (i+1) + ". " + whiteMoves[i];
            System.out.println("Playing " + whiteMoves[i]);
            pgn = chain.execute(pgn);
            System.out.println(pgn);
        }
    }
}

มาดูรายละเอียดกันทีละขั้นตอน

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

เมื่อเรียกใช้คลาสนี้ด้วยการเคลื่อนไหวเหล่านี้ คุณควรเห็นเอาต์พุตต่อไปนี้

$ ./gradlew run -DjavaMainClass=palm.workshop.ChatPrompts
Starting a Gradle Daemon (subsequent builds will be faster)

> Task :app:run
Playing Nf3
1... e5
Playing c4
2... Nc6
Playing Nc3
3... Nf6
Playing e3
4... Bb4
Playing Dc2
5... O-O
Playing Cd5
6... exd5 

ว้าว PaLM รู้วิธีเล่นหมากรุกด้วยเหรอ ไม่เชิง แต่ในระหว่างการฝึก โมเดลต้องเคยเห็นการบรรยายเกมหมากรุก หรือแม้แต่ไฟล์ PGN (Portable Game Notation) ของเกมที่ผ่านมา อย่างไรก็ตาม แชทบ็อตนี้อาจไม่ชนะ AlphaZero (AI ที่เอาชนะผู้เล่นหมากล้อม โชกิ และหมากรุกที่เก่งที่สุด) และการสนทนาอาจหลุดประเด็นไปเรื่อยๆ โดยโมเดลอาจจำสถานะที่แท้จริงของเกมไม่ได้

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

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

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

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

คุณจะอัปเดตคลาส ChatPrompts ดังนี้

package palm.workshop;

import dev.langchain4j.model.vertexai.VertexAiChatModel;
import dev.langchain4j.service.AiServices;
import dev.langchain4j.service.UserMessage;

public class ChatPrompts {

    static class Person {
        String name;
        int age;
    }

    interface PersonExtractor {
        @UserMessage("""
            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:
            ---
            {{it}}
            ---
            JSON: 
            """)
        Person extractPerson(String text);
    }

    public static void main(String[] args) {
        VertexAiChatModel model = VertexAiChatModel.builder()
            .endpoint("us-central1-aiplatform.googleapis.com:443")
            .project("YOUR_PROJECT_ID")
            .location("us-central1")
            .publisher("google")
            .modelName("chat-bison@001")
            .maxOutputTokens(300)
            .build();
        
        PersonExtractor extractor = AiServices.create(PersonExtractor.class, model);

        Person person = extractor.extractPerson("""
            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.    
            """
        );

        System.out.println(person.name);
        System.out.println(person.age);
    }
}

มาดูขั้นตอนต่างๆ ในไฟล์นี้กัน

  • Person คลาสจะกำหนดขึ้นเพื่อแสดงรายละเอียดที่อธิบายบุคคล (ชื่อและอายุ)
  • อินเทอร์เฟซ PersonExtractor สร้างขึ้นด้วยเมธอดที่เมื่อระบุสตริงข้อความที่ไม่มีโครงสร้างแล้ว จะส่งกลับอินสแตนซ์ Person ที่สร้างขึ้น
  • extractPerson() มีคำอธิบายประกอบ@UserMessageที่เชื่อมโยงพรอมต์กับextractPerson() ซึ่งเป็นพรอมต์ที่โมเดลจะใช้เพื่อดึงข้อมูลและแสดงรายละเอียดในรูปแบบเอกสาร JSON ที่จะได้รับการแยกวิเคราะห์และยกเลิกการมาร์ชัลเป็นอินสแตนซ์ Person

ตอนนี้มาดูเนื้อหาของเมธอด main() กัน

  • สร้างอินสแตนซ์โมเดลแชท
  • ระบบจะสร้างออบเจ็กต์ PersonExtractor ด้วยคลาส AiServices ของ LangChain4J
  • จากนั้นคุณก็โทรหา Person person = extractor.extractPerson(...) เพื่อดึงรายละเอียดของบุคคลจากข้อความที่ไม่มีโครงสร้าง และรับอินสแตนซ์ Person ที่มีชื่อและอายุ

ตอนนี้ให้เรียกใช้คลาสนี้ด้วยคำสั่งต่อไปนี้

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

> Task :app:run
Anna
23

ได้ นี่คือแอนนา อายุ 23 ปี

สิ่งที่น่าสนใจเป็นพิเศษเกี่ยวกับแนวทาง AiServices นี้คือคุณจะดำเนินการกับออบเจ็กต์ที่มีการพิมพ์อย่างเข้มงวด คุณไม่ได้โต้ตอบกับ LLM แชทโดยตรง แต่คุณจะทำงานกับคลาสที่เป็นรูปธรรม เช่น คลาส Person เพื่อแสดงข้อมูลส่วนบุคคลที่แยกออกมา และคุณมีPersonExtractorคลาสที่มีเมธอด extractPerson() ซึ่งจะแสดงผลอินสแตนซ์ Person แนวคิดของ LLM จะได้รับการแยกออกไป และในฐานะนักพัฒนาซอฟต์แวร์ Java คุณเพียงแค่จัดการคลาสและออบเจ็กต์ปกติ

7. การสร้างแบบดึงข้อมูลเสริม: แชทกับเอกสาร

กลับมาที่การสนทนากัน คราวนี้คุณจะถามคำถามเกี่ยวกับเอกสารได้ คุณจะสร้างแชทบอทที่สามารถดึงข้อมูลที่เกี่ยวข้องจากฐานข้อมูลของข้อความที่แยกออกมาจากเอกสาร และโมเดลจะใช้ข้อมูลดังกล่าวเพื่อ"อ้างอิง"คำตอบ แทนที่จะพยายามสร้างคำตอบที่มาจากการฝึก รูปแบบนี้เรียกว่า RAG หรือ Retrieval Augmented Generation

โดยสรุปแล้ว ในการสร้างข้อความโดยใช้การดึงข้อมูลเสริม (Retrieval Augmented Generation) จะมี 2 เฟส ดังนี้

  1. ระยะการนำเข้า - ระบบจะโหลดเอกสาร แบ่งออกเป็นส่วนย่อยๆ และจัดเก็บการแสดงเวกเตอร์ของเอกสาร ("การฝังเวกเตอร์") ไว้ใน"ฐานข้อมูลเวกเตอร์" ซึ่งสามารถทำการค้นหาเชิงความหมายได้

6c5bb5cb2e3b8088.png

  1. ระยะการค้นหา - ตอนนี้ผู้ใช้สามารถถามคำถามเกี่ยวกับเอกสารประกอบกับแชทบอทของคุณได้แล้ว ระบบจะแปลงคำถามเป็นเวกเตอร์ด้วยเช่นกัน และนำไปเปรียบเทียบกับเวกเตอร์อื่นๆ ทั้งหมดในฐานข้อมูล เวกเตอร์ที่คล้ายกันมากที่สุดมักจะเกี่ยวข้องกับความหมาย และฐานข้อมูลเวกเตอร์จะแสดงเวกเตอร์ดังกล่าว จากนั้น LLM จะได้รับบริบทของการสนทนา ข้อมูลโค้ดของข้อความที่สอดคล้องกับเวกเตอร์ที่ฐานข้อมูลส่งคืน และจะได้รับคำขอให้ยึดตามข้อมูลโค้ดเหล่านั้นในการตอบ

2c279c506d7606cd.png

การเตรียมเอกสาร

สำหรับการสาธิตใหม่นี้ คุณจะถามคำถามเกี่ยวกับสถาปัตยกรรมโครงข่ายประสาทเทียม "Transformer" ซึ่ง Google เป็นผู้บุกเบิก และเป็นวิธีที่ใช้ในการติดตั้งใช้งานโมเดลภาษาขนาดใหญ่ที่ทันสมัยทั้งหมดในปัจจุบัน

คุณสามารถดึงข้อมูลงานวิจัยที่อธิบายสถาปัตยกรรมนี้ ("Attention is all you need") ได้โดยใช้คำสั่ง wget เพื่อดาวน์โหลด PDF จากอินเทอร์เน็ต

wget -O attention-is-all-you-need.pdf \
    https://proceedings.neurips.cc/paper_files/paper/2017/file/3f5ee243547dee91fbd053c1c4a845aa-Paper.pdf

การใช้เชนการดึงข้อมูลแบบสนทนา

มาดูทีละขั้นตอนวิธีสร้างแนวทาง 2 เฟสกัน โดยเริ่มจากการนำเข้าเอกสารก่อน แล้วจึงเป็นเวลาการค้นหาเมื่อผู้ใช้ถามคำถามเกี่ยวกับเอกสาร

การส่งผ่านข้อมูลเอกสาร

ขั้นตอนแรกของระยะการนำเข้าเอกสารคือการค้นหาไฟล์ PDF ที่เราดาวน์โหลดมา และเตรียม PdfParser เพื่ออ่านไฟล์

PdfDocumentParser pdfParser = new PdfDocumentParser();
Document document = pdfParser.parse(
    new FileInputStream(new File("/home/YOUR_USER_NAME/palm-workshop/attention-is-all-you-need.pdf")));

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

VertexAiEmbeddingModel embeddingModel = VertexAiEmbeddingModel.builder()
    .endpoint("us-central1-aiplatform.googleapis.com:443")
    .project("YOUR_PROJECT_ID")
    .location("us-central1")
    .publisher("google")
    .modelName("textembedding-gecko@001")
    .maxRetries(3)
    .build();

จากนั้นคุณจะต้องมีชั้นเรียน 2-3 ชั้นเรียนเพื่อทำงานร่วมกันในการดำเนินการต่อไปนี้

  • โหลดและแยกเอกสาร PDF ออกเป็นส่วนๆ
  • สร้างการฝังเวกเตอร์สำหรับก้อนข้อมูลทั้งหมดนี้
InMemoryEmbeddingStore<TextSegment> embeddingStore = 
    new InMemoryEmbeddingStore<>();

EmbeddingStoreIngestor storeIngestor = EmbeddingStoreIngestor.builder()
    .documentSplitter(DocumentSplitters.recursive(500, 100))
    .embeddingModel(embeddingModel)
    .embeddingStore(embeddingStore)
    .build();
storeIngestor.ingest(document);

EmbeddingStoreRetriever retriever = EmbeddingStoreRetriever.from(embeddingStore, embeddingModel);

ระบบจะสร้างอินสแตนซ์ของ InMemoryEmbeddingStore ซึ่งเป็นฐานข้อมูลเวกเตอร์ในหน่วยความจำเพื่อจัดเก็บการฝังเวกเตอร์

เอกสารจะแบ่งออกเป็นส่วนๆ ด้วยDocumentSplitters คลาส โดยจะแยกข้อความในไฟล์ PDF ออกเป็นข้อมูลโค้ดที่มีอักขระ 500 ตัว โดยมีส่วนที่ทับซ้อนกัน 100 ตัว (กับก้อนข้อมูลถัดไป เพื่อหลีกเลี่ยงการตัดคำหรือประโยคออกเป็นชิ้นเล็กๆ)

"โปรแกรมรับส่งข้อมูล" ของร้านค้าจะลิงก์ตัวแยกเอกสาร โมเดลการฝังเพื่อคำนวณเวกเตอร์ และฐานข้อมูลเวกเตอร์ในหน่วยความจำ จากนั้นเมธอด ingest() จะจัดการการส่งผ่านข้อมูล

ตอนนี้ระยะแรกสิ้นสุดลงแล้ว ระบบได้แปลงเอกสารเป็นกลุ่มข้อความพร้อมการฝังเวกเตอร์ที่เชื่อมโยงกัน และจัดเก็บไว้ในฐานข้อมูลเวกเตอร์

การถามคำถาม

ได้เวลาเตรียมพร้อมถามคำถามแล้ว คุณสร้างแชทโมเดลปกติเพื่อเริ่มการสนทนาได้โดยทำดังนี้

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

นอกจากนี้ คุณยังต้องมีคลาส "retriever" ที่จะลิงก์ฐานข้อมูลเวกเตอร์ (ในตัวแปร embeddingStore) กับโมเดลการฝัง หน้าที่ของโมเดลคือการค้นหาฐานข้อมูลเวกเตอร์โดยการคำนวณการฝังเวกเตอร์สำหรับคำค้นหาของผู้ใช้ เพื่อค้นหาเวกเตอร์ที่คล้ายกันในฐานข้อมูล

EmbeddingStoreRetriever retriever = 
    EmbeddingStoreRetriever.from(embeddingStore, embeddingModel);

ในขั้นตอนนี้ คุณสามารถสร้างอินสแตนซ์ของคลาส ConversationalRetrievalChain ได้ (นี่เป็นเพียงชื่ออื่นของรูปแบบการสร้างที่เพิ่มการดึงข้อมูล)

ConversationalRetrievalChain rag = ConversationalRetrievalChain.builder()
    .chatLanguageModel(model)
    .retriever(retriever)
    .promptTemplate(PromptTemplate.from("""
        Answer to the following query the best as you can: {{question}}
        Base your answer on the information provided below:
        {{information}}
        """
    ))
    .build();

"เชน" นี้จะเชื่อมโยงสิ่งต่อไปนี้เข้าด้วยกัน

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

และตอนนี้คุณก็พร้อมที่จะถามคำถามแล้ว

String result = rag.execute("What neural network architecture can be used for language models?");
System.out.println(result);
System.out.println("------------");

result = rag.execute("What are the different components of a transformer neural network?");
System.out.println(result);
System.out.println("------------");

result = rag.execute("What is attention in large language models?");
System.out.println(result);
System.out.println("------------");

result = rag.execute("What is the name of the process that transforms text into vectors?");
System.out.println(result);

เรียกใช้โปรแกรมด้วย

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

ในเอาต์พุต คุณควรเห็นคำตอบของคำถาม

The Transformer is a neural network architecture that can be used for 
language models. It is based solely on attention mechanisms, dispensing 
with recurrence and convolutions. The Transformer has been shown to 
outperform recurrent neural networks and convolutional neural networks on 
a variety of language modeling tasks.
------------
The Transformer is a neural network architecture that can be used for 
language models. It is based solely on attention mechanisms, dispensing 
with recurrence and convolutions. The Transformer has been shown to 
outperform recurrent neural networks and convolutional neural networks on a 
variety of language modeling tasks. The Transformer consists of an encoder 
and a decoder. The encoder is responsible for encoding the input sequence 
into a fixed-length vector representation. The decoder is responsible for 
decoding the output sequence from the input sequence. The decoder uses the 
attention mechanism to attend to different parts of the input sequence when 
generating the output sequence.
------------
Attention is a mechanism that allows a neural network to focus on specific 
parts of an input sequence. In the context of large language models, 
attention is used to allow the model to focus on specific words or phrases 
in a sentence when generating output. This allows the model to generate 
more relevant and informative output.
------------
The process of transforming text into vectors is called word embedding. 
Word embedding is a technique that represents words as vectors in a 
high-dimensional space. The vectors are typically learned from a large 
corpus of text, and they capture the semantic and syntactic relationships 
between words. Word embedding has been shown to be effective for a variety 
of natural language processing tasks, such as machine translation, question 
answering, and sentiment analysis.

วิธีแก้ปัญหาทั้งหมด

เนื้อหาทั้งหมดของคลาส ChatPrompts มีดังนี้เพื่อให้คัดลอกและวางได้ง่าย

package palm.workshop;

import dev.langchain4j.chain.ConversationalRetrievalChain;
import dev.langchain4j.data.document.Document;
import dev.langchain4j.data.document.parser.PdfDocumentParser;
import dev.langchain4j.data.document.splitter.DocumentSplitters;
import dev.langchain4j.data.segment.TextSegment; 
import dev.langchain4j.model.input.PromptTemplate;
import dev.langchain4j.model.vertexai.VertexAiChatModel;
import dev.langchain4j.model.vertexai.VertexAiEmbeddingModel;
import dev.langchain4j.retriever.EmbeddingStoreRetriever;
import dev.langchain4j.store.embedding.EmbeddingStoreIngestor;
import dev.langchain4j.store.embedding.inmemory.InMemoryEmbeddingStore;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

public class ChatPrompts {
    public static void main(String[] args) throws IOException {
        PdfDocumentParser pdfParser = new PdfDocumentParser();
        Document document = pdfParser.parse(new FileInputStream(new File("/ABSOLUTE_PATH/attention-is-all-you-need.pdf")));

        VertexAiEmbeddingModel embeddingModel = VertexAiEmbeddingModel.builder()
            .endpoint("us-central1-aiplatform.googleapis.com:443")
            .project("YOUR_PROJECT_ID")
            .location("us-central1")
            .publisher("google")
            .modelName("textembedding-gecko@001")
            .maxRetries(3)
            .build();

        InMemoryEmbeddingStore<TextSegment> embeddingStore = 
            new InMemoryEmbeddingStore<>();

        EmbeddingStoreIngestor storeIngestor = EmbeddingStoreIngestor.builder()
            .documentSplitter(DocumentSplitters.recursive(500, 100))
            .embeddingModel(embeddingModel)
            .embeddingStore(embeddingStore)
            .build();
        storeIngestor.ingest(document);

        EmbeddingStoreRetriever retriever = EmbeddingStoreRetriever.from(embeddingStore, embeddingModel);

        VertexAiChatModel model = VertexAiChatModel.builder()
            .endpoint("us-central1-aiplatform.googleapis.com:443")
            .project("genai-java-demos")
            .location("us-central1")
            .publisher("google")
            .modelName("chat-bison@001")
            .maxOutputTokens(1000)
            .build();

        ConversationalRetrievalChain rag = ConversationalRetrievalChain.builder()
            .chatLanguageModel(model)
            .retriever(retriever)
            .promptTemplate(PromptTemplate.from("""
                Answer to the following query the best as you can: {{question}}
                Base your answer on the information provided below:
                {{information}}
                """
            ))
            .build();

        String result = rag.execute("What neural network architecture can be used for language models?");
        System.out.println(result);
        System.out.println("------------");

        result = rag.execute("What are the different components of a transformer neural network?");
        System.out.println(result);
        System.out.println("------------");

        result = rag.execute("What is attention in large language models?");
        System.out.println(result);
        System.out.println("------------");

        result = rag.execute("What is the name of the process that transforms text into vectors?");
        System.out.println(result);
    }
}

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

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

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

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

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

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