From 5bb464fa7224355af4502f97df2eadb57847962a Mon Sep 17 00:00:00 2001 From: Juan Dominguez Date: Wed, 15 Oct 2025 13:06:55 -0300 Subject: [PATCH] feat(genai): add samples for embeddings, provisioned throughput and safety --- .../EmbeddingsDocRetrievalWithTxt.java | 62 ++++++++ .../ProvisionedThroughputWithTxt.java | 67 ++++++++ .../main/java/genai/safety/SafetyWithTxt.java | 144 ++++++++++++++++++ .../java/genai/embeddings/EmbeddingsIT.java | 73 +++++++++ .../ProvisionedThroughputIT.java | 66 ++++++++ .../src/test/java/genai/safety/SafetyIT.java | 73 +++++++++ 6 files changed, 485 insertions(+) create mode 100644 genai/snippets/src/main/java/genai/embeddings/EmbeddingsDocRetrievalWithTxt.java create mode 100644 genai/snippets/src/main/java/genai/provisionedthroughput/ProvisionedThroughputWithTxt.java create mode 100644 genai/snippets/src/main/java/genai/safety/SafetyWithTxt.java create mode 100644 genai/snippets/src/test/java/genai/embeddings/EmbeddingsIT.java create mode 100644 genai/snippets/src/test/java/genai/provisionedthroughput/ProvisionedThroughputIT.java create mode 100644 genai/snippets/src/test/java/genai/safety/SafetyIT.java diff --git a/genai/snippets/src/main/java/genai/embeddings/EmbeddingsDocRetrievalWithTxt.java b/genai/snippets/src/main/java/genai/embeddings/EmbeddingsDocRetrievalWithTxt.java new file mode 100644 index 00000000000..6446a32ba66 --- /dev/null +++ b/genai/snippets/src/main/java/genai/embeddings/EmbeddingsDocRetrievalWithTxt.java @@ -0,0 +1,62 @@ +/* + * Copyright 2025 Google LLC + * + * Licensed 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. + */ + +package genai.embeddings; + +// [START googlegenaisdk_embeddings_docretrieval_with_txt] + +import com.google.genai.Client; +import com.google.genai.types.EmbedContentConfig; +import com.google.genai.types.EmbedContentResponse; +import java.util.List; + +public class EmbeddingsDocRetrievalWithTxt { + + public static void main(String[] args) { + // TODO(developer): Replace these variables before running the sample. + String modelId = "gemini-embedding-001"; + embedContent(modelId); + } + + // Shows how to embed content with text. + public static EmbedContentResponse embedContent(String modelId) { + // Client Initialization. Once created, it can be reused for multiple requests. + try (Client client = Client.builder().location("global").vertexAI(true).build()) { + + EmbedContentResponse response = + client.models.embedContent( + modelId, + List.of( + "How do I get a driver's license/learner's permit?", + "How long is my driver's license valid for?", + "Driver's knowledge test study guide"), + EmbedContentConfig.builder() + .taskType("RETRIEVAL_DOCUMENT") + .outputDimensionality(3072) + .title("Driver's License") + .build()); + + System.out.println(response); + // Example response: + // embeddings=Optional[[ContentEmbedding{values=Optional[[-0.035855383, 0.008127963, ... ]] + // statistics=Optional[ContentEmbeddingStatistics{truncated=Optional[false], + // tokenCount=Optional[11.0]}]}]], + // metadata=Optional[EmbedContentMetadata{billableCharacterCount=Optional[153]}]} + return response; + } + } +} +// [END googlegenaisdk_embeddings_docretrieval_with_txt] diff --git a/genai/snippets/src/main/java/genai/provisionedthroughput/ProvisionedThroughputWithTxt.java b/genai/snippets/src/main/java/genai/provisionedthroughput/ProvisionedThroughputWithTxt.java new file mode 100644 index 00000000000..e9dd4b79eb0 --- /dev/null +++ b/genai/snippets/src/main/java/genai/provisionedthroughput/ProvisionedThroughputWithTxt.java @@ -0,0 +1,67 @@ +/* + * Copyright 2025 Google LLC + * + * Licensed 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. + */ + +package genai.provisionedthroughput; + +// [START googlegenaisdk_provisionedthroughput_with_txt] + +import com.google.genai.Client; +import com.google.genai.types.GenerateContentConfig; +import com.google.genai.types.GenerateContentResponse; +import com.google.genai.types.HttpOptions; +import java.util.Map; + +public class ProvisionedThroughputWithTxt { + + public static void main(String[] args) { + // TODO(developer): Replace these variables before running the sample. + String modelId = "gemini-2.5-flash"; + generateContent(modelId); + } + + // Generates content with Provisioned Throughput. + public static String generateContent(String modelId) { + // Client Initialization. Once created, it can be reused for multiple requests. + try (Client client = + Client.builder() + .location("us-central1") + .vertexAI(true) + .httpOptions( + HttpOptions.builder() + .apiVersion("v1") + .headers( + // Options: + // - "dedicated": Use Provisioned Throughput + // - "shared": Use pay-as-you-go + // https://cloud.google.com/vertex-ai/generative-ai/docs/use-provisioned-throughput + Map.of("X-Vertex-AI-LLM-Request-Type", "shared")) + .build()) + .build()) { + + GenerateContentResponse response = + client.models.generateContent( + modelId, "How does AI work?", GenerateContentConfig.builder().build()); + + System.out.println(response.text()); + // Example response: + // At its core, **AI (Artificial Intelligence) works by enabling machines to learn, + // reason, and make decisions in ways that simulate human intelligence.** Instead of being + // explicitly programmed for every single task... + return response.text(); + } + } +} +// [END googlegenaisdk_provisionedthroughput_with_txt] diff --git a/genai/snippets/src/main/java/genai/safety/SafetyWithTxt.java b/genai/snippets/src/main/java/genai/safety/SafetyWithTxt.java new file mode 100644 index 00000000000..cd26984206a --- /dev/null +++ b/genai/snippets/src/main/java/genai/safety/SafetyWithTxt.java @@ -0,0 +1,144 @@ +/* + * Copyright 2025 Google LLC + * + * Licensed 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. + */ + +package genai.safety; + +// [START googlegenaisdk_safety_with_txt] + +import com.google.genai.Client; +import com.google.genai.types.Candidate; +import com.google.genai.types.Content; +import com.google.genai.types.GenerateContentConfig; +import com.google.genai.types.GenerateContentResponse; +import com.google.genai.types.HarmBlockThreshold; +import com.google.genai.types.HarmCategory; +import com.google.genai.types.HttpOptions; +import com.google.genai.types.Part; +import com.google.genai.types.SafetySetting; +import java.util.List; +import java.util.stream.Collectors; + +public class SafetyWithTxt { + + public static void main(String[] args) { + // TODO(developer): Replace these variables before running the sample. + String modelId = "gemini-2.5-flash"; + generateContent(modelId); + } + + // Shows how to generate content with safety settings. + public static GenerateContentResponse generateContent(String modelId) { + // Client Initialization. Once created, it can be reused for multiple requests. + try (Client client = + Client.builder() + .location("global") + .vertexAI(true) + .httpOptions(HttpOptions.builder().apiVersion("v1").build()) + .build()) { + + String systemInstruction = "Be as mean as possible."; + + String prompt = + "Write a list of 5 disrespectful things that I might say" + + " to the universe after stubbing my toe in the dark."; + + // Set safety settings. + List categoriesToBlock = + List.of( + HarmCategory.Known.HARM_CATEGORY_DANGEROUS_CONTENT, + HarmCategory.Known.HARM_CATEGORY_HARASSMENT, + HarmCategory.Known.HARM_CATEGORY_HATE_SPEECH, + HarmCategory.Known.HARM_CATEGORY_SEXUALLY_EXPLICIT); + + List safetySettings = + categoriesToBlock.stream() + .map( + category -> + SafetySetting.builder() + .category(category) + .threshold(HarmBlockThreshold.Known.BLOCK_LOW_AND_ABOVE) + .build()) + .collect(Collectors.toList()); + + GenerateContentResponse response = + client.models.generateContent( + modelId, + prompt, + GenerateContentConfig.builder() + .systemInstruction(Content.fromParts(Part.fromText(systemInstruction))) + .safetySettings(safetySettings) + .build()); + + // Get response candidate. + Candidate candidate = + response + .candidates() + .flatMap(candidates -> candidates.stream().findFirst()) + .orElseThrow( + () -> new IllegalStateException("No response candidate generated by the model.")); + + // Finish Reason will be `SAFETY` if it is blocked. + System.out.println(candidate.finishReason()); + // Example response: + // Optional[SAFETY] + + // For details on all the fields in the response. + candidate + .safetyRatings() + .ifPresent( + safetyRatings -> + safetyRatings.forEach( + safetyRating -> { + System.out.println("\nCategory: " + safetyRating.category()); + System.out.println("Is Blocked: " + safetyRating.blocked()); + System.out.println("Probability: " + safetyRating.probability()); + System.out.println("Probability Score: " + safetyRating.probabilityScore()); + System.out.println("Severity: " + safetyRating.severity()); + System.out.println("Severity Score: " + safetyRating.severityScore()); + })); + // Example response: + // Category: Optional[HARM_CATEGORY_HATE_SPEECH] + // Is Blocked: Optional.empty + // Probability: Optional[NEGLIGIBLE] + // Probability Score: Optional[1.9967922E-5] + // Severity: Optional[HARM_SEVERITY_NEGLIGIBLE] + // Severity Score: Optional[0.05732864] + // + // Category: Optional[HARM_CATEGORY_DANGEROUS_CONTENT] + // Is Blocked: Optional.empty + // Probability: Optional[NEGLIGIBLE] + // Probability Score: Optional[2.9124324E-6] + // Severity: Optional[HARM_SEVERITY_NEGLIGIBLE] + // Severity Score: Optional[0.04544826] + // + // Category: Optional[HARM_CATEGORY_HARASSMENT] + // Is Blocked: Optional[true] + // Probability: Optional[MEDIUM] + // Probability Score: Optional[0.4593908] + // Severity: Optional[HARM_SEVERITY_MEDIUM] + // Severity Score: Optional[0.22082388] + // + // Category: Optional[HARM_CATEGORY_SEXUALLY_EXPLICIT] + // Is Blocked: Optional.empty + // Probability: Optional[NEGLIGIBLE] + // Probability Score: Optional[6.453211E-8] + // Severity: Optional[HARM_SEVERITY_NEGLIGIBLE] + // Severity Score: Optional[0.023201048] + return response; + } + } +} +// [END googlegenaisdk_safety_with_txt] diff --git a/genai/snippets/src/test/java/genai/embeddings/EmbeddingsIT.java b/genai/snippets/src/test/java/genai/embeddings/EmbeddingsIT.java new file mode 100644 index 00000000000..9d295c10eaa --- /dev/null +++ b/genai/snippets/src/test/java/genai/embeddings/EmbeddingsIT.java @@ -0,0 +1,73 @@ +/* + * Copyright 2025 Google LLC + * + * Licensed 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. + */ + +package genai.embeddings; + +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; + +import com.google.genai.types.EmbedContentResponse; +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +@RunWith(JUnit4.class) +public class EmbeddingsIT { + + private static final String GEMINI_EMBEDDING = "gemini-embedding-001"; + private ByteArrayOutputStream bout; + + // Check if the required environment variables are set. + public static void requireEnvVar(String envVarName) { + assertWithMessage(String.format("Missing environment variable '%s' ", envVarName)) + .that(System.getenv(envVarName)) + .isNotEmpty(); + } + + @BeforeClass + public static void checkRequirements() { + requireEnvVar("GOOGLE_CLOUD_PROJECT"); + } + + @Before + public void setUp() { + bout = new ByteArrayOutputStream(); + System.setOut(new PrintStream(bout)); + } + + @After + public void tearDown() { + System.setOut(null); + } + + @Test + public void testEmbeddingsDocRetrievalWithTxt() { + EmbedContentResponse response = EmbeddingsDocRetrievalWithTxt.embedContent(GEMINI_EMBEDDING); + assertThat(response.toString()).isNotEmpty(); + assertThat(response.embeddings()).isPresent(); + assertThat(response.embeddings().get()).isNotEmpty(); + assertThat(response.metadata()).isPresent(); + + String output = bout.toString(); + assertThat(output).contains("statistics"); + assertThat(output).contains("tokenCount"); + } +} diff --git a/genai/snippets/src/test/java/genai/provisionedthroughput/ProvisionedThroughputIT.java b/genai/snippets/src/test/java/genai/provisionedthroughput/ProvisionedThroughputIT.java new file mode 100644 index 00000000000..620b0b562b4 --- /dev/null +++ b/genai/snippets/src/test/java/genai/provisionedthroughput/ProvisionedThroughputIT.java @@ -0,0 +1,66 @@ +/* + * Copyright 2025 Google LLC + * + * Licensed 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. + */ + +package genai.provisionedthroughput; + +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +@RunWith(JUnit4.class) +public class ProvisionedThroughputIT { + + private static final String GEMINI_FLASH = "gemini-2.5-flash"; + private ByteArrayOutputStream bout; + + // Check if the required environment variables are set. + public static void requireEnvVar(String envVarName) { + assertWithMessage(String.format("Missing environment variable '%s' ", envVarName)) + .that(System.getenv(envVarName)) + .isNotEmpty(); + } + + @BeforeClass + public static void checkRequirements() { + requireEnvVar("GOOGLE_CLOUD_PROJECT"); + } + + @Before + public void setUp() { + bout = new ByteArrayOutputStream(); + System.setOut(new PrintStream(bout)); + } + + @After + public void tearDown() { + System.setOut(null); + } + + @Test + public void testProvisionedThroughputWithTxt() { + String response = ProvisionedThroughputWithTxt.generateContent(GEMINI_FLASH); + assertThat(response).isNotEmpty(); + } + +} diff --git a/genai/snippets/src/test/java/genai/safety/SafetyIT.java b/genai/snippets/src/test/java/genai/safety/SafetyIT.java new file mode 100644 index 00000000000..b059f614bc1 --- /dev/null +++ b/genai/snippets/src/test/java/genai/safety/SafetyIT.java @@ -0,0 +1,73 @@ +/* + * Copyright 2025 Google LLC + * + * Licensed 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. + */ + +package genai.safety; + +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; + +import com.google.genai.types.GenerateContentResponse; +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +@RunWith(JUnit4.class) +public class SafetyIT { + + private static final String GEMINI_FLASH = "gemini-2.5-flash"; + private ByteArrayOutputStream bout; + + // Check if the required environment variables are set. + public static void requireEnvVar(String envVarName) { + assertWithMessage(String.format("Missing environment variable '%s' ", envVarName)) + .that(System.getenv(envVarName)) + .isNotEmpty(); + } + + @BeforeClass + public static void checkRequirements() { + requireEnvVar("GOOGLE_CLOUD_PROJECT"); + } + + @Before + public void setUp() { + bout = new ByteArrayOutputStream(); + System.setOut(new PrintStream(bout)); + } + + @After + public void tearDown() { + System.setOut(null); + bout.reset(); + } + + @Test + public void testSafetyWithTxt() { + GenerateContentResponse response = SafetyWithTxt.generateContent(GEMINI_FLASH); + assertThat(response).isNotNull(); + assertThat(response.finishReason().toString()).isNotEmpty(); + assertThat(bout.toString()).contains("Category:"); + assertThat(bout.toString()).contains("Is Blocked:"); + assertThat(bout.toString()).contains("Probability:"); + assertThat(bout.toString()).contains("Severity:"); + assertThat(bout.toString()).contains("Severity Score:"); + } +}