Prompt Builder Basics¶
This notebook explains FewShotPromptBuilder in order: main input, generated output, and practical benefits.
1. Input: purpose, cautions, and examples¶
Define what you want, constraints, and a few representative examples.
In [1]:
Copied!
import os
import openaivec
from openaivec import FewShotPromptBuilder
assert os.getenv("OPENAI_API_KEY") or os.getenv("AZURE_OPENAI_BASE_URL"), (
"Set OPENAI_API_KEY or Azure OpenAI environment variables before running this notebook."
)
openaivec.set_responses_model("gpt-5.4")
base_prompt = (
FewShotPromptBuilder()
.purpose("Classify fruit names into color and taste notes.")
.caution("Return concise English.")
.caution("Use one sentence.")
.example(
input_value="apple",
output_value="Red or green fruit with a sweet-tart taste.",
)
.example(
input_value="lemon",
output_value="Yellow citrus fruit with a sour taste.",
)
.build()
)
import os
import openaivec
from openaivec import FewShotPromptBuilder
assert os.getenv("OPENAI_API_KEY") or os.getenv("AZURE_OPENAI_BASE_URL"), (
"Set OPENAI_API_KEY or Azure OpenAI environment variables before running this notebook."
)
openaivec.set_responses_model("gpt-5.4")
base_prompt = (
FewShotPromptBuilder()
.purpose("Classify fruit names into color and taste notes.")
.caution("Return concise English.")
.caution("Use one sentence.")
.example(
input_value="apple",
output_value="Red or green fruit with a sweet-tart taste.",
)
.example(
input_value="lemon",
output_value="Yellow citrus fruit with a sour taste.",
)
.build()
)
2. Output: reusable prompt string¶
build() returns a prompt string you can pass to response APIs.
In [2]:
Copied!
print(base_prompt)
print(base_prompt)
<Prompt>
<Purpose>Classify fruit names into color and taste notes.</Purpose>
<Cautions>
<Caution>Return concise English.</Caution>
<Caution>Use one sentence.</Caution>
</Cautions>
<Examples>
<Example>
<Input>apple</Input>
<Output>Red or green fruit with a sweet-tart taste.</Output>
</Example>
<Example>
<Input>lemon</Input>
<Output>Yellow citrus fruit with a sour taste.</Output>
</Example>
</Examples>
</Prompt>
3. Structured examples (optional)¶
When output shape matters, provide Pydantic models as examples.
In [3]:
Copied!
from pydantic import BaseModel, Field
class FruitProfile(BaseModel):
color: str = Field(description="Main color")
taste: str = Field(description="Primary taste")
structured_prompt = (
FewShotPromptBuilder()
.purpose("Extract fruit profile with fixed fields.")
.caution("taste must be one of: sweet, sour, bitter, umami.")
.example(
input_value="banana",
output_value=FruitProfile(color="yellow", taste="sweet"),
)
.example(
input_value="grapefruit",
output_value=FruitProfile(color="orange", taste="bitter"),
)
.build()
)
print(structured_prompt)
from pydantic import BaseModel, Field
class FruitProfile(BaseModel):
color: str = Field(description="Main color")
taste: str = Field(description="Primary taste")
structured_prompt = (
FewShotPromptBuilder()
.purpose("Extract fruit profile with fixed fields.")
.caution("taste must be one of: sweet, sour, bitter, umami.")
.example(
input_value="banana",
output_value=FruitProfile(color="yellow", taste="sweet"),
)
.example(
input_value="grapefruit",
output_value=FruitProfile(color="orange", taste="bitter"),
)
.build()
)
print(structured_prompt)
<Prompt>
<Purpose>Extract fruit profile with fixed fields.</Purpose>
<Cautions>
<Caution>taste must be one of: sweet, sour, bitter, umami.</Caution>
</Cautions>
<Examples>
<Example>
<Input>banana</Input>
<Output>{"color":"yellow","taste":"sweet"}</Output>
</Example>
<Example>
<Input>grapefruit</Input>
<Output>{"color":"orange","taste":"bitter"}</Output>
</Example>
</Examples>
</Prompt>
4. Improve and explain (optional)¶
improve() refines your prompt with an LLM, and explain() shows each improvement step as a diff. This example uses gpt-5.2.
In [4]:
Copied!
improved_builder = (
FewShotPromptBuilder()
.purpose("Classify fruit names into color and taste notes.")
.caution("Return concise English.")
.caution("Use one sentence.")
.example(
input_value="apple",
output_value="Red or green fruit with a sweet-tart taste.",
)
.example(
input_value="lemon",
output_value="Yellow citrus fruit with a sour taste.",
)
.improve()
)
improved_builder.explain()
improved_prompt = improved_builder.build()
improved_builder = (
FewShotPromptBuilder()
.purpose("Classify fruit names into color and taste notes.")
.caution("Return concise English.")
.caution("Use one sentence.")
.example(
input_value="apple",
output_value="Red or green fruit with a sweet-tart taste.",
)
.example(
input_value="lemon",
output_value="Yellow citrus fruit with a sour taste.",
)
.improve()
)
improved_builder.explain()
improved_prompt = improved_builder.build()
=== Iteration 1 ===
Instruction: The purpose was understandable but slightly underspecified because it did not clearly state the expected output structure. That ambiguity can cause inconsistent answers, such as listing only color or only taste. I refined the purpose to preserve the original meaning while making the task objective explicit: classify fruit names by giving both color and taste notes in English.
--- before
+++ after
@@ -1,5 +1,5 @@
<Prompt>
- <Purpose>Classify fruit names into color and taste notes.</Purpose>
+ <Purpose>Classify fruit names by providing their typical color and taste notes in concise English.</Purpose>
<Cautions>
<Caution>Return concise English.</Caution>
<Caution>Use one sentence.</Caution>
=== Iteration 2 ===
Instruction: The cautions were brief but incomplete because they did not mention common edge cases already implied by the examples, especially that some fruits can have more than one typical color and that the response should stay at a general, typical-description level. Without these cautions, outputs may become overly specific, verbose, or inconsistent. I updated only the cautions to make these constraints clearer.
--- before
+++ after
@@ -3,6 +3,8 @@
<Cautions>
<Caution>Return concise English.</Caution>
<Caution>Use one sentence.</Caution>
+ <Caution>Use typical color and taste notes rather than rare varieties.</Caution>
+ <Caution>If a fruit commonly has multiple colors, include the main ones concisely.</Caution>
</Cautions>
<Examples>
<Example>
=== Iteration 3 ===
Instruction: The examples covered the basic pattern but were too narrow, which can reduce generalization and leave uncertainty about how to handle additional common fruits and different taste profiles. I expanded only the examples to cover a wider range of non-redundant scenarios while preserving the original examples count and increasing it for better coverage.
--- before
+++ after
@@ -15,5 +15,21 @@
<Input>lemon</Input>
<Output>Yellow citrus fruit with a sour taste.</Output>
</Example>
+ <Example>
+ <Input>banana</Input>
+ <Output>Yellow fruit with a sweet taste.</Output>
+ </Example>
+ <Example>
+ <Input>lime</Input>
+ <Output>Green citrus fruit with a sour taste.</Output>
+ </Example>
+ <Example>
+ <Input>grape</Input>
+ <Output>Green or purple fruit with a sweet taste.</Output>
+ </Example>
+ <Example>
+ <Input>orange</Input>
+ <Output>Orange citrus fruit with a sweet-tart taste.</Output>
+ </Example>
</Examples>
</Prompt>
=== Iteration 4 ===
Instruction: In this final review, the prompt is now consistent, unambiguous, and aligned across purpose, cautions, and examples. One remaining minor issue was that the purpose did not explicitly emphasize the single-sentence output format, which is a critical instruction from the original prompt. I made that final purpose-only adjustment so the main goal and formatting requirement are fully aligned. The examples array remains non-empty and has increased from the original count of 2 to 6, so no reduction explanation is needed.
--- before
+++ after
@@ -1,5 +1,5 @@
<Prompt>
- <Purpose>Classify fruit names by providing their typical color and taste notes in concise English.</Purpose>
+ <Purpose>Classify fruit names by providing their typical color and taste notes in one concise English sentence.</Purpose>
<Cautions>
<Caution>Return concise English.</Caution>
<Caution>Use one sentence.</Caution>
In [5]:
Copied!
print(improved_prompt)
print(improved_prompt)
<Prompt>
<Purpose>Classify fruit names by providing their typical color and taste notes in one concise English sentence.</Purpose>
<Cautions>
<Caution>Return concise English.</Caution>
<Caution>Use one sentence.</Caution>
<Caution>Use typical color and taste notes rather than rare varieties.</Caution>
<Caution>If a fruit commonly has multiple colors, include the main ones concisely.</Caution>
</Cautions>
<Examples>
<Example>
<Input>apple</Input>
<Output>Red or green fruit with a sweet-tart taste.</Output>
</Example>
<Example>
<Input>lemon</Input>
<Output>Yellow citrus fruit with a sour taste.</Output>
</Example>
<Example>
<Input>banana</Input>
<Output>Yellow fruit with a sweet taste.</Output>
</Example>
<Example>
<Input>lime</Input>
<Output>Green citrus fruit with a sour taste.</Output>
</Example>
<Example>
<Input>grape</Input>
<Output>Green or purple fruit with a sweet taste.</Output>
</Example>
<Example>
<Input>orange</Input>
<Output>Orange citrus fruit with a sweet-tart taste.</Output>
</Example>
</Examples>
</Prompt>
5. Benefits¶
Main input
- Prompt purpose (
purpose) - Constraints (
caution) - Example pairs (
example)
Main output
- Reusable prompt string (
build) - Optionally refined prompt and diff history (
improve+explain)
Why this helps
- Makes prompt design explicit and reviewable
- Reduces ambiguity by encoding examples in code
- Reuses the same prompt across notebooks and production paths