Generative AI-Textgenerierung in Java mit PaLM und LangChain4J

Generative AI-Textgenerierung in Java mit PaLM und LangChain4J

Informationen zu diesem Codelab

subjectZuletzt aktualisiert: Dez. 4, 2023
account_circleVerfasst von Guillaume Laforge

1. Einführung

Zuletzt aktualisiert:27.11.2023

Bei der generativen KI (der generativen künstlichen Intelligenz) wird KI verwendet, um neue Inhalte wie Text, Bilder, Musik, Audio und Videos zu erstellen.

Die Generative AI basiert auf Fundamentmodellen (große KI-Modelle), die Multitaskingfähig sind und vordefinierte Aufgaben ausführen, darunter Zusammenfassungen, Fragen-/Antworten-Sessions, Klassifizierung und mehr. Außerdem lassen sich Foundation Models bei minimalem Trainingsaufwand mit sehr wenigen Beispieldaten für gezielte Anwendungsfälle anpassen.

Wie funktioniert generative KI?

Generative KI nutzt ein ML-Modell (Machine Learning), um die Muster und Beziehungen in einem Dataset mit von Menschen erstellten Inhalten zu erlernen. Anschließend werden anhand der erlernten Muster neue Inhalte generiert.

Die gängigste Methode zum Trainieren eines Generative-AI-Modells ist das überwachte Lernen – das Modell erhält eine Reihe von von Menschen erstellten Inhalten und entsprechenden Labels. Anschließend lernt es, Inhalte zu erstellen, die den von Menschen erstellten Inhalten ähneln und mit denselben Labels gekennzeichnet sind.

Was sind gängige Generative AI-Anwendungen?

Generative AI verarbeitet umfangreiche Inhalte und stellt über Texte, Bilder und nutzerfreundliche Formate Erkenntnisse und Antworten bereit. Mit generativer KI können Sie:

  • Bessere Kundeninteraktionen durch verbesserte Chat- und Suchfunktionen
  • Große Mengen unstrukturierter Daten über dialogorientierte Benutzeroberflächen und Zusammenfassungen untersuchen
  • Unterstützung bei sich wiederholenden Aufgaben wie dem Beantworten von Angebotsanfragen, der Lokalisierung von Marketinginhalten in fünf Sprachen und der Überprüfung von Kundenverträgen auf Compliance usw.

Welche generative KI-Angebote bietet Google Cloud?

Mit Vertex AI können Sie mit Foundation Models interagieren, sie anpassen und in Ihre Anwendungen einbetten – ohne oder mit nur wenig ML-Kenntnissen. In Model Garden können Sie auf Foundation Models zugreifen, sie über eine einfache Benutzeroberfläche in Generative AI Studio abstimmen oder sie in einem Data-Science-Notebook verwenden.

Vertex AI Search and Conversation bietet Entwicklern die schnellste Möglichkeit, auf generativer KI basierende Suchmaschinen und Chatbots zu erstellen.

Duet-KI ist Ihr KI-gestütztes Tool, mit dem Sie in Google Cloud und IDEs schneller mehr erledigen können.

Worum geht es in diesem Codelab?

Dieses Codelab konzentriert sich auf das PaLM 2 Large Language Model (LLM), das in Google Cloud Vertex AI gehostet wird und alle Produkte und Dienste für maschinelles Lernen umfasst.

Für die Interaktion mit der PaLM API verwenden Sie Java in Verbindung mit dem LLM-Framework-Orchestrator LangChain4J. Sie werden verschiedene konkrete Beispiele durchgehen, um das LLM für die Beantwortung von Fragen, die Ideenentwicklung, die Extraktion von Entitäten und strukturierten Inhalten sowie die Zusammenfassung zu nutzen.

Ich möchte mehr über das LangChain4J-Framework erfahren.

Das LangChain4J-Framework ist eine Open-Source-Bibliothek zur Integration von Large Language Models in Ihre Java-Anwendungen. Dabei werden verschiedene Komponenten wie das LLM selbst, aber auch andere Tools wie Vektordatenbanken (für semantische Suchen), Dokumentladeprogramme und Aufteilungen (zum Analysieren und Lernen von Dokumenten) sowie Ausgabeparser und mehr orchestriert.

c6d7f7c3fd0d2951.png

Aufgaben in diesem Lab

  • Java-Projekt für PaLM und LangChain4J einrichten
  • Wie Sie das PaLM-Textmodell zum ersten Mal aufrufen, um Inhalte zu generieren und Fragen zu beantworten
  • Nützliche Informationen aus unstrukturierten Inhalten extrahieren (Extraktion von Entitäten oder Suchbegriffen, Ausgabe im JSON-Format)
  • Inhaltsklassifizierung oder Sentimentanalyse mit wenigen Aufnahmen

Voraussetzungen

  • Kenntnisse der Programmiersprache Java
  • Ein Google Cloud-Projekt
  • Ein Browser wie Chrome oder Firefox

2. Einrichtung und Anforderungen

Umgebung für das selbstbestimmte Lernen einrichten

  1. Melden Sie sich in der Google Cloud Console an und erstellen Sie ein neues Projekt oder verwenden Sie ein vorhandenes Projekt. Wenn Sie noch kein Gmail- oder Google Workspace-Konto haben, müssen Sie eines erstellen.

295004821bab6a87.png

37d264871000675d.png

96d86d3d5655cdbe.png

  • Der Projektname ist der Anzeigename für die Projektteilnehmer. Es handelt sich um eine Zeichenfolge, die von Google APIs nicht verwendet wird. Sie können sie jederzeit aktualisieren.
  • Die Projekt-ID ist für alle Google Cloud-Projekte eindeutig und unveränderlich. Sie kann nach dem Festlegen nicht mehr geändert werden. Die Cloud Console generiert automatisch einen eindeutigen String. ist Ihnen meist egal, was es ist. In den meisten Codelabs musst du auf deine Projekt-ID verweisen, die üblicherweise als PROJECT_ID bezeichnet wird. Wenn Ihnen die generierte ID nicht gefällt, können Sie eine weitere zufällige ID generieren. Alternativ können Sie einen eigenen verwenden und nachsehen, ob er verfügbar ist. Sie kann nach diesem Schritt nicht mehr geändert werden und bleibt für die Dauer des Projekts erhalten.
  • Zur Information gibt es noch einen dritten Wert, die Projektnummer, die von manchen APIs verwendet wird. Weitere Informationen zu allen drei Werten finden Sie in der Dokumentation.
  1. Als Nächstes müssen Sie in der Cloud Console die Abrechnung aktivieren, um Cloud-Ressourcen/APIs verwenden zu können. Dieses Codelab ist kostengünstig. Sie können die von Ihnen erstellten Ressourcen oder das Projekt löschen, um Ressourcen herunterzufahren, um zu vermeiden, dass über diese Anleitung hinaus Kosten anfallen. Neue Google Cloud-Nutzer haben Anspruch auf das kostenlose Testprogramm mit 300$Guthaben.

Cloud Shell starten

Sie können Google Cloud zwar von Ihrem Laptop aus der Ferne bedienen, in diesem Codelab verwenden Sie jedoch Cloud Shell, eine Befehlszeilenumgebung, die in der Cloud ausgeführt wird.

Cloud Shell aktivieren

  1. Klicken Sie in der Cloud Console auf Cloud Shell aktivieren d1264ca30785e435.png.

cb81e7c8e34bc8d.png

Wenn Sie Cloud Shell zum ersten Mal starten, wird ein Zwischenbildschirm mit einer Beschreibung der Funktion angezeigt. Wenn ein Zwischenbildschirm angezeigt wird, klicken Sie auf Weiter.

d95252b003979716.png

Die Bereitstellung und Verbindung mit Cloud Shell dauert nur einen Moment.

7833d5e1c5d18f54.png

Diese virtuelle Maschine verfügt über alle erforderlichen Entwicklertools. Es bietet ein Basisverzeichnis mit 5 GB nichtflüchtigem Speicher und wird in Google Cloud ausgeführt. Dadurch werden die Netzwerkleistung und die Authentifizierung erheblich verbessert. Viele, wenn nicht sogar alle Arbeiten in diesem Codelab können mit einem Browser erledigt werden.

Sobald Sie mit Cloud Shell verbunden sind, sollten Sie sehen, dass Sie authentifiziert sind und das Projekt auf Ihre Projekt-ID eingestellt ist.

  1. Führen Sie in Cloud Shell den folgenden Befehl aus, um zu prüfen, ob Sie authentifiziert sind:
gcloud auth list

Befehlsausgabe

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

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. Führen Sie in Cloud Shell den folgenden Befehl aus, um zu prüfen, ob der gcloud-Befehl Ihr Projekt kennt:
gcloud config list project

Befehlsausgabe

[core]
project = <PROJECT_ID>

Ist dies nicht der Fall, können Sie die Einstellung mit diesem Befehl vornehmen:

gcloud config set project <PROJECT_ID>

Befehlsausgabe

Updated property [core/project].

3. Entwicklungsumgebung vorbereiten

In diesem Codelab verwenden Sie das Cloud Shell-Terminal und den Code-Editor, um Ihre Java-Programme zu entwickeln.

Vertex AI APIs aktivieren

  1. Prüfen Sie, ob der Projektname in der Google Cloud Console oben in der Google Cloud Console angezeigt wird. Ist dies nicht der Fall, klicken Sie auf Projekt auswählen, um die Projektauswahl zu öffnen und das gewünschte Projekt auszuwählen.
  2. Wenn Sie sich nicht im Vertex AI-Bereich der Google Cloud Console befinden, gehen Sie so vor:
  3. Geben Sie unter Suche „Vertex AI“ ein und kehren Sie dann zurück
  4. Klicken Sie in den Suchergebnissen auf Vertex AI. Das Vertex AI-Dashboard wird angezeigt.
  5. Klicken Sie im Vertex AI-Dashboard auf Enable All Recommended APIs (Alle empfohlenen APIs aktivieren).

Dadurch werden mehrere APIs aktiviert. Die wichtigste für das Codelab ist jedoch das aiplatform.googleapis.com. Sie können es auch in der Befehlszeile im Cloud Shell-Terminal aktivieren, indem Sie den folgenden Befehl ausführen:

$ gcloud services enable aiplatform.googleapis.com

Projektstruktur mit Gradle erstellen

Für Java-Codebeispiele verwenden Sie das Build-Tool Gradle und Version 17 von Java. Um Ihr Projekt mit Gradle einzurichten, erstellen Sie im Cloud Shell-Terminal ein Verzeichnis (hier palm-workshop) und führen Sie den Befehl gradle init in diesem Verzeichnis aus:

$ 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

Sie erstellen eine Anwendung (Option 2) mit der Java-Sprache (Option 3), ohne Unterprojekte (Option 1), mit der Groovy-Syntax für die Build-Datei (Option 1), verwenden Sie keine neuen Build-Funktionen (Option 4), generieren Sie Tests mit JUnit Jupiter (Option 4) und verwenden Sie für den Projektnamen palm-workshop.Ähnlich können Sie palm-workshop verwenden.

Die Projektstruktur sieht so aus:

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

Wir aktualisieren die Datei app/build.gradle, um einige erforderliche Abhängigkeiten hinzuzufügen. Sie können die guava-Abhängigkeit, sofern vorhanden, entfernen und durch die Abhängigkeiten für das LangChain4J-Projekt sowie die Logging-Bibliothek ersetzen, um zu vermeiden, dass bei fehlenden Protokollierungsmeldungen lästige Probleme auftreten:

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'
}

Für LangChain4J gibt es zwei Abhängigkeiten:

  • eine für das Kernprojekt,
  • und eines für das dedizierte Vertex AI-Modul.

Um Java 17 zum Kompilieren und Ausführen unserer Programme zu verwenden, fügen Sie den folgenden Block unter dem Block plugins {} ein:

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

Eine weitere Änderung ist erforderlich: Aktualisieren Sie den application-Block von app/build.gradle, damit Nutzer die in der Befehlszeile ausgeführte Hauptklasse überschreiben können, wenn sie das Build-Tool aufrufen:

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

Wenn Sie prüfen möchten, ob die Build-Datei zur Ausführung Ihrer Anwendung bereit ist, können Sie die Standardhauptklasse ausführen, die eine einfache Hello World!-Nachricht ausgibt:

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

> Task :app:run
Hello World!

BUILD SUCCESSFUL in 3s
2 actionable tasks: 2 executed

Jetzt sind Sie bereit, mit dem Large Language Model „PaLM“ mithilfe des LangChain4J-Projekts zu programmieren.

So sollte die vollständige app/build.gradle-Build-Datei jetzt aussehen:

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. Das Textmodell von PaLM zum ersten Mal aufrufen

Nachdem das Projekt nun ordnungsgemäß eingerichtet ist, können Sie die PaLM API aufrufen.

Erstellen Sie im Verzeichnis app/src/main/java/palm/workshop (neben der Standardklasse App.java) eine neue Klasse mit dem Namen TextPrompts.java und geben Sie den folgenden Inhalt ein:

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

In diesem ersten Beispiel müssen Sie die Klasse Response und das Vertex AI-Sprachmodell für PaLM importieren.

Als Nächstes konfigurieren Sie in der Methode main das Sprachmodell. Dazu verwenden Sie den Builder für VertexAiLanguageModel, um Folgendes anzugeben:

  • den Endpunkt,
  • das Projekt,
  • die Region,
  • den Herausgeber,
  • und Name des Modells (text-bison@001).

Da das Sprachmodell nun bereit ist, können Sie die Methode generate() aufrufen und die Aufforderung übergeben. (d. h. Ihre Frage oder Anweisungen, die Sie an das LLM senden sollen). Hier stellen Sie eine einfache Frage dazu, was LLMs sind. Sie können diesen Vorschlag jedoch ändern, um andere Fragen oder Aufgaben auszuprobieren.

Führen Sie zum Ausführen dieser Klasse den folgenden Befehl im Cloud Shell-Terminal aus:

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

Die Ausgabe sollte in etwa so aussehen:

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.

Mit dem VertexAILanguageModel-Builder können Sie optionale Parameter definieren, die bereits einige Standardwerte haben, die Sie überschreiben können. Beispiele:

  • .temperature(0.2), um zu definieren, wie kreativ die Antwort sein soll. 0 steht für wenig Creative und ist oft sachlicher, während 1 für mehr kreative Ergebnisse steht.
  • .maxOutputTokens(50): Im Beispiel wurden 500 Tokens angefordert (3 Tokens entsprechen in etwa vier Wörtern), je nachdem, wie lang die generierte Antwort sein soll.
  • .topK(20) – zur zufälligen Auswahl eines Wortes aus einer maximalen Anzahl wahrscheinlicher Wörter für die Textvervollständigung (1 bis 40)
  • .topP(0.95) – zur Auswahl der möglichen Wörter, deren Gesamtwahrscheinlichkeit diese Gleitkommazahl (zwischen 0 und 1) ergibt
  • .maxRetries(3): Falls das Kontingent für die Anfrage pro Zeit überschritten wird, kann das Modell den Aufruf dreimal wiederholen lassen, z. B.

Large Language Models sind sehr leistungsfähig, können Antworten auf komplexe Fragen liefern und eine Vielzahl interessanter Aufgaben bewältigen. Im nächsten Abschnitt geht es um das Extrahieren strukturierter Daten aus Text.

5. Informationen aus unstrukturiertem Text extrahieren

Im vorherigen Abschnitt haben Sie eine Textausgabe generiert. Das ist in Ordnung, wenn Sie diese Ausgabe Ihren Endnutzern direkt zeigen möchten. Aber wie extrahieren Sie diese Informationen aus dem unstrukturierten Text, wenn Sie die in dieser Ausgabe erwähnten Daten abrufen möchten?

Angenommen, Sie möchten den Namen und das Alter einer Person anhand einer Biografie oder Beschreibung dieser Person extrahieren. Sie können das Large Language Model anweisen, JSON-Datenstrukturen zu generieren, indem Sie den Prompt folgendermaßen anpassen (dies wird allgemein als „Prompt Engineering“ bezeichnet):

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: 

Ändern Sie den model.generate()-Aufruf in der Klasse TextPrompts, um ihm den gesamten obigen Text-Prompt zu übergeben:

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

);

Wenn Sie diese Eingabeaufforderung in unserer TextPrompts-Klasse ausführen, sollte sie den folgenden JSON-String zurückgeben, den Sie mit einem JSON-Parser wie der GSON-Bibliothek parsen können:

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

Ja! Anna wird 23!

6. Vorlagen für Prompts und strukturierte Prompts

Mehr als nur die Beantwortung von Fragen

Large Language Models wie PaLM sind leistungsfähig, um Fragen zu beantworten, aber Sie können sie für viele weitere Aufgaben verwenden. Probieren Sie beispielsweise die folgenden Prompts in Generative AI Studio aus (oder ändern Sie die Klasse TextPrompts). Ändern Sie die Großbuchstaben in Ihre eigenen Ideen und prüfen Sie deren Ausgabe:

  • Übersetzung – "Übersetze den folgenden Satz ins Französische: YOUR_SENTENCE_HERE"
  • Zusammenfassung – "Stelle eine Zusammenfassung des folgenden Dokuments bereit: PASTE_YOUR_DOC"
  • Kreative Erstellung – "Schreib ein Gedicht über TOPIC_OF_THE_POEM"
  • Programmierung – „Wie schreibt man eine Fibonacci-Funktion in PROGRAMMING_LANGUAGE?“

Prompt-Vorlagen

Wenn Sie die obigen Vorschläge für Übersetzungs-, Zusammenfassungs-, Creative-Erstellung oder Programmieraufgaben ausprobiert haben, haben Sie die Platzhalterwerte durch Ihre eigenen Ideen ersetzt. Statt String-Mangling durchzuführen, können Sie auch Prompt-Vorlagen nutzen, mit denen Sie diese Platzhalterwerte definieren und die Lücke anschließend mit Ihren Daten ausfüllen können.

Sehen wir uns einen leckeren und kreativen Prompt an, bei dem wir den gesamten Inhalt der main()-Methode durch den folgenden Code ersetzen:

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

Und indem Sie die folgenden Importe hinzufügen:

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

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

Führen Sie die Anwendung dann noch einmal aus. Die Ausgabe sollte in etwa so aussehen:

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

Köstlich!

Mit Prompt-Vorlagen können Sie die erforderlichen Parameter einspeisen, bevor Sie die Methode zur Textgenerierung aufrufen. Das ist eine gute Möglichkeit, Daten zu übergeben und Prompts für verschiedene Werte anzupassen, die von Ihren Nutzern bereitgestellt werden.

Wie der Name der Klasse schon sagt, erstellt die Klasse PromptTemplate eine Vorlagen-Eingabeaufforderung und Sie können den Platzhalterelementen Werte zuweisen, indem Sie eine Zuordnung von Platzhalternamen und -werten anwenden.

Strukturierte Prompts (OPTIONAL)

Prompts lassen sich auch mit der Anmerkung @StructuredPrompt strukturieren, wenn Sie einen umfassenderen objektorientierten Ansatz verwenden möchten. Sie annotieren eine Klasse mit dieser Annotation, und ihre Felder entsprechen den in der Aufforderung definierten Platzhaltern. Sehen wir uns das in der Praxis an.

Zunächst benötigen wir einige neue Importe:

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

Anschließend können wir eine innere statische Klasse in unserer TextPrompts-Klasse erstellen, die die Daten sammelt, die zum Übergeben der Platzhalter in dem in der Annotation @StructuredPrompt beschriebenen Prompt erforderlich sind:

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

Instanziieren Sie dann diese neue Klasse und geben Sie ihr das Gericht und die Zutaten unseres Rezepts. Erstellen Sie dann den Prompt und übergeben Sie ihn wie zuvor an die Methode 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);

Anstatt die Lücken über eine Karte zu füllen, können Sie ein Java-Objekt mit Feldern verwenden, die von Ihrer IDE auf typsicherere Weise automatisch ausgefüllt werden können.

Hier ist der gesamte Code für den Fall, dass Sie diese Änderungen leichter in Ihren TextPrompts-Kurs einfügen möchten:

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. Text klassifizieren und Stimmung analysieren

Ähnlich wie im vorherigen Abschnitt werden Sie eine weitere Prompt Engineering-Technik kennenlernen, mit der das PaLM-Modell Text klassifiziert oder Stimmungen analysiert. Sprechen wir nun über wenige Prompts. Es ist eine Möglichkeit, Ihre Prompts mit einigen Beispielen zu verbessern, die dabei helfen, das Sprachmodell in die gewünschte Richtung zu lenken und Ihre Absicht besser zu verstehen.

Jetzt überarbeiten wir unseren TextPrompts-Kurs, um die Vorteile der Prompt-Vorlagen nutzen zu können:

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

Beachten Sie den Ansatz, in der Prompts einige Beispiele für Ein- und Ausgaben zu präsentieren. Dies sind nur einige wenige Aufnahmen, die dem LLM helfen, derselben Struktur zu folgen. Wenn das Modell dann eine Eingabe erhält, möchte es eine Ausgabe zurückgeben, die dem Eingabe-/Ausgabemuster entspricht.

Das Ausführen des Programms sollte nur das Wort POSITIVE zurückgeben, da Erdbeeren auch lecker sind!

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

> Task :app:run
POSITIVE

Die Sentimentanalyse ist ebenfalls ein Szenario zur Inhaltsklassifizierung. Sie können denselben Wenig-Shot-Prompting-Ansatz anwenden, um verschiedene Dokumente in verschiedene Kategorie-Buckets zu kategorisieren.

8. Glückwunsch

Herzlichen Glückwunsch, Sie haben mithilfe von LangChain4J und der PaLM API Ihre erste Generative AI-Anwendung in Java erstellt. Dabei haben Sie erfahren, dass Large Language Models ziemlich leistungsstark sind und in der Lage sind, verschiedene Aufgaben wie Fragen und Antworten, Datenextraktion, Zusammenfassung, Textklassifizierung oder Sentimentanalyse zu bewältigen.

Was liegt als Nächstes an?

Sehen Sie sich einige der folgenden Codelabs an, um mit PaLM in Java noch besser zu werden:

Weitere Informationen

Referenzdokumente