Skip to content

Commit a6380a9

Browse files
authored
Merge pull request #14 from gemini-cli-extensions/few-shot-po
feat: Adding Few-Shot Prompt Optimization as a tool
2 parents 89ae418 + 794b6a1 commit a6380a9

9 files changed

Lines changed: 168 additions & 9 deletions

File tree

GEMINI.md

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Vertex AI Gemini CLI Extension
22

3-
This extension provides tools to manage prompts and use the data-driven prompt
3+
This extension provides tools to manage prompts and use prompt
44
optimization in Vertex AI directly from the Gemini CLI.
55

66
## Available Tools
@@ -12,8 +12,10 @@ optimization in Vertex AI directly from the Gemini CLI.
1212
- `delete_prompt`: To remove prompts.
1313
- `list_prompts`: To search and list prompts, useful for finding IDs.
1414

15-
### Data-Driven Optimization Tools
16-
- `run_data_driven_optimize`: Starts a data-driven prompt optimization job on
15+
### Prompt Optimization Tools
16+
- `run_few_shot_optimization`: optimize user prompt based on examples provided
17+
in the CSV file stored in the GCS bucket.
18+
-`run_data_driven_optimize`: Starts a data-driven prompt optimization job on
1719
Vertex AI using a configuration file stored in GCS.
1820
- `analyze_data_driven_optimize_results`: Analyzes the output of a Data-Driven
1921
Optimize job to identify trends and best-performing candidates.
@@ -275,6 +277,28 @@ If any tool call fails with an error indicating a project permission issue (e.g.
275277

276278
---
277279

280+
## Few-Shot Prompt Optimization Guide
281+
Few-shot prompt optimization is a tool used to refine a prompt (or system instructions) based on user-provided examples. These examples are stored in a CSV file and user must provide a GCS path to this data. The examples must follow one of two formats:
282+
`("prompt", "model_response", "target_response")` or
283+
`("prompt", "model_response", "rubrics", "rubrics_evaluations")`.
284+
Depending on the format of the examples provided in the user's CSV file, the optimization uses one of the following methods:
285+
`TARGET_RESPONSE`: The prompt is tuned to generate outputs that closely align with a provided ground-truth answer.
286+
`RUBRICS`: The model analyzes rubric rules and evaluation scores to tune the prompt and address specific failures.
287+
For more details, please refer to this guide: @./src/vertex/prompt_optimizer/docs/few_shot_prompt_optimization_guide.md
288+
The tool is accessed through `run_few_shot_prompt_optimization(prompt_to_optimize: str,
289+
example_path: str, method: str)`. This tool should be called directly on the raw prompt without invoking create_prompt or any other tool first.
290+
291+
## Few-shot Optimization Workflows
292+
293+
- When asked to run few-shot prompt optimization, identify if all required parameters are passed.
294+
1. **Identify Essential Parameters**: Proactively ask the user for the
295+
following required fields:
296+
- `prompt_to_optimize`
297+
- `example_path`
298+
- `method`
299+
300+
2. Once the parameters are set, call the `run_few_shot_prompt_optimization` with those params.
301+
278302
## Data-Driven Prompt Optimizer Overall Guide
279303

280304
For a general understanding of Data-Driven Prompt Optimizer and its
@@ -283,7 +307,7 @@ refer to the Data-Driven Optimize Overall Guide:
283307

284308
@./src/vertex/prompt_optimizer/docs/data_driven_optimize_overall_guide.md
285309

286-
## Optimization Tool Details
310+
## Data-Driven Optimization Tool Details
287311

288312
The extension provides a suite of tools to parse and analyze the output of a
289313
Data-Driven Prompt Optimizer job. The `output_path` for these tools stores
@@ -322,14 +346,14 @@ file system for analysis.
322346
Supports specifying the `prompt_optimizer_method`. The `config_gcs_path`
323347
must point to a JSON file in GCS.
324348

325-
## Optimization Method Considerations
349+
## Data-Driven Optimization Method Considerations
326350
- **VAPO**: Standard prompt optimization. The `batch_size` parameter
327351
will be automatically removed during configuration generation to ensure SDK
328352
compatibility.
329353
- **OPTIMIZATION_TARGET_GEMINI_NANO**: Specialized target for Gemini Nano.
330354
Requires a `target_model_endpoint_url`. Supports `batch_size`.
331355

332-
## Optimization Tuning Considerations
356+
## Data-Driven Optimization Tuning Considerations
333357

334358
Only suggest modifications for the parameters explicitly listed as tunable in
335359
the Data-Driven Optimize Tuning Guide:
@@ -341,7 +365,7 @@ previous results. Ensure you only modify the parameters listed in the approved
341365
list. If a user asks to modify a parameter that is not on the approved list
342366
(and is not a path-related field), confirm with the user before proceeding.
343367

344-
## Optimization Workflows
368+
## Data-Driven Optimization Workflows
345369

346370
- **Initial Setup**: When asked to help configure a new optimization run, use
347371
the example configuration in the Overall Guide as a valid default base.

README.md

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ This extension provides tools to manage prompts and work with data-driven prompt
1717
* **Results Analysis**: Perform deep-dive analysis of optimization results, including learning curves and candidate comparisons.
1818
* **Automated Reporting**: Generate comprehensive HTML reports with tuning suggestions for subsequent runs.
1919

20+
### Few-Shot Prompt Optimizer
21+
* **Prompt Optimization**: tunes the given prompt by utilizing small set of user-provided examples using few-shot prompt optimization. For more details about the algorithm, please refer to this [documentation](https://docs.cloud.google.com/vertex-ai/generative-ai/docs/learn/prompts/few-shot-optimizer) or this [guide](@./src/vertex/prompt_optimizer/docs/few_shot_prompt_optimization_guide.md).
22+
23+
2024
## Prerequisites
2125

2226
* You have the [Gemini CLI](https://github.com/google-gemini/gemini-cli) installed.
@@ -63,7 +67,7 @@ Here are a few examples:
6367

6468
For more detailed information on all available commands and their parameters, please refer to the `extension/commands` files.
6569

66-
### Prompt Optimizer Examples
70+
### Data-Driven Prompt Optimizer Examples
6771

6872
* **Analyze optimization results**:
6973
```bash
@@ -82,6 +86,17 @@ For more detailed information on all available commands and their parameters, pl
8286

8387
For more detailed information on all available commands and workflows, please refer to the `GEMINI.md` file in this repository.
8488

89+
### Few-Shot Prompt Optimization Examples
90+
* **Few-shot optimization with target response**:
91+
When user examples consit of `(question, model_response, target_response)`, few-shot optimization should be run with "target response" method.
92+
```bash
93+
gemini "Apply few-shot prompt optimization using target response with data from gs://your_bucket/your_examples.csv. Here is the prompt: '...'"
94+
95+
* **Few-shot optimization with rubrics and evaluations**:
96+
When user examples consit of `(question, model_response, rubrics, rubrics_evaluations)`, few-shot optimization should be run with "rubrics" method.
97+
```bash
98+
gemini "Apply few-shot prompt optimization using rubrics with data from gs://your_bucket/your_examples.csv. Here is the prompt: '...'"
99+
85100
## Development
86101

87102
### Local Development Setup
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
name = "run_few_shot_prompt_optimization"
2+
description = "Optimize a prompt based on few examples using few-shot optimization from Vertex AI SDK."
3+
prompt = """
4+
You are tasked to call `run_few_shot_prompt_optimization` tool call.
5+
6+
**Parameters:**
7+
8+
1. **`prompt_to_optimize` (string, required):**
9+
* **Source:** Prompt (or system instructions) that will be optimized.
10+
2. **`example_path` (string, required):**
11+
* **Source:** The GCS URI to the CSV file containing examples
12+
3. **`method:` (string, required):**
13+
* **Source:** The method for prompt optimization. Either "TARGET_RESPONSE" or "RUBRICS"
14+
15+
16+
**Clarification Policy:**
17+
If `prompt_to_optimize`, `example_path` or `method` is missing, ask the user for it.
18+
"""
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Few-Shot Prompt Optimizer
2+
3+
The **Few-Shot Prompt Optimizer** helps you improve your system instructions by learning from examples.
4+
5+
You provide your current instructions you want to tune along with a CSV file containing questions(prompts), the model's current responses, and your feedback. The optimizer analyzes where the model fell short and automatically updates your instructions to fix those gaps.
6+
7+
Your example data must be saved as a CSV file in Google Cloud Storage (GCS). You can format your feedback using one of two methods:
8+
9+
## Method 1: Target Responses
10+
11+
Use this method to show the optimizer exactly what the model *should* have said. The tool compares the actual output to your ideal output and adjusts the instructions to bridge the gap.
12+
13+
Your CSV must include these three columns:
14+
15+
* **`prompt`**: The original user instruction or question.
16+
* **`model_response`**: The current model output that needs improvement.
17+
* **`target_response`**: The ideal, correct response you want the model to generate.
18+
19+
## Method 2: Rubrics (Grading Criteria)
20+
21+
Use this method to score responses based on specific rules. The tool learns from which rules the model passed or failed. Rubrics can be consistent across all rows or customized for each individual example.
22+
23+
Your CSV must include these four columns:
24+
25+
* **`prompt`**: The original user instruction or question.
26+
* **`model_response`**: The actual output generated by the model.
27+
* **`rubrics`**: A list of specific grading criteria (formatted as a string representation of a Python list of strings, e.g., `"['Tone is polite', 'Mentions pricing']"`).
28+
* **`rubrics_evaluations`**: True/False scores indicating if the model met each rule (formatted as a string representation of a Python list of booleans, e.g., `"['True', 'False']"`).

src/vertex/prompt_optimizer/prompt_optimizer.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from google.cloud import storage
88
from vertexai._genai import Client
99

10+
from . import storage as storage_utils
1011
from . import utils
1112

1213

@@ -232,3 +233,39 @@ def run_data_driven_optimize(
232233
) from re
233234
except Exception as e:
234235
raise RuntimeError(f"An unexpected error occurred: {e}") from e
236+
237+
def run_few_shot_optimization(
238+
self,
239+
prompt_to_optimize: str,
240+
example_path: str,
241+
method: str,
242+
) -> str:
243+
"""Applies few shot prompt optimization to a prompt using user provided dataset and method.
244+
245+
Args:
246+
prompt_to_optimize: The zero-based index of the prompt to improve.
247+
example_path: GCS path to the csv file containg few-shot examples
248+
method: The optimization method to use for few shot prompt improvement. The
249+
method should be one of the following:
250+
- TARGET_RESPONSE: Optimize the prompt to match the target response.
251+
- RUBRICS: Optimize the prompt to improve the rubrics scores.
252+
253+
Returns:
254+
Optimized prompt.
255+
"""
256+
if not self.client:
257+
raise ValueError(
258+
"Error: Client was not initialized properly. Try authenticating then rerunning"
259+
)
260+
261+
example_df = storage_utils._read_csv_from_gcs(example_path)
262+
optimization_target = utils._get_optimization_target(method)
263+
config = vertexai.types.OptimizeConfig(
264+
optimization_target=optimization_target,
265+
examples_dataframe=example_df,
266+
)
267+
response = self.client.prompts.optimize(
268+
prompt=prompt_to_optimize,
269+
config=config,
270+
)
271+
return response.parsed_response.suggested_prompt

src/vertex/prompt_optimizer/storage.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
"""Utility functions for reading from and writing to GCS or local paths."""
22

3+
import io
34
import json
45
from pathlib import Path
56
from typing import Any
67

8+
import pandas as pd
79
from google.cloud import storage
810

911
EXPECTED_GCS_PARTS = 2
@@ -33,6 +35,23 @@ def _read_json_from_gcs(gcs_uri: str) -> Any:
3335
raise RuntimeError(f"Failed to read from GCS URI {gcs_uri}: {e}") from e
3436

3537

38+
def _read_csv_from_gcs(path: str) -> pd.DataFrame:
39+
if not _is_gcs_path(path) or not path.endswith(".csv"):
40+
raise ValueError(
41+
"Few-shot examples must be stored as CSV file in a GCS bucket, ",
42+
f"but `{path}` was provided",
43+
)
44+
try:
45+
storage_client = storage.Client()
46+
bucket_name, blob_name = _parse_gcs_uri(path)
47+
bucket = storage_client.bucket(bucket_name)
48+
blob = bucket.blob(blob_name)
49+
csv_bytes = blob.download_as_bytes()
50+
return pd.read_csv(io.BytesIO(csv_bytes))
51+
except Exception as e:
52+
raise RuntimeError(f"Failed to read from GCS URI {path}: {e}") from e
53+
54+
3655
def _write_json_to_gcs(data: Any, gcs_uri: str):
3756
"""Writes a JSON object to a GCS file."""
3857
storage_client = storage.Client()

src/vertex/prompt_optimizer/utils.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
from typing import Any
44

5+
import vertexai
6+
57

68
def merge_configs(
79
base_config: dict[str, Any], modifications: dict[str, Any]
@@ -19,3 +21,15 @@ def merge_configs(
1921
else:
2022
merged_config[key] = value
2123
return merged_config
24+
25+
26+
def _get_optimization_target(method: str) -> vertexai.types.OptimizeTarget:
27+
"""Returns the optimization target for the given method."""
28+
if method == "TARGET_RESPONSE":
29+
return vertexai.types.OptimizeTarget.OPTIMIZATION_TARGET_FEW_SHOT_TARGET_RESPONSE
30+
elif method == "RUBRICS":
31+
return (
32+
vertexai.types.OptimizeTarget.OPTIMIZATION_TARGET_FEW_SHOT_RUBRICS
33+
)
34+
else:
35+
raise ValueError(f"Unsupported optimization method: {method}")

src/vertex/server.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ def main(argv: Sequence[str]) -> None:
3838
optimizer_tools.run_data_driven_optimize,
3939
name="run_data_driven_optimize",
4040
)
41+
mcp.add_tool(
42+
optimizer_tools.run_few_shot_optimization,
43+
name="run_few_shot_optimization",
44+
)
4145
mcp.add_tool(
4246
analyzer.analyze_results, name="analyze_data_driven_optimize_results"
4347
)

uv.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)