From 5ca8720387154146cc64cc261879a79a7ee5ea2b Mon Sep 17 00:00:00 2001 From: Christian Tzolov Date: Mon, 14 Apr 2025 09:12:16 +0200 Subject: [PATCH] Add Prompt Egineering examples --- pom.xml | 2 + .../prompt-engineering-patterns/.gitignore | 33 + .../.mvn/wrapper/maven-wrapper.properties | 19 + .../prompt-engineering-patterns/README.md | 23 + .../prompt-engineering-patterns/mvnw | 259 ++++++ .../prompt-engineering-patterns/mvnw.cmd | 149 ++++ .../prompt-engineering-patterns/pom.xml | 55 ++ .../prompt-engineering-spring-ai.png | Bin 0 -> 92598 bytes .../PromptEngineeringApplication.java | 821 ++++++++++++++++++ .../src/main/resources/application.properties | 44 + 10 files changed, 1405 insertions(+) create mode 100644 prompt-engineering/prompt-engineering-patterns/.gitignore create mode 100644 prompt-engineering/prompt-engineering-patterns/.mvn/wrapper/maven-wrapper.properties create mode 100644 prompt-engineering/prompt-engineering-patterns/README.md create mode 100755 prompt-engineering/prompt-engineering-patterns/mvnw create mode 100644 prompt-engineering/prompt-engineering-patterns/mvnw.cmd create mode 100644 prompt-engineering/prompt-engineering-patterns/pom.xml create mode 100644 prompt-engineering/prompt-engineering-patterns/prompt-engineering-spring-ai.png create mode 100644 prompt-engineering/prompt-engineering-patterns/src/main/java/org/springframework/ai/example/prompt_engineering/PromptEngineeringApplication.java create mode 100644 prompt-engineering/prompt-engineering-patterns/src/main/resources/application.properties diff --git a/pom.xml b/pom.xml index ccf070f..ed37e24 100644 --- a/pom.xml +++ b/pom.xml @@ -41,6 +41,8 @@ model-context-protocol/web-search/brave-chatbot model-context-protocol/sampling/mcp-weather-webmvc-server model-context-protocol/sampling/mcp-sampling-client + + prompt-engineering/prompt-engineering-patterns diff --git a/prompt-engineering/prompt-engineering-patterns/.gitignore b/prompt-engineering/prompt-engineering-patterns/.gitignore new file mode 100644 index 0000000..549e00a --- /dev/null +++ b/prompt-engineering/prompt-engineering-patterns/.gitignore @@ -0,0 +1,33 @@ +HELP.md +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ diff --git a/prompt-engineering/prompt-engineering-patterns/.mvn/wrapper/maven-wrapper.properties b/prompt-engineering/prompt-engineering-patterns/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 0000000..d58dfb7 --- /dev/null +++ b/prompt-engineering/prompt-engineering-patterns/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1,19 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +wrapperVersion=3.3.2 +distributionType=only-script +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip diff --git a/prompt-engineering/prompt-engineering-patterns/README.md b/prompt-engineering/prompt-engineering-patterns/README.md new file mode 100644 index 0000000..60e2176 --- /dev/null +++ b/prompt-engineering/prompt-engineering-patterns/README.md @@ -0,0 +1,23 @@ +# Prompt Engineering with Spring AI + +![Spring AI Prompt Engineering](prompt-engineering-spring-ai.png) + +## Overview + +This repository contains practical implementations of Prompt Engineering techniques using [Spring AI](https://docs.spring.io/spring-ai/reference/index.html). These examples accompany the blog post: [Spring AI Prompt Engineering Patterns](https://spring.io/blog/2025/04/14/spring-ai-prompt-engineering-patterns). + +The examples and patterns are based on the comprehensive [Prompt Engineering Guide](https://www.kaggle.com/whitepaper-prompt-engineering) that covers the theory, principles, and patterns of effective prompt engineering. + +Here we shows how to translate those concepts into working Java code using Spring AI's fluent [ChatClient API](https://docs.spring.io/spring-ai/reference/api/chatclient.html). + + +#### Structure + +The examples follow the same structure and patterns outlined in the original Goolge Prompt Egineering guide, making it easy to reference between theory and implementation. + +## Resources + +- [Spring AI Documentation](https://docs.spring.io/spring-ai/reference/index.html) +- [ChatClient API Reference](https://docs.spring.io/spring-ai/reference/api/chatclient.html) +- [Google's Prompt Engineering Guide](https://www.kaggle.com/whitepaper-prompt-engineering) +- [Spring AI Prompt Engineering Patterns Blog](https://spring.io/blog/2025/04/14/spring-ai-prompt-engineering-patterns) diff --git a/prompt-engineering/prompt-engineering-patterns/mvnw b/prompt-engineering/prompt-engineering-patterns/mvnw new file mode 100755 index 0000000..19529dd --- /dev/null +++ b/prompt-engineering/prompt-engineering-patterns/mvnw @@ -0,0 +1,259 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Apache Maven Wrapper startup batch script, version 3.3.2 +# +# Optional ENV vars +# ----------------- +# JAVA_HOME - location of a JDK home dir, required when download maven via java source +# MVNW_REPOURL - repo url base for downloading maven distribution +# MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven +# MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; others: silence the output +# ---------------------------------------------------------------------------- + +set -euf +[ "${MVNW_VERBOSE-}" != debug ] || set -x + +# OS specific support. +native_path() { printf %s\\n "$1"; } +case "$(uname)" in +CYGWIN* | MINGW*) + [ -z "${JAVA_HOME-}" ] || JAVA_HOME="$(cygpath --unix "$JAVA_HOME")" + native_path() { cygpath --path --windows "$1"; } + ;; +esac + +# set JAVACMD and JAVACCMD +set_java_home() { + # For Cygwin and MinGW, ensure paths are in Unix format before anything is touched + if [ -n "${JAVA_HOME-}" ]; then + if [ -x "$JAVA_HOME/jre/sh/java" ]; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACCMD="$JAVA_HOME/jre/sh/javac" + else + JAVACMD="$JAVA_HOME/bin/java" + JAVACCMD="$JAVA_HOME/bin/javac" + + if [ ! -x "$JAVACMD" ] || [ ! -x "$JAVACCMD" ]; then + echo "The JAVA_HOME environment variable is not defined correctly, so mvnw cannot run." >&2 + echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" or \"\$JAVA_HOME/bin/javac\" does not exist." >&2 + return 1 + fi + fi + else + JAVACMD="$( + 'set' +e + 'unset' -f command 2>/dev/null + 'command' -v java + )" || : + JAVACCMD="$( + 'set' +e + 'unset' -f command 2>/dev/null + 'command' -v javac + )" || : + + if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ]; then + echo "The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run." >&2 + return 1 + fi + fi +} + +# hash string like Java String::hashCode +hash_string() { + str="${1:-}" h=0 + while [ -n "$str" ]; do + char="${str%"${str#?}"}" + h=$(((h * 31 + $(LC_CTYPE=C printf %d "'$char")) % 4294967296)) + str="${str#?}" + done + printf %x\\n $h +} + +verbose() { :; } +[ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; } + +die() { + printf %s\\n "$1" >&2 + exit 1 +} + +trim() { + # MWRAPPER-139: + # Trims trailing and leading whitespace, carriage returns, tabs, and linefeeds. + # Needed for removing poorly interpreted newline sequences when running in more + # exotic environments such as mingw bash on Windows. + printf "%s" "${1}" | tr -d '[:space:]' +} + +# parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties +while IFS="=" read -r key value; do + case "${key-}" in + distributionUrl) distributionUrl=$(trim "${value-}") ;; + distributionSha256Sum) distributionSha256Sum=$(trim "${value-}") ;; + esac +done <"${0%/*}/.mvn/wrapper/maven-wrapper.properties" +[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in ${0%/*}/.mvn/wrapper/maven-wrapper.properties" + +case "${distributionUrl##*/}" in +maven-mvnd-*bin.*) + MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ + case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in + *AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;; + :Darwin*x86_64) distributionPlatform=darwin-amd64 ;; + :Darwin*arm64) distributionPlatform=darwin-aarch64 ;; + :Linux*x86_64*) distributionPlatform=linux-amd64 ;; + *) + echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version" >&2 + distributionPlatform=linux-amd64 + ;; + esac + distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip" + ;; +maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;; +*) MVN_CMD="mvn${0##*/mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;; +esac + +# apply MVNW_REPOURL and calculate MAVEN_HOME +# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ +[ -z "${MVNW_REPOURL-}" ] || distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}" +distributionUrlName="${distributionUrl##*/}" +distributionUrlNameMain="${distributionUrlName%.*}" +distributionUrlNameMain="${distributionUrlNameMain%-bin}" +MAVEN_USER_HOME="${MAVEN_USER_HOME:-${HOME}/.m2}" +MAVEN_HOME="${MAVEN_USER_HOME}/wrapper/dists/${distributionUrlNameMain-}/$(hash_string "$distributionUrl")" + +exec_maven() { + unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || : + exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec $MAVEN_HOME/bin/$MVN_CMD" +} + +if [ -d "$MAVEN_HOME" ]; then + verbose "found existing MAVEN_HOME at $MAVEN_HOME" + exec_maven "$@" +fi + +case "${distributionUrl-}" in +*?-bin.zip | *?maven-mvnd-?*-?*.zip) ;; +*) die "distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'" ;; +esac + +# prepare tmp dir +if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then + clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; } + trap clean HUP INT TERM EXIT +else + die "cannot create temp dir" +fi + +mkdir -p -- "${MAVEN_HOME%/*}" + +# Download and Install Apache Maven +verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." +verbose "Downloading from: $distributionUrl" +verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" + +# select .zip or .tar.gz +if ! command -v unzip >/dev/null; then + distributionUrl="${distributionUrl%.zip}.tar.gz" + distributionUrlName="${distributionUrl##*/}" +fi + +# verbose opt +__MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR='' +[ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v + +# normalize http auth +case "${MVNW_PASSWORD:+has-password}" in +'') MVNW_USERNAME='' MVNW_PASSWORD='' ;; +has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;; +esac + +if [ -z "${MVNW_USERNAME-}" ] && command -v wget >/dev/null; then + verbose "Found wget ... using wget" + wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O "$TMP_DOWNLOAD_DIR/$distributionUrlName" || die "wget: Failed to fetch $distributionUrl" +elif [ -z "${MVNW_USERNAME-}" ] && command -v curl >/dev/null; then + verbose "Found curl ... using curl" + curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o "$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" || die "curl: Failed to fetch $distributionUrl" +elif set_java_home; then + verbose "Falling back to use Java to download" + javaSource="$TMP_DOWNLOAD_DIR/Downloader.java" + targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName" + cat >"$javaSource" <<-END + public class Downloader extends java.net.Authenticator + { + protected java.net.PasswordAuthentication getPasswordAuthentication() + { + return new java.net.PasswordAuthentication( System.getenv( "MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() ); + } + public static void main( String[] args ) throws Exception + { + setDefault( new Downloader() ); + java.nio.file.Files.copy( java.net.URI.create( args[0] ).toURL().openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() ); + } + } + END + # For Cygwin/MinGW, switch paths to Windows format before running javac and java + verbose " - Compiling Downloader.java ..." + "$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" || die "Failed to compile Downloader.java" + verbose " - Running Downloader.java ..." + "$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" Downloader "$distributionUrl" "$(native_path "$targetZip")" +fi + +# If specified, validate the SHA-256 sum of the Maven distribution zip file +if [ -n "${distributionSha256Sum-}" ]; then + distributionSha256Result=false + if [ "$MVN_CMD" = mvnd.sh ]; then + echo "Checksum validation is not supported for maven-mvnd." >&2 + echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 + exit 1 + elif command -v sha256sum >/dev/null; then + if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c >/dev/null 2>&1; then + distributionSha256Result=true + fi + elif command -v shasum >/dev/null; then + if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 256 -c >/dev/null 2>&1; then + distributionSha256Result=true + fi + else + echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2 + echo "Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 + exit 1 + fi + if [ $distributionSha256Result = false ]; then + echo "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised." >&2 + echo "If you updated your Maven version, you need to update the specified distributionSha256Sum property." >&2 + exit 1 + fi +fi + +# unzip and move +if command -v unzip >/dev/null; then + unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed to unzip" +else + tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar" +fi +printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/mvnw.url" +mv -- "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME" + +clean || : +exec_maven "$@" diff --git a/prompt-engineering/prompt-engineering-patterns/mvnw.cmd b/prompt-engineering/prompt-engineering-patterns/mvnw.cmd new file mode 100644 index 0000000..249bdf3 --- /dev/null +++ b/prompt-engineering/prompt-engineering-patterns/mvnw.cmd @@ -0,0 +1,149 @@ +<# : batch portion +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Apache Maven Wrapper startup batch script, version 3.3.2 +@REM +@REM Optional ENV vars +@REM MVNW_REPOURL - repo url base for downloading maven distribution +@REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven +@REM MVNW_VERBOSE - true: enable verbose log; others: silence the output +@REM ---------------------------------------------------------------------------- + +@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0) +@SET __MVNW_CMD__= +@SET __MVNW_ERROR__= +@SET __MVNW_PSMODULEP_SAVE=%PSModulePath% +@SET PSModulePath= +@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @( + IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B) +) +@SET PSModulePath=%__MVNW_PSMODULEP_SAVE% +@SET __MVNW_PSMODULEP_SAVE= +@SET __MVNW_ARG0_NAME__= +@SET MVNW_USERNAME= +@SET MVNW_PASSWORD= +@IF NOT "%__MVNW_CMD__%"=="" (%__MVNW_CMD__% %*) +@echo Cannot start maven from wrapper >&2 && exit /b 1 +@GOTO :EOF +: end batch / begin powershell #> + +$ErrorActionPreference = "Stop" +if ($env:MVNW_VERBOSE -eq "true") { + $VerbosePreference = "Continue" +} + +# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties +$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl +if (!$distributionUrl) { + Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" +} + +switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) { + "maven-mvnd-*" { + $USE_MVND = $true + $distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip" + $MVN_CMD = "mvnd.cmd" + break + } + default { + $USE_MVND = $false + $MVN_CMD = $script -replace '^mvnw','mvn' + break + } +} + +# apply MVNW_REPOURL and calculate MAVEN_HOME +# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ +if ($env:MVNW_REPOURL) { + $MVNW_REPO_PATTERN = if ($USE_MVND) { "/org/apache/maven/" } else { "/maven/mvnd/" } + $distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace '^.*'+$MVNW_REPO_PATTERN,'')" +} +$distributionUrlName = $distributionUrl -replace '^.*/','' +$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$','' +$MAVEN_HOME_PARENT = "$HOME/.m2/wrapper/dists/$distributionUrlNameMain" +if ($env:MAVEN_USER_HOME) { + $MAVEN_HOME_PARENT = "$env:MAVEN_USER_HOME/wrapper/dists/$distributionUrlNameMain" +} +$MAVEN_HOME_NAME = ([System.Security.Cryptography.MD5]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join '' +$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME" + +if (Test-Path -Path "$MAVEN_HOME" -PathType Container) { + Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME" + Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" + exit $? +} + +if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) { + Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl" +} + +# prepare tmp dir +$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile +$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir" +$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null +trap { + if ($TMP_DOWNLOAD_DIR.Exists) { + try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } + catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } + } +} + +New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null + +# Download and Install Apache Maven +Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." +Write-Verbose "Downloading from: $distributionUrl" +Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" + +$webclient = New-Object System.Net.WebClient +if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) { + $webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD) +} +[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 +$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null + +# If specified, validate the SHA-256 sum of the Maven distribution zip file +$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum +if ($distributionSha256Sum) { + if ($USE_MVND) { + Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." + } + Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash + if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) { + Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property." + } +} + +# unzip and move +Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null +Rename-Item -Path "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" -NewName $MAVEN_HOME_NAME | Out-Null +try { + Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null +} catch { + if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) { + Write-Error "fail to move MAVEN_HOME" + } +} finally { + try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } + catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } +} + +Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" diff --git a/prompt-engineering/prompt-engineering-patterns/pom.xml b/prompt-engineering/prompt-engineering-patterns/pom.xml new file mode 100644 index 0000000..7e84fa0 --- /dev/null +++ b/prompt-engineering/prompt-engineering-patterns/pom.xml @@ -0,0 +1,55 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 3.4.4 + + + org.springframework.ai.example + prompt-engineering-patterns + 0.0.1-SNAPSHOT + prompt-engineering-patterns + Demo project for Spring Boot + + + 17 + 1.0.0-M7 + + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.ai + spring-ai-starter-model-anthropic + + + + + + + org.springframework.ai + spring-ai-bom + ${spring-ai.version} + pom + import + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/prompt-engineering/prompt-engineering-patterns/prompt-engineering-spring-ai.png b/prompt-engineering/prompt-engineering-patterns/prompt-engineering-spring-ai.png new file mode 100644 index 0000000000000000000000000000000000000000..a1effddc0a1b8f314991e8023485861cd29f24e3 GIT binary patch literal 92598 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 { + + ChatClient chatClient = chatClientBuilder.build(); + + //@formatter:off + // 2. Prompting techniques (page 13) + + // 2.1 General prompting / zero shot (page 15) + pt_zero_shot(chatClient); + + // 2.2 One-shot & few-shot + pt_ones_shot_few_shots(chatClient); + + // 2.3 System, contextual and role prompting + + // 2.3.1 System prompting + pt_system_prompting_1(chatClient); + pt_system_prompting_2(chatClient); + pt_system_prompting_2_springai_style(chatClient); + + // 2.3.2 Role prompting + pt_role_prompting_1(chatClient); + pt_role_prompting_2(chatClient); // in a humorous style. + + // 2.3.3 Contextual prompting + pt_contextual_prompting(chatClient); + + // 2.4 Step-back prompting + pt_step_back_prompting(chatClient.mutate()); + + // 2.5 Chain of Thought (CoT) + pt_chain_of_thought_zero_shot(chatClient); + pt_chain_of_thought_singleshot_fewshots(chatClient); + + // 2.6 Self-consistency + pt_self_consistency(chatClient); + + // 2.7 Tree of Thoughts (ToT) + pt_tree_of_thoughts_game(chatClient); + pt_tree_of_thoughts_problem(chatClient); + + + // 2.8 Automatic Prompt Engineering + pt_automatic_prompt_engineering(chatClient); + + // 2.9 Code prompting + + // 2.9.1 Prompts for writing code + pt_code_prompting_writing_code(chatClient); + + // 2.9.2 Prompts for explaining code + pt_code_prompting_explaining_code(chatClient); + + // 2.9.3 Prompts for translating code + pt_code_prompting_translating_code(chatClient); + //@formatter:on + }; + } + + // 2.1 General prompting / zero shot (page 15) + public void pt_zero_shot(ChatClient chatClient) { + // General prompting / zero shot (page 15) + + enum Sentiment { + POSITIVE, NEUTRAL, NEGATIVE + } + + Sentiment reviewSentiment = chatClient.prompt(""" + Classify movie reviews as POSITIVE, NEUTRAL or NEGATIVE. + Review: "Her" is a disturbing study revealing the direction + humanity is headed if AI is allowed to keep evolving, + unchecked. I wish there were more movies like this masterpiece. + Sentiment: + """) + .options(ChatOptions.builder() + .model("claude-3-7-sonnet-latest") + .temperature(0.1) + .maxTokens(5) + .build()) + .call() + .entity(Sentiment.class); + + System.out.println("Output: " + reviewSentiment); + } + + // 2.2 One-shot & few-shot + public void pt_ones_shot_few_shots(ChatClient chatClient) { + + // One-shot & few-shot + // When creating prompts for AI models, it is helpful to provide examples. + // These examples can help the model understand what you are asking for. + // - one-shot prompt: provides a single example to the model. + // - few-shot prompt: provides multiple examples to the model. + + // A few-shot prompt example, let's use the same gemini-pro model + // configuration settings as before, other than increasing the token limit to + // accommodate the + // need for a longer response. (page 16) + + String pizzaOrder = chatClient.prompt(""" + Parse a customer's pizza order into valid JSON + + EXAMPLE 1: + I want a small pizza with cheese, tomato sauce, and pepperoni. + JSON Response: + ``` + { + "size": "small", + "type": "normal", + "ingredients": ["cheese", "tomato sauce", "peperoni"] + } + ``` + + EXAMPLE 2: + Can I get a large pizza with tomato sauce, basil and mozzarella. + JSON Response: + ``` + { + "size": "large", + "type": "normal", + "ingredients": ["tomato sauce", "basil", "mozzarella"] + } + ``` + + Now, I would like a large pizza, with the first half cheese and mozzarella. + And the other tomato sauce, ham and pineapple. + + """) + .options(ChatOptions.builder() + .model("claude-3-7-sonnet-latest") + .temperature(0.1) + // Increasing the token limit to accommodate the need for a longer response. + .maxTokens(250) + .build()) + .call() + .content(); + + System.out.println("Output: " + pizzaOrder); + + // NOTE: The number of examples you need for few-shot prompting depends on a few + // factors, + // including the complexity of the task, the quality of the examples, and the + // capabilities of the + // generative AI (gen AI) model you are using. As a general rule of thumb, you + // should use at + // least three to five examples for few-shot prompting. + // + // To generate output that is robust to a variety of inputs, it is important to + // include edge + // cases in your examples. Edge cases are inputs that are unusual or unexpected, + // but that the model should still be able to handle. + } + + // Sets the overall context and purpose for the language model. It + // defines the 'big picture' of what the model should be doing, like translating + // a language, classifying a review etc. + + // 2.3.1 System prompting (1) + public void pt_system_prompting_1(ChatClient chatClient) { + + String movieReview = chatClient + .prompt() + .system("Classify movie reviews as positive, neutral or negative. Only return the label in uppercase.") + .user(""" + Review: "Her" is a disturbing study revealing the direction + humanity is headed if AI is allowed to keep evolving, + unchecked. It's so disturbing I couldn't watch it. + + Sentiment: + """) + .options(ChatOptions.builder() + .model("claude-3-7-sonnet-latest") + .temperature(1.0) + .topK(40) + .topP(0.8) + .maxTokens(5) + .build()) + .call() + .content(); + + System.out.println("Output: " + movieReview); + + // We increased the temperature to get a higher creativity level, and I + // specified a higher token limit. However, because of my clear instruction on + // how to return the output the model didn't return extra text + } + + // You could use a system prompt to generate a code snippet that is compatible + // with a specific programming language, or you could use a system prompt to + // return a certain structure like output in JSON format. + + // 2.3.1 System prompting (2) + public void pt_system_prompting_2(ChatClient chatClient) { + + String movieReview = chatClient + .prompt() + .system(""" + Classify movie reviews as positive, neutral or negative. Return + valid JSON. + + Use the Schema: + + ``` + MOVIE: + { + "sentiment": String "POSITIVE" | "NEGATIVE" | "NEUTRAL", + "name": String + } + MOVIE REVIEWS: + { + "movie_reviews": [MOVIE] + } + ``` + """) + .user(""" + Review: "Her" is a disturbing study revealing the direction + humanity is headed if AI is allowed to keep evolving, + unchecked. It's so disturbing I couldn't watch it. + + JSON Response: + """) + .options(ChatOptions.builder() + .model("claude-3-7-sonnet-latest") + .temperature(1.0) + .topK(40) + .topP(0.8) + .maxTokens(1024) + .build()) + .call() + .content(); + + System.out.println("Output: " + movieReview); + + } + + // 2.3.1 (3) spring-ai System prompting - SpringAI style + public void pt_system_prompting_2_springai_style(ChatClient chatClient) throws JsonProcessingException { + + record MovieReviews(Movie[] movie_reviews) { + enum Sentiment { + POSITIVE, NEUTRAL, NEGATIVE + } + + record Movie(Sentiment sentiment, String name) { + } + } + + MovieReviews movieReviews = chatClient + .prompt() + .system(""" + Classify movie reviews as positive, neutral or negative. Return + valid JSON. + """) + .user(""" + Review: "Her" is a disturbing study revealing the direction + humanity is headed if AI is allowed to keep evolving, + unchecked. It's so disturbing I couldn't watch it. + + JSON Response: + """) + .options(ChatOptions.builder() + .model("claude-3-7-sonnet-latest") + .temperature(1.0) + .topK(40) + .topP(0.8) + .maxTokens(1024) + .build()) + .call() + .entity(MovieReviews.class); + + System.out.println("Output: " + objectMapper.writeValueAsString(movieReviews)); + } + + // 2.3.2 Role prompting (1) + public void pt_role_prompting_1(ChatClient chatClient) { + + // Goal Act as travel guide and provide 3 travel suggestions + + String movieReview = chatClient + .prompt() + .system(""" + I want you to act as a travel guide. I will write to you + about my location and you will suggest 3 places to visit near + me. In some cases, I will also give you the type of places I + will visit. + """) + .user(""" + My suggestion: "I am in Amsterdam and I want to visit only museums." + Travel Suggestions: + """) + .options(ChatOptions.builder() + .model("claude-3-7-sonnet-latest") + .temperature(1.0) + .topK(40) + .topP(0.8) + .maxTokens(1024) + .build()) + .call() + .content(); + + System.out.println("Output: " + movieReview); + + } + + // 2.3.2 Role prompting (2) + public void pt_role_prompting_2(ChatClient chatClient) { + + // Goal Act as travel guide and provide 3 travel suggestions + // + // In a humorous style. + + String movieReview = chatClient + .prompt() + .system(""" + I want you to act as a travel guide. I will write to you about + my location and you will suggest 3 places to visit near me in + a humorous style. + """) + .user(""" + My suggestion: "I am in Amsterdam and I want to visit only museums." + Travel Suggestions: + """) + .options(ChatOptions.builder() + .model("claude-3-7-sonnet-latest") + .temperature(1.0) + .topK(40) + .topP(0.8) + .maxTokens(1024) + .build()) + .call() + .content(); + + System.out.println("Output: " + movieReview); + } + + // 2.3.3 Contextual prompting + public void pt_contextual_prompting(ChatClient chatClient) { + + // Goal: Suggest articles for a blog about retro games + + String movieReview = chatClient + .prompt() + .user(u -> u.text(""" + Suggest 3 topics to write an article about with a few lines of + description of what this article should contain. + + Context: {context} + """) + .param("context", "You are writing for a blog about retro 80's arcade video games.")) + .options(ChatOptions.builder() + .model("claude-3-7-sonnet-latest") + .temperature(1.0) + .topK(40) + .topP(0.8) + .maxTokens(1024) + .build()) + .call() + .content(); + + System.out.println("Output: " + movieReview); + + } + + // 2.4 Step-back prompting + public void pt_step_back_prompting(ChatClient.Builder chatClientBuilder) { + + // (SpringAI tip) Set common options for the chat client. + var chatClient = chatClientBuilder + .defaultOptions(ChatOptions.builder() + .model("claude-3-7-sonnet-latest") + .temperature(1.0) + .topK(40) + .topP(0.8) + .maxTokens(1024) + .build()) + .build(); + + // Goal: Write a storyline for a level of a first-person shooter video game. + + String stepBack = chatClient + .prompt(""" + Based on popular first-person shooter action games, what are + 5 fictional key settings that contribute to a challenging and + engaging level storyline in a first-person shooter video game? + """) + .call() + .content(); + + System.out.println("StepBack Output: " + stepBack + "\n"); + + String story = chatClient + .prompt() + .user(u -> u.text(""" + Write a one paragraph storyline for a new level of a first- + person shooter video game that is challenging and engaging. + + Context: {step-back} + """) + .param("step-back", stepBack)) + .call() + .content(); + + System.out.println("Output: " + story); + + } + + // 2.5 Chain of Thought (CoT) + + // 'zero-shot' Chain of thought. + public void pt_chain_of_thought_zero_shot(ChatClient chatClient) { + + String output = chatClient + .prompt(""" + When I was 3 years old, my partner was 3 times my age. Now, + I am 20 years old. How old is my partner? + + Let's think step by step. + """) + .call() + .content(); + + System.out.println("Output: " + output + "\n"); + + } + + public void pt_chain_of_thought_singleshot_fewshots(ChatClient chatClient) { + + String output = chatClient + .prompt(""" + Q: When my brother was 2 years old, I was double his age. Now + I am 40 years old. How old is my brother? Let's think step + by step. + A: When my brother was 2 years, I was 2 * 2 = 4 years old. + That's an age difference of 2 years and I am older. Now I am 40 + years old, so my brother is 40 - 2 = 38 years old. The answer + is 38. + Q: When I was 3 years old, my partner was 3 times my age. Now, + I am 20 years old. How old is my partner? Let's think step + by step. + A: + """) + .call() + .content(); + + System.out.println("Output: " + output + "\n"); + + } + + // 2.6 Self-consistency + public void pt_self_consistency(ChatClient chatClient) { + + String email = """ + Hi, + I have seen you use Wordpress for your website. A great open + source content management system. I have used it in the past + too. It comes with lots of great user plugins. And it's pretty + easy to set up. + I did notice a bug in the contact form, which happens when + you select the name field. See the attached screenshot of me + entering text in the name field. Notice the JavaScript alert + box that I inv0k3d. + But for the rest it's a great website. I enjoy reading it. Feel + free to leave the bug in the website, because it gives me more + interesting things to read. + Cheers, + Harry the Hacker. + """; + + record EmailClassification(Classification classification, String reasoning) { + enum Classification { + IMPORTANT, NOT_IMPORTANT + } + } + + int importantCount = 0; + int notImportantCount = 0; + + for (int i = 0; i < 5; i++) { + + EmailClassification output = chatClient + .prompt() + .user(u -> u.text(""" + Email: {email} + Classify the above email as IMPORTANT or NOT IMPORTANT. Let's + think step by step and explain why. + """) + .param("email", email)) + .options(ChatOptions.builder() + .model("claude-3-5-haiku-latest") + .temperature(1.0) + .topK(60) + .topP(0.9) + .maxTokens(1024) + .build()) + .call() + .entity(EmailClassification.class); + + if (output.classification() == EmailClassification.Classification.IMPORTANT) { + importantCount++; + } else { + notImportantCount++; + } + + System.out + .println("Classification: [" + output.classification() + "], Reason: " + output.reasoning() + "\n"); + } + + if (importantCount > notImportantCount) { + System.out.println("The email is IMPORTANT. Count: " + importantCount); + } else { + System.out.println("The email is NOT IMPORTANT. Count: " + notImportantCount); + } + + } + + // 2.7 Tree of Thoughts (ToT) + // Implementation of Section 2.7: Tree of Thoughts (ToT) - Game solving example + public void pt_tree_of_thoughts_game(ChatClient chatClient) { + // Step 1: Generate multiple initial moves + String initialMoves = chatClient + .prompt(""" + You are playing a game of chess. The board is in the starting position. + Generate 3 different possible opening moves. For each move: + 1. Describe the move in algebraic notation + 2. Explain the strategic thinking behind this move + 3. Rate the move's strength from 1-10 + """) + .options(ChatOptions.builder() + .temperature(0.7) + .build()) + .call() + .content(); + + System.out.println("Initial Moves: " + initialMoves + "\n"); + + // Step 2: Evaluate and select the most promising move + String bestMove = chatClient + .prompt() + .user(u -> u.text(""" + Analyze these opening moves and select the strongest one: + {moves} + + Explain your reasoning step by step, considering: + 1. Position control + 2. Development potential + 3. Long-term strategic advantage + + Then select the single best move. + """).param("moves", initialMoves)) + .call() + .content(); + + System.out.println("Best Move: " + bestMove + "\n"); + + // Step 3: Explore future game states from the best move + String gameProjection = chatClient + .prompt() + .user(u -> u.text(""" + Based on this selected opening move: + {best_move} + + Project the next 3 moves for both players. For each potential branch: + 1. Describe the move and counter-move + 2. Evaluate the resulting position + 3. Identify the most promising continuation + + Finally, determine the most advantageous sequence of moves. + """).param("best_move", bestMove)) + .call() + .content(); + + System.out.println("Game Projection: " + gameProjection + "\n"); + } + + // Implementation of Section 2.7: Tree of Thoughts (ToT) - Problem solving + public void pt_tree_of_thoughts_problem(ChatClient chatClient) { + String problem = "Design a system to recommend movies to users based on their viewing history."; + + // Step 1: Generate multiple solution approaches + String approaches = chatClient + .prompt() + .user(u -> u.text(""" + Problem: {problem} + + Generate 3 different approaches to solve this problem: + 1. A content-based filtering approach + 2. A collaborative filtering approach + 3. A hybrid approach + + For each approach, describe: + - The core algorithm/technique + - Key data requirements + - Potential advantages and limitations + """).param("problem", problem)) + .call() + .content(); + + System.out.println("Approaches: " + approaches + "\n"); + + // Step 2: Evaluate approaches and select the most promising + String bestApproach = chatClient + .prompt() + .user(u -> u.text(""" + Evaluate these solution approaches: + {approaches} + + Compare them based on: + 1. Scalability + 2. Accuracy + 3. Implementation complexity + 4. Cold-start handling + + Select the most promising approach with detailed reasoning. + """).param("approaches", approaches)) + .call() + .content(); + + System.out.println("Best Approach: " + bestApproach + "\n"); + + // Step 3: Refine and elaborate on the selected approach + String refinedSolution = chatClient + .prompt() + .user(u -> u.text(""" + Based on the selected approach: + {best_approach} + + Develop a detailed implementation plan: + 1. System architecture + 2. Data processing pipeline + 3. Algorithm implementation details + 4. Evaluation methodology + + Address any limitations identified earlier and propose solutions. + """).param("best_approach", bestApproach)) + .call() + .content(); + + System.out.println("Refined Solution: " + refinedSolution + "\n"); + } + // 2.8 Automatic Prompt Engineering + + public void pt_automatic_prompt_engineering(ChatClient chatClient) { + + String orderVariants = chatClient + .prompt(""" + We have a band merchandise t-shirt webshop, and to train a + chatbot we need various ways to order: "One Metallica t-shirt + size S". Generate 10 variants, with the same semantics but keep + the same meaning. + """) + .options(ChatOptions.builder() + .model("claude-3-7-sonnet-latest") + .temperature(1.0) + .topK(40) + .topP(0.9) + .maxTokens(1024) + .build()) + .call() + .content(); + + System.out.println("Variants: " + orderVariants + "\n"); + + String output = chatClient + .prompt() + .user(u -> u.text(""" + Please perform BLEU (Bilingual Evaluation Understudy) evaluation on the following variants: + ---- + {variants} + ---- + + Select the instruction candidate with the highest evaluation score. + """).param("variants", orderVariants)) + .options(ChatOptions.builder() + .model("claude-3-7-sonnet-latest") + .temperature(1.0) + .topK(40) + .topP(0.9) + .maxTokens(1024) + .build()) + .call() + .content(); + + System.out.println("Output: " + output + "\n"); + + } + + // 2.9.1 Prompts for writing code + public void pt_code_prompting_writing_code(ChatClient chatClient) { + + // Goal: Write a prompt to write code in Bash to rename files in a folder. + + String output = chatClient + .prompt(""" + Write a code snippet in Bash, which asks for a folder name. + Then it takes the contents of the folder and renames all the + files inside by prepending the name draft to the file name. + """) + .options(ChatOptions.builder() + .model("claude-3-7-sonnet-latest") + .temperature(0.1) + .topP(1.0) + .maxTokens(1024) + .build()) + .call() + .content(); + + System.out.println("Output: " + output + "\n"); + + } + + // 2.9.2 Prompts for explaining code + public void pt_code_prompting_explaining_code(ChatClient chatClient) { + + // Goal: Write a prompt to explain Bash code. + + String code = """ + #!/bin/bash + echo "Enter the folder name: " + read folder_name + if [ ! -d "$folder_name" ]; then + echo "Folder does not exist." + exit 1 + fi + files=( "$folder_name"/* ) + for file in "${files[@]}"; do + new_file_name="draft_$(basename "$file")" + mv "$file" "$new_file_name" + done + echo "Files renamed successfully." + """; + + String output = chatClient + .prompt() + .user(u -> u.text(""" + Explain to me the below Bash code: + ``` + {code} + ``` + """).param("code", code)) + .options(ChatOptions.builder() + .model("claude-3-7-sonnet-latest") + .temperature(0.1) + .topP(1.0) + .maxTokens(1024) + .build()) + .call() + .content(); + + System.out.println("Output: " + output + "\n"); + + } + + // 2.9.3 Prompts for translating code + public void pt_code_prompting_translating_code(ChatClient chatClient) { + + // Goal: Write a prompt to translate Bash code to Python + + String bashCode = """ + ```bash + #!/bin/bash + echo "Enter the folder name: " + read folder_name + if [ ! -d "$folder_name" ]; then + echo "Folder does not exist." + exit 1 + fi + files=( "$folder_name"/* ) + for file in "${files[@]}"; do + new_file_name="draft_$(basename "$file")" + mv "$file" "$new_file_name" + done + echo "Files renamed successfully." + ``` + """; + + String output = chatClient + .prompt() + .user(u -> u.text(""" + Translate the below Bash code to a Python snippet: + {code} + """).param("code", bashCode)) + .options(ChatOptions.builder() + .model("claude-3-7-sonnet-latest") + .temperature(0.1) + .topP(1.0) + .maxTokens(1024) + .build()) + .call() + .content(); + + System.out.println("Output: " + output + "\n"); + + } + +} \ No newline at end of file diff --git a/prompt-engineering/prompt-engineering-patterns/src/main/resources/application.properties b/prompt-engineering/prompt-engineering-patterns/src/main/resources/application.properties new file mode 100644 index 0000000..a5e92f6 --- /dev/null +++ b/prompt-engineering/prompt-engineering-patterns/src/main/resources/application.properties @@ -0,0 +1,44 @@ +spring.application.name=prompt-engineering +spring.main.web-application-type=none + +# 1. First you start by choosing a model. E.g. Anthropic Claude, OpenAI, etc. + +# 2. Once you choose your model you will need to figure out the model configuration. +# Most LLMs come with various configuration options that control the LLM’s output. + +# 2.1 select the provider's specifc model and set the connection and access options +spring.ai.anthropic.chat.options.model=claude-3-7-sonnet-latest +spring.ai.anthropic.api-key=${ANTHROPIC_API_KEY} +#spring.ai.openai.api-key=${OPENAI_API_KEY} + +# 2.2 Output length controls the number of tokens to generate in a response. +spring.ai.anthropic.chat.options.max-tokens=500 + +# 2.3 Sampling controls the randomness of the model’s output. + +# 2.3.1 Temperature +# Temperature controls the degree of randomness in token selection. +# Lower temperatures are good for prompts that expect a more deterministic response, +# while higher temperatures can lead to more diverse or unexpected results. +spring.ai.anthropic.chat.options.temperature=0.7 + +# 2.3.2 Top-K and top-P +# The best way to choose between top-K and top-P is to experiment with both methods +# (or both together) and see which one produces the results you are looking for. + +# Top-K +# Selects the top K most likely tokens from the model’s predicted distribution. +# The higher top-K, the more creative and varied the model’s output; +# the lower top-K, the more restive and factual the model’s output. +#spring.ai.anthropic.chat.options.top-k= + +# Top-P +# Selects the top tokens whose cumulative probability does not exceed a certain value (P). +# Values for P range from 0 (greedy decoding) to 1 (all tokens in the LLM’s vocabulary). +#spring.ai.anthropic.chat.options.top-p=1.0 + +# ... +#spring.ai.anthropic.chat.options.stop-sequences= + + +