PromptBuilder¶
Fluent API for constructing prompts programmatically at runtime. Use PromptBuilder when prompt configuration depends on runtime conditions -- user input, feature flags, A/B tests, or dynamic model selection.
Quick Example¶
from promptise.prompts.builder import PromptBuilder
from promptise.prompts.context import UserContext, BaseContext, tool_context
from promptise.prompts.strategies import chain_of_thought, analyst
from promptise.prompts.guards import content_filter, length
prompt = (
PromptBuilder("analyze")
.system("Expert data analyst")
.user(UserContext(expertise_level="expert"))
.world(project=BaseContext(name="Alpha", deadline="March 2026"))
.context(tool_context())
.strategy(chain_of_thought)
.perspective(analyst)
.constraint("Must include confidence scores")
.guard(content_filter(blocked=["secret"]), length(max_length=5000))
.template("Analyze: {data}")
.model("openai:gpt-5-mini")
.build()
)
result = await prompt(data="quarterly figures...")
Concepts¶
The PromptBuilder provides a fluent (chainable) API where every method returns self. This lets you incrementally configure a prompt, then call .build() to produce the final Prompt instance.
Key differences from the @prompt decorator:
- Runtime configuration -- you can build prompts based on runtime conditions instead of static decoration.
- Dynamic templates -- set templates from variables, databases, or user input.
- Programmatic composition -- loop through configurations, conditionally add guards, etc.
The builder extracts {variable} names from the template text and creates a synthetic async function with matching parameters. The resulting Prompt behaves identically to one created with @prompt.
Detailed Walkthrough¶
Step 1: Create the Builder¶
The name is used for logging, observability traces, and the PromptInspector.
Step 2: Set System Text and Template¶
builder.system("You are a senior financial analyst.")
builder.template("Analyze the following report:\n{report}\nFocus: {focus}")
The system text is prepended to the template. Both support {variable} placeholders.
Step 3: Configure the Model¶
The default model is openai:gpt-5-mini if not explicitly set.
Step 4: Add World Context¶
from promptise.prompts.context import UserContext, EnvironmentContext, BaseContext
builder.user(UserContext(name="Alice", expertise_level="expert"))
builder.env(EnvironmentContext(platform="linux", timezone="UTC"))
builder.world(
project=BaseContext(name="Q1 Report", deadline="March 2026"),
team=BaseContext(size=5, department="analytics"),
)
Step 5: Add Context Providers¶
from promptise.prompts.context import tool_context, memory_context
builder.context(tool_context(), memory_context(limit=10))
Step 6: Set Strategy and Perspective¶
from promptise.prompts.strategies import chain_of_thought, analyst
builder.strategy(chain_of_thought)
builder.perspective(analyst)
Step 7: Add Constraints and Guards¶
from promptise.prompts.guards import content_filter, length
builder.constraint("Must include confidence scores", "Cite data sources")
builder.guard(content_filter(blocked=["confidential"]), length(max_length=5000))
Step 8: Add Lifecycle Hooks¶
async def log_before(ctx):
print(f"About to call: {ctx.prompt_name}")
async def log_after(ctx, result):
print(f"Got result: {len(str(result))} chars")
async def handle_error(ctx, error):
print(f"Error: {error}")
builder.on_before(log_before)
builder.on_after(log_after)
builder.on_error(handle_error)
Step 9: Set Output Type¶
from pydantic import BaseModel
class AnalysisResult(BaseModel):
summary: str
confidence: float
recommendations: list[str]
builder.output_type(AnalysisResult)
Step 10: Build and Use¶
Chaining Everything¶
Since all builder methods return self, you can chain the entire configuration:
prompt = (
PromptBuilder("quick_summary")
.system("Expert summarizer")
.template("Summarize in {max_words} words: {text}")
.model("openai:gpt-5-mini")
.strategy(chain_of_thought)
.constraint("Be concise")
.guard(length(max_length=1000))
.build()
)
result = await prompt(text="long article...", max_words="100")
Dynamic Prompt Construction¶
The real power of PromptBuilder is in dynamic, conditional construction:
from promptise.prompts.builder import PromptBuilder
from promptise.prompts.strategies import chain_of_thought, self_critique
from promptise.prompts.guards import content_filter, length
def create_analysis_prompt(user_level: str, strict_mode: bool) -> "Prompt":
builder = (
PromptBuilder("analysis")
.template("Analyze: {data}")
.model("openai:gpt-5-mini")
)
# Adjust strategy based on user level
if user_level == "expert":
builder.strategy(chain_of_thought + self_critique)
builder.constraint("Include statistical confidence intervals")
else:
builder.strategy(chain_of_thought)
builder.constraint("Explain in simple terms")
# Add guards in strict mode
if strict_mode:
builder.guard(
content_filter(blocked=["confidential", "internal"]),
length(max_length=2000),
)
return builder.build()
# Usage
prompt = create_analysis_prompt(user_level="expert", strict_mode=True)
result = await prompt(data="quarterly revenue figures...")
Observability¶
Enable observability recording on the built prompt:
prompt = (
PromptBuilder("tracked_prompt")
.template("Process: {input}")
.model("openai:gpt-5-mini")
.observe(True)
.build()
)
API Summary¶
| Method | Returns | Description |
|---|---|---|
PromptBuilder(name) |
PromptBuilder |
Create a new builder |
.system(text) |
self |
Set system/instruction text |
.template(text) |
self |
Set prompt template with {variable} placeholders |
.model(name) |
self |
Set the LLM model identifier |
.observe(enabled) |
self |
Enable/disable observability recording |
.output_type(t) |
self |
Set output type for structured parsing |
.user(user_ctx) |
self |
Set user context |
.env(env_ctx) |
self |
Set environment context |
.world(**contexts) |
self |
Add named world contexts |
.context(*providers) |
self |
Add context providers |
.strategy(s) |
self |
Set reasoning strategy |
.perspective(p) |
self |
Set cognitive perspective |
.constraint(*texts) |
self |
Add constraint strings |
.guard(*guards) |
self |
Add input/output guards |
.on_before(fn) |
self |
Set pre-execution hook |
.on_after(fn) |
self |
Set post-execution hook |
.on_error(fn) |
self |
Set error-handling hook |
.build() |
Prompt |
Construct the final Prompt instance |
Builder vs. decorator
Use @prompt for static, declarative prompt definitions. Use PromptBuilder when you need to construct prompts based on runtime conditions. Both produce identical Prompt objects.
Template is required
If neither .system() nor .template() is called, the builder uses a default placeholder text. Always set an explicit template for production prompts.
Default model
If .model() is not called, the builder defaults to openai:gpt-5-mini. This keeps quick prototyping fast without specifying a model every time.
What's Next¶
- Context System -- Dynamic context injection
- Guards -- Input/output validation
- Strategies -- Reasoning strategies and perspectives