Generative AI·July 21, 2026·4 min read

Prompting Best Practices

Prompt engineering is the practice of designing inputs to an LLM to reliably get the outputs you want — it's often the fastest way to improve AI behavior before reaching for fine-tuning.

generative-aipromptingprompt-engineeringllm

Prompt engineering is the practice of crafting inputs to an LLM to reliably produce the outputs you want. A well-designed prompt is the difference between a model that occasionally does what you need and one that consistently does it. If Cartara flagged this in your diff, you're likely writing or modifying a system prompt, adding few-shot examples, or structuring inputs for a pipeline that calls an LLM API.

Foundational Principles

Be specific about the task. Vague instructions produce vague outputs. The more precisely you describe what you want, the more reliably you get it.

  • Weak: "Write something about climate change."
  • Strong: "Write a 200-word executive summary of the economic risks of climate change for a CFO audience, focusing on supply chain and insurance exposure."

Describe the output, not just the input. Tell the model what the result should look like — format (JSON, markdown table, bullet list), length (one sentence, 300 words), tone (formal, casual, technical), and audience (software engineer, board member).

Use positive instructions. Models follow positive instructions more reliably than prohibitions. Instead of "Don't use jargon," write "Use plain language accessible to a non-technical reader."

Prompt Structure

A well-structured prompt typically contains some combination of:

  1. Role / Persona — who the model should behave as
  2. Context — background the model needs
  3. Task — what you want it to do
  4. Input — the data to work with
  5. Output format — how the result should be structured
  6. Constraints — length, tone, restrictions

Not every prompt needs all six, but complex tasks benefit from being explicit about each.

You are a senior technical writer at a software company.

Context: We're releasing a new API endpoint for user authentication.
The audience is external developers familiar with REST APIs.

Task: Write release notes for the endpoint described below.

Input: {{endpoint_spec}}

Format: Markdown. Include a one-sentence summary, a "What's New" section,
and a "Breaking Changes" section (write "None" if none).

Constraints: Max 150 words. No marketing language.

Few-Shot Examples

Examples are one of the most reliable ways to shape model behavior. Showing the model what good output looks like often beats describing it.

Classify the sentiment of each review as positive, negative, or neutral.

Review: "The product arrived quickly and works perfectly."
Sentiment: positive

Review: "Doesn't do what the description says."
Sentiment: negative

Review: "{{new_review}}"
Sentiment:

Aim for 2–5 examples. More than that yields diminishing returns and adds token cost.

Chain-of-Thought Prompting

For complex reasoning tasks, asking the model to think step by step before answering improves accuracy significantly.

Zero-shot CoT: Add "Think step by step." or "Reason through this carefully before answering."

Few-shot CoT: Include examples that show the reasoning process, not just the answer.

Use chain-of-thought for multi-step problems, math, and logic. Skip it for simple classification or lookup tasks — it costs tokens without improving results.

System Prompts vs. User Prompts

Most LLM APIs separate the system prompt (instructions, persona, context) from the user prompt (the actual input). Use this deliberately:

System PromptUser Prompt
Persona and roleThe task or question
Persistent instructionsVariable input
Output format rulesThe data to process
Constraints and guardrailsUser-specific context

Keep the system prompt stable and reusable. Keep the user prompt focused on the current input. This also makes prompt caching more effective — consistent system prompts can be cached and reused across requests.

What You'll See in Your Code

A typical API call with a structured system prompt:

response = client.messages.create(
    model="claude-sonnet-4-5",
    max_tokens=1024,
    system="""You are a plain-language editor. Your job is to rewrite 
technical content so a non-technical reader can understand it. 
Always use short sentences and active voice. Maximum 150 words.""",
    messages=[
        {"role": "user", "content": f"Rewrite this:\n\n{technical_text}"}
    ]
)

For structured output, be explicit and use the model's native features where available — see Structured Outputs.

Iteration and Refinement

Start simple, add complexity. Begin with the minimal prompt that could work. Add constraints and examples only when the simple version fails in specific ways. Over-engineered prompts are harder to maintain and can introduce contradictions.

Diagnose failures specifically:

  • Wrong format → add format instructions or examples
  • Wrong tone → add persona or tone guidance
  • Missing information → provide the information in context
  • Hallucinated facts → ground with retrieved data (see RAG - Retrieval-Augmented Generation)
  • Too long/short → add explicit length constraints

Version your prompts. Treat prompts like code. Track changes, document why changes were made. Model updates can change how a prompt behaves even if you didn't change the prompt.

Common Mistakes

  • Assuming the model knows what you mean. It doesn't. Be explicit.
  • Contradictory instructions. "Be concise but comprehensive" is ambiguous — resolve it before prompting.
  • Ignoring output format. If you don't specify format, you'll get prose when you needed JSON.
  • Chasing perfection with longer prompts. More words often adds noise. The fix is usually more precision, not more length.
  • Relying on training knowledge for facts. Ground the model with retrieved or provided data for anything factual, current, or proprietary.
  • Not testing on real inputs. Prompts that work on toy examples often fail on real, messy data.

Advanced Techniques

Prompt chaining — break complex tasks into a sequence of simpler prompts, each feeding the next. More reliable than a single mega-prompt for multi-stage tasks.

Self-consistency — run the same prompt multiple times and take a majority vote. Reduces variance on reasoning tasks. Expensive but useful for high-stakes outputs.

Meta-prompting — ask the model to generate or improve a prompt for a given task. Useful for bootstrapping new prompts quickly.

Related concepts

Structured Outputs
Structured outputs are techniques for getting LLMs to reliably produce machine-parseable data like JSON — essential for any pipeline that needs to process model responses programmatically.
Evaluating LLM Outputs
How to build evaluation systems for LLM-powered features — covering human eval, automated checks, LLM-as-judge, eval datasets, and regression prevention.
RAG — Retrieval-Augmented Generation
RAG gives an LLM access to specific knowledge at query time by retrieving relevant documents and passing them as context — without retraining the model.

Turn shipping into understanding

Cartara measures what your team actually learns from every AI coding session.

Join the waitlist