Table of Contents

Advanced Features

This guide covers the advanced capabilities of the Prompt library beyond basic template rendering and conversations. Each feature is designed to be composable — you can use them individually or combine them into sophisticated prompt engineering workflows.

Prompt Pipeline

The PromptPipeline lets you chain middleware components that process prompts before they reach the model. Each middleware can inspect, validate, transform, or log the prompt at different stages.

var pipeline = new PromptPipeline()
    .Use(new ValidationMiddleware())     // Reject unsafe prompts
    .Use(new LoggingMiddleware(logger))  // Log every request
    .Use(new CachingMiddleware(cache))   // Return cached responses
    .Use(new RetryMiddleware(maxRetries: 3))
    .Use(new MetricsMiddleware());       // Track latency & tokens

var context = new PromptPipelineContext
{
    PromptText = "Summarize this article: {{content}}",
    Variables = new Dictionary<string, string>
    {
        ["content"] = articleText
    }
};

await pipeline.ExecuteAsync(context);
string result = context.RenderedPrompt;

Custom Middleware

Implement IPromptMiddleware or pass a lambda:

pipeline.Use(async (context, next) =>
{
    context.Variables["timestamp"] = DateTime.UtcNow.ToString("o");
    await next(context);
    // Post-process the response here
});

Prompt Caching

PromptCache provides an LRU cache with TTL expiration for prompt responses. Avoid redundant API calls when the same prompt is sent repeatedly.

var cache = new PromptCache(maxEntries: 1000, ttl: TimeSpan.FromMinutes(30));

// Store a response
cache.Set("summarize-article-123", response);

// Retrieve (returns null if expired or evicted)
var cached = cache.Get("summarize-article-123");

// Statistics
CacheStats stats = cache.GetStats();
Console.WriteLine($"Hit rate: {stats.HitRate:P1}");  // e.g., "87.3%"

Cost Estimation

PromptCostEstimator tracks token usage and estimates costs across models.

var estimator = new PromptCostEstimator();

// Estimate before sending
decimal inputCost = estimator.InputCost(tokenCount: 1500);
decimal outputCost = estimator.OutputCost(tokenCount: 500);
decimal total = estimator.TotalCost(inputTokens: 1500, outputTokens: 500);

// Track cumulative spending
estimator.RecordUsage(inputTokens: 1500, outputTokens: 500);
var report = estimator.GetReport();
Console.WriteLine($"Total spend: ${report.TotalCost:F4}");

Token Budget

TokenBudget helps you stay within model context limits by allocating tokens across prompt sections.

var budget = new TokenBudget(maxTokens: 4096);

budget.Allocate("system", maxTokens: 500);
budget.Allocate("examples", maxTokens: 1000);
budget.Allocate("conversation", maxTokens: 2000);
budget.Allocate("response", maxTokens: 596);  // Reserve for output

// Check before adding content
if (budget.CanFit("examples", exampleText))
{
    budget.Fill("examples", exampleText);
}

// Auto-truncate to fit
string truncated = budget.FitToSection("conversation", longHistory);

Few-Shot Examples

FewShotBuilder manages example sets for in-context learning.

var builder = new FewShotBuilder()
    .AddExample(new FewShotExample
    {
        Input = "The food was amazing and the service was great!",
        Output = "positive"
    })
    .AddExample(new FewShotExample
    {
        Input = "Terrible experience, would not recommend.",
        Output = "negative"
    });

// Select most relevant examples for a new input
var selected = builder.SelectBest(
    query: "The hotel room was clean but noisy",
    maxExamples: 2
);

// Render as prompt text
string fewShotBlock = builder.Render(selected);

Prompt Fingerprinting

PromptFingerprint generates content-aware hashes for deduplication and similarity detection.

var fp = new PromptFingerprint(NormalizationLevel.CaseInsensitive);

// Hash a prompt
string hash = fp.Compute("Summarize the following article...");

// Compare two prompts for similarity
double similarity = fp.Similarity(promptA, promptB);
// Returns 0.0 (completely different) to 1.0 (identical after normalization)

// Detect near-duplicates in a collection
var duplicates = fp.FindDuplicates(promptList, threshold: 0.9);

Normalization Levels

Level Effect
None Raw text, exact matching
Whitespace Collapse whitespace, trim
CaseInsensitive + lowercase
Punctuation + remove punctuation
OrderIndependent + sort words (bag-of-words matching)

Prompt Composer

PromptComposer builds structured prompts from reusable blocks.

var composer = new PromptComposer()
    .WithRole("You are a senior code reviewer.")
    .WithContext("Language: C#, Framework: .NET 8")
    .AddConstraint("Focus on security vulnerabilities")
    .AddConstraint("Suggest specific fixes, not just descriptions")
    .AddSection("Code to Review", codeBlock)
    .AddExample("Good review", exampleReview);

string prompt = composer.Build();

Prompt Versioning

PromptVersionManager tracks prompt evolution with full history.

var versions = new PromptVersionManager("classify-sentiment");

// Save a new version
versions.Save(templateText, metadata: new { author = "team-ml" });

// Compare versions
var diff = versions.Diff(fromVersion: 2, toVersion: 3);

// Rollback
versions.Rollback(toVersion: 2);

A/B Testing

PromptABTester runs controlled experiments across prompt variants.

var tester = new PromptABTester();
tester.AddVariant("concise", conciseTemplate);
tester.AddVariant("detailed", detailedTemplate);
tester.AddVariant("structured", structuredTemplate);

// Route traffic
var variant = tester.SelectVariant();  // Weighted random selection

// Record outcome
tester.RecordResult(variant.Name, score: 0.92);

// Analyze results
var analysis = tester.Analyze();
Console.WriteLine($"Winner: {analysis.Winner} (p={analysis.PValue:F4})");

Prompt Routing

PromptRouter directs prompts to different templates based on content.

var router = new PromptRouter();
router.AddRoute("code", @"\b(function|class|def|var)\b", codeReviewTemplate);
router.AddRoute("math", @"\b(calculate|equation|formula)\b", mathTemplate);
router.AddRoute("creative", @"\b(write|story|poem)\b", creativeTemplate);
router.SetDefault(generalTemplate);

// Automatically select the best template
var matched = router.Route(userInput);

Localization

PromptLocalizer manages prompt translations for multilingual applications.

var localizer = new PromptLocalizer(defaultLocale: "en");
localizer.Add("en", "greeting", "Hello! How can I help you?");
localizer.Add("es", "greeting", "\u00a1Hola! \u00bfC\u00f3mo puedo ayudarte?");
localizer.Add("ja", "greeting", "\u3053\u3093\u306b\u3061\u306f\uff01");

string prompt = localizer.Get("greeting", locale: "es");

See Also