

System Prompts for AI Presentation Agents: A Developer's Guide (2026)
System prompts for AI presentation agents are different from user prompts — they encode the agent's role, constraints, and output contract rather than the specific task. A well-crafted system prompt turns a general LLM into a reliable slide-generation agent: consistent voice, predictable structure, and callable tool use. This developer guide covers the 7-section system prompt template used in production by 2Slides' own agent pipeline, a ready-to-paste system prompt for building a slide agent with Claude, GPT-4o, or DeepSeek, the three anti-patterns that produce unreliable output, and how to integrate a system prompt with the 2Slides V1 API (generate, create-pdf-slides, create-like-this, generate-narration, jobs/:id, themes/search). The guide ends with three worked examples: a pitch-deck agent that converts founder notes into investor decks, a board-deck agent that formats quarterly metrics for executive audiences, and an ingestion agent that converts PDFs to presentations.
If you are building a chatbot, a coding assistant that ships slide output, or an internal tool that automates reporting, the difference between a demo and production is almost entirely in the system prompt. This guide is written for the developer audience: no marketing fluff, real code, real endpoints.
System Prompts vs User Prompts: What's the Actual Difference?
A user prompt is the task. A system prompt is the operating manual.
When a product manager types "make me 10 slides about Q3 revenue," that is a user prompt. When your agent consistently returns valid JSON, never exceeds your slide budget, always cites sources in speaker notes, and calls the create-pdf-slides endpoint when the user uploads a file — that behavior comes from the system prompt.
In the OpenAI, Anthropic, and Google APIs, the system prompt is a separate field (system in Anthropic, system role in OpenAI chat completions, systemInstruction in Gemini). Models are trained to weight it higher than user turns and to treat it as non-overridable by later messages. That makes it the right place for:
- Role definition — what kind of agent this is
- Output contracts — JSON schema, markdown format, or tool-call shape
- Hard constraints — word limits, tone rules, forbidden content
- Tool/API inventory — which functions are callable and when
- Escalation rules — when to refuse, ask for clarification, or hand off
User prompts that try to encode all of this break the moment the user's task text gets long. System prompts survive every turn.
The 7-Section System Prompt Template
Every reliable slide-generation agent we have shipped or audited at 2Slides uses some variant of this seven-section structure. The order matters — LLMs weight earlier instructions more heavily, so role and contract come first, worked examples come last.
- Identity & Role — one-paragraph description of who the agent is and what it does
- Output Contract — exact schema or format the agent must return
- Hard Constraints — non-negotiable rules (length, tone, forbidden patterns)
- Tool Inventory — each available API or function, with when-to-call guidance
- Reasoning Policy — how the agent should think (chain-of-thought, self-check, escalation)
- Failure Handling — what to do when input is ambiguous, malformed, or off-topic
- Worked Examples — two to four complete input/output pairs demonstrating correct behavior
The template is deliberately opinionated. When we audit agents that misbehave in production, the cause is almost always a missing section rather than a bad one. Agents without a tool inventory hallucinate endpoints. Agents without a failure handling section make up data when inputs are thin. Agents without worked examples drift tone over long conversations.
Production-Ready System Prompt (Copy-Pasteable)
Here is the full template, filled in for a slide-generation agent that uses the 2Slides V1 API as its backend. Paste this into the system field of Claude, GPT-4o, DeepSeek, Gemini, or any OpenAI-compatible endpoint.
# Identity & Role
You are SlideAgent, a presentation-generation assistant. Your job is to take
unstructured user input (notes, transcripts, PDFs, raw data) and return a
structured slide deck specification that can be rendered by the 2Slides V1 API.
You are not a general-purpose chatbot. You do not answer trivia, write code,
or hold long conversations. You produce slide decks, then stop.
# Output Contract
For every user turn that describes a deck to be built, you MUST output a single
JSON object matching this schema:
{
"title": string, // 3-10 words, title case
"audience": string, // e.g. "series-a investors", "exec staff"
"tone": "formal" | "conversational" | "technical",
"slide_count": integer, // 5 <= n <= 40
"language": string, // ISO 639-1 code, default "en"
"theme_hint": string, // free-text, will be passed to themes/search
"slides": [
{
"layout": "title" | "content" | "two-column" | "quote" | "chart" | "image",
"heading": string, // <= 12 words
"bullets": string[], // 0-5 items, each <= 18 words
"speaker_notes": string, // 30-80 words, full sentences
"image_prompt": string?, // optional, for image layouts
"chart_data": object? // optional, for chart layouts
}
],
"api_call": {
"endpoint": "generate" | "create-pdf-slides" | "create-like-this",
"reasoning": string // one sentence: why this endpoint
}
}
No prose before or after the JSON. No markdown fences around the JSON. If
the user asks a question that is not a deck request, return:
{ "error": "not_a_deck_request", "suggestion": string }
# Hard Constraints
- Never exceed 40 slides. If the user asks for more, cap at 40 and note it in
speaker_notes of slide 1.
- Every slide must have speaker_notes. Empty speaker_notes is a bug.
- Bullets must be parallel grammatically (all start with verb, or all noun
phrases — never mixed).
- Do not invent statistics. If the user did not provide a number, do not
write one. Use "[source needed]" as a placeholder.
- Do not include contact information, phone numbers, or email addresses
unless the user explicitly provided them.
- Titles are title case. Bullets are sentence case. No ALL CAPS.
- Refuse to produce content that is defamatory, or that makes medical,
legal, or financial claims the user did not source.
# Tool Inventory (2Slides V1 API)
You may direct the calling code to invoke these endpoints. You do not call
them yourself; you name them in the "api_call" field.
- generate — Default. Text-in, deck-out. Use for most requests.
- create-pdf-slides — When the user uploaded or pasted a PDF URL.
Pass the PDF URL in the user prompt.
- create-like-this — When the user said "like my last deck" or provided
a reference deck URL. Reuses theme + structure.
- generate-narration — After a deck is built, to add TTS voiceover to
each slide. Only call when user asks for video
or narration explicitly.
- download-slides-pages-voices — Batch download rendered pages and audio.
Call at the end of a video workflow.
- jobs/:id — Poll for async job status. The calling code
handles polling; you do not.
- themes/search — Find a theme by keyword. Your "theme_hint" field
will be passed here by the calling code.
# Reasoning Policy
Before emitting JSON, think step by step inside <thinking> tags:
1. Parse the user input. What is the actual deck about?
2. Identify the audience. Investors? Engineers? Board? Sales team?
3. Choose slide_count based on content density, not user flattery.
4. Select endpoint: generate (default) | create-pdf-slides | create-like-this.
5. Draft the outline, then self-check: are bullets parallel? Are numbers sourced?
After </thinking>, emit the JSON object. Do not include the thinking in the
final output — the calling code strips <thinking> blocks before rendering.
# Failure Handling
- Ambiguous topic: ask ONE clarifying question in the "suggestion" field of an
error response. Do not ask multiple questions.
- Malformed input (user pasted gibberish): return
{ "error": "unintelligible_input", "suggestion": "..." }.
- Conflicting instructions (user wants 50 slides in 5 minutes): honor the
hard constraint (max 40) and note the conflict in slide 1 speaker_notes.
- PDF URL that looks invalid: still emit the JSON with api_call =
create-pdf-slides; the backend will return a clear error if the URL
cannot be fetched.
# Worked Examples
## Example 1: Minimal input
User: "make me a deck about our Q3 revenue, we hit $4.2M, up 30% YoY,
audience is the board"
<thinking>
Board audience -> formal tone. Revenue deck -> 8-12 slides is standard.
Numbers are sourced (user provided them). Endpoint: generate.
</thinking>
{
"title": "Q3 Revenue Review",
"audience": "board of directors",
"tone": "formal",
"slide_count": 10,
"language": "en",
"theme_hint": "minimal corporate finance",
"slides": [
{ "layout": "title", "heading": "Q3 Revenue Review",
"bullets": [], "speaker_notes": "Opening slide. ..." },
...
],
"api_call": { "endpoint": "generate",
"reasoning": "Text-only input, no reference deck or PDF." }
}
## Example 2: PDF ingestion
User: "turn this whitepaper into a 12-slide summary for engineers:
https://example.com/whitepaper.pdf"
<thinking>
PDF URL present -> create-pdf-slides. Engineer audience -> technical tone.
User specified 12 slides -> honor it.
</thinking>
{
"title": "Whitepaper Summary",
"audience": "software engineers",
"tone": "technical",
"slide_count": 12,
"language": "en",
"theme_hint": "technical documentation dark",
"slides": [ ... ],
"api_call": { "endpoint": "create-pdf-slides",
"reasoning": "User supplied PDF URL." }
}
## Example 3: Not a deck request
User: "what is the capital of France?"
{ "error": "not_a_deck_request",
"suggestion": "I build slide decks. Try: 'make a 5-slide briefing on France'." }The prompt above is roughly 1,800 tokens. That is the ceiling we recommend — anything longer starts to crowd out the user's actual input on models with 8k or 16k context windows. For 200k-context models you can safely expand the worked examples to cover more edge cases.
Integrating with the 2Slides V1 API
The system prompt names endpoints; the calling code invokes them. Here is what each endpoint does and when your agent should reach for it.
POST /api/v1/slides/generate— The workhorse. Accepts a text prompt plus optional structured hints (slide count, language, theme ID) and returns a job ID. Ninety percent of agent traffic hits this endpoint.POST /api/v1/slides/create-pdf-slides— Accepts a PDF URL and converts it to a deck. Use when the user uploads a document. Handles extraction, chunking, and summarization server-side so your agent does not need a PDF parser.POST /api/v1/slides/create-like-this— Accepts a reference deck URL or ID and a new topic. Reuses the visual theme and structural rhythm of the reference. Use for "make it look like our last board deck" workflows.POST /api/v1/slides/generate-narration— Adds TTS voiceover to an existing deck. Returns per-slide audio URLs. Chain it aftergeneratewhen the downstream output is a video.GET /api/v1/slides/download-slides-pages-voices— Batch endpoint that returns rendered page images and narration audio in one response. Use in the final step of a video-export pipeline.GET /api/v1/jobs/:id— Polling endpoint. Your agent does not call this; your calling code does. Returnspending,processing,success, orfailedplus the final deck URL on completion.GET /api/v1/themes/search?query=...— Keyword search across the public theme library. Pass thetheme_hintfield from your system-prompt output here to resolve it to a concrete theme ID before callinggenerate.
A complete agent loop looks like this in pseudocode:
const completion = await llm.messages.create({
system: SYSTEM_PROMPT, // the 7-section template above
messages: [{ role: "user", content: userInput }],
});
const spec = JSON.parse(stripThinking(completion.content));
if (spec.error) return handleError(spec);
const theme = await fetch(`/api/v1/themes/search?query=${spec.theme_hint}`);
const job = await fetch(`/api/v1/slides/${spec.api_call.endpoint}`, {
method: "POST",
body: JSON.stringify({ ...spec, themeId: theme.id }),
});
const result = await pollJob(job.id); // hits /api/v1/jobs/:id
return result.deckUrl;If you are new to the API shape, the developer guide for building an AI presentation agent walks through the full flow with working TypeScript. For a higher-level skill-based architecture — where the system prompt is just one skill among several — see the AI slide agent skills overview.
3 Anti-Patterns That Break Slide Agents
After reviewing dozens of production agents — from internal analytics tools to public-facing sales copilots — the same three failure modes show up over and over.
Anti-Pattern 1: The Unbounded Output Contract
Symptom: Agent sometimes returns JSON, sometimes markdown, sometimes a polite paragraph. Your parser throws SyntaxError: Unexpected token once every 50 requests.
Cause: The system prompt says "return a slide deck" without specifying the exact shape, or it specifies a shape but allows prose around it.
Fix: Write the schema in the system prompt. Say explicitly: "No prose before or after the JSON. No markdown fences around the JSON." Then run every output through a validator (Zod, Pydantic, io-ts) and retry on failure. Treat schema compliance as a hard product requirement, not a nice-to-have.
Anti-Pattern 2: Tool Inventory Drift
Symptom: Agent confidently tells the user "I'll call the refine-deck endpoint" — an endpoint that does not exist. The user's deck never arrives.
Cause: The system prompt mentions tools in prose rather than in a structured inventory, so the model hallucinates variations. Or the inventory is out of date after you shipped new endpoints.
Fix: Maintain a single canonical tool inventory in the system prompt, refreshed every time the API changes. If your API has 7 endpoints, list exactly 7, each with one line describing when to call it. Forbid the model from naming anything else — "If none of the endpoints above apply, return api_call: null and escalate."
Anti-Pattern 3: Statistics Hallucination
Symptom: User says "make a deck about our Q3 numbers" without providing numbers. Agent cheerfully writes "Revenue grew 47.3% to $8.2M." The CFO is furious.
Cause: No hard constraint forbids inventing data. The model defaults to plausible-sounding fiction because that is what most LLMs do when under-specified.
Fix: Add an explicit rule: "Do not invent statistics. If the user did not provide a number, use [source needed] as a placeholder." Then scan outputs with a regex or separate LLM check for suspicious specificity. This one rule has caught more customer-escalation-tier bugs in our review than any other.
Worked Example 1: Pitch-Deck Agent
The pitch-deck agent converts founder notes into a 10-slide investor deck. Add these lines to the base system prompt:
# Specialization: Pitch-Deck Mode
When building a pitch deck, use exactly this structure:
1. Title
2. Problem
3. Solution
4. Market size (TAM/SAM/SOM)
5. Product demo / screenshot
6. Traction metrics
7. Business model
8. Competition
9. Team
10. Ask (funding amount + use of funds)
Force slide_count = 10. Force tone = "conversational but confident."
If the user did not provide a number for market size, traction, or ask,
use "[source needed]" — do not invent.Sample input: "B2B SaaS for dental offices, we help them automate insurance claims, have 12 paying customers, raising $1.5M seed."
Sample output (abbreviated): Ten-slide JSON with the fixed structure, api_call.endpoint = "generate", theme_hint = "pitch deck modern gradient", and traction slide showing ["12 paying dental offices", "[source needed] — MRR", "[source needed] — retention"] rather than made-up numbers.
Worked Example 2: Board-Deck Agent
Board decks have a different contract: formal tone, dense tables, zero emoji, specific slide order that CFOs expect. Add:
# Specialization: Board-Deck Mode
Use exactly this structure for board meetings:
1. Executive summary (3 bullets)
2. Financials (revenue, margin, runway)
3. KPI scorecard (table layout)
4. Strategic initiatives (status + risk)
5. Hiring plan
6. Risks & mitigations
7. Asks from the board
Force tone = "formal." Force language to match user locale.
Every number must have a source in speaker_notes.
No image slides — board decks are text and tables.The board-deck agent pairs well with create-like-this when the board has seen previous quarterly decks. Pass the prior deck URL; the new deck inherits the theme and pacing.
Worked Example 3: PDF-to-Deck Ingestion Agent
This agent converts customer whitepapers, research PDFs, or RFPs into digestible summary decks. It is the simplest to build because the 2Slides create-pdf-slides endpoint does most of the heavy lifting.
# Specialization: PDF Ingestion Mode
Trigger: user provides a URL ending in .pdf OR explicitly says
"turn this PDF/whitepaper/report into slides."
Always set api_call.endpoint = "create-pdf-slides".
Set slide_count based on PDF length:
- < 5 pages -> 5 slides
- 5-20 pages -> 8-12 slides
- 20-50 pages -> 15-20 slides
- > 50 pages -> 25-30 slides (cap at 30)
Extract the PDF title for the deck title. If the user specified an
audience different from the PDF's original audience, flag that in
slide 1 speaker_notes so the renderer knows to adapt tone.For agents that live inside Claude Desktop or a similar MCP host, the PDF ingestion flow can be wired up in under an hour — see how to use Claude MCP to generate presentations for the full walkthrough.
Frequently Asked Questions
Should I put the system prompt in code or in a database?
For production agents, put it in version control (as a .md file imported at build time) and tag releases. Database-stored prompts sound flexible but they make rollbacks painful and obscure which prompt produced which output in your logs. If you need per-tenant customization, store tenant-specific overrides in the database and merge them with the base prompt at request time.
How long should a system prompt be?
For slide-generation agents, 1,500 to 2,500 tokens is the sweet spot. Shorter prompts miss constraints and fail on edge cases. Longer prompts crowd out the user's actual input on smaller-context models and often repeat themselves. If you are over 3,000 tokens, audit for redundancy — the same rule is probably stated twice.
Do I need different system prompts for Claude vs GPT-4o vs DeepSeek?
Minor adjustments only. The 7-section template works across all three. Claude responds well to XML-tag scaffolding (<thinking>, <output>). GPT-4o prefers clean markdown with numbered rules. DeepSeek handles both but benefits from more explicit examples. Write one base prompt, then A/B test small format variants per model.
Can I update the system prompt without redeploying?
Yes — and you should be able to, for fast iteration. Store the prompt in an environment variable or a feature-flag service so that SRE can roll back a bad prompt in seconds. Treat a bad prompt like a bad deploy: it is a production incident and it needs the same blast-radius controls.
How do I test a system prompt?
Build a regression set of 50 to 200 input/output pairs that cover your real user distribution: happy-path decks, adversarial inputs, malformed JSON attempts, off-topic requests. Run the full set on every prompt change and score schema compliance plus human-rated quality. This is the single highest-leverage engineering investment for agent reliability.
The Takeaway
A system prompt is infrastructure, not copy. It is the thing that turns a generic LLM into a reliable slide-generation agent with a known output contract, a fixed tool inventory, and predictable failure modes. Developers who treat the system prompt as a product artifact — versioned, tested, monitored — ship agents that survive contact with real users. Developers who treat it as a one-time prompt-engineering exercise ship demos.
The 7-section template and production-ready example in this guide are the starting point, not the endpoint. Fork them, specialize them for your use case, wire them into the 2Slides V1 API, and — most importantly — build the regression harness before you ship. The agents that win in 2026 are the ones whose prompts are engineered with the same rigor as their code.
Ship your slide agent in production — get a 2Slides API key or explore the MCP server.
About 2Slides
Create stunning AI-powered presentations in seconds. Transform your ideas into professional slides with 2slides AI Agent.
Try For Free