AI Systemsintermediate
Building a Prompt Library
Organize, version, and reuse prompts across your team. Build a prompt library with templates, variables, composition patterns, and a management system.
Asma Hafeez KhanMay 16, 20267 min read
Prompt EngineeringPrompt LibraryTemplatesProduction
Why a Prompt Library?
Without a shared library, prompts are scattered across codebases, often duplicated with slight variations, and modified without tracking. A prompt library:
- Gives every team member access to tested, production-quality prompts
- Prevents duplication — one prompt maintained in one place
- Enables version tracking — know which prompt version produced which output
- Supports composition — build complex prompts from tested components
Prompt Template Structure
Each prompt in the library has consistent metadata:
Python
from dataclasses import dataclass, field
from typing import Optional
import re
from datetime import date
@dataclass
class PromptTemplate:
"""A versioned, reusable prompt template."""
id: str
name: str
description: str
template: str # The prompt text with {variable} placeholders
variables: list[str] # Required template variables
optional_variables: dict[str, str] = field(default_factory=dict) # var → default
version: str = "1.0"
author: str = ""
created_date: str = ""
tags: list[str] = field(default_factory=list)
eval_score: Optional[float] = None # Latest eval suite score
use_cases: list[str] = field(default_factory=list)
def render(self, **kwargs) -> str:
"""Render the template with provided variables."""
# Check required variables
missing = [v for v in self.variables if v not in kwargs]
if missing:
raise ValueError(f"Missing required variables: {missing}")
# Apply defaults for optional variables
context = {**self.optional_variables, **kwargs}
# Render
try:
return self.template.format(**context)
except KeyError as e:
raise ValueError(f"Unknown variable in template: {e}")
def get_variables(self) -> set[str]:
"""Extract all {variable} placeholders from the template."""
return set(re.findall(r'\{(\w+)\}', self.template))
def validate(self) -> list[str]:
"""Validate template consistency."""
errors = []
template_vars = self.get_variables()
declared_vars = set(self.variables) | set(self.optional_variables.keys())
undeclared = template_vars - declared_vars
if undeclared:
errors.append(f"Template uses undeclared variables: {undeclared}")
declared_unused = declared_vars - template_vars
if declared_unused:
errors.append(f"Declared variables not used in template: {declared_unused}")
return errorsBuilding the Library
Python
# Pharmaceutical assistant prompt library
PROMPT_LIBRARY = {
"drug_interaction_analysis": PromptTemplate(
id="drug_interaction_analysis",
name="Drug Interaction Analysis",
description="Analyze a drug-drug interaction for clinical significance and management",
template="""You are a clinical pharmacologist.
Analyze the interaction between {drug_a} and {drug_b}.
Provide:
1. Severity: [major | moderate | minor | contraindicated]
2. Mechanism: [pharmacokinetic | pharmacodynamic | both]
3. Clinical effect: What happens to the patient
4. Onset: When the interaction typically manifests
5. Management: Specific recommended action
6. Monitoring: Parameters to monitor and frequency
{additional_context}
Format as a structured clinical summary. Use precise pharmacological language.""",
variables=["drug_a", "drug_b"],
optional_variables={"additional_context": ""},
version="1.2",
author="pharmacist_team",
tags=["interactions", "clinical", "pharmacokinetics"],
eval_score=0.91,
use_cases=["medication review", "order verification", "patient counseling"],
),
"medication_extraction": PromptTemplate(
id="medication_extraction",
name="Medication Extraction from Clinical Notes",
description="Extract structured medication data from unstructured clinical text",
template="""Extract all medications from the following clinical note.
Return a JSON array. Each medication object must have:
- "name": generic drug name (lowercase)
- "dose": dose with unit (e.g., "5 mg") or null
- "frequency": dosing frequency or null
- "route": route of administration or null
- "indication": why prescribed or null
- "status": "active" | "discontinued" | "prn" | "unknown"
Return ONLY valid JSON, no other text.
Clinical note:
{clinical_text}""",
variables=["clinical_text"],
version="2.1",
author="informatics_team",
tags=["extraction", "json", "medications", "NLP"],
eval_score=0.88,
use_cases=["EHR extraction", "medication reconciliation", "data pipeline"],
),
"dose_adjustment_renal": PromptTemplate(
id="dose_adjustment_renal",
name="Renal Dose Adjustment",
description="Calculate appropriate drug dose given patient's renal function",
template="""You are a clinical pharmacist specializing in renal dosing.
Drug: {drug_name}
Indication: {indication}
Patient eGFR: {egfr} mL/min/1.73m²
Standard dose: {standard_dose}
{additional_patient_context}
Provide:
1. Recommended dose for this eGFR level (reference: KDIGO staging or FDA prescribing information)
2. Rationale for the adjustment
3. Whether the drug should be avoided below a certain eGFR threshold
4. Monitoring parameters
Use evidence-based dose adjustments from published guidelines.""",
variables=["drug_name", "indication", "egfr", "standard_dose"],
optional_variables={"additional_patient_context": ""},
version="1.0",
tags=["dosing", "renal", "pharmacokinetics"],
eval_score=0.85,
use_cases=["renal dosing", "medication adjustment", "CKD management"],
),
"patient_counseling": PromptTemplate(
id="patient_counseling",
name="Patient Medication Counseling",
description="Generate patient-friendly medication counseling content",
template="""Generate patient counseling information for {drug_name}.
The patient:
- Age: {patient_age}
- Education level: {education_level}
- Language preference: {language}
- Indication for the medication: {indication}
Include:
1. What this medication does (in plain language)
2. How to take it correctly
3. What to do if a dose is missed
4. Common side effects to expect
5. Warning signs that need immediate medical attention
6. What NOT to do while taking this medication (foods, activities, other medications to avoid)
Use {reading_level} reading level. Avoid medical jargon. If jargon is necessary, define it immediately.""",
variables=["drug_name", "patient_age", "indication"],
optional_variables={
"education_level": "high school",
"language": "English",
"reading_level": "6th grade",
},
version="1.1",
tags=["patient education", "counseling", "plain language"],
use_cases=["discharge counseling", "patient portal content", "medication guides"],
),
}
# Add prompt to library
def add_prompt(template: PromptTemplate) -> None:
errors = template.validate()
if errors:
raise ValueError(f"Template validation failed: {errors}")
PROMPT_LIBRARY[template.id] = template
print(f"Added prompt: {template.id} v{template.version}")Using the Library
Python
from openai import OpenAI
client = OpenAI()
def run_prompt(
prompt_id: str,
model: str = "gpt-4o",
temperature: float = 0,
**variables,
) -> dict:
"""Render and execute a prompt from the library."""
if prompt_id not in PROMPT_LIBRARY:
raise KeyError(f"Prompt not found: {prompt_id}. Available: {list(PROMPT_LIBRARY.keys())}")
template = PROMPT_LIBRARY[prompt_id]
rendered = template.render(**variables)
response = client.chat.completions.create(
model=model,
messages=[{"role": "user", "content": rendered}],
temperature=temperature,
)
return {
"prompt_id": prompt_id,
"prompt_version": template.version,
"model": model,
"output": response.choices[0].message.content,
"usage": {
"input_tokens": response.usage.prompt_tokens,
"output_tokens": response.usage.completion_tokens,
},
}
# Use a library prompt
result = run_prompt(
"drug_interaction_analysis",
drug_a="warfarin",
drug_b="clarithromycin",
additional_context="Patient has stable AFib and is starting clarithromycin for pneumonia.",
)
print(f"Using prompt: {result['prompt_id']} v{result['prompt_version']}")
print(result["output"])Prompt Composition
Build complex prompts from simpler library components:
Python
@dataclass
class CompositePrompt:
"""A prompt built from multiple library components."""
components: list[str] # List of prompt IDs to compose
combination_strategy: str = "sequential" # or "parallel"
def compose(self, **all_variables) -> str:
"""Combine prompt components into a single prompt."""
parts = []
for component_id in self.components:
template = PROMPT_LIBRARY[component_id]
# Extract only the variables this component needs
component_vars = {k: v for k, v in all_variables.items()
if k in template.variables or k in template.optional_variables}
parts.append(template.render(**component_vars))
return "\n\n---\n\n".join(parts)
# Example: compose an analysis + counseling prompt
def generate_clinical_summary(drug_name: str, patient_context: dict) -> str:
# Build a combined analysis
interaction_analysis = run_prompt(
"drug_interaction_analysis",
drug_a=drug_name,
drug_b=patient_context.get("current_medication", "aspirin"),
)
counseling = run_prompt(
"patient_counseling",
drug_name=drug_name,
patient_age=patient_context.get("age", "65"),
indication=patient_context.get("indication", "cardiovascular disease"),
)
return {
"interaction_analysis": interaction_analysis["output"],
"patient_counseling": counseling["output"],
}Prompt Search and Discovery
Python
def search_prompts(
query: str = "",
tags: list[str] = None,
min_eval_score: float = 0.0,
) -> list[PromptTemplate]:
"""Search the prompt library."""
results = []
for prompt in PROMPT_LIBRARY.values():
# Tag filter
if tags and not any(t in prompt.tags for t in tags):
continue
# Eval score filter
if prompt.eval_score and prompt.eval_score < min_eval_score:
continue
# Text search
if query:
searchable = f"{prompt.name} {prompt.description} {' '.join(prompt.tags)}".lower()
if not any(word.lower() in searchable for word in query.split()):
continue
results.append(prompt)
return sorted(results, key=lambda p: p.eval_score or 0, reverse=True)
# Find prompts for drug interactions
interaction_prompts = search_prompts(tags=["interactions"], min_eval_score=0.8)
print("Matching prompts:")
for p in interaction_prompts:
score = f" (eval: {p.eval_score:.0%})" if p.eval_score else ""
print(f" {p.id} v{p.version}{score}: {p.description}")Exporting and Sharing
Python
import json
def export_library(path: str) -> None:
"""Export prompt library to JSON for sharing with team."""
library_data = {}
for prompt_id, template in PROMPT_LIBRARY.items():
library_data[prompt_id] = {
"id": template.id,
"name": template.name,
"description": template.description,
"template": template.template,
"variables": template.variables,
"optional_variables": template.optional_variables,
"version": template.version,
"author": template.author,
"tags": template.tags,
"eval_score": template.eval_score,
"use_cases": template.use_cases,
}
with open(path, "w") as f:
json.dump(library_data, f, indent=2)
print(f"Exported {len(library_data)} prompts to {path}")
def import_library(path: str) -> None:
"""Import prompt library from JSON."""
with open(path) as f:
data = json.load(f)
for prompt_id, prompt_data in data.items():
template = PromptTemplate(**prompt_data)
errors = template.validate()
if errors:
print(f"Warning: {prompt_id} has validation errors: {errors}")
else:
PROMPT_LIBRARY[prompt_id] = template
print(f"Imported {len(data)} prompts")
# Version control: store library JSON in Git
# Review prompt changes in PRs the same way you review code changesFound this helpful?
Leave a comment
Have a question, correction, or just found this helpful? Leave a note below.