Tạo văn bản bằng AI tạo sinh trong Java bằng PaLM và LangChain4J

1. Giới thiệu

Lần cập nhật gần đây nhất: 27/11/2023

AI tạo sinh là gì

AI tạo sinh là hình thức sử dụng AI để tạo ra nội dung mới, chẳng hạn như văn bản, hình ảnh, nhạc, âm thanh và video.

AI tạo sinh được hỗ trợ bởi các mô hình nền tảng (mô hình AI lớn) có thể thực hiện nhiều nhiệm vụ cùng một lúc và đáp ứng các yêu cầu sáng tạo, chẳng hạn như tóm tắt, hỏi đáp, phân loại và hơn thế. Ngoài ra, với yêu cầu tối thiểu về việc huấn luyện, các mô hình cơ sở có thể được điều chỉnh cho các trường hợp sử dụng mục tiêu với rất ít dữ liệu mẫu.

AI tạo sinh hoạt động như thế nào?

AI tạo sinh hoạt động bằng cách sử dụng mô hình học máy (ML) để tìm hiểu các mẫu hình và mối quan hệ trong một tập dữ liệu gồm nội dung do con người tạo. Sau đó, AI sẽ sử dụng các mẫu đã học được để tạo nội dung mới.

Cách phổ biến nhất để huấn luyện một mô hình AI tạo sinh là sử dụng phương pháp học có giám sát. Theo đó, mô hình sẽ được cung cấp một tập hợp nội dung do con người tạo và các nhãn tương ứng. Sau đó, mô hình này sẽ học cách tạo nội dung tương tự như nội dung do con người tạo ra và được gắn nhãn tương tự.

Các ứng dụng phổ biến của AI tạo sinh là gì?

AI tạo sinh xử lý lượng nội dung khổng lồ, tạo ra thông tin chi tiết và câu trả lời thông qua văn bản, hình ảnh và các định dạng thân thiện với người dùng. AI tạo sinh có thể được dùng để:

  • Cải thiện hoạt động tương tác với khách hàng thông qua trải nghiệm trò chuyện và tìm kiếm nâng cao
  • Khám phá lượng lớn dữ liệu không có cấu trúc thông qua các giao diện đàm thoại và bản tóm tắt
  • Hỗ trợ các công việc lặp đi lặp lại như trả lời yêu cầu đề xuất (RFP), bản địa hoá nội dung tiếp thị bằng 5 ngôn ngữ, kiểm tra hợp đồng của khách hàng để đảm bảo tuân thủ và nhiều việc khác

Google Cloud có những giải pháp nào dựa trên AI tạo sinh?

Với Vertex AI, bạn có thể tương tác, tuỳ chỉnh và nhúng các mô hình cơ sở vào ứng dụng của mình mà không cần hoặc chỉ cần rất ít kiến thức chuyên môn về học máy. Truy cập vào các mô hình cơ sở trên Model Garden, điều chỉnh các mô hình thông qua một giao diện người dùng đơn giản trên Generative AI Studio hoặc sử dụng các mô hình trong sổ tay khoa học dữ liệu.

Vertex AI Search and Conversation cung cấp cho nhà phát triển cách nhanh nhất để tạo công cụ tìm kiếm và chatbot dựa trên AI tạo sinh.

Ngoài ra, Duet AI là cộng sự dựa trên AI, có mặt trên Google Cloud và các IDE để giúp bạn làm được nhiều việc hơn và nhanh hơn.

Lớp học lập trình này tập trung vào vấn đề gì?

Lớp học lập trình này tập trung vào Mô hình ngôn ngữ lớn (LLM) PaLM 2, được lưu trữ trên Vertex AI của Google Cloud, bao gồm tất cả các sản phẩm và dịch vụ học máy.

Bạn sẽ sử dụng Java để tương tác với PaLM API, kết hợp với trình điều phối khung LLM LangChain4J. Bạn sẽ xem xét nhiều ví dụ cụ thể để tận dụng LLM cho việc trả lời câu hỏi, tạo ý tưởng, trích xuất thực thể và nội dung có cấu trúc, cũng như tóm tắt.

Cho tôi biết thêm về khung LangChain4J!

Khung LangChain4J là một thư viện nguồn mở để tích hợp các mô hình ngôn ngữ lớn vào các ứng dụng Java của bạn, bằng cách điều phối nhiều thành phần, chẳng hạn như chính LLM, mà còn các công cụ khác như cơ sở dữ liệu vectơ (để tìm kiếm ngữ nghĩa), trình tải và trình phân tách tài liệu (để phân tích tài liệu và học hỏi từ tài liệu), trình phân tích cú pháp đầu ra, v.v.

c6d7f7c3fd0d2951.png

Kiến thức bạn sẽ học được

  • Cách thiết lập dự án Java để sử dụng PaLM và LangChain4J
  • Cách thực hiện lệnh gọi đầu tiên đến mô hình văn bản PaLM để tạo nội dung và trả lời câu hỏi
  • Cách trích xuất thông tin hữu ích từ nội dung không có cấu trúc (trích xuất thực thể hoặc từ khoá, đầu ra ở định dạng JSON)
  • Cách phân loại nội dung hoặc phân tích cảm xúc bằng cách sử dụng phương pháp đặt câu lệnh dựa trên một vài ví dụ

Bạn cần có

  • Kiến thức về ngôn ngữ lập trình Java
  • Một dự án trên Google Cloud
  • Một trình duyệt, chẳng hạn như Chrome hoặc Firefox

2. Thiết lập và yêu cầu

Thiết lập môi trường theo tốc độ của riêng bạn

  1. Đăng nhập vào Google Cloud Console rồi tạo một dự án mới hoặc sử dụng lại một dự án hiện có. Nếu chưa có tài khoản Gmail hoặc Google Workspace, bạn phải tạo một tài khoản.

295004821bab6a87.png

37d264871000675d.png

96d86d3d5655cdbe.png

  • Tên dự án là tên hiển thị của những người tham gia dự án này. Đây là một chuỗi ký tự mà các API của Google không sử dụng. Bạn luôn có thể cập nhật thông tin này.
  • Mã dự án là mã duy nhất trên tất cả các dự án trên Google Cloud và không thể thay đổi (bạn không thể thay đổi mã này sau khi đã đặt). Cloud Console sẽ tự động tạo một chuỗi duy nhất; thường thì bạn không cần quan tâm đến chuỗi này. Trong hầu hết các lớp học lập trình, bạn sẽ cần tham chiếu đến Mã dự án (thường được xác định là PROJECT_ID). Nếu không thích mã nhận dạng được tạo, bạn có thể tạo một mã nhận dạng ngẫu nhiên khác. Hoặc bạn có thể thử tên người dùng của riêng mình để xem tên đó có được chấp nhận hay không. Bạn không thể thay đổi tên này sau bước này và tên này sẽ tồn tại trong suốt thời gian của dự án.
  • Để bạn nắm được thông tin, có một giá trị thứ ba là Số dự án mà một số API sử dụng. Tìm hiểu thêm về cả 3 giá trị này trong tài liệu.
  1. Tiếp theo, bạn cần bật tính năng thanh toán trong Cloud Console để sử dụng các tài nguyên/API trên đám mây. Việc thực hiện lớp học lập trình này sẽ không tốn nhiều chi phí, nếu có. Để tắt các tài nguyên nhằm tránh bị tính phí ngoài phạm vi hướng dẫn này, bạn có thể xoá các tài nguyên đã tạo hoặc xoá dự án. Người dùng mới của Google Cloud đủ điều kiện tham gia chương trình Dùng thử miễn phí trị giá 300 USD.

Khởi động Cloud Shell

Mặc dù có thể vận hành Google Cloud từ xa trên máy tính xách tay, nhưng trong lớp học lập trình này, bạn sẽ sử dụng Cloud Shell, một môi trường dòng lệnh chạy trên đám mây.

Kích hoạt Cloud Shell

  1. Trong Cloud Console, hãy nhấp vào Kích hoạt Cloud Shell d1264ca30785e435.png.

cb81e7c8e34bc8d.png

Nếu đây là lần đầu tiên bạn khởi động Cloud Shell, bạn sẽ thấy một màn hình trung gian mô tả về Cloud Shell. Nếu bạn thấy màn hình trung gian, hãy nhấp vào Tiếp tục.

d95252b003979716.png

Quá trình cung cấp và kết nối với Cloud Shell chỉ mất vài giây.

7833d5e1c5d18f54.png

Máy ảo này được trang bị tất cả các công cụ phát triển cần thiết. Nền tảng này cung cấp một thư mục chính có dung lượng 5 GB và chạy trong Google Cloud, giúp tăng cường đáng kể hiệu suất mạng và hoạt động xác thực. Bạn có thể thực hiện hầu hết, nếu không muốn nói là tất cả, công việc của mình trong lớp học lập trình này bằng trình duyệt.

Sau khi kết nối với Cloud Shell, bạn sẽ thấy rằng mình đã được xác thực và dự án được đặt thành mã dự án của bạn.

  1. Chạy lệnh sau trong Cloud Shell để xác nhận rằng bạn đã được xác thực:
gcloud auth list

Đầu ra của lệnh

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

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. Chạy lệnh sau trong Cloud Shell để xác nhận rằng lệnh gcloud biết về dự án của bạn:
gcloud config list project

Đầu ra của lệnh

[core]
project = <PROJECT_ID>

Nếu không, bạn có thể đặt nó bằng lệnh sau:

gcloud config set project <PROJECT_ID>

Đầu ra của lệnh

Updated property [core/project].

3. Chuẩn bị môi trường phát triển

Trong lớp học lập trình này, bạn sẽ sử dụng thiết bị đầu cuối và trình soạn thảo mã Cloud Shell để phát triển các chương trình Java.

Bật các API của Vertex AI

  1. Trong bảng điều khiển Cloud, hãy đảm bảo tên dự án của bạn xuất hiện ở đầu bảng điều khiển Cloud. Nếu không, hãy nhấp vào Chọn dự án để mở Trình chọn dự án rồi chọn dự án bạn muốn.
  2. Nếu bạn không ở phần Vertex AI của bảng điều khiển Cloud Google, hãy làm như sau:
  3. Trong phần Tìm kiếm, hãy nhập Vertex AI rồi nhấn phím Return
  4. Trong kết quả tìm kiếm, hãy nhấp vào Vertex AI. Trang tổng quan Vertex AI sẽ xuất hiện.
  5. Nhấp vào Bật tất cả API được đề xuất trong trang tổng quan Vertex AI.

Thao tác này sẽ bật một số API, nhưng API quan trọng nhất đối với lớp học lập trình là aiplatform.googleapis.com. Bạn cũng có thể bật API này trên dòng lệnh trong cửa sổ Cloud Shell bằng cách chạy lệnh sau:

$ gcloud services enable aiplatform.googleapis.com

Tạo cấu trúc dự án bằng Gradle

Để tạo các ví dụ về mã Java, bạn sẽ sử dụng công cụ tạo Gradle và Java phiên bản 17. Để thiết lập dự án bằng Gradle, trong thiết bị đầu cuối Cloud Shell, hãy tạo một thư mục (ở đây là palm-workshop), chạy lệnh gradle init trong thư mục đó:

$ 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

Bạn sẽ tạo một ứng dụng (lựa chọn 2), bằng ngôn ngữ Java (lựa chọn 3), không dùng các dự án con (lựa chọn 1), dùng cú pháp Groovy cho tệp bản dựng (lựa chọn 1), không dùng các tính năng bản dựng mới (lựa chọn không), tạo các kiểm thử bằng JUnit Jupiter (lựa chọn 4) và bạn có thể dùng palm-workshop cho tên dự án, cũng như palm.workshop cho gói nguồn.

Cấu trúc dự án sẽ có dạng như sau:

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

Hãy cập nhật tệp app/build.gradle để thêm một số phần phụ thuộc cần thiết. Bạn có thể xoá phần phụ thuộc guava nếu có và thay thế bằng các phần phụ thuộc cho dự án LangChain4J và thư viện ghi nhật ký để tránh các thông báo thiếu trình ghi nhật ký gây phiền toái:

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 có 2 phần phụ thuộc:

  • một cho dự án cốt lõi,
  • và một cho mô-đun Vertex AI chuyên dụng.

Để sử dụng Java 17 cho việc biên dịch và chạy các chương trình, hãy thêm khối sau bên dưới khối plugins {}:

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

Một thay đổi nữa cần thực hiện: cập nhật khối application của app/build.gradle để cho phép người dùng có thể ghi đè lớp chính để chạy trên dòng lệnh khi gọi công cụ tạo:

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

Để kiểm tra xem tệp bản dựng đã sẵn sàng chạy ứng dụng hay chưa, bạn có thể chạy lớp chính mặc định để in một thông báo Hello World! đơn giản:

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

> Task :app:run
Hello World!

BUILD SUCCESSFUL in 3s
2 actionable tasks: 2 executed

Giờ đây, bạn đã sẵn sàng lập trình bằng mô hình văn bản ngôn ngữ lớn PaLM bằng cách sử dụng dự án LangChain4J!

Để tham khảo, sau đây là nội dung của tệp app/build.gradle đầy đủ hiện tại:

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. Thực hiện lệnh gọi đầu tiên đến mô hình văn bản của PaLM

Bây giờ dự án đã được thiết lập đúng cách, đã đến lúc gọi API PaLM.

Tạo một lớp mới có tên là TextPrompts.java trong thư mục app/src/main/java/palm/workshop (cùng với lớp App.java mặc định) rồi nhập nội dung sau:

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());
    }
}

Trong ví dụ đầu tiên này, bạn cần nhập lớp Response và mô hình ngôn ngữ Vertex AI cho PaLM.

Tiếp theo, trong phương thức main, bạn sẽ định cấu hình mô hình ngôn ngữ bằng cách sử dụng trình tạo cho VertexAiLanguageModel để chỉ định:

  • điểm cuối,
  • dự án,
  • khu vực,
  • nhà xuất bản,
  • và tên của mô hình (text-bison@001).

Giờ đây, khi mô hình ngôn ngữ đã sẵn sàng, bạn có thể gọi phương thức generate() và truyền "prompt" (tức là câu hỏi hoặc hướng dẫn của bạn để gửi đến LLM). Ở đây, bạn đặt một câu hỏi đơn giản về LLM. Tuy nhiên, bạn có thể thay đổi câu lệnh này để thử các câu hỏi hoặc nhiệm vụ khác.

Để chạy lớp này, hãy chạy lệnh sau trong cửa sổ dòng lệnh Cloud Shell:

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

Bạn sẽ thấy kết quả tương tự như sau:

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.

Trình tạo VertexAILanguageModel cho phép bạn xác định các tham số không bắt buộc. Các tham số này đã có một số giá trị mặc định mà bạn có thể ghi đè. Dưới đây là một số ví dụ:

  • .temperature(0.2) – để xác định mức độ sáng tạo mà bạn muốn câu trả lời có được (0 là mức độ sáng tạo thấp và thường mang tính thực tế hơn, trong khi 1 là mức độ sáng tạo cao hơn)
  • .maxOutputTokens(50) – trong ví dụ này, 500 mã thông báo đã được yêu cầu (3 mã thông báo tương đương với khoảng 4 từ), tuỳ thuộc vào độ dài mà bạn muốn câu trả lời được tạo có
  • .topK(20) – để chọn ngẫu nhiên một từ trong số tối đa các từ có thể có để hoàn thành văn bản (từ 1 đến 40)
  • .topP(0.95) – để chọn những từ có thể có tổng xác suất bằng với số thực đó (từ 0 đến 1)
  • .maxRetries(3) – trong trường hợp vượt quá hạn mức yêu cầu theo thời gian, bạn có thể yêu cầu mô hình thử lại lệnh gọi 3 lần, chẳng hạn

Mô hình ngôn ngữ lớn có sức mạnh vượt trội, có thể trả lời các câu hỏi phức tạp và xử lý nhiều loại nhiệm vụ thú vị. Trong phần tiếp theo, chúng ta sẽ xem xét một nhiệm vụ hữu ích: trích xuất dữ liệu có cấu trúc từ văn bản.

5. Trích xuất thông tin từ văn bản không có cấu trúc

Trong phần trước, bạn đã tạo một số kết quả đầu ra dưới dạng văn bản. Bạn có thể sử dụng cách này nếu muốn hiển thị trực tiếp đầu ra này cho người dùng cuối. Nhưng nếu bạn muốn truy xuất dữ liệu được đề cập trong đầu ra này, thì làm cách nào để trích xuất thông tin đó từ văn bản không có cấu trúc?

Giả sử bạn muốn trích xuất tên và tuổi của một người, dựa trên tiểu sử hoặc nội dung mô tả về người đó. Bạn có thể hướng dẫn mô hình ngôn ngữ lớn tạo cấu trúc dữ liệu JSON bằng cách điều chỉnh câu lệnh như sau (thường được gọi là "thiết kế câu lệnh"):

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: 

Sửa đổi lệnh gọi model.generate() trong lớp TextPrompts để truyền toàn bộ câu lệnh văn bản ở trên:

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: 
    """
);

Nếu chạy câu lệnh này trong lớp TextPrompts, bạn sẽ nhận được chuỗi JSON sau đây. Bạn có thể phân tích cú pháp chuỗi này bằng một trình phân tích cú pháp JSON như thư viện 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

Có! Anna 23 tuổi!

6. Mẫu câu lệnh và câu lệnh có cấu trúc

Ngoài việc trả lời câu hỏi

Các mô hình ngôn ngữ lớn như PaLM có khả năng trả lời câu hỏi rất hiệu quả, nhưng bạn có thể dùng các mô hình này cho nhiều việc khác! Ví dụ: hãy thử các câu lệnh sau trong Generative AI Studio (hoặc bằng cách sửa đổi lớp TextPrompts). Thay đổi các từ viết hoa bằng ý tưởng của riêng bạn và kiểm tra kết quả:

  • Bản dịch – "Dịch câu sau sang tiếng Pháp: YOUR_SENTENCE_HERE"
  • Tóm tắt – "Tóm tắt tài liệu sau: DÁN_TÀI_LIỆU_CỦA_BẠN"
  • Tạo mẫu quảng cáo – "Viết một bài thơ về TOPIC_OF_THE_POEM"
  • Lập trình – "Cách viết hàm Fibonacci bằng PROGRAMMING_LANGUAGE?"

Mẫu câu lệnh

Nếu đã thử các câu lệnh trên để dịch, tóm tắt, tạo mẫu quảng cáo hoặc thực hiện các tác vụ lập trình, thì bạn đã thay thế các giá trị trình giữ chỗ bằng ý tưởng của riêng mình. Tuy nhiên, thay vì thực hiện một số thao tác xử lý chuỗi, bạn cũng có thể tận dụng "mẫu câu lệnh". Mẫu này cho phép bạn xác định các giá trị phần giữ chỗ đó và sau đó điền dữ liệu của bạn vào chỗ trống.

Hãy xem một câu lệnh hấp dẫn và sáng tạo bằng cách thay thế toàn bộ nội dung của phương thức main() bằng đoạn mã sau:

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());

Và bằng cách thêm các mục nhập sau:

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

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

Sau đó, hãy chạy lại ứng dụng. Kết quả đầu ra sẽ có dạng như sau:

$ ./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.

Ngon quá!

Với mẫu câu lệnh, bạn có thể cung cấp các tham số bắt buộc trước khi gọi phương thức tạo văn bản. Đây là một cách hiệu quả để truyền dữ liệu và tuỳ chỉnh câu lệnh cho nhiều giá trị do người dùng cung cấp.

Như tên của lớp này cho thấy, lớp PromptTemplate sẽ tạo một lời nhắc mẫu và bạn có thể chỉ định các giá trị cho các phần tử giữ chỗ bằng cách áp dụng một bản đồ tên và giá trị giữ chỗ.

Câu lệnh có cấu trúc (KHÔNG BẮT BUỘC)

Một cách khác để cấu trúc câu lệnh là sử dụng chú thích @StructuredPrompt nếu bạn muốn sử dụng một phương pháp hướng đối tượng phong phú hơn. Bạn chú thích một lớp bằng chú giải này và các trường của lớp đó sẽ tương ứng với các phần giữ chỗ được xác định trong câu lệnh. Hãy xem ví dụ thực tế.

Trước tiên, chúng ta sẽ cần một số lệnh nhập mới:

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

Sau đó, chúng ta có thể tạo một lớp tĩnh bên trong trong lớp TextPrompts để thu thập dữ liệu cần thiết để truyền vào các phần giữ chỗ trong câu lệnh được mô tả trong chú thích @StructuredPrompt:

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

Sau đó, hãy tạo thực thể cho lớp mới đó và cung cấp cho lớp đó món ăn và nguyên liệu của công thức, tạo và truyền câu lệnh đến phương thức generate() như trước:

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);

Thay vì điền vào các khoảng trống thông qua một bản đồ, bạn có thể sử dụng một đối tượng Java có các trường mà IDE có thể tự động hoàn thành theo cách an toàn hơn về kiểu.

Sau đây là toàn bộ mã nếu bạn muốn dán những thay đổi đó vào lớp TextPrompts một cách dễ dàng hơn:

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. Phân loại văn bản và phân tích cảm xúc

Tương tự như những gì bạn đã học trong phần trước, bạn sẽ khám phá một kỹ thuật "thiết kế câu lệnh" khác để giúp mô hình PaLM phân loại văn bản hoặc phân tích tình cảm. Hãy nói về "đặt câu lệnh dựa trên một vài ví dụ". Đây là một cách để nâng cao câu lệnh bằng một vài ví dụ giúp định hướng mô hình ngôn ngữ đi theo hướng bạn muốn, nhằm hiểu rõ hơn ý định của bạn.

Hãy chỉnh sửa lớp TextPrompts để tận dụng các mẫu câu lệnh:

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());
    }
}

Lưu ý cách tiếp cận là đưa ra một vài ví dụ về đầu vào và đầu ra trong câu lệnh. Đây là "một vài ví dụ" giúp LLM tuân theo cùng một cấu trúc. Khi nhận được dữ liệu đầu vào, mô hình sẽ muốn trả về dữ liệu đầu ra phù hợp với mẫu đầu vào/đầu ra.

Khi chạy chương trình, bạn chỉ nhận được từ POSITIVE, vì dâu tây cũng rất ngon!

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

> Task :app:run
POSITIVE

Phân tích cảm xúc cũng là một trường hợp phân loại nội dung. Bạn có thể áp dụng phương pháp "đặt câu lệnh dựa trên một vài ví dụ" tương tự để phân loại các tài liệu khác nhau vào các nhóm danh mục khác nhau.

8. Xin chúc mừng

Xin chúc mừng! Bạn đã tạo thành công ứng dụng AI tạo sinh đầu tiên của mình bằng Java, sử dụng LangChain4j và PaLM API! Trong quá trình này, bạn nhận thấy rằng các mô hình ngôn ngữ lớn khá mạnh mẽ và có khả năng xử lý nhiều tác vụ như hỏi/đáp, trích xuất dữ liệu, tóm tắt, phân loại văn bản, phân tích cảm xúc, v.v.

Tiếp theo là gì?

Hãy xem một số lớp học lập trình sau đây để tìm hiểu thêm về PaLM trong Java:

Tài liệu đọc thêm

Tài liệu tham khảo