Community content. Review instructions before giving them to an AI agent — treat modules like open-source code.
Prompt Template Rules
Rules for building reusable LLM prompt templates: variable delimiting, system/user separation, input escaping, versioning, few-shot examples as data, edge-case testing, and output format contracts.
Mby @markdownersPublished August 21, 2026 · ~4 min read
0 downloads · Used by 0 stacks
A prompt template is code, not a saved string — it has inputs, a contract for its output, and failure modes that need testing, exactly like a function. Treat it with the same rigor: version it, test its edge cases, and never let unescaped user input change its structure.
Variables clearly delimited
- Mark every variable slot with an unambiguous delimiter (
{{variable_name}}or equivalent) that can't collide with natural prompt text — a bare{name}risks colliding with literal braces the template author writes elsewhere, especially in templates that include code or JSON examples. - Name variables for what they semantically hold (
{{customer_complaint}}, not{{input}}or{{x}}) — a template with generic variable names becomes unmaintainable once it has more than two or three slots. - Fail loudly (throw, don't silently render an empty string) when a required variable is missing at render time — a template that silently renders
{{customer_name}}as blank instead of erroring produces broken output that looks superficially fine.
System vs user content separation
- Keep instructions (what the model should do, its role, constraints) in the system message and keep the variable content being acted on (the document, the user's message, the data to transform) in the user message — collapsing everything into one big user-message string makes it harder for the model to distinguish "instruction" from "content to process."
- Never let variable content leak into the system message — the system message should be static instruction text with at most stable configuration values, not a place where per-request user data gets interpolated.
Escaping user input in templates
- Treat every variable populated from user input as untrusted: strip or escape sequences that look like prompt instructions (e.g. "ignore previous instructions", role-switch markers, delimiter characters the template itself uses) before interpolation, especially when the variable's content will be echoed into a system-level or high-trust position.
- Wrap untrusted variable content in an explicit delimiter (XML-style tags or a clearly marked block) inside the prompt, and instruct the model explicitly to treat content inside that delimiter as data, not instructions — this is a mitigation, not a guarantee, but it meaningfully reduces prompt injection surface.
- Never concatenate raw user input directly into a prompt string with no delimiter or escaping — this is the single most common cause of prompt injection in production LLM applications.
Versioning templates
- Version every template explicitly (a version number or content hash stored alongside logged completions) — when output quality regresses, the first question is always "did the template change," and without versioning that question is unanswerable after the fact.
- Never edit a live template in place for anything beyond a trivial typo fix — ship a new version, compare its outputs against the old version's on a fixed test set, and only then roll it forward.
- Log which template version produced each completion in production, not just the final rendered prompt — the rendered prompt alone doesn't tell you which template family it came from once several templates share similar wording.
Few-shot examples as data, not prose
- Store few-shot examples as structured data (a list of input/output pairs) separate from the template's instruction text, and render them into the prompt programmatically — hand-written examples baked directly into prose drift out of sync with the current output format contract and are hard to update independently.
- Keep few-shot examples representative of the real input distribution, including at least one example near a known edge case — examples that are all easy, canonical cases don't teach the model how to handle the inputs that actually cause failures.
Testing templates with edge-case inputs
- Build a fixed test set of edge-case inputs (empty string, very long input, input containing the template's own delimiter syntax, input in an unexpected language, adversarial injection attempts) and run it against every new template version before shipping.
- Test with realistic messy input, not just clean examples — real user input has typos, partial sentences, and unexpected formatting that a template tested only on tidy examples will mishandle in production.
Documenting expected output format
- State the exact expected output format (JSON schema, specific fields, plain text with a defined structure) explicitly in the template's instructions, not left implicit for the model to infer from examples alone.
- Validate the model's output against that format contract at runtime (schema validation, not just "looks reasonable") and have a defined fallback (retry with an error hint, or a structured failure) for when it doesn't conform — an LLM will occasionally violate even an explicit format contract, and the calling code must not assume perfect compliance.
Badge
Link back to this module from your own README.
[](https://markdowners.com/m/markdowners/prompt-template-rules)Discussions about this module
No discussions about this module yet.
Start a discussion
Comments (0)
Sign in to comment. Sign in
No comments yet. Be the first to add one.