AI Automation of Presentation Preparation
Preparing a pitch or report presentation takes 4–8 hours for designer and 2–3 hours for analyst. An AI system generates structure, slide text, selects illustrations, and assembles ready PPTX or Google Slides in 5–15 minutes from brief or dataset.
Presentation Structure and Content Generator
from openai import AsyncOpenAI
from dataclasses import dataclass
import json
client = AsyncOpenAI()
@dataclass
class PresentationBrief:
title: str
purpose: str # pitch, report, educational, sales, internal
audience: str # investors, clients, board, employees, students
slides_count: int # desired number of slides
key_messages: list[str]
data_points: list[dict] = None # {"metric": "...", "value": "...", "context": "..."}
company_context: str = ""
duration_minutes: int = 15
style: str = "professional" # professional, minimal, bold, corporate
async def generate_presentation_structure(brief: PresentationBrief) -> dict:
response = await client.chat.completions.create(
model="gpt-4o",
messages=[{
"role": "system",
"content": f"""You are a presentation strategist and storyteller.
Create presentation structure for audience: {brief.audience}.
Purpose: {brief.purpose}. Duration: {brief.duration_minutes} min (~{brief.duration_minutes // brief.slides_count * 60} sec/slide).
PRINCIPLES:
- One slide = one idea
- Slide headline = conclusion, not topic ("Revenue grew 40%" instead of "Financial Results")
- Opening: hook — not "hello, my name is..."
- Closing: concrete next step for audience
For each slide:
- slide_type: title, problem, data, solution, case_study, timeline, cta
- headline: conclusion headline
- key_points: 2–3 thesis
- visual_suggestion: what to illustrate
- speaker_notes: 2–3 sentences for speaker
Return JSON: {{slides: [...]}}"""
}, {
"role": "user",
"content": f"""
Topic: {brief.title}
Key messages: {', '.join(brief.key_messages)}
Data: {json.dumps(brief.data_points or [], ensure_ascii=False)}
Company context: {brief.company_context}
Number of slides: {brief.slides_count}
"""
}],
response_format={"type": "json_object"}
)
return json.loads(response.choices[0].message.content)
Slide Illustration Generation
async def generate_slide_visual(
slide_type: str,
headline: str,
data_points: list = None,
style: str = "professional"
) -> str:
"""Return either DALL-E prompt or chart type for Chart.js"""
CHART_SLIDES = {"data", "timeline", "comparison"}
if slide_type in CHART_SLIDES and data_points:
# For data slides — generate chart spec
response = await client.chat.completions.create(
model="gpt-4o",
messages=[{
"role": "system",
"content": "Create Chart.js configuration for data visualization on slide. Return JSON with type, data, options."
}, {
"role": "user",
"content": f"Data: {json.dumps(data_points, ensure_ascii=False)}\nSlide headline: {headline}"
}],
response_format={"type": "json_object"}
)
return json.loads(response.choices[0].message.content)
# For others — image generation prompt
style_map = {
"professional": "clean corporate illustration, flat design, blue palette",
"minimal": "minimalist line art, monochrome, white background",
"bold": "bold graphic design, high contrast, modern typography"
}
return f"{headline}, {style_map.get(style, style_map['professional'])}, presentation slide visual, 16:9"
PPTX Assembly via python-pptx
from pptx import Presentation
from pptx.util import Inches, Pt, Emu
from pptx.dml.color import RGBColor
from pptx.enum.text import PP_ALIGN
import io
class PresentationBuilder:
def __init__(self, theme: dict):
self.prs = Presentation()
self.prs.slide_width = Emu(9144000) # 16:9 widescreen
self.prs.slide_height = Emu(5143500)
self.theme = theme
def add_content_slide(self, headline: str, key_points: list[str], notes: str = "") -> None:
layout = self.prs.slide_layouts[1] # Title and Content
slide = self.prs.slides.add_slide(layout)
# Headline
title = slide.shapes.title
title.text = headline
title.text_frame.paragraphs[0].font.size = Pt(28)
title.text_frame.paragraphs[0].font.color.rgb = RGBColor(*self.theme["primary"])
# Content
body = slide.placeholders[1]
tf = body.text_frame
tf.clear()
for point in key_points:
p = tf.add_paragraph()
p.text = point
p.font.size = Pt(18)
p.level = 0
# Speaker notes
if notes:
notes_slide = slide.notes_slide
notes_slide.notes_text_frame.text = notes
def save(self) -> bytes:
buf = io.BytesIO()
self.prs.save(buf)
return buf.getvalue()
Full Pipeline
async def create_presentation(brief: PresentationBrief) -> bytes:
# 1. Generate structure
structure = await generate_presentation_structure(brief)
# 2. Generate visuals in parallel
visual_tasks = [
generate_slide_visual(s["slide_type"], s["headline"], brief.data_points, brief.style)
for s in structure["slides"]
]
import asyncio
visuals = await asyncio.gather(*visual_tasks)
# 3. Assemble PPTX
builder = PresentationBuilder(theme={"primary": (67, 97, 238)})
for slide_data, visual in zip(structure["slides"], visuals):
builder.add_content_slide(
headline=slide_data["headline"],
key_points=slide_data["key_points"],
notes=slide_data.get("speaker_notes", "")
)
return builder.save()
Export to Google Slides
Via Google Slides API system creates presentation in corporate account: uploads generated content, applies company Slides Theme, shares by email. For companies working in Google Workspace, this is more convenient than PPTX generation.
Automation Options:
- Webhook from Notion/Confluence → presentation generation from page template
- Weekly reports from BI systems (Metabase, Grafana) → slides with current data
- Pitch deck from one-page brief in 10 minutes
Presentation generator with PPTX export and 3 themes — 2–3 weeks. Platform with Google Slides integration, industry template base, and auto-scheduled reports — 6–8 weeks.







