-
Notifications
You must be signed in to change notification settings - Fork 2.9k
feat(genai): add thinking samples #10160
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
jdomingr
wants to merge
6
commits into
GoogleCloudPlatform:main
Choose a base branch
from
jdomingr:genai-sdk-thinking-samples
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+380
−0
Open
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
2ae0919
feat: add new genAI thinking with text sample
2a1028d
feat: add new GenAI sdk thinking with budget sample
5771f64
feat: add new GenAI sdk thinking with thoughts sample
e855135
feat(genai): add test for ThinkingIncludeThoughts sample
b7417c7
refactor: change the way of getting the first candidate for an stream…
410c1a6
refactor: change gemini model and change example responses
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
79 changes: 79 additions & 0 deletions
79
genai/snippets/src/main/java/genai/thinking/ThinkingBudgetWithText.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
/* | ||
* 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.thinking; | ||
|
||
// [START googlegenaisdk_thinking_budget_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 com.google.genai.types.ThinkingConfig; | ||
|
||
public class ThinkingBudgetWithText { | ||
|
||
public static void main(String[] args) { | ||
// TODO(developer): Replace these variables before running the sample. | ||
String modelId = "gemini-2.5-flash"; | ||
generateContent(modelId); | ||
} | ||
|
||
// Generates text controlling the thinking budget | ||
public static String generateContent(String modelId) { | ||
// Initialize client that will be used to send requests. This client only needs to be created | ||
// once, and can be reused for multiple requests. | ||
try (Client client = | ||
Client.builder() | ||
.location("global") | ||
.vertexAI(true) | ||
.httpOptions(HttpOptions.builder().apiVersion("v1").build()) | ||
.build()) { | ||
|
||
GenerateContentConfig contentConfig = | ||
GenerateContentConfig.builder() | ||
.thinkingConfig(ThinkingConfig.builder().thinkingBudget(1024).build()) | ||
.build(); | ||
|
||
GenerateContentResponse response = | ||
client.models.generateContent(modelId, "solve x^2 + 4x + 4 = 0", contentConfig); | ||
|
||
System.out.println(response.text()); | ||
// Example response: | ||
// To solve the equation $x^2 + 4x + 4 = 0$, we can use several methods: | ||
// | ||
// **Method 1: Factoring (Recognizing a Perfect Square Trinomial)** | ||
// | ||
// Notice that the left side of the equation is a perfect square trinomial. It fits the form | ||
// $a^2 + 2ab + b^2 = (a+b)^2$... | ||
// ... | ||
// The solution is $x = -2$. | ||
|
||
response | ||
.usageMetadata() | ||
.ifPresent( | ||
metadata -> { | ||
System.out.println("Token count for thinking: " + metadata.thoughtsTokenCount()); | ||
System.out.println("Total token count: " + metadata.totalTokenCount()); | ||
}); | ||
// Example response: | ||
// Token count for thinking: Optional[885] | ||
// Total token count: Optional[1468] | ||
return response.text(); | ||
} | ||
} | ||
} | ||
// [END googlegenaisdk_thinking_budget_with_txt] |
118 changes: 118 additions & 0 deletions
118
genai/snippets/src/main/java/genai/thinking/ThinkingIncludeThoughtsWithText.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
/* | ||
* 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.thinking; | ||
|
||
// [START googlegenaisdk_thinking_includethoughts_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.HttpOptions; | ||
import com.google.genai.types.ThinkingConfig; | ||
|
||
public class ThinkingIncludeThoughtsWithText { | ||
|
||
public static void main(String[] args) { | ||
// TODO(developer): Replace these variables before running the sample. | ||
String modelId = "gemini-2.5-pro"; | ||
generateContent(modelId); | ||
} | ||
|
||
// Generates text including thoughts in the response | ||
public static String generateContent(String modelId) { | ||
// Initialize client that will be used to send requests. This client only needs to be created | ||
// once, and can be reused for multiple requests. | ||
try (Client client = | ||
Client.builder() | ||
.location("global") | ||
.vertexAI(true) | ||
.httpOptions(HttpOptions.builder().apiVersion("v1").build()) | ||
.build()) { | ||
|
||
GenerateContentConfig contentConfig = | ||
GenerateContentConfig.builder() | ||
.thinkingConfig(ThinkingConfig.builder().includeThoughts(true).build()) | ||
.build(); | ||
|
||
GenerateContentResponse response = | ||
client.models.generateContent(modelId, "solve x^2 + 4x + 4 = 0", contentConfig); | ||
|
||
System.out.println(response.text()); | ||
// Example response: | ||
// We can solve the equation x² + 4x + 4 = 0 using a couple of common methods. | ||
// | ||
// ### Method 1: Factoring (The Easiest Method for this Problem) | ||
// **Recognize the pattern:** The pattern for a perfect square trinomial | ||
// is a² + 2ab + b² = (a + b)². | ||
// ... | ||
// ### Final Answer: | ||
// The solution is **x = -2**. | ||
|
||
// Get parts of the response and print thoughts | ||
response | ||
.candidates() | ||
.flatMap(candidates -> candidates.stream().findFirst()) | ||
.flatMap(Candidate::content) | ||
.flatMap(Content::parts) | ||
.ifPresent( | ||
parts -> { | ||
parts.forEach( | ||
part -> { | ||
if (part.thought().orElse(false)) { | ||
part.text().ifPresent(System.out::println); | ||
} | ||
}); | ||
}); | ||
// Example response: | ||
// Alright, let's break down this quadratic equation, x² + 4x + 4 = 0. My initial thought is, | ||
// "classic quadratic." I'll need to find the values of 'x' that make this equation true. The | ||
// equation is in standard form, and since the coefficients are relatively small, I | ||
// immediately suspect that factoring might be the easiest route. It's worth checking. | ||
// | ||
// First, I assessed what I had. *a* is 1, *b* is 4, and *c* is 4. I consider my toolkit. | ||
// Factoring is the likely first choice, then I can use the quadratic formula as a backup, | ||
// because that ALWAYS works, and I could use graphing. However, for this, factoring seems the | ||
// cleanest approach. | ||
// | ||
// Okay, factoring. I need two numbers that multiply to *c* (which is 4) and add up to *b* | ||
// (also 4). I quickly run through the factor pairs of 4: (1, 4), (-1, -4), (2, 2), (-2, -2). | ||
// Aha! 2 and 2 fit the bill. They multiply to 4 *and* add up to 4. Therefore, I can rewrite | ||
// the equation as (x + 2)(x + 2) = 0. That simplifies to (x + 2)² = 0. Perfect square | ||
// trinomial – nice and tidy. Seeing that pattern from the outset can save a step or two. Now, | ||
// to solve for *x*: if (x + 2)² = 0, then x + 2 must equal 0. Therefore, x = -2. Done. | ||
// | ||
// But, for the sake of a full explanation, let's use the quadratic formula as a second | ||
// method. It's a reliable way to double-check the answer, plus it's good practice. I plug my | ||
// *a*, *b*, and *c* values into the formula: x = [-b ± √(b² - 4ac)] / (2a). That gives me x | ||
// = [-4 ± √(4² - 4 * 1 * 4)] / (2 * 1). Simplifying under the radical, I get x = [-4 ± √(16 - | ||
// 16)] / 2. So, x = [-4 ± √0] / 2. The square root of 0 is zero, which is very telling! When | ||
// the discriminant (b² - 4ac) is zero, you get one real solution, a repeated root. This means | ||
// x = -4 / 2, which simplifies to x = -2. Exactly the same as before. | ||
// | ||
// Therefore, the answer is x = -2. Factoring was the most straightforward route. For | ||
// completeness, I showed the solution via the quadratic formula, too. Both approaches lead to | ||
// the same single solution. This is a repeated root – a double root, if you will. | ||
// | ||
// And to be absolutely sure...let's check our answer! Substitute -2 back into the original | ||
// equation. (-2)² + 4(-2) + 4 = 4 - 8 + 4 = 0. Yep, 0 = 0. The solution is correct. | ||
return response.text(); | ||
} | ||
} | ||
} | ||
// [END googlegenaisdk_thinking_includethoughts_with_txt] |
101 changes: 101 additions & 0 deletions
101
genai/snippets/src/main/java/genai/thinking/ThinkingWithText.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
/* | ||
* 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.thinking; | ||
|
||
// [START googlegenaisdk_thinking_with_txt] | ||
|
||
import com.google.genai.Client; | ||
import com.google.genai.types.GenerateContentResponse; | ||
import com.google.genai.types.HttpOptions; | ||
|
||
public class ThinkingWithText { | ||
|
||
public static void main(String[] args) { | ||
// TODO(developer): Replace these variables before running the sample. | ||
String modelId = "gemini-2.5-pro"; | ||
generateContent(modelId); | ||
} | ||
|
||
// Generates text with text input | ||
public static String generateContent(String modelId) { | ||
// Initialize client that will be used to send requests. This client only needs to be created | ||
// once, and can be reused for multiple requests. | ||
try (Client client = | ||
Client.builder() | ||
.location("global") | ||
.vertexAI(true) | ||
.httpOptions(HttpOptions.builder().apiVersion("v1").build()) | ||
.build()) { | ||
|
||
GenerateContentResponse response = | ||
client.models.generateContent(modelId, "solve x^2 + 4x + 4 = 0", null); | ||
|
||
System.out.println(response.text()); | ||
// Example response: | ||
// There are a couple of common ways to solve this quadratic equation. | ||
// | ||
// The equation is: **x² + 4x + 4 = 0** | ||
// | ||
// ### Method 1: Factoring (The Easiest Method for this Problem) | ||
// | ||
// This equation is a special case called a "perfect square trinomial". | ||
// | ||
// 1. **Find two numbers** that multiply to the last term (4) and add up to the middle term | ||
// (4). | ||
// * The numbers are +2 and +2. (Since 2 * 2 = 4 and 2 + 2 = 4) | ||
// | ||
// 2. **Factor the equation** using these numbers. | ||
// * (x + 2)(x + 2) = 0 | ||
// * This can be written as: (x + 2)² = 0 | ||
// | ||
// 3. **Solve for x.** | ||
// * If (x + 2)² is zero, then (x + 2) must be zero. | ||
// * x + 2 = 0 | ||
// * x = -2 | ||
// | ||
// ### Method 2: The Quadratic Formula | ||
// | ||
// You can use the quadratic formula for any equation in the form ax² + bx + c = 0. | ||
// | ||
// The formula is: **x = [-b ± √(b² - 4ac)] / 2a** | ||
// | ||
// 1. **Identify a, b, and c** from your equation (x² + 4x + 4 = 0). | ||
// * a = 1 | ||
// * b = 4 | ||
// * c = 4 | ||
// | ||
// 2. **Plug the values into the formula.** | ||
// * x = [-4 ± √(4² - 4 * 1 * 4)] / (2 * 1) | ||
// | ||
// 3. **Simplify.** | ||
// * x = [-4 ± √(16 - 16)] / 2 | ||
// * x = [-4 ± √0] / 2 | ||
// * x = -4 / 2 | ||
// * x = -2 | ||
// | ||
// Both methods give the same solution. | ||
// | ||
// --- | ||
// | ||
// ### Final Answer | ||
// | ||
// The solution is **x = -2**. | ||
return response.text(); | ||
} | ||
} | ||
} | ||
// [END googlegenaisdk_thinking_with_txt] |
82 changes: 82 additions & 0 deletions
82
genai/snippets/src/test/java/genai/thinking/ThinkingIT.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
/* | ||
* 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.thinking; | ||
|
||
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 ThinkingIT { | ||
|
||
private static final String GEMINI_FLASH = "gemini-2.5-flash"; | ||
private ByteArrayOutputStream bout; | ||
private PrintStream out; | ||
|
||
// 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(); | ||
out = new PrintStream(bout); | ||
System.setOut(out); | ||
} | ||
|
||
@After | ||
public void tearDown() { | ||
System.setOut(null); | ||
bout.reset(); | ||
} | ||
|
||
@Test | ||
public void testThinkingWithText() { | ||
String response = ThinkingWithText.generateContent(GEMINI_FLASH); | ||
assertThat(response).isNotEmpty(); | ||
} | ||
|
||
@Test | ||
public void testThinkingBudgetWithText() { | ||
String response = ThinkingBudgetWithText.generateContent(GEMINI_FLASH); | ||
assertThat(response).isNotEmpty(); | ||
assertThat(bout.toString()).contains("Token count for thinking: "); | ||
assertThat(bout.toString()).contains("Total token count: "); | ||
} | ||
|
||
@Test | ||
public void testThinkingIncludeThoughtsWithText() { | ||
String response = ThinkingIncludeThoughtsWithText.generateContent(GEMINI_FLASH); | ||
assertThat(response).isNotEmpty(); | ||
jdomingr marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.