Prompt Structure
A production prompt usually combines several layers:
- System message - role, policies, output format, safety rules
- Context - retrieved documents, user profile, tool results
- User message - the actual task or question
- Few-shot examples - optional demonstrations of desired input-output pairs
Clarity beats cleverness. Explicit instructions ("respond in JSON", "cite sources by ID", "refuse if unsure") outperform vague requests. Chat templates wrap these pieces with model-specific tokens; never hand-craft separators that fight the tokenizer template.
messages = [
{"role": "system", "content": "Answer only from provided context. Cite [id]. Refuse if unsure."},
{"role": "user", "content": f"Context:\n{retrieved_chunks}\n\nQuestion: {query}"},
]
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=messages,
temperature=0.2,
max_tokens=512,
response_format={"type": "json_object"},
)
Reasoning Techniques
Chain-of-thought (CoT)
Asking the model to reason step by step before answering improves performance on math, logic, and multi-hop questions. Variants include zero-shot CoT ("think step by step") and few-shot CoT with worked examples in the prompt.
Structured decomposition
Break complex tasks into stages: plan, retrieve, draft, verify. Each stage can be a separate LLM call with a narrower prompt, reducing error compounding in one shot.
Self-consistency
Sample multiple reasoning paths at higher temperature and majority-vote the final answer. Trades compute for reliability on hard problems.
Sampling Parameters
- Temperature - scales logits before softmax; low (0-0.3) for deterministic extraction, higher for creative writing
- Top-p (nucleus) - sample from the smallest set of tokens whose cumulative probability exceeds p
- Top-k - restrict to k highest-probability tokens
- Max tokens - cap completion length to control cost and rambling
- Stop sequences - halt generation at delimiters (e.g., end of JSON object)
Output Format Control
Structured outputs reduce parsing failures in downstream code:
- JSON mode or schema-constrained decoding where the API supports it
- Grammar-guided generation (GBNF, outlines) for open models
- Retry with repair prompts when validation fails
- Separate "thinking" and "answer" sections with clear markers for extraction
Always validate LLM JSON with a strict parser. Models hallucinate keys and slip out of schema under edge inputs.
Prompt Injection and Defensive Design
Prompt injection embeds adversarial instructions in untrusted content (emails, web pages, user uploads) that override system intent. Defenses layer together:
- Treat retrieved text as data, not instructions (delimiter fencing, "untrusted context" labels)
- Output filtering and tool permission scopes
- Separate models for classification vs generation
- Human approval for high-impact tool actions
No single prompt trick is foolproof. Security is architectural, not cosmetic wording.
Iteration and Versioning
Prompts are code. Store them in version control, A/B test changes against eval sets, and log prompt hashes with responses in production. Regression in prompt v2 often comes from subtle example ordering or whitespace changes that alter tokenization.
Automated prompt optimization (DSPy, evolutionary search) can tune few-shot sets, but human review remains important for safety-critical policies.