Prompt Templates
The prompts layer provides a template engine for managing, versioning, and composing prompts. Define reusable templates with typed variables, track versions, and compose complex prompts from smaller pieces.
Quick Start
Section titled “Quick Start”const agent = await ReactiveAgents.create() .withProvider("anthropic") .withPrompts() // Enable prompt template engine .build();Defining Templates
Section titled “Defining Templates”Templates use {{variable}} syntax for interpolation:
import { PromptService } from "@reactive-agents/prompts";import { Effect } from "effect";
const program = Effect.gen(function* () { const prompts = yield* PromptService;
// Register a template yield* prompts.register({ id: "research-task", name: "Research Task", version: 1, template: `You are a {{role}} researching {{topic}}.
Your goal is to {{objective}}.
Focus on these aspects:{{#each aspects}}- {{this}}{{/each}}
Provide your findings in {{format}} format.`, variables: [ { name: "role", required: true, type: "string", description: "Agent's role" }, { name: "topic", required: true, type: "string", description: "Research topic" }, { name: "objective", required: true, type: "string", description: "Research goal" }, { name: "aspects", required: false, type: "array", description: "Focus areas" }, { name: "format", required: false, type: "string", description: "Output format", defaultValue: "markdown" }, ], metadata: { author: "team", description: "General-purpose research prompt", tags: ["research", "analysis"], maxTokens: 4096, }, });});Compiling Templates
Section titled “Compiling Templates”Compile a template by interpolating variables:
const compiled = yield* prompts.compile("research-task", { role: "senior analyst", topic: "quantum computing applications", objective: "identify the top 5 commercial applications", format: "bullet points",});
console.log(compiled.content);// "You are a senior analyst researching quantum computing applications..."
console.log(compiled.tokenEstimate);// Estimated token count for the compiled promptToken-Aware Compilation
Section titled “Token-Aware Compilation”Set a max token budget — the template engine truncates if the compiled prompt exceeds it:
const compiled = yield* prompts.compile("research-task", variables, { maxTokens: 1000, // Truncate to fit within 1000 tokens});Composing Prompts
Section titled “Composing Prompts”Combine multiple compiled prompts into one:
const systemPrompt = yield* prompts.compile("system-context", { agent: "researcher" });const taskPrompt = yield* prompts.compile("research-task", { topic: "CRISPR" });const formatPrompt = yield* prompts.compile("output-format", { format: "academic" });
const combined = yield* prompts.compose( [systemPrompt, taskPrompt, formatPrompt], { separator: "\n\n---\n\n", maxTokens: 8000 },);
console.log(combined.content); // All three prompts joinedconsole.log(combined.tokenEstimate); // Total token estimateVersion Control
Section titled “Version Control”Templates are automatically versioned. Register a new version by using the same id:
// Version 1yield* prompts.register({ id: "research-task", name: "Research Task", version: 1, template: "Original template...", variables: [...],});
// Version 2 (improved)yield* prompts.register({ id: "research-task", name: "Research Task v2", version: 2, template: "Improved template with better instructions...", variables: [...],});
// Get specific versionconst v1 = yield* prompts.getVersion("research-task", 1);
// Get all versionsconst history = yield* prompts.getVersionHistory("research-task");// Sorted by version numberBuilt-in Templates
Section titled “Built-in Templates”The framework includes templates for internal reasoning strategies:
| Template | Used By |
|---|---|
react | ReAct reasoning strategy |
plan-execute | Plan-Execute-Reflect strategy |
reflexion | Reflexion self-improvement strategy |
tree-of-thought | Tree-of-Thought exploration strategy |
fact-check | Verification layer |
These are used internally by the reasoning and verification layers — you don’t need to register them manually.
A/B Experiments
Section titled “A/B Experiments”Run statistically-tracked prompt experiments to find the best-performing template variant for a task:
import { ExperimentService } from "@reactive-agents/prompts";import { Effect } from "effect";
const program = Effect.gen(function* () { const experiments = yield* ExperimentService;
// Register two prompt variants as an experiment const experimentId = yield* experiments.register({ name: "research-prompt-ab", variants: [ { id: "variant-a", templateId: "research-task", variables: { tone: "formal", depth: "comprehensive" }, weight: 0.5, }, { id: "variant-b", templateId: "research-task", variables: { tone: "concise", depth: "focused" }, weight: 0.5, }, ], metric: "user_satisfaction", });
// Get the next variant to run (weighted random selection) const variant = yield* experiments.nextVariant(experimentId); const compiled = yield* prompts.compile(variant.templateId, variant.variables);
// ... run the agent with compiled.content as the system prompt ...
// Record outcome (0.0–1.0 score, or pass/fail) yield* experiments.recordOutcome(experimentId, variant.id, { score: 0.87, metadata: { responseTime: 1200, userRating: 4 }, });
// Query results to see which variant is winning const results = yield* experiments.getResults(experimentId); console.log(results.variants); // [ // { id: "variant-a", runs: 45, avgScore: 0.82, p95: 0.90 }, // { id: "variant-b", runs: 47, avgScore: 0.87, p95: 0.93 }, // ] console.log(results.winner); // "variant-b"});Enable with Builder
Section titled “Enable with Builder”const agent = await ReactiveAgents.create() .withProvider("anthropic") .withPrompts({ experiments: true }) .build();Experiment Lifecycle
Section titled “Experiment Lifecycle”| Method | Description |
|---|---|
register(config) | Create a new experiment with two or more weighted variants |
nextVariant(id) | Select the next variant to run (respects weights + exploration) |
recordOutcome(id, variantId, outcome) | Record a score for a completed variant run |
getResults(id) | Get aggregate statistics per variant with a winner field |
pause(id) | Pause variant selection (all calls get variant A) |
archive(id) | Archive a completed experiment |
Outcomes are persisted to SQLite for cross-session aggregation, so experiments can run over thousands of agent invocations and still converge.
Template Variables
Section titled “Template Variables”Each variable has a type and can be required or optional:
| Type | Description |
|---|---|
string | Text value |
number | Numeric value |
boolean | True/false |
array | List of values |
object | Key-value map |
Optional variables can have a defaultValue that’s used when the variable isn’t provided during compilation.